diff --git a/client/components/button/PatientNotificationButton.tsx b/client/components/button/PatientNotificationButton.tsx index 1330b948..547c3489 100644 --- a/client/components/button/PatientNotificationButton.tsx +++ b/client/components/button/PatientNotificationButton.tsx @@ -5,19 +5,21 @@ import { Badge } from "@/components/ui/badge"; import { ButtonV2 } from "@/components/common/ButtonV2"; import NotificationModal from "@/components/models/NotificationModel"; import { useState } from "react"; -import { useGetAllPatientNotifications } from "@/lib/hooks/notification/useSlotPatient"; +import { useGetAllPatientNotifications } from "@/lib/hooks/notification/useNotificationPatient"; import { INotification } from "@/types"; const NotificationButton = () => { const [isNotificationModalOpen, setIsNotificationModalOpen] = useState(false); - const { data: notifications, isLoading } = useGetAllPatientNotifications(); - + const { data: notifications, refetch, error } = useGetAllPatientNotifications(); + const notificationCount = notifications?.length || 0; const handleNotificationClick = () => { setIsNotificationModalOpen(true); }; + const unauthorized = error?.status === 401 || error?.status === 403; + return ( <> @@ -34,8 +36,10 @@ const NotificationButton = () => { ); diff --git a/client/components/models/NotificationModel.tsx b/client/components/models/NotificationModel.tsx index 5197b854..74b78086 100644 --- a/client/components/models/NotificationModel.tsx +++ b/client/components/models/NotificationModel.tsx @@ -1,5 +1,7 @@ -import { Dispatch, SetStateAction } from "react"; -import Image from "next/image"; +'use client' + +import { Dispatch, SetStateAction } from "react" +import Image from "next/image" import { AlertDialog, AlertDialogContent, @@ -7,22 +9,53 @@ import { AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, -} from "@/components/ui/alert-dialog"; -import { Button } from "@/components/ui/button"; -import { Card, CardContent } from "@/components/ui/card"; -import { INotification, NotificationTypes } from "@/types"; -import getNotificationDetails from "@/lib/utils/getNotificationDetails"; +} from "@/components/ui/alert-dialog" +import { Card, CardContent } from "@/components/ui/card" +import { INotification } from "@/types" +import getNotificationDetails from "@/lib/utils/getNotificationDetails" +import { useClearMultiplePatientNotifications, useClearPatientNotification } from "@/lib/hooks/notification/useNotificationPatient" +import { XIcon, Trash2Icon } from "lucide-react" +import { ButtonV2 } from "../common/ButtonV2" type Props = { - open: boolean; - setOpen: Dispatch>; - notifications: INotification[]; -}; + open: boolean + setOpen: Dispatch> + notifications: INotification[] + unauthorized: boolean, + refetch: any +} -const NotificationModal = ({ open, setOpen, notifications }: Props) => { +export default function NotificationModal({ open, setOpen, notifications, unauthorized, refetch }: Props) { const closeModal = () => { - setOpen(false); - }; + setOpen(false) + } + const { mutate: clearSingleNotification } = useClearPatientNotification() + const { mutate: clearMultipleNotification } = useClearMultiplePatientNotifications() + + const handleClearSingleNotification = (notificationId: string) => { + clearSingleNotification( + { notificationId }, + { + onSuccess: refetch, + onError: (error) => { + console.error("Failed to clear notification:", error) + }, + }, + ) + } + + const handleClearAllNotifications = () => { + const notificationIds = notifications.map(notification => notification._id!) + clearMultipleNotification( + { notificationIds }, + { + onSuccess: refetch, + onError: (error) => { + console.error("Failed to clear multiple notifications:", error) + }, + } + ) + } return ( @@ -30,46 +63,93 @@ const NotificationModal = ({ open, setOpen, notifications }: Props) => { Notifications - + + +
- {notifications.map((notification) => { - const { icon, title } = getNotificationDetails(notification.type!); - return ( - - - {title} -
-

{title}

-

{notification.message}

-
-
-
- ); - })} + {unauthorized ? ( +
+ Unauthorized +

+ You are not authorized to view these notifications. +

+
+ ) : notifications && notifications.length > 0 ? ( + <> + {notifications.map((notification) => { + const { icon, title } = getNotificationDetails(notification.type!) + return ( + + +
+ {title} +
+

{title}

+

{notification.message}

+
+
+ handleClearSingleNotification(notification._id!)} + iconPlacement="left" + Icon={Trash2Icon} + className="text-muted-foreground hover:text-primary w-20" + > + Clear + + +
+
+ ) + })} + + ) : ( +
+ No Notifications +

+ You're all caught up! No new notifications. +

+
+ )}
+ - +
+ {notifications.length > 0 && ( + + Clear All + + )} + Close +
- ); -} - -export default NotificationModal; \ No newline at end of file + ) +} \ No newline at end of file diff --git a/client/lib/hooks/notification/useSlotDoctor.ts b/client/lib/hooks/notification/useNotificationDoctor.ts similarity index 90% rename from client/lib/hooks/notification/useSlotDoctor.ts rename to client/lib/hooks/notification/useNotificationDoctor.ts index b75c9d98..cc62a577 100644 --- a/client/lib/hooks/notification/useSlotDoctor.ts +++ b/client/lib/hooks/notification/useNotificationDoctor.ts @@ -8,7 +8,10 @@ import { AxiosError } from "axios" export const useGetAllDoctorNotifications = ()=>{ return useQuery>({ queryKey:["notifications"], - queryFn:getDoctorNotifications + queryFn:getDoctorNotifications, + retry:1, + retryOnMount:false, + refetchInterval:1000*60 }) } diff --git a/client/lib/hooks/notification/useSlotPatient.ts b/client/lib/hooks/notification/useNotificationPatient.ts similarity index 90% rename from client/lib/hooks/notification/useSlotPatient.ts rename to client/lib/hooks/notification/useNotificationPatient.ts index 47dc4dd3..fa4bbd2f 100644 --- a/client/lib/hooks/notification/useSlotPatient.ts +++ b/client/lib/hooks/notification/useNotificationPatient.ts @@ -8,7 +8,10 @@ import { AxiosError } from "axios" export const useGetAllPatientNotifications = ()=>{ return useQuery>({ queryKey:["notifications"], - queryFn:getPatientNotifications + queryFn:getPatientNotifications, + retry:1, + retryOnMount:false, + refetchInterval:1000*60 }) } diff --git "a/client/public/assets/icons/emoji/\360\237\230\221.svg" "b/client/public/assets/icons/emoji/\360\237\230\221.svg" new file mode 100644 index 00000000..77068fa7 --- /dev/null +++ "b/client/public/assets/icons/emoji/\360\237\230\221.svg" @@ -0,0 +1 @@ + \ No newline at end of file