fix header dashboard

This commit is contained in:
2025-04-14 12:03:14 +08:00
parent 94e202db8d
commit 8e8789aa2d
14 changed files with 977 additions and 149 deletions

View File

@@ -0,0 +1,350 @@
import {
gs_adminDonasi_triggerReview,
gs_adminEvent_triggerReview,
gs_adminJob_triggerReview,
gs_adminVoting_triggerReview,
ITypeStatusNotifikasi,
} from "@/lib/global_state";
import { AccentColor } from "@/app_modules/_global/color";
import { ComponentGlobal_CardLoadingOverlay } from "@/app_modules/_global/component";
import { MODEL_NOTIFIKASI } from "@/app_modules/notifikasi/model/interface";
import { Badge, Card, Divider, Group, Stack, Text } from "@mantine/core";
import { IconCheck, IconChecks, IconSpeakerphone } from "@tabler/icons-react";
import { useAtom } from "jotai";
import { useRouter } from "next/navigation";
import { useState } from "react";
import { clientLogger } from "@/util/clientLogger";
import moment from "moment";
import "moment/locale/id";
import {
IAdmin_ActivePage,
IAdmin_ActiveChildId,
} from "../../notifikasi/route_setting/type_of_select_page";
import { adminNotifikasi_findRouterJob } from "../../notifikasi/route_setting/job";
export default function Admin_V3_ComponentCardNotifikasi({
data,
activePage,
onChangeNavbar,
onToggleNavbar,
// onLoadCountNotif,
// onLoadDataNotifikasi,
}: {
data: MODEL_NOTIFIKASI;
activePage: number;
onChangeNavbar: (val: {
id: IAdmin_ActivePage;
childId: IAdmin_ActiveChildId;
}) => void;
onToggleNavbar: (val: any) => void;
// onLoadCountNotif: (val: any) => void;
// onLoadDataNotifikasi: (val: any) => void;
}) {
const router = useRouter();
const [visible, setVisible] = useState(false);
const [dataId, setDataId] = useState<string>("");
// Realtime
const [isAdminJob_TriggerReview, setIsAdminJob_TriggerReview] = useAtom(
gs_adminJob_triggerReview
);
const [isAdminEvent_TriggerReview, setIsAdminEvent_TriggerReview] = useAtom(
gs_adminEvent_triggerReview
);
const [isAdminVoting_TriggerReview, setIsAdminVoting_TriggerReview] = useAtom(
gs_adminVoting_triggerReview
);
const [isAdminDonasi_TriggerReview, setIsAdminDonasi_TriggerReview] = useAtom(
gs_adminDonasi_triggerReview
);
async function onRead() {
// ========================== JOB ========================== //
try {
setVisible(true);
if (data?.kategoriApp === "JOB") {
setDataId(data.id);
const checkJob = await adminNotifikasi_findRouterJob({
appId: data.appId,
notifikasiId: data.id,
router: router,
activePage: activePage,
// onLoadCountNotif(val) {
// onLoadCountNotif(val);
// },
// onLoadDataNotifikasi(val) {
// onLoadDataNotifikasi(val);
// },
onChangeNavbar(val) {
onChangeNavbar({
id: val.id,
childId: val.childId,
});
},
});
if (checkJob) {
setIsAdminJob_TriggerReview(false);
setVisible(false);
setDataId("");
onToggleNavbar(false);
}
return;
}
// ========================== JOB ========================== //
// ========================== EVENT ========================== //
// if (data.kategoriApp == "EVENT") {
// setDataId(data.id);
// const checkEvent = await adminNotifikasi_findRouterEvent({
// appId: data.appId,
// notifikasiId: data.id,
// router: router,
// activePage: activePage,
// onLoadCountNotif(val) {
// onLoadCountNotif(val);
// },
// onLoadDataNotifikasi(val) {
// onLoadDataNotifikasi(val);
// },
// onChangeNavbar(val) {
// onChangeNavbar({
// id: val.id,
// childId: val.childId,
// });
// },
// });
// if (checkEvent) {
// setIsAdminEvent_TriggerReview(false);
// setVisible(false);
// setDataId("");
// onToggleNavbar(false);
// }
// return;
// }
// ========================== EVENT ========================== //
// ========================== VOTING ========================== //
// if (data.kategoriApp == "VOTING") {
// setDataId(data.id);
// const checkVoting = await adminNotifikasi_findRouterVoting({
// router: router,
// appId: data.appId,
// notifikasiId: data.id,
// activePage: activePage,
// onLoadCountNotif(val) {
// onLoadCountNotif(val);
// },
// onLoadDataNotifikasi(val) {
// onLoadDataNotifikasi(val);
// },
// onChangeNavbar(val) {
// onChangeNavbar({
// id: val.id,
// childId: val.childId,
// });
// },
// });
// if (checkVoting) {
// setIsAdminVoting_TriggerReview(false);
// setVisible(false);
// setDataId("");
// onToggleNavbar(false);
// }
// return;
// }
// ========================== VOTING ========================== //
// ========================== DONASI ========================== //
// if (data.kategoriApp == "DONASI") {
// setDataId(data.id);
// const checkDonasi = await adminNotifikasi_findRouterDonasi({
// appId: data.appId,
// notifikasiId: data.id,
// router: router,
// status: data.status as ITypeStatusNotifikasi,
// onLoadCountNotif(val) {
// onLoadCountNotif(val);
// },
// onLoadDataNotifikasi(val) {
// onLoadDataNotifikasi(val);
// },
// onChangeNavbar(val) {
// onChangeNavbar({
// id: val.id,
// childId: val.childId,
// });
// },
// });
// if (checkDonasi) {
// setIsAdminDonasi_TriggerReview(false);
// setVisible(false);
// setDataId("");
// onToggleNavbar(false);
// }
// return;
// }
// ========================== DONASI ========================== //
// ========================== INVESTASI ========================== //
// if (data.kategoriApp == "INVESTASI") {
// setDataId(data.id);
// const checkInvestasi = await adminNotifikasi_findRouterInvestasi({
// appId: data.appId,
// notifikasiId: data.id,
// status: data.status as ITypeStatusNotifikasi,
// router: router,
// onLoadCountNotif(val) {
// onLoadCountNotif(val);
// },
// onLoadDataNotifikasi(val) {
// onLoadDataNotifikasi(val);
// },
// onChangeNavbar(val) {
// onChangeNavbar({
// id: val.id,
// childId: val.childId,
// });
// },
// });
// if (checkInvestasi) {
// setIsAdminDonasi_TriggerReview(false);
// setVisible(false);
// setDataId("");
// onToggleNavbar(false);
// }
// return;
// }
// // FORUM
// e?.kategoriApp === "FORUM" &&
// adminNotifikasi_findRouterForum({
// data: e,
// router: router,
// onChangeNavbar(val) {
// onChangeNavbar(val);
// },
// onToggleNavbar(val) {
// onToggleNavbar(val);
// },
// });
} catch (error) {
clientLogger.error("Error notifikasi function", error);
} finally {
setVisible(false);
}
}
return (
<>
<Card
style={{
transition: "0.5s",
}}
mb={"15px"}
c={"white"}
key={data.id}
bg={data.isRead ? AccentColor.blackgray : AccentColor.darkblue}
sx={{
borderColor: AccentColor.blue,
borderStyle: "solid",
borderWidth: "2px",
borderRadius: "10px",
":hover": {
// backgroundColor: AccentColor.blue,
borderColor: AccentColor.softblue,
borderStyle: "solid",
borderWidth: "2px",
},
}}
onClick={() => {
onRead();
}}
>
<Card.Section p={"sm"}>
<Stack spacing={"xs"}>
<Group position="apart">
<Group>
<IconSpeakerphone size={15} color="white" />
<Text fw={"bold"} fz={10}>
{data.kategoriApp}
</Text>
</Group>
{data.status ? (
<Badge fz={10} size="sm">
{data.status}
</Badge>
) : (
""
)}
</Group>
<Divider color="gray.3" />
</Stack>
</Card.Section>
<Card.Section px={"sm"} pb={"sm"}>
<Stack spacing={0}>
<Text lineClamp={2} fw={"bold"} fz={"xs"}>
{data.title}
</Text>
<Text lineClamp={2} fz={"xs"}>
{data.pesan}
</Text>
</Stack>
</Card.Section>
<Card.Section p={"sm"}>
<Group position="apart">
<Text fz={10} color="gray">
{moment(data.createdAt).format("LLL")}
</Text>
{/* <Text fz={10}>
{new Intl.DateTimeFormat("id-ID", {
dateStyle: "long",
}).format(data.createdAt)}
<Text span inherit fz={10}>
{", "}
{new Intl.DateTimeFormat("id-ID", {
timeStyle: "short",
}).format(data.createdAt)}
</Text>
</Text> */}
{data.isRead ? (
<Group spacing={5}>
<IconChecks size={10} />
<Text fz={10}>Sudah dilihat</Text>
</Group>
) : (
<Group spacing={5}>
<IconCheck size={10} />
<Text fz={10}>Belum dilihat</Text>
</Group>
)}
</Group>
{visible && dataId === data.id && (
<ComponentGlobal_CardLoadingOverlay />
)}
</Card.Section>
</Card>
</>
);
}

View File

@@ -0,0 +1,213 @@
import { MODEL_NOTIFIKASI } from "@/app_modules/notifikasi/model/interface";
import {
Box,
Button,
Center,
Group,
Loader,
Paper,
Stack,
Text,
} from "@mantine/core";
import { useShallowEffect } from "@mantine/hooks";
import _ from "lodash";
import { ScrollOnly } from "next-scroll-loader";
import adminNotifikasi_getByUserId from "../../notifikasi/fun/get/get_notifikasi_by_user_id";
import { useState } from "react";
import {
apiGetNotifikasiByUserId,
apiPostIsReadNotifikasi,
} from "../../notifikasi/lib/api_fetch_notifikasi";
import AdminNotifikasi_ViewCardDrawer from "../../notifikasi/view_card_drawer";
import Admin_V3_ComponentCardNotifikasi from "./comp_card_notifikasi";
import CustomSkeleton from "@/app_modules/components/CustomSkeleton";
import {
IAdmin_ActivePage,
IAdmin_ActiveChildId,
} from "../../notifikasi/route_setting/type_of_select_page";
export function Admin_V3_ViewDrawerNotifikasi({
userLoginId,
openedDrawer,
onChangeNavbar,
onToggleNavbar,
}: {
userLoginId: string;
openedDrawer: boolean;
onChangeNavbar: (val: {
id: IAdmin_ActivePage;
childId: IAdmin_ActiveChildId;
}) => void;
onToggleNavbar: (val: any) => void;
}) {
// newAdminNtf,
// listNotifikasi,
// onChangeNavbar,
// }: {
// newAdminNtf: number;
// listNotifikasi: MODEL_NOTIFIKASI[];
// onChangeNavbar: (val: {
// id: IAdmin_ActivePage;
// childId: IAdmin_ActiveChildId;
// }) => void;
const [data, setData] = useState<MODEL_NOTIFIKASI[] | null>(null);
const [activePage, setActivePage] = useState<number>(1);
// Action Button
const [isRead, setIsRead] = useState<boolean>(false);
const [isUnRead, setIsUnRead] = useState<boolean>(false);
useShallowEffect(() => {
if (openedDrawer || isRead || isUnRead) {
handleLoadtData();
}
}, [openedDrawer, isRead, isUnRead]);
async function handleLoadtData() {
try {
const response = await apiGetNotifikasiByUserId({
id: userLoginId,
page: `${activePage}`,
});
if (response && response.success) {
setData(response.data);
setIsRead(false);
setIsUnRead(false);
} else {
console.error("Failed to fetch user data", response);
setData(null);
}
} catch (error) {
console.error("Error fetching data:", error);
setData(null);
}
}
async function handleMoreData() {
try {
const nextPage = activePage + 1;
const response = await apiGetNotifikasiByUserId({
id: userLoginId,
page: `${nextPage}`,
});
if (response && response.success) {
setActivePage(nextPage);
return response.data;
} else {
console.error("Failed to fetch user data", response);
return null;
}
} catch (error) {
console.error("Error fetching data:", error);
return null;
}
}
async function handleUpdateReadAll() {
try {
const response = await apiPostIsReadNotifikasi({
id: userLoginId,
isRead: true,
});
if (response && response.success) {
console.log("Berhasil tandai baca semua");
setIsRead(true);
} else {
console.error("Failed to update notification", response);
return null;
}
} catch (error) {
console.error("Error updating notification:", error);
return null;
}
}
async function handleUpdateUnRead() {
try {
const response = await apiPostIsReadNotifikasi({
id: userLoginId,
isRead: false,
});
if (response && response.success) {
console.log("Berhasil tandai belum baca");
setIsUnRead(true);
} else {
console.error("Failed to update notification", response);
return null;
}
} catch (error) {
console.error("Error updating notification:", error);
return null;
}
}
if (!data) {
return (
<>
<Stack pt="sm">
{Array.from({ length: 3 }, (_, i) => (
<CustomSkeleton key={i} height={150} />
))}
</Stack>
</>
);
}
return (
<>
<Stack pt={"sm"} pb={"xl"}>
<Group>
<Button
radius={"xl"}
onClick={() => {
handleUpdateReadAll();
}}
>
Tandai baca semua
</Button>
<Button
radius={"xl"}
onClick={() => {
handleUpdateUnRead();
}}
>
Tandai belum baca
</Button>
</Group>
{_.isEmpty(data) ? (
<Center>
<Text c={"gray"} fz={"xs"}>
Tidak ada notifikasi
</Text>
</Center>
) : (
<ScrollOnly
height="80vh"
renderLoading={() => (
<Center mt={"lg"}>
<Loader color={"yellow"} />
</Center>
)}
data={data}
setData={setData as any}
moreData={handleMoreData}
>
{(item) => (
<Admin_V3_ComponentCardNotifikasi
data={item}
activePage={activePage}
onChangeNavbar={(val) => onChangeNavbar(val)}
onToggleNavbar={(val) => onToggleNavbar(val)}
// onLoadCountNotif={(val) => onLoadCountNotif(val)}
// onLoadDataNotifikasi={(val) => setData(val)}
/>
)}
</ScrollOnly>
)}
</Stack>
</>
);
}