read all notif

This commit is contained in:
hamid zarghami
2025-12-25 10:18:47 +03:30
parent f84d5156b0
commit f532a1514f
5 changed files with 68 additions and 11 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

@@ -17,3 +17,14 @@ export const useDeleteNotification = () => {
},
});
};
export const useReadAllNotifications = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: api.readAll,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["notifications"] });
queryClient.invalidateQueries({ queryKey: ["notificationsCount"] });
},
});
};
@@ -6,8 +6,10 @@ import { useRouter } from 'next/navigation';
import React from 'react'
import Image from 'next/image';
import { useTranslation } from 'react-i18next';
import { useGetNotifications, useDeleteNotification } from './hooks/useNotificationData';
import { useGetNotifications, useDeleteNotification, useReadAllNotifications } from './hooks/useNotificationData';
import type { Notification } from './types/Types';
import { useGetNotificationsCount } from '../../(Main)/hooks/useMenuData';
import Prompt from '@/components/utils/Prompt';
type Props = object
@@ -33,6 +35,9 @@ export default function NotificationsIndex({ }: Props) {
const router = useRouter();
const { data, isLoading } = useGetNotifications();
const { mutate: deleteNotification } = useDeleteNotification();
const { mutate: readAllNotifications } = useReadAllNotifications();
const { data: notificationsCount } = useGetNotificationsCount();
const [showReadAllConfirm, setShowReadAllConfirm] = React.useState(false);
const notifications = React.useMemo(() => {
return data?.data ?? [];
@@ -42,6 +47,23 @@ export default function NotificationsIndex({ }: Props) {
deleteNotification(id);
};
const handleReadAll = (e: React.MouseEvent) => {
e?.preventDefault();
e?.stopPropagation();
readAllNotifications();
setShowReadAllConfirm(false);
};
const toggleReadAllConfirm = (e: React.MouseEvent) => {
e?.preventDefault();
e?.stopPropagation();
setShowReadAllConfirm(false);
};
const handleReadAllClick = () => {
setShowReadAllConfirm(true);
};
return (
<div className='overflow-y-auto h-full noscrollbar flex flex-col'>
<div className='grid grid-cols-3 items-center'>
@@ -55,6 +77,9 @@ export default function NotificationsIndex({ }: Props) {
/>
</div>
<div>
</div>
<div className="mt-8 flex-1 h-full">
{isLoading ? (
<div className='flex flex-col items-center justify-center gap-2 py-12 text-sm2 text-muted-foreground'>
@@ -75,7 +100,15 @@ export default function NotificationsIndex({ }: Props) {
</div>
</div>
) : (
<ul className='flex flex-col gap-4 pb-20'>
<ul className='flex flex-col gap-4 pb-20 px-0.5'>
{
notificationsCount?.data?.count && notificationsCount?.data?.count > 0 ? (
<div className='flex'>
<Image src={'/assets/images/readall.png'} alt='notification' width={20} height={20} className='object-contain -mt-3 cursor-pointer' onClick={handleReadAllClick} />
</div>
)
: null
}
{notifications.map((notification: Notification) => {
const isNew = !notification.sentAt;
const formattedDate = formatDate(notification.createdAt);
@@ -83,7 +116,7 @@ export default function NotificationsIndex({ }: Props) {
return (
<li key={notification.id} className='bg-container py-5 px-4 rounded-container shadow-lg'>
<h5 className='font-medium text-sm'>{notification.title}</h5>
{/* <h5 className='font-medium text-sm'>{notification.title}</h5> */}
<p className='text-xs mt-2 leading-5'>{notification.content}</p>
<div className='flex items-center justify-between mt-5 '>
@@ -101,11 +134,6 @@ export default function NotificationsIndex({ }: Props) {
{ef(formattedTime)}
</span>
</div>
<Trash
size={24}
className='stroke-primary dark:stroke-foreground cursor-pointer'
onClick={() => handleDelete(notification.id)}
/>
</div>
</li>
);
@@ -113,6 +141,19 @@ export default function NotificationsIndex({ }: Props) {
</ul>
)}
</div>
<div className={showReadAllConfirm ? 'fixed inset-0 z-1001' : 'pointer-events-none fixed inset-0 z-1001'}>
<Prompt
title='خواندن همه اعلان‌ها'
description='آیا از خواندن همه اعلان‌ها اطمینان دارید؟'
textConfirm='بله'
textCancel='خیر'
onConfirm={handleReadAll}
onCancel={toggleReadAllConfirm}
visible={showReadAllConfirm}
onClick={toggleReadAllConfirm}
/>
</div>
</div>
)
}
@@ -4,7 +4,7 @@ import { BaseResponse } from "@/app/[name]/(Main)/types/Types";
export const getNotifications = async (): Promise<NotificationsResponse> => {
const { data } = await api.get<NotificationsResponse>(
"/public/notifications"
"/public/notifications?status=unseen"
);
return data;
};
@@ -17,3 +17,8 @@ export const deleteNotification = async (
);
return data;
};
export const readAll = async () => {
const { data } = await api.put("/public/notifications/read/all");
return data;
};
+1 -1
View File
@@ -29,7 +29,7 @@ export default function SearchBox ({
onChange={onChange}
value={value}
placeholder={placeholder}
className='text-[#8C90A3] pt-1 block outline-none border-none focus:ring-0 focus:outline-none text-sm px-[7px] h-full items-center w-full'
className='text-[#8C90A3] pt-1 block outline-none border-none focus:ring-0 focus:outline-none px-[7px] h-full items-center w-full text-xs!'
type='search'
{...props}
/>