# Fix
- Loading card
- Create : saat memilih jam sesuai dengan batas jam di hari itu
## No isuuee
This commit is contained in:
2024-05-23 17:17:40 +08:00
parent 10cf9c3a46
commit 166b1349f5
22 changed files with 484 additions and 400 deletions

View File

@@ -1,13 +1,13 @@
import { Event_StatusPage } from "@/app_modules/event"; import { Event_StatusPage } from "@/app_modules/event";
import { Event_getByStatusId } from "@/app_modules/event/fun/get/get_event_by_status_id"; import { Event_getListByStatusId } from "@/app_modules/event/fun/get/get_list_event_by_status_id";
import { user_getOneUserId } from "@/app_modules/fun_global/get_user_token"; import { user_getOneUserId } from "@/app_modules/fun_global/get_user_token";
export default async function Page() { export default async function Page() {
const authorId = await user_getOneUserId(); const authorId = await user_getOneUserId();
const listPublish = await Event_getByStatusId("1", authorId); const listPublish = await Event_getListByStatusId("1", authorId);
const listReview = await Event_getByStatusId("2", authorId); const listReview = await Event_getListByStatusId("2", authorId);
const listDraft = await Event_getByStatusId("3", authorId); const listDraft = await Event_getListByStatusId("3", authorId);
const listReject = await Event_getByStatusId("4", authorId); const listReject = await Event_getListByStatusId("4", authorId);
return ( return (
<Event_StatusPage <Event_StatusPage

View File

@@ -75,15 +75,15 @@ function DetailRiwayat({ listRiwayat }: { listRiwayat: MODEL_EVENT[] }) {
Peserta Peserta
</Button> </Button>
</td> </td>
<td>{e.title}</td> <td>{e?.Author?.Profile?.name}</td>
<td>{e.lokasi}</td> <td>{e?.title}</td>
<td>{e.EventMaster_TipeAcara.name}</td> <td>{e?.lokasi}</td>
<td>{e.tanggal.toLocaleString("id-ID", { dateStyle: "full" })}</td> <td>{e?.EventMaster_TipeAcara?.name}</td>
<td>{e?.tanggal.toLocaleString("id-ID", { dateStyle: "full" })}</td>
<td> <td>
{e.tanggal.toLocaleTimeString([], { {e.tanggal.toLocaleTimeString([], {
hour: "2-digit", hour: "2-digit",
minute: "2-digit", minute: "2-digit",
hour12: false,
})} })}
</td> </td>
<td> <td>
@@ -121,23 +121,24 @@ function DetailRiwayat({ listRiwayat }: { listRiwayat: MODEL_EVENT[] }) {
<Stack> <Stack>
{peserta?.map((e) => ( {peserta?.map((e) => (
<Stack key={e.id} spacing={"xs"}> <Stack key={e.id} spacing={"xs"}>
<Grid > <Grid>
<Grid.Col span={"content"}> <Grid.Col span={"content"}>
<Avatar <Avatar
sx={{ borderStyle: "solid", borderWidth: "0.5px" }} sx={{ borderStyle: "solid", borderWidth: "0.5px" }}
radius={"xl"} radius={"xl"}
src={ src={
RouterProfile.api_foto_profile + e?.User?.Profile?.imagesId RouterProfile.api_foto_profile +
} e?.User?.Profile?.imagesId
/> }
</Grid.Col> />
<Grid.Col span={"auto"}> </Grid.Col>
<Group align="center" h={"100%"}> <Grid.Col span={"auto"}>
<Text>{e?.User?.Profile?.name}</Text> <Group align="center" h={"100%"}>
</Group> <Text>{e?.User?.Profile?.name}</Text>
</Grid.Col> </Group>
</Grid> </Grid.Col>
<Divider/> </Grid>
<Divider />
</Stack> </Stack>
))} ))}
</Stack> </Stack>
@@ -164,6 +165,9 @@ function DetailRiwayat({ listRiwayat }: { listRiwayat: MODEL_EVENT[] }) {
<th> <th>
<Center>Aksi</Center> <Center>Aksi</Center>
</th> </th>
<th>
<Center>Author</Center>
</th>
<th> <th>
<Center>Judul</Center> <Center>Judul</Center>
</th> </th>

View File

@@ -50,13 +50,13 @@ export default function AdminEvent_Main({
path: RouterAdminEvent.table_review, path: RouterAdminEvent.table_review,
color: "orange", color: "orange",
}, },
{ // {
id: 3, // id: 3,
name: "Draft", // name: "Draft",
jumlah: countDraft, // jumlah: countDraft,
path: "", // path: "",
color: "yellow", // color: "yellow",
}, // },
{ {
id: 4, id: 4,
name: "Reject", name: "Reject",

View File

@@ -72,15 +72,15 @@ function TableStatus({ listPublish }: { listPublish: MODEL_EVENT[] }) {
const TableRows = data.map((e, i) => ( const TableRows = data.map((e, i) => (
<tr key={i}> <tr key={i}>
<td>{e.title}</td> <td>{e?.Author?.Profile?.name}</td>
<td>{e.lokasi}</td> <td>{e?.title}</td>
<td>{e.EventMaster_TipeAcara.name}</td> <td>{e?.lokasi}</td>
<td>{e.tanggal.toLocaleString("id-ID", { dateStyle: "full" })}</td> <td>{e?.EventMaster_TipeAcara?.name}</td>
<td>{e?.tanggal.toLocaleString("id-ID", { dateStyle: "full" })}</td>
<td> <td>
{e.tanggal.toLocaleTimeString([], { {e.tanggal.toLocaleTimeString([], {
hour: "2-digit", hour: "2-digit",
minute: "2-digit", minute: "2-digit",
hour12: false,
})} })}
</td> </td>
<td> <td>
@@ -121,28 +121,34 @@ function TableStatus({ listPublish }: { listPublish: MODEL_EVENT[] }) {
<Title order={3}>Daftar Peserta</Title> <Title order={3}>Daftar Peserta</Title>
</Center> </Center>
<Stack> <Stack>
{peserta?.map((e) => ( {_.isEmpty(peserta) ? (
<Stack key={e.id} spacing={"xs"}> <Center>
<Grid> <Text c={"gray"}>Tidak ada peserta</Text>
<Grid.Col span={"content"}> </Center>
<Avatar ) : (
sx={{ borderStyle: "solid", borderWidth: "0.5px" }} peserta?.map((e) => (
radius={"xl"} <Stack key={e.id} spacing={"xs"}>
src={ <Grid>
RouterProfile.api_foto_profile + <Grid.Col span={"content"}>
e?.User?.Profile?.imagesId <Avatar
} sx={{ borderStyle: "solid", borderWidth: "0.5px" }}
/> radius={"xl"}
</Grid.Col> src={
<Grid.Col span={"auto"}> RouterProfile.api_foto_profile +
<Group align="center" h={"100%"}> e?.User?.Profile?.imagesId
<Text>{e?.User?.Profile?.name}</Text> }
</Group> />
</Grid.Col> </Grid.Col>
</Grid> <Grid.Col span={"auto"}>
<Divider /> <Group align="center" h={"100%"}>
</Stack> <Text>{e?.User?.Profile?.name}</Text>
))} </Group>
</Grid.Col>
</Grid>
<Divider />
</Stack>
))
)}
</Stack> </Stack>
</Stack> </Stack>
</Paper> </Paper>
@@ -163,6 +169,7 @@ function TableStatus({ listPublish }: { listPublish: MODEL_EVENT[] }) {
> >
<thead> <thead>
<tr> <tr>
<th>Author</th>
<th>Judul</th> <th>Judul</th>
<th>Lokasi</th> <th>Lokasi</th>
<th>Tipe Acara</th> <th>Tipe Acara</th>

View File

@@ -90,7 +90,6 @@ function TableStatus({ listReject }: { listReject: MODEL_EVENT[] }) {
{e.tanggal.toLocaleTimeString([], { {e.tanggal.toLocaleTimeString([], {
hour: "2-digit", hour: "2-digit",
minute: "2-digit", minute: "2-digit",
hour12: false,
})} })}
</Box> </Box>
</td> </td>

View File

@@ -75,7 +75,6 @@ function TableStatus({ listReview }: { listReview: MODEL_EVENT[] }) {
{e.tanggal.toLocaleTimeString([], { {e.tanggal.toLocaleTimeString([], {
hour: "2-digit", hour: "2-digit",
minute: "2-digit", minute: "2-digit",
hour12: false,
})} })}
</td> </td>
<td> <td>
@@ -90,7 +89,7 @@ function TableStatus({ listReview }: { listReview: MODEL_EVENT[] }) {
color={"green"} color={"green"}
leftIcon={<IconEyeShare />} leftIcon={<IconEyeShare />}
radius={"xl"} radius={"xl"}
onClick={() => onPublish(e.id, setData)} onClick={() => onPublish(e.id, setData, e.tanggal)}
> >
Publish Publish
</Button> </Button>
@@ -194,7 +193,12 @@ function TableStatus({ listReview }: { listReview: MODEL_EVENT[] }) {
); );
} }
async function onPublish(eventId: string, setData: any) { async function onPublish(eventId: string, setData: any, tanggal: Date) {
if (moment(tanggal).diff(Date.now(), "minutes") < 0)
return ComponentGlobal_NotifikasiPeringatan(
"Waktu acara telah lewat, Report untuk memberitahu user !"
);
await AdminEvent_funEditStatusPublishById(eventId, "1").then(async (res) => { await AdminEvent_funEditStatusPublishById(eventId, "1").then(async (res) => {
if (res.status === 200) { if (res.status === 200) {
await AdminEvent_getListTableByStatusId("2").then((res) => { await AdminEvent_getListTableByStatusId("2").then((res) => {

View File

@@ -1,10 +1,12 @@
"use client"; "use client";
import { RouterEvent } from "@/app/lib/router_hipmi/router_event"; import { RouterEvent } from "@/app/lib/router_hipmi/router_event";
import { Paper, Stack, Group, Title, Text, Grid } from "@mantine/core"; import { Paper, Stack, Group, Title, Text, Grid, Card } from "@mantine/core";
import moment from "moment"; import moment from "moment";
import { MODEL_EVENT } from "../model/interface"; import { MODEL_EVENT } from "../model/interface";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { useState } from "react";
import ComponentGlobal_CardLoadingOverlay from "@/app_modules/component_global/loading_card";
export default function ComponentEvent_BoxListStatus({ export default function ComponentEvent_BoxListStatus({
data, data,
@@ -14,15 +16,22 @@ export default function ComponentEvent_BoxListStatus({
path: string; path: string;
}) { }) {
const router = useRouter(); const router = useRouter();
const [eventId, setEventId] = useState("");
const [visible, setVisible] = useState(false);
return ( return (
<> <>
<Paper <Card
shadow="lg" shadow="lg"
radius={"md"} radius={"md"}
p={"md"} p={"md"}
withBorder withBorder
mb={"sm"} mb={"sm"}
onClick={() => router.push(path + data.id)} onClick={() => {
setEventId(data?.id);
setVisible(true);
router.push(path + data.id);
}}
> >
<Stack> <Stack>
<Grid> <Grid>
@@ -42,7 +51,12 @@ export default function ComponentEvent_BoxListStatus({
{data.deskripsi} {data.deskripsi}
</Text> </Text>
</Stack> </Stack>
</Paper> {visible && eventId !== "" ? (
<ComponentGlobal_CardLoadingOverlay />
) : (
""
)}
</Card>
</> </>
); );
} }

View File

@@ -16,74 +16,73 @@ export default function ComponentEvent_DetailMainData({
const jam = tgl.toLocaleTimeString([], { const jam = tgl.toLocaleTimeString([], {
hour: "2-digit", hour: "2-digit",
minute: "2-digit", minute: "2-digit",
hour12: false,
}); });
return ( return (
<> <>
<Paper withBorder p={"md"} shadow="lg"> <Paper withBorder p={"md"} shadow="lg">
<Stack> <Stack>
<ComponentGlobal_AuthorNameOnHeader <ComponentGlobal_AuthorNameOnHeader
authorName={data.Author.Profile.name} authorName={data.Author.Profile.name}
imagesId={data.Author.Profile.imagesId} imagesId={data.Author.Profile.imagesId}
profileId={data.Author.Profile.id} profileId={data.Author.Profile.id}
/> />
<Stack px={"sm"}> <Stack px={"sm"}>
<Title order={4}>{data ? data.title : null}</Title> <Title order={4}>{data ? data.title : null}</Title>
<Grid> <Grid>
<Grid.Col span={4}> <Grid.Col span={4}>
<Text fw={"bold"} fz={"sm"}>
Lokasi
</Text>
</Grid.Col>
<Grid.Col span={1}>:</Grid.Col>
<Grid.Col span={"auto"}>
<Text>{data ? data.lokasi : null}</Text>
</Grid.Col>
</Grid>
<Grid>
<Grid.Col span={4}>
<Text fw={"bold"} fz={"sm"}>
Tipe Acara
</Text>
</Grid.Col>
<Grid.Col span={1}>:</Grid.Col>
<Grid.Col span={"auto"}>
<Text>{data ? data.EventMaster_TipeAcara.name : null}</Text>
</Grid.Col>
</Grid>
<Grid>
<Grid.Col span={4}>
<Text fw={"bold"} fz={"sm"}>
Tanggal
</Text>
</Grid.Col>
<Grid.Col span={1}>:</Grid.Col>
<Grid.Col span={"auto"}>{hari}</Grid.Col>
</Grid>
<Grid>
<Grid.Col span={4}>
<Text fw={"bold"} fz={"sm"}>
Jam
</Text>
</Grid.Col>
<Grid.Col span={1}>:</Grid.Col>
<Grid.Col span={"auto"}>{jam}</Grid.Col>
</Grid>
<Stack spacing={2}>
<Text fw={"bold"} fz={"sm"}> <Text fw={"bold"} fz={"sm"}>
Lokasi Deskripsi
</Text> </Text>
</Grid.Col> <Spoiler
<Grid.Col span={1}>:</Grid.Col> hideLabel="Lihat sedikit"
<Grid.Col span={"auto"}> maxHeight={50}
<Text>{data ? data.lokasi : null}</Text> showLabel="Lihat banyak"
</Grid.Col> >
</Grid> {data ? data.deskripsi : null}
<Grid> </Spoiler>
<Grid.Col span={4}> </Stack>
<Text fw={"bold"} fz={"sm"}>
Tipe Acara
</Text>
</Grid.Col>
<Grid.Col span={1}>:</Grid.Col>
<Grid.Col span={"auto"}>
<Text>{data ? data.EventMaster_TipeAcara.name : null}</Text>
</Grid.Col>
</Grid>
<Grid>
<Grid.Col span={4}>
<Text fw={"bold"} fz={"sm"}>
Tanggal
</Text>
</Grid.Col>
<Grid.Col span={1}>:</Grid.Col>
<Grid.Col span={"auto"}>{hari}</Grid.Col>
</Grid>
<Grid>
<Grid.Col span={4}>
<Text fw={"bold"} fz={"sm"}>
Jam
</Text>
</Grid.Col>
<Grid.Col span={1}>:</Grid.Col>
<Grid.Col span={"auto"}>{jam}</Grid.Col>
</Grid>
<Stack spacing={2}>
<Text fw={"bold"} fz={"sm"}>
Deskripsi
</Text>
<Spoiler
hideLabel="Lihat sedikit"
maxHeight={50}
showLabel="Lihat banyak"
>
{data ? data.deskripsi : null}
</Spoiler>
</Stack> </Stack>
</Stack> </Stack>
</Stack>
</Paper> </Paper>
</> </>
); );

View File

@@ -36,6 +36,7 @@ import toast from "react-simple-toasts";
import moment from "moment"; import moment from "moment";
import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/component_global/notif_global/notifikasi_peringatan"; import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/component_global/notif_global/notifikasi_peringatan";
import ComponentEvent_ErrorMaximalInput from "../component/error_maksimal_input"; import ComponentEvent_ErrorMaximalInput from "../component/error_maksimal_input";
import ComponentGlobal_InputCountDown from "@/app_modules/component_global/input_countdown";
export default function Event_Create({ export default function Event_Create({
listTipeAcara, listTipeAcara,
@@ -69,13 +70,6 @@ export default function Event_Create({
placeholder="Masukan judul" placeholder="Masukan judul"
withAsterisk withAsterisk
maxLength={100} maxLength={100}
error={
value.title.length >= 100 ? (
<ComponentEvent_ErrorMaximalInput max={100} />
) : (
""
)
}
onChange={(val) => { onChange={(val) => {
setValue({ setValue({
...value, ...value,
@@ -104,13 +98,6 @@ export default function Event_Create({
placeholder="Masukan lokasi acara" placeholder="Masukan lokasi acara"
withAsterisk withAsterisk
maxLength={100} maxLength={100}
error={
value.lokasi.length >= 100 ? (
<ComponentEvent_ErrorMaximalInput max={100} />
) : (
""
)
}
onChange={(val) => { onChange={(val) => {
setValue({ setValue({
...value, ...value,
@@ -146,33 +133,38 @@ export default function Event_Create({
}); });
}} }}
/> />
<Textarea
label="Deskripsi" <Stack spacing={5}>
placeholder="Deskripsikan acara yang akan di selenggarakan" <Textarea
withAsterisk label="Deskripsi"
autosize placeholder="Deskripsikan acara yang akan di selenggarakan"
maxLength={200} withAsterisk
error={ autosize
value.deskripsi.length >= 200 ? ( maxLength={300}
<ComponentEvent_ErrorMaximalInput max={200} /> onChange={(val) => {
) : ( setValue({
"" ...value,
) deskripsi: val.target.value,
} });
onChange={(val) => { }}
setValue({ />
...value, <ComponentGlobal_InputCountDown
deskripsi: val.target.value, lengthInput={value.deskripsi.length}
}); maxInput={300}
}} />
/> </Stack>
<Button <Button
style={{
transition: "0.5s",
}}
disabled={ disabled={
value.title === "" || value.title === "" ||
value.lokasi === "" || value.lokasi === "" ||
value.deskripsi === "" || value.deskripsi === "" ||
value.eventMaster_TipeAcaraId === 0 || value.eventMaster_TipeAcaraId === 0 ||
value.tanggal === "function Date() { [native code] }" value.tanggal === "function Date() { [native code] }" ||
moment(value.tanggal).diff(moment(), "minutes") < 0
} }
loaderPosition="center" loaderPosition="center"
loading={isLoading ? true : false} loading={isLoading ? true : false}
@@ -196,20 +188,16 @@ async function onSave(
setHotMenu: any, setHotMenu: any,
setLoading: any setLoading: any
) { ) {
if (_.values(value).includes("")) // if (_.values(value).includes(""))
return ComponentGlobal_NotifikasiPeringatan("Lengkapi Data"); // return ComponentGlobal_NotifikasiPeringatan("Lengkapi Data");
// if (value.eventMaster_TipeAcaraId === 0)
if (value.title.length >= 100) return null; // return ComponentGlobal_NotifikasiPeringatan("Pilih Tipe Acara");
if (value.lokasi.length >= 100) return null; // if (moment(value.tanggal).format() === "Invalid date")
if (value.eventMaster_TipeAcaraId === 0) // return ComponentGlobal_NotifikasiPeringatan("Lengkapi Tanggal");
return ComponentGlobal_NotifikasiPeringatan("Pilih Tipe Acara"); // if (
if (moment(value.tanggal).format() === "Invalid date") // moment(value.tanggal.toISOString().toString()).diff(moment(), "minutes") < 0
return ComponentGlobal_NotifikasiPeringatan("Lengkapi Tanggal"); // )
if ( // return null;
moment(value.tanggal.toISOString().toString()).diff(moment(), "minutes") < 0
)
return null;
if (value.deskripsi.length >= 200) return null;
await Event_funCreate(value).then((res) => { await Event_funCreate(value).then((res) => {
if (res.status === 201) { if (res.status === 201) {

View File

@@ -1,6 +1,6 @@
"use client"; "use client";
import { Button, Group, Stack } from "@mantine/core"; import { Button, Group, Modal, Stack, Title } from "@mantine/core";
import ComponentEvent_DetailData from "../../component/detail/detail_data"; import ComponentEvent_DetailData from "../../component/detail/detail_data";
import { AppRouterInstance } from "next/dist/shared/lib/app-router-context.shared-runtime"; import { AppRouterInstance } from "next/dist/shared/lib/app-router-context.shared-runtime";
@@ -13,6 +13,10 @@ import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/component_global/
import React, { useState } from "react"; import React, { useState } from "react";
import ComponentEvent_CatatanReject from "../../component/catatan_reject"; import ComponentEvent_CatatanReject from "../../component/catatan_reject";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import moment from "moment";
import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/component_global/notif_global/notifikasi_peringatan";
import { Event_funDeleteById } from "../../fun/delete/fun_delete";
import { useDisclosure } from "@mantine/hooks";
export default function Event_DetailDraft({ export default function Event_DetailDraft({
dataEvent, dataEvent,
@@ -29,25 +33,42 @@ export default function Event_DetailDraft({
"" ""
)} )}
<ComponentEvent_DetailData data={dataEvent} /> <ComponentEvent_DetailData data={dataEvent} />
<ButtonAction eventId={dataEvent?.id} /> <ButtonAction eventId={dataEvent?.id} tanggal={dataEvent.tanggal} />
</Stack> </Stack>
</> </>
); );
} }
function ButtonAction({ eventId }: { eventId: string }) { function ButtonAction({ eventId, tanggal }: { eventId: string; tanggal: any }) {
const router = useRouter(); const router = useRouter();
const [isLoadingDelete, setLoadingDelete] = useState(false);
const [isLoadingAjukan, setLoadingAjukan] = useState(false);
const [tabsStatus, setTabsStatus] = useAtom(gs_event_status); const [tabsStatus, setTabsStatus] = useAtom(gs_event_status);
const [opened, { open, close }] = useDisclosure(false);
async function onDelete() { async function onDelete() {
console.log(eventId); await Event_funDeleteById(eventId).then((res) => {
if (res.status === 200) {
ComponentGlobal_NotifikasiBerhasil(res.message, 2000);
setLoadingDelete(true);
setTabsStatus("Draft");
close();
router.back();
} else {
ComponentGlobal_NotifikasiGagal(res.message);
}
});
} }
async function onAjukan() { async function onAjukan() {
if (moment(tanggal.toISOString().toString()).diff(moment(), "minutes") < 0)
return ComponentGlobal_NotifikasiPeringatan("Waktu acara telah lewat");
await Event_funEditStatusById("2", eventId).then((res) => { await Event_funEditStatusById("2", eventId).then((res) => {
if (res.status === 200) { if (res.status === 200) {
ComponentGlobal_NotifikasiBerhasil(res.message, 2000); ComponentGlobal_NotifikasiBerhasil(res.message, 2000);
setTabsStatus("Review"); setTabsStatus("Review");
setLoadingAjukan(true);
router.back(); router.back();
} else { } else {
ComponentGlobal_NotifikasiGagal(res.message); ComponentGlobal_NotifikasiGagal(res.message);
@@ -57,8 +78,32 @@ function ButtonAction({ eventId }: { eventId: string }) {
return ( return (
<> <>
<Modal opened={opened} onClose={close} centered withCloseButton={false}>
<Stack>
<Title order={6}>Yakin akan menghapus event ini?</Title>
<Group position="center">
<Button radius={"xl"} onClick={close}>
Batal
</Button>
<Button
loaderPosition="center"
loading={isLoadingDelete ? true : false}
radius={"xl"}
onClick={() => {
onDelete();
}}
color="red"
>
Hapus
</Button>
</Group>
</Stack>
</Modal>
<Group grow> <Group grow>
<Button <Button
loaderPosition="center"
loading={isLoadingAjukan ? true : false}
radius={"xl"} radius={"xl"}
color="yellow" color="yellow"
onClick={() => { onClick={() => {
@@ -71,7 +116,7 @@ function ButtonAction({ eventId }: { eventId: string }) {
radius={"xl"} radius={"xl"}
color="red" color="red"
onClick={() => { onClick={() => {
// onClick(router, setTabsStatus, dataEvent.id); open();
}} }}
> >
Hapus Hapus

View File

@@ -43,6 +43,8 @@ export default function Event_DetailMain({
const router = useRouter(); const router = useRouter();
const [total, setTotal] = useState(totalPeserta); const [total, setTotal] = useState(totalPeserta);
const [peserta, setPeserta] = useState(listPeserta); const [peserta, setPeserta] = useState(listPeserta);
const [isLoading, setLoading] = useState(false);
return ( return (
<> <>
<Stack spacing={"lg"}> <Stack spacing={"lg"}>
@@ -53,10 +55,18 @@ export default function Event_DetailMain({
</Button> </Button>
) : ( ) : (
<Button <Button
loaderPosition="center"
loading={isLoading ? true : false}
radius={"xl"} radius={"xl"}
color="green" color="green"
onClick={() => { onClick={() => {
onJoin(userLoginId, dataEvent.id, setPeserta, setTotal); onJoin(
userLoginId,
dataEvent.id,
setPeserta,
setTotal,
setLoading
);
}} }}
> >
JOIN JOIN
@@ -64,55 +74,6 @@ export default function Event_DetailMain({
)} )}
<ComponentEvent_ListPeserta listPeserta={listPeserta} total={total} /> <ComponentEvent_ListPeserta listPeserta={listPeserta} total={total} />
{/* <Paper withBorder mt={"lg"}>
<Stack spacing={"md"} p={"md"}>
<Center>
<Title order={5}>Daftar Peserta ({total})</Title>
</Center>
{_.isEmpty(peserta) ? (
<Center>
<Text fz={"xs"} fw={"bold"}>
- Tidak ada peserta -
</Text>
</Center>
) : (
<Stack>
{peserta.map((e, i) => (
<Stack key={i} spacing={"sm"}>
<Grid>
<Grid.Col
span={"content"}
onClick={() => {
router.push(
RouterProfile.katalog + e.User.Profile.id
);
}}
>
<Avatar
sx={{ borderStyle: "solid", borderWidth: "0.5px" }}
radius={"xl"}
bg={"gray"}
size={30}
src={
RouterProfile.api_foto_profile +
e.User.Profile.imagesId
}
/>
</Grid.Col>
<Grid.Col span={"auto"}>
<Stack justify="center" h={"100%"}>
<Text>{e.User.Profile.name}</Text>
</Stack>
</Grid.Col>
</Grid>
<Divider />
</Stack>
))}
</Stack>
)}
</Stack>
</Paper> */}
</Stack> </Stack>
</> </>
); );
@@ -122,7 +83,8 @@ async function onJoin(
userId: string, userId: string,
eventId: string, eventId: string,
setPeserta: any, setPeserta: any,
setTotal: any setTotal: any,
setLoading: any
) { ) {
const body = { const body = {
userId: userId, userId: userId,
@@ -135,6 +97,7 @@ async function onJoin(
await Event_countTotalPesertaById(eventId).then((ttl) => { await Event_countTotalPesertaById(eventId).then((ttl) => {
setPeserta(val); setPeserta(val);
setTotal(ttl); setTotal(ttl);
setLoading(true);
ComponentGlobal_NotifikasiBerhasil(res.message, 2000); ComponentGlobal_NotifikasiBerhasil(res.message, 2000);
}); });
}); });

View File

@@ -23,6 +23,8 @@ import _ from "lodash";
import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/component_global/notif_global/notifikasi_peringatan"; import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/component_global/notif_global/notifikasi_peringatan";
import { IconAlertTriangle } from "@tabler/icons-react"; import { IconAlertTriangle } from "@tabler/icons-react";
import ComponentEvent_ErrorMaximalInput from "../component/error_maksimal_input"; import ComponentEvent_ErrorMaximalInput from "../component/error_maksimal_input";
import ComponentGlobal_InputCountDown from "@/app_modules/component_global/input_countdown";
import ComponentGlobal_ErrorInput from "@/app_modules/component_global/error_input";
export default function Event_Edit({ export default function Event_Edit({
dataEvent, dataEvent,
@@ -32,6 +34,8 @@ export default function Event_Edit({
listTipeAcara: MODEL_DEFAULT_MASTER[]; listTipeAcara: MODEL_DEFAULT_MASTER[];
}) { }) {
const router = useRouter(); const router = useRouter();
const [isLoading, setLoading] = useState(false);
const [value, setValue] = useState(dataEvent); const [value, setValue] = useState(dataEvent);
const [tipe, setTipe] = useState(listTipeAcara); const [tipe, setTipe] = useState(listTipeAcara);
@@ -45,13 +49,13 @@ export default function Event_Edit({
<Stack px={"sm"}> <Stack px={"sm"}>
<TextInput <TextInput
label="Judul" label="Judul"
placeholder="Masukan judul" placeholder="judul"
withAsterisk withAsterisk
value={value.title} value={value.title}
maxLength={100} maxLength={100}
error={ error={
maxTitle.length >= 100 ? ( value.title === "" ? (
<ComponentEvent_ErrorMaximalInput max={100} /> <ComponentGlobal_ErrorInput text="Masukan judul" />
) : ( ) : (
"" ""
) )
@@ -86,13 +90,13 @@ export default function Event_Edit({
<TextInput <TextInput
label="Lokasi" label="Lokasi"
placeholder="Masukan lokasi acara" placeholder="lokasi acara"
withAsterisk withAsterisk
value={value.lokasi} value={value.lokasi}
maxLength={200} maxLength={100}
error={ error={
maxLokasi.length >= 200 ? ( value.lokasi === "" ? (
<ComponentEvent_ErrorMaximalInput max={200} /> <ComponentGlobal_ErrorInput text="Masukan lokasi" />
) : ( ) : (
"" ""
) )
@@ -113,6 +117,16 @@ export default function Event_Edit({
label="Tanggal & Waktu " label="Tanggal & Waktu "
placeholder="Masukan tangal dan waktu acara" placeholder="Masukan tangal dan waktu acara"
value={value.tanggal} value={value.tanggal}
error={
moment(value.tanggal.toISOString().toString()).diff(
moment(),
"minutes"
) < 0 ? (
<ComponentGlobal_ErrorInput text="Invalid Time" />
) : (
""
)
}
onChange={(val) => { onChange={(val) => {
setValue({ setValue({
...(value as any), ...(value as any),
@@ -120,30 +134,55 @@ export default function Event_Edit({
}); });
}} }}
/> />
<Textarea
label="Deskripsi"
placeholder="Deskripsikan acara yang akan di selenggarakan"
withAsterisk
autosize
value={value.deskripsi}
maxLength={500}
error={
maxDeskripsi.length >= 500 ? (
<ComponentEvent_ErrorMaximalInput max={500} />
) : (
""
)
}
onChange={(val) => {
setMaxDeskripsi(val.target.value);
setValue({
...value,
deskripsi: val.target.value,
});
}}
/>
<Button radius={"xl"} mt={"xl"} onClick={() => onUpdate(router, value)}> <Stack spacing={5}>
<Textarea
label="Deskripsi"
placeholder="Deskripsikan acara yang akan di selenggarakan"
withAsterisk
autosize
value={value.deskripsi}
maxLength={300}
error={
value.deskripsi === "" ? (
<ComponentGlobal_ErrorInput text="Masukan deskripsi" />
) : (
""
)
}
onChange={(val) => {
setMaxDeskripsi(val.target.value);
setValue({
...value,
deskripsi: val.target.value,
});
}}
/>
<ComponentGlobal_InputCountDown
maxInput={300}
lengthInput={value.deskripsi.length}
/>
</Stack>
<Button
style={{
transition: "0.5s",
}}
disabled={
value.title === "" ||
value.lokasi === "" ||
value.deskripsi === "" ||
value.eventMaster_TipeAcaraId === 0 ||
value.tanggal.toISOString.toString() ===
"function Date() { [native code] }" ||
moment(value.tanggal).diff(moment(), "minutes") < 0
}
loaderPosition="center"
loading={isLoading ? true : false}
radius={"xl"}
mt={"xl"}
onClick={() => onUpdate(router, value, setLoading)}
>
Update Update
</Button> </Button>
</Stack> </Stack>
@@ -151,13 +190,18 @@ export default function Event_Edit({
); );
} }
async function onUpdate(router: AppRouterInstance, value: MODEL_EVENT) { async function onUpdate(
router: AppRouterInstance,
value: MODEL_EVENT,
setLoading: any
) {
if (_.values(value).includes("")) if (_.values(value).includes(""))
return ComponentGlobal_NotifikasiPeringatan("Lengkapi Data"); return ComponentGlobal_NotifikasiPeringatan("Lengkapi Data");
await Event_funEditById(value).then((res) => { await Event_funEditById(value).then((res) => {
if (res.status === 200) { if (res.status === 200) {
ComponentGlobal_NotifikasiBerhasil(res.message); ComponentGlobal_NotifikasiBerhasil(res.message);
setLoading(true);
router.back(); router.back();
} else { } else {
ComponentGlobal_NotifikasiGagal(res.message); ComponentGlobal_NotifikasiGagal(res.message);

View File

@@ -9,8 +9,18 @@ export async function Event_funDeleteById(eventId: string) {
id: eventId, id: eventId,
}, },
}); });
if (!del) return { status: 400, message: "Gagal hapus data" }; if (!del) return { status: 400, message: "Gagal hapus data" };
// const delTemporary = await prisma.event.update({
// where: {
// id: eventId,
// },
// data: {
// active: false,
// },
// });
// if (!delTemporary) return { status: 400, message: "Gagal hapus data" };
revalidatePath("/dev/event/main/status_page"); revalidatePath("/dev/event/main/status_page");
return { return {
status: 200, status: 200,

View File

@@ -2,7 +2,10 @@
import prisma from "@/app/lib/prisma"; import prisma from "@/app/lib/prisma";
export async function Event_getByStatusId(statusId: string, authorId: string) { export async function Event_getListByStatusId(
statusId: string,
authorId: string
) {
if (statusId === "1") { if (statusId === "1") {
const data = await prisma.event.findMany({ const data = await prisma.event.findMany({
orderBy: { orderBy: {

View File

@@ -29,9 +29,10 @@ import ComponentEvent_BoxListStatus from "../component/box_list_status";
import { RouterProfile } from "@/app/lib/router_hipmi/router_katalog"; import { RouterProfile } from "@/app/lib/router_hipmi/router_katalog";
import ComponentGlobal_AuthorNameOnHeader from "@/app_modules/component_global/author_name_on_header"; import ComponentGlobal_AuthorNameOnHeader from "@/app_modules/component_global/author_name_on_header";
import _ from "lodash"; import _ from "lodash";
import { IconCirclePlus } from "@tabler/icons-react"; import { IconCirclePlus, IconPencilPlus } from "@tabler/icons-react";
import ComponentEvent_IsEmptyData from "../component/is_empty_data"; import ComponentEvent_IsEmptyData from "../component/is_empty_data";
import { useWindowScroll } from "@mantine/hooks"; import { useWindowScroll } from "@mantine/hooks";
import ComponentGlobal_CardLoadingOverlay from "@/app_modules/component_global/loading_card";
export default function Event_Beranda({ export default function Event_Beranda({
dataEvent, dataEvent,
@@ -41,6 +42,8 @@ export default function Event_Beranda({
const router = useRouter(); const router = useRouter();
const [isLoading, setLoading] = useState(false); const [isLoading, setLoading] = useState(false);
const [scroll, scrollTo] = useWindowScroll(); const [scroll, scrollTo] = useWindowScroll();
const [eventId, setEventId] = useState("");
const [visible, setVisible] = useState(false);
return ( return (
<> <>
@@ -60,50 +63,56 @@ export default function Event_Beranda({
router.push(RouterEvent.create); router.push(RouterEvent.create);
}} }}
> >
<IconCirclePlus color="white" size={40} /> <IconPencilPlus color="white" />
</ActionIcon> </ActionIcon>
</Affix> </Affix>
{_.isEmpty(dataEvent) ? ( {_.isEmpty(dataEvent) ? (
<ComponentEvent_IsEmptyData text="Tidak ada data" /> <ComponentEvent_IsEmptyData text="Tidak ada data" />
) : ( ) : (
<Box> dataEvent.map((e, i) => (
{Array(10) <Card key={i} shadow="lg" radius={"md"} withBorder mb={"sm"}>
.fill(0) <Card.Section px={"sm"} pt={"sm"}>
.map((e, i) => ( <ComponentGlobal_AuthorNameOnHeader
<Card key={i} shadow="lg" radius={"md"} withBorder mb={"sm"}> profileId={e?.Author?.Profile?.id}
<Card.Section px={"sm"} pt={"sm"}> imagesId={e?.Author?.Profile?.imagesId}
<ComponentGlobal_AuthorNameOnHeader authorName={e?.Author?.Profile?.name}
profileId={e?.Author.Profile.id} isPembatas={true}
imagesId={e?.Author.Profile.imagesId} />
authorName={e?.Author.Profile.name} </Card.Section>
/> <Card.Section
</Card.Section> p={"sm"}
<Card.Section onClick={() => {
p={"sm"} setEventId(e?.id);
onClick={() => router.push(RouterEvent.detail_main + e?.id)} setVisible(true);
> router.push(RouterEvent.detail_main + e?.id);
<Stack> }}
<Grid> >
<Grid.Col span={8}> <Stack>
<Title order={6} truncate> <Grid>
{e?.title} <Grid.Col span={8}>
</Title> <Title order={6} truncate>
</Grid.Col> {e?.title}
<Grid.Col span={4}> </Title>
<Text fz={"sm"} truncate> </Grid.Col>
{moment(e?.tanggal).format("ll")} <Grid.Col span={4}>
</Text> <Text fz={"sm"} truncate>
</Grid.Col> {moment(e?.tanggal).format("ll")}
</Grid>
<Text fz={"sm"} lineClamp={2}>
{e?.deskripsi}
</Text> </Text>
</Stack> </Grid.Col>
</Card.Section> </Grid>
</Card>
))} <Text fz={"sm"} lineClamp={2}>
</Box> {e?.deskripsi}
</Text>
</Stack>
</Card.Section>
{visible && e?.id === eventId ? (
<ComponentGlobal_CardLoadingOverlay />
) : (
""
)}
</Card>
))
)} )}
</> </>
); );

View File

@@ -23,6 +23,7 @@ import { MODEL_EVENT_PESERTA } from "../../model/interface";
import ComponentGlobal_AuthorNameOnHeader from "@/app_modules/component_global/author_name_on_header"; import ComponentGlobal_AuthorNameOnHeader from "@/app_modules/component_global/author_name_on_header";
import { RouterProfile } from "@/app/lib/router_hipmi/router_katalog"; import { RouterProfile } from "@/app/lib/router_hipmi/router_katalog";
import _ from "lodash"; import _ from "lodash";
import ComponentGlobal_CardLoadingOverlay from "@/app_modules/component_global/loading_card";
export default function Event_Kontribusi({ export default function Event_Kontribusi({
listKontribusi, listKontribusi,
@@ -30,19 +31,8 @@ export default function Event_Kontribusi({
listKontribusi: MODEL_EVENT_PESERTA[]; listKontribusi: MODEL_EVENT_PESERTA[];
}) { }) {
const router = useRouter(); const router = useRouter();
const [tabsKontribusi, setTabsKontribusi] = useState<string | any>("Panitia"); const [eventId, setEventId] = useState("");
const listTabs = [ const [visible, setVisible] = useState(false);
{
id: 1,
path: <Event_KontribusiPanitia />,
value: "Panitia",
},
{
id: 2,
path: <Event_KontribusiPeserta />,
value: "Peserta",
},
];
if (_.isEmpty(listKontribusi)) if (_.isEmpty(listKontribusi))
return ( return (
@@ -67,9 +57,10 @@ export default function Event_Kontribusi({
</Card.Section> </Card.Section>
<Card.Section <Card.Section
p={"sm"} p={"sm"}
onClick={() => onClick={() => {
router.push(RouterEvent.detail_kontribusi + e.Event.id) setEventId(e?.id), setVisible(true);
} router.push(RouterEvent.detail_kontribusi + e.Event.id);
}}
> >
<Stack> <Stack>
<Grid> <Grid>
@@ -90,15 +81,15 @@ export default function Event_Kontribusi({
</Text> */} </Text> */}
<Group position="center"> <Group position="center">
{e.Event.Event_Peserta.map((val) => ( {e.Event.Event_Peserta.map((val, i) => (
<Box key={val.id}> <Box key={i}>
<Avatar <Avatar
size={"lg"} size={"lg"}
radius={"xl"} radius={"xl"}
sx={{ borderStyle: "solid", borderWidth: "0.5px" }} sx={{ borderStyle: "solid", borderWidth: "0.5px" }}
src={ src={
RouterProfile.api_foto_profile + RouterProfile.api_foto_profile +
val.User.Profile.imagesId val?.User?.Profile?.imagesId
} }
/> />
</Box> </Box>
@@ -106,40 +97,13 @@ export default function Event_Kontribusi({
</Group> </Group>
</Stack> </Stack>
</Card.Section> </Card.Section>
{visible && eventId === e?.id ? (
<ComponentGlobal_CardLoadingOverlay />
) : (
""
)}
</Card> </Card>
))} ))}
</> </>
); );
// return (
// <>
// <Tabs
// color="blue"
// variant="pills"
// radius="xl"
// defaultValue="Panitia"
// value={tabsKontribusi}
// onTabChange={setTabsKontribusi}
// >
// <Stack>
// <Tabs.List grow>
// {listTabs.map((e) => (
// <Tabs.Tab
// key={e.id}
// value={e.value}
// bg={tabsKontribusi === e.value ? "blue" : "gray.1"}
// >
// Sebagai {e.value}
// </Tabs.Tab>
// ))}
// </Tabs.List>
// {listTabs.map((e) => (
// <Tabs.Panel key={e.id} value={e.value}>
// {e.path}
// </Tabs.Panel>
// ))}
// </Stack>
// </Tabs>
// </>
// );
} }

View File

@@ -44,7 +44,7 @@ export default function LayoutEvent_Main({
{ {
id: "2", id: "2",
name: "Status Event", name: "Status",
path: RouterEvent.status_page, path: RouterEvent.status_page,
icon: <IconTimelineEventText />, icon: <IconTimelineEventText />,
}, },

View File

@@ -8,28 +8,25 @@ import { MODEL_EVENT } from "../../model/interface";
import { useState } from "react"; import { useState } from "react";
import ComponentEvent_BoxListStatus from "../../component/box_list_status"; import ComponentEvent_BoxListStatus from "../../component/box_list_status";
import _ from "lodash"; import _ from "lodash";
import ComponentEvent_IsEmptyData from "../../component/is_empty_data";
export default function Event_StatusDraft({ export default function Event_StatusDraft({
listDraft, listDraft,
}: { }: {
listDraft: MODEL_EVENT[]; listDraft: MODEL_EVENT[];
}) { }) {
const router = useRouter();
if (_.isEmpty(listDraft)) if (_.isEmpty(listDraft))
return ( return <ComponentEvent_IsEmptyData text="Tidak ada data" />;
<Center h={"50vh"} fz={"sm"} fw={"bold"}>
Tidak Ada Event
</Center>
);
return ( return (
<> <>
{listDraft {listDraft.map((e, i) => (
.map((e, i) => ( <Box key={e.id}>
<Box key={e.id}> <ComponentEvent_BoxListStatus
<ComponentEvent_BoxListStatus data={e} path={RouterEvent.detail_draft}/> data={e}
</Box> path={RouterEvent.detail_draft}
))} />
</Box>
))}
</> </>
); );
} }

View File

@@ -7,6 +7,9 @@ import { useRouter } from "next/navigation";
import { MODEL_EVENT } from "../../model/interface"; import { MODEL_EVENT } from "../../model/interface";
import ComponentEvent_BoxListStatus from "../../component/box_list_status"; import ComponentEvent_BoxListStatus from "../../component/box_list_status";
import _ from "lodash"; import _ from "lodash";
import ComponentEvent_IsEmptyData from "../../component/is_empty_data";
import { useState } from "react";
import ComponentGlobal_CardLoadingOverlay from "@/app_modules/component_global/loading_card";
export default function Event_StatusPublish({ export default function Event_StatusPublish({
listPublish, listPublish,
@@ -14,22 +17,29 @@ export default function Event_StatusPublish({
listPublish: MODEL_EVENT[]; listPublish: MODEL_EVENT[];
}) { }) {
const router = useRouter(); const router = useRouter();
if (_.isEmpty(listPublish)) if (_.isEmpty(listPublish))
return ( return <ComponentEvent_IsEmptyData text="Tidak ada data" />;
<Center h={"50vh"} fz={"sm"} fw={"bold"}>
Tidak Ada Event
</Center>
);
return ( return (
<> <>
{listPublish {listPublish.map((e, i) => (
.map((e, i) => ( <Box key={e.id}>
<Box key={e.id}> <Box>
<ComponentEvent_BoxListStatus data={e} path={RouterEvent.detail_publish}/> <ComponentEvent_BoxListStatus
</Box> data={e}
))} path={RouterEvent.detail_publish}
/>
{/* {visible && e?.id === eventId ? (
<ComponentGlobal_CardLoadingOverlay />
) : (
""
)} */}
</Box>
</Box>
))}
</> </>
); );
} }

View File

@@ -7,19 +7,15 @@ import { useRouter } from "next/navigation";
import { MODEL_EVENT } from "../../model/interface"; import { MODEL_EVENT } from "../../model/interface";
import ComponentEvent_BoxListStatus from "../../component/box_list_status"; import ComponentEvent_BoxListStatus from "../../component/box_list_status";
import _ from "lodash"; import _ from "lodash";
import ComponentEvent_IsEmptyData from "../../component/is_empty_data";
export default function Event_StatusReject({ export default function Event_StatusReject({
listReject, listReject,
}: { }: {
listReject: MODEL_EVENT[]; listReject: MODEL_EVENT[];
}) { }) {
const router = useRouter();
if (_.isEmpty(listReject)) if (_.isEmpty(listReject))
return ( return <ComponentEvent_IsEmptyData text="Tidak ada data" />;
<Center h={"50vh"} fz={"sm"} fw={"bold"}>
Tidak Ada Event
</Center>
);
return ( return (
<> <>
{listReject.map((e, i) => ( {listReject.map((e, i) => (

View File

@@ -9,7 +9,8 @@ import { useState } from "react";
import ComponentEvent_BoxListStatus from "../../component/box_list_status"; import ComponentEvent_BoxListStatus from "../../component/box_list_status";
import _ from "lodash"; import _ from "lodash";
import { useShallowEffect } from "@mantine/hooks"; import { useShallowEffect } from "@mantine/hooks";
import { Event_getByStatusId } from "../../fun/get/get_event_by_status_id"; import { Event_getListByStatusId } from "../../fun/get/get_list_event_by_status_id";
import ComponentEvent_IsEmptyData from "../../component/is_empty_data";
export default function Event_StatusReview({ export default function Event_StatusReview({
listReview, listReview,
@@ -21,12 +22,8 @@ export default function Event_StatusReview({
const router = useRouter(); const router = useRouter();
if (_.isEmpty(listReview)) if (_.isEmpty(listReview))
return ( return <ComponentEvent_IsEmptyData text="Tidak ada data"/>
<Center h={"50vh"} fz={"sm"} fw={"bold"}>
Tidak Ada Event
</Center>
);
return ( return (
<> <>
{listReview.map((e, i) => ( {listReview.map((e, i) => (

View File

@@ -5,21 +5,52 @@ import mqtt_client from "./mqtt_client";
import { useAtom } from "jotai"; import { useAtom } from "jotai";
import { gs_coba_chat } from "@/app/makuro/gs_coba"; import { gs_coba_chat } from "@/app/makuro/gs_coba";
import { evnPesan } from "./evn"; import { evnPesan } from "./evn";
import { Button, Stack } from "@mantine/core";
export default function MqttLoader() { export default function MqttLoader() {
useEffect(() => { useEffect(() => {
mqtt_client.on("connect", () => { mqtt_client.on("connect", () => {
console.log("connected"); console.log("connected");
// mqtt_client.subscribe("pesan"); mqtt_client.subscribe("pesan");
mqtt_client.subscribe("pesan2");
// fetch("").then((res) => { // fetch("").then((res) => {
// mqtt_client.subscribe("pesan"); // mqtt_client.subscribe("pesan");
// }); // });
}); });
// mqtt_client.on("message", (apa: any, itu: any) => { mqtt_client.on("message", (topic: any, message: any) => {
// console.log(itu) // console.log(itu)
// evnPesan.emit("pesan", itu); // evnPesan.emit("pesan", itu);
// }); const data = JSON.parse(message.toString());
if (data) {
if (data.id === "1") {
console.log("ini untuk id satu", data.data);
}
}
});
}, []); }, []);
return null;
const onClick = async () => {
mqtt_client.publish("pesan2", "apa pesannya 2");
};
const onClick2 = () => {
mqtt_client.publish(
"pesan",
JSON.stringify({
id: "2",
title: "donasi",
data: "databta",
})
);
};
return null
// (
// <Stack>
// <Button onClick={onClick}>Tekan</Button>
// <Button onClick={onClick2}>Tekan 2</Button>
// </Stack>
// );
} }