155 lines
6.8 KiB
TypeScript
155 lines
6.8 KiB
TypeScript
'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>
|
||
)
|
||
} |