Files
dmenu-plus-front/src/app/[name]/(Dialogs)/notifications/page.tsx
T
hamid zarghami d34a3a92f1 glass other page
2026-06-21 15:02:18 +03:30

155 lines
6.8 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client';
import { ef } from '@/lib/helpers/utfNumbers';
import { ArrowLeft } from 'iconsax-react';
import { useRouter } from 'next/navigation';
import React from 'react'
import Image from 'next/image';
import { useTranslation } from 'react-i18next';
import { useGetNotifications, useReadAllNotifications } from './hooks/useNotificationData';
import type { Notification } from './types/Types';
import { useGetNotificationsCount } from '../../(Main)/hooks/useMenuData';
import Prompt from '@/components/utils/Prompt';
import { glassSurfaceCard } from '@/lib/styles/glassSurface';
type Props = object
const formatDate = (dateString: string): string => {
const date = new Date(dateString);
return date.toLocaleDateString('fa-IR', {
year: 'numeric',
month: 'long',
day: 'numeric'
});
};
const formatTime = (dateString: string): string => {
const date = new Date(dateString);
return date.toLocaleTimeString('fa-IR', {
hour: '2-digit',
minute: '2-digit'
});
};
export default function NotificationsIndex({ }: Props) {
const { t } = useTranslation('notifications')
const router = useRouter();
const { data, isLoading } = useGetNotifications();
const { mutate: readAllNotifications } = useReadAllNotifications();
const { data: notificationsCount } = useGetNotificationsCount();
const [showReadAllConfirm, setShowReadAllConfirm] = React.useState(false);
const notifications = React.useMemo(() => {
return data?.data ?? [];
}, [data?.data]);
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'>
<span></span>
<h1 className='text-sm2 place-self-center font-medium'>{t("Heading")}</h1>
<ArrowLeft
className='cursor-pointer place-self-end'
size='24'
color='currentColor'
onClick={() => { router.back() }}
/>
</div>
<div>
</div>
<div className="mt-2 flex-1 h-full">
{isLoading ? (
<div className='flex flex-col items-center justify-center gap-2 py-12 text-sm2 text-muted-foreground'>
<span className='h-4 w-4 animate-spin rounded-full border border-dashed border-foreground border-t-transparent'></span>
<p>در حال دریافت اعلانها...</p>
</div>
) : notifications.length === 0 ? (
<div className='flex flex-col items-center justify-center gap-4 h-full'>
<Image
src='/assets/images/notification.png'
alt='notification'
width={120}
height={120}
className='object-contain'
/>
<div className='flex flex-col items-center gap-2 text-sm2 text-muted-foreground'>
<p>اعلانی وجود ندارد</p>
</div>
</div>
) : (
<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 dark:invert -mt-3 cursor-pointer' onClick={handleReadAllClick} />
</div>
)
: null
}
{notifications.map((notification: Notification) => {
// const isNew = !notification.sentAt;
const formattedDate = formatDate(notification.createdAt);
const formattedTime = formatTime(notification.createdAt);
return (
<li key={notification.id} className={glassSurfaceCard('py-5 px-4')}>
{/* <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 '>
<div className="flex items-center justify-start gap-2">
{/* {isNew && (
<span className='px-4 pt-1 pb-0.5 text-xs bg-primary text-white rounded-md'>
{t('Tags.New')}
</span>
)} */}
<span className='text-disabled2 text-xs pt-0.5'>
{ef(formattedDate)}
</span>
<span className='size-1.5 bg-disabled rounded-full'></span>
<span className='text-disabled2 text-xs pt-0.5'>
{ef(formattedTime)}
</span>
</div>
</div>
</li>
);
})}
</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>
)
}