From 1944728c059782036c44b56a5182451b1d76dfff Mon Sep 17 00:00:00 2001 From: Raja Oktafrianto Date: Fri, 9 May 2025 18:41:02 +0700 Subject: [PATCH] add date filter to manage notification --- src/pages/notification/blocks/ListToolbar.tsx | 155 ++++++++++++++---- .../hooks/ManageNotificationContext.tsx | 37 ++++- 2 files changed, 149 insertions(+), 43 deletions(-) diff --git a/src/pages/notification/blocks/ListToolbar.tsx b/src/pages/notification/blocks/ListToolbar.tsx index 4406253..f82c647 100644 --- a/src/pages/notification/blocks/ListToolbar.tsx +++ b/src/pages/notification/blocks/ListToolbar.tsx @@ -1,50 +1,126 @@ import { DefaultTooltip, KeenIcon, useDataGrid } from '@/components'; import { useManageNotificationContext } from '../hooks/useManageNotificationContext'; import { Button } from '@/components/ui/button'; -import { useEffect, useState } from 'react'; +import { useCallback, useEffect, useState } from 'react'; +import { toast } from 'sonner'; +import { DateRangePicker } from '@/pages/dashboards/home/blocks'; + +const getOneMonthsAgo = () => { + const today = new Date(); + return new Date(today.getFullYear(), today.getMonth() - 1, today.getDate()); +}; + +const formatDate = (date: Date): string => date.toISOString().split('T')[0]; const ListToolBar = () => { const { table, reload } = useDataGrid(); const { handleAddDialog } = useManageNotificationContext(); + const [dateRange, setDateRange] = useState({ from: '', to: '' }); const [searchValue, setSearchValue] = useState( (table.getColumn('content')?.getFilterValue() as string) ?? '' ); - const handleKeyDown = (event: React.KeyboardEvent) => { - if (event.key === 'Enter') { - handleSearch(); - } - }; - - const handleSearch = () => { - table.getColumn('content')?.setFilterValue(searchValue); - table.setPageIndex(0); - }; + useEffect(() => { + const today = new Date(); + const threeMonthsAgo = getOneMonthsAgo(); + setDateRange({ from: formatDate(threeMonthsAgo), to: formatDate(today) }); + }, []); useEffect(() => { const timer = setTimeout(() => { table.getColumn('content')?.setFilterValue(searchValue); table.setPageIndex(0); }, 200); - return () => clearTimeout(timer); }, [searchValue, table]); + const handleFilterByDate = useCallback(() => { + try { + table.getColumn('created_at')?.setFilterValue(dateRange); + } catch (error) { + toast.error('Error applying date filter'); + console.error('Error applying date filter:', error); + } + }, [dateRange, table]); + + useEffect(() => { + if (dateRange.from && dateRange.to) { + handleFilterByDate(); + } + }, [dateRange, handleFilterByDate]); + + const handleClearAllFilters = () => { + const today = new Date(); + const oneMonthAgo = getOneMonthsAgo(); + const resetDateRange = { + from: formatDate(oneMonthAgo), + to: formatDate(today) + }; + + setSearchValue(''); + setDateRange(resetDateRange); + + table.getColumn('content')?.setFilterValue(''); + table.getColumn('created_at')?.setFilterValue(resetDateRange); + + setTimeout(() => { + table.setPageIndex(0); + reload(); + }, 0); + }; + + const handleRefresh = () => { + const today = new Date(); + const threeMonthsAgo = getOneMonthsAgo(); + const resetDateRange = { + from: formatDate(threeMonthsAgo), + to: formatDate(today) + }; + + setSearchValue(''); + setDateRange(resetDateRange); + + table.setColumnFilters([{ id: 'created_at', value: resetDateRange }]); + table.setPageIndex(0); + reload(); + }; + return (
-
-
- - {/* +
+ + + + + + {/* */} -
-
+
+ +
+ + - - - -
+
+ + +
diff --git a/src/pages/notification/hooks/ManageNotificationContext.tsx b/src/pages/notification/hooks/ManageNotificationContext.tsx index 80ea544..aad0a33 100644 --- a/src/pages/notification/hooks/ManageNotificationContext.tsx +++ b/src/pages/notification/hooks/ManageNotificationContext.tsx @@ -86,7 +86,8 @@ const ManageNotifContextProvider = ({ children }: { children: React.ReactNode }) enableSorting: true, enableHiding: false, meta: { - headerClassName: 'w-[350px]' + headerClassName: 'w-[350px]', + searchable: true } }, { @@ -111,7 +112,7 @@ const ManageNotifContextProvider = ({ children }: { children: React.ReactNode }) enableHiding: false }, { - accessorFn: (row) => row.created_at, + accessorKey: 'created_at', id: 'created_at', header: ({ column }) => , enableSorting: true, @@ -124,16 +125,36 @@ const ManageNotifContextProvider = ({ children }: { children: React.ReactNode }) const getNotificationList = async (page: number, limit: number, sorting: any, filter: any) => { try { - sorting = sorting.length === 0 ? [{ id: 'created_at', desc: true }] : sorting; - filter = - filter.length == 0 ? {} : { content: { like: `%${filter[0].value?.toLowerCase()}%` } }; + const sortField = sorting.length > 0 ? sorting[0].id : 'created_at'; + const sortDirection = sorting.length > 0 ? (sorting[0].desc ? 'DESC' : 'ASC') : 'DESC'; + + // Initialize filter object + let filterParams: any = {}; + + // Process filter array + if (Array.isArray(filter)) { + filter.forEach((f: any) => { + if (f.id === 'content' && f.value) { + filterParams.content = { like: `%${f.value.toLowerCase()}%` }; + } + + // Handle date range filter + if (f.id === 'created_at' && f.value?.from && f.value?.to) { + filterParams.created_at = { + from: `${f.value.from} 00:00:00`, + to: `${f.value.to} 23:59:59` + }; + } + }); + } + const response = await GetData(`${API_URL_NOTIFICATION}/list`, { limit: limit, page: page + 1, with_deleted: false, - order_field: sorting[0].id, - order_direction: sorting[0].desc == false ? 'ASC' : 'DESC', - filter: JSON.stringify(filter) + order_field: sortField, + order_direction: sortDirection, + filter: JSON.stringify(filterParams) }); // console.log('API Response notif: ', response.); return { data: response?.data.list, totalCount: response?.data.total_count };