'use client' import { useTranslations } from 'next-intl'; import { IconCheck, IconArrowLeft, IconArrowRight, IconDoubleArrowLeft, IconDoubleArrowRight } from '@/app/ui/icons/icons'; import { useEffect, useState } from 'react'; import { useAllNotifications } from '@/app/hooks/react-query/useAllNotificationsList'; import { notificationsMarkAsRead, notificationsDelete, NotificationBody } from '@/app/actions/notificationActions'; import { useQueryClient } from '@tanstack/react-query'; import { formatDate, formatDateTime } from '@/app/lib/formatDate'; import { useReactTable, getCoreRowModel, getPaginationRowModel, flexRender, createColumnHelper, RowSelectionState, } from '@tanstack/react-table'; import { NotificationTextHandler } from '@/app/components/NotificationTextHandler'; export function NotificationsList() { const t = useTranslations('Global'); const norificationTranslate = useTranslations('Notifications'); const queryClient = useQueryClient(); const [rowSelection, setRowSelection] = useState({}); const [loadingIds, setLoadingIds] = useState>(new Set()); const [error, setError] = useState(null); const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 10, }); const { data: allNotifications, isLoading } = useAllNotifications( pagination.pageIndex, pagination.pageSize ); const totalPages = allNotifications?.totalPages || 0; const totalRecords = allNotifications?.totalElements || 0; const columnHelper = createColumnHelper(); const columns = [ columnHelper.display({ id: 'select', header: ({ table }) => { const currentPageRows = table.getCoreRowModel().rows; const unreadRowsOnPage = currentPageRows.filter(row => row.original.status !== 'READIED'); const allNotificationSelectedOnPage = currentPageRows.every(row => rowSelection[row.original.id]); const unreadIdsSet = new Set(unreadRowsOnPage.map(row => row.original.id)); const selectedUnreadIds = Object.keys(rowSelection) .map(Number) .filter(id => unreadIdsSet.has(id)); return (
{selectedUnreadIds.length > 0 && ( )} {Object.keys(rowSelection).length > 0 && ( <> )} {allNotifications?.notifications.length !== 0 && ( )}
); }, cell: ({ row }) => { const isReadied = row.original.status === 'READIED'; const isSelected = !!rowSelection[row.original.id]; return (
); }, }), columnHelper.accessor('message', { id: 'message', header: () => null, cell: ({ row }) => { const item = row.original; return (
{norificationTranslate.has(item.message) ? norificationTranslate(item.message) : item.message} ({item.id})
{item.createdAt ? `${formatDate(item.createdAt)}: ${formatDateTime(item.createdAt)}` : '---'}
); }, }), ]; const table = useReactTable({ data: allNotifications?.notifications || [], columns, state: { rowSelection, pagination, }, enableRowSelection: true, onRowSelectionChange: setRowSelection, onPaginationChange: setPagination, getCoreRowModel: getCoreRowModel(), getPaginationRowModel: getPaginationRowModel(), manualPagination: true, pageCount: totalPages, }); async function notificationActionHandler(ids: number[], action: 'remove' | 'mark-as-read') { setLoadingIds(prev => { const newSet = new Set(prev); ids.forEach(id => newSet.add(id)); return newSet; }); try { let response; if (action === 'mark-as-read') { response = await notificationsMarkAsRead(ids); } else if (action === 'remove') { response = await notificationsDelete(ids); } if (response?.success) { setRowSelection({}); await queryClient.invalidateQueries({ queryKey: ['activeNotifications'] }); await queryClient.invalidateQueries({ queryKey: ['allNotifications'] }); } } catch (error) { const errorMessage = action === 'mark-as-read' ? 'Failed to mark as read' : 'Failed to remove'; setError(errorMessage); } finally { setLoadingIds(prev => { const newSet = new Set(prev); ids.forEach(id => newSet.delete(id)); return newSet; }); } } const getPageNumbers = (): (number | string)[] => { const delta: number = 2; const currentPageNum = pagination.pageIndex; const range: number[] = []; const rangeWithDots: (number | string)[] = []; let l: number | undefined; for (let i = 0; i < totalPages; i++) { if (i === 0 || i === totalPages - 1 || (i >= currentPageNum - delta && i <= currentPageNum + delta)) { range.push(i); } } range.forEach((i: number) => { if (l !== undefined) { if (i - l === 2) { rangeWithDots.push(l + 1); } else if (i - l !== 1) { rangeWithDots.push('...'); } } rangeWithDots.push(i); l = i; }); return rangeWithDots; }; return (

{t('all-notifications')}

{table.getHeaderGroups().map((headerGroup) => (
{headerGroup.headers.map((header) => (
{flexRender( header.column.columnDef.header, header.getContext() )}
))}
))}
{/*
{(selectedFiles.size !== 0) && ( <> )}
*/}
{allNotifications?.notifications.length !== 0 ? (
{table.getRowModel().rows.map((row) => (
{row.getVisibleCells().map((cell) => (
{flexRender( cell.column.columnDef.cell, cell.getContext() )}
))}
))}
) : (
{t('no-notifications')}
)}
{totalPages > 0 && (
{getPageNumbers().map((pageNum, index) => ( ))}
)}
{error &&
{error}
}
); }