diff --git a/src/pages/notification/blocks/ListToolbar.tsx b/src/pages/notification/blocks/ListToolbar.tsx index e0fbe89..3aca567 100644 --- a/src/pages/notification/blocks/ListToolbar.tsx +++ b/src/pages/notification/blocks/ListToolbar.tsx @@ -5,11 +5,6 @@ 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 = () => { @@ -22,8 +17,8 @@ const ListToolBar = () => { useEffect(() => { const today = new Date(); - const threeMonthsAgo = getOneMonthsAgo(); - setDateRange({ from: formatDate(threeMonthsAgo), to: formatDate(today) }); + const formatted = formatDate(today); + setDateRange({ from: formatted, to: formatted }); }, []); useEffect(() => { @@ -34,26 +29,25 @@ const ListToolBar = () => { 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(); + const today = new Date(); + const formatted = formatDate(today); + const initialDateRange = { from: formatted, to: formatted }; + + setDateRange(initialDateRange); + + try { + table.getColumn('created_at')?.setFilterValue(initialDateRange); + } catch (error) { + toast.error('Error applying initial date filter'); + console.error('Initial date filter error:', error); } - }, [dateRange, handleFilterByDate]); + }, []); const handleClearAllFilters = () => { const today = new Date(); - const oneMonthAgo = getOneMonthsAgo(); const resetDateRange = { - from: formatDate(oneMonthAgo), + from: formatDate(today), to: formatDate(today) }; @@ -69,21 +63,27 @@ const ListToolBar = () => { }, 0); }; - const handleRefresh = () => { - const today = new Date(); - const threeMonthsAgo = getOneMonthsAgo(); - const resetDateRange = { - from: formatDate(threeMonthsAgo), - to: formatDate(today) + useEffect(() => { + try { + table.getColumn('created_at')?.setFilterValue(dateRange); + } catch (error) { + toast.error('Error applying date filter'); + console.error('Date filter error:', error); + } + }, [dateRange]); + + useEffect(() => { + const checkNewDay = () => { + const now = new Date(); + const formattedNow = formatDate(now); + if (formattedNow !== dateRange.from || formattedNow !== dateRange.to) { + setDateRange({ from: formattedNow, to: formattedNow }); + } }; - setSearchValue(''); - setDateRange(resetDateRange); - - table.setColumnFilters([{ id: 'created_at', value: resetDateRange }]); - table.setPageIndex(0); - reload(); - }; + const interval = setInterval(checkNewDay, 60 * 1000); + return () => clearInterval(interval); + }, [dateRange]); return (
diff --git a/src/pages/notification/blocks/ShowDetailDialog.tsx b/src/pages/notification/blocks/ShowDetailDialog.tsx new file mode 100644 index 0000000..2edfd25 --- /dev/null +++ b/src/pages/notification/blocks/ShowDetailDialog.tsx @@ -0,0 +1,97 @@ +import { useState } from 'react'; +import { useManageNotificationContext } from '../hooks/useManageNotificationContext'; +import { + Dialog, + DialogBody, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle +} from '@/components/ui/dialog'; +import moment from 'moment'; + +const ShowDialog = () => { + const { showDetailDialog, setShowDetailDialog, selectedNotification } = + useManageNotificationContext(); + const [isLoading, setIsLoading] = useState(false); + + return ( + + + + Notification Details + + +
+ {isLoading ? ( +
Loading details...
+ ) : ( +
+ {/* Mobile View (Card Layout) */} +
+ {selectedNotification ? ( +
+
+

Send

+

+ {selectedNotification.all_customers === 'Y' + ? 'All Customers' + : selectedNotification.customer_name || '-'} +

+
+
+

Content

+

+ {selectedNotification.content} +

+
+ {/* Field lainnya... */} +
+ ) : null} +
+ + {/* Desktop View (Table) */} +
+ + + + + + + + + + + + + {selectedNotification && ( + + + + + + + + + )} + +
SendContentSubjectTypeViaDate Create
+ {selectedNotification.all_customers === 'Y' + ? 'All Customers' + : selectedNotification.customer_name || '-'} + + {selectedNotification.content} + {selectedNotification.subject}{selectedNotification.type}{selectedNotification.via} + {moment(selectedNotification.created_at).format('YYYY-MM-DD HH:mm:ss')} +
+
+
+ )} +
+
+
+
+ ); +}; + +export default ShowDialog; diff --git a/src/pages/notification/hooks/ManageNotificationContext.tsx b/src/pages/notification/hooks/ManageNotificationContext.tsx index d43702d..c4995f3 100644 --- a/src/pages/notification/hooks/ManageNotificationContext.tsx +++ b/src/pages/notification/hooks/ManageNotificationContext.tsx @@ -6,18 +6,23 @@ import React, { createContext, useCallback, useMemo, useState } from 'react'; import { ListToolBar } from '../blocks/ListToolbar'; import { useCallApi } from '@/hooks'; import moment from 'moment'; +import ShowDetailDialog from '../blocks/ShowDetailDialog'; interface ContextProps { + showDetailDialog: boolean; + setShowDetailDialog: React.Dispatch>; showAddDialog: boolean; handleAddDialog: (show: boolean) => void; showEditDialog: boolean; handleEditDialog: (show: boolean, selected_notification: string | null) => void; showDeleteDialog: boolean; handleDeleteDialog: (show: boolean, selected_notification: string | null) => void; - selectedNotification: string | null; + selectedNotification: any | null; } const initialProps: ContextProps = { + showDetailDialog: false, + setShowDetailDialog: () => {}, showAddDialog: false, handleAddDialog: (show: boolean) => {}, showEditDialog: false, @@ -31,10 +36,11 @@ const ManageNotifContext = createContext(initialProps); const API_URL_NOTIFICATION = apiConfig.service_notification; const ManageNotifContextProvider = ({ children }: { children: React.ReactNode }) => { + const [showDetailDialog, setShowDetailDialog] = useState(false); const [showEditDialog, setShowEditDialog] = useState(false); const [showAddDialog, setShowAddDialog] = useState(false); const [showDeleteDialog, setShowDeleteDialog] = useState(false); - const [selectedNotification, setSelectedNotification] = useState(null); + const [selectedNotification, setSelectedNotification] = useState(null); const { GetData } = useCallApi(); const handleAddDialog = useCallback((show: boolean) => { @@ -77,6 +83,20 @@ const ManageNotifContextProvider = ({ children }: { children: React.ReactNode }) meta: { headerClassName: 'w-[350px]', searchable: true + }, + cell: ({ row }) => { + const content = row.original.content; + const paragraphs = content.split(/\n+/); + + const preview = paragraphs.slice(0, 2).join('\n'); + const isTruncated = paragraphs.length > 2; + + return ( +
+ {preview} + {isTruncated && '...'} +
+ ); } }, { @@ -107,6 +127,29 @@ const ManageNotifContextProvider = ({ children }: { children: React.ReactNode }) enableSorting: true, enableHiding: false, cell: ({ row }) => moment(row.original.created_at).format('YYYY-MM-DD HH:mm:ss') + }, + { + accessorKey: 'detail', + id: 'detail', + header: ({ column }) => , + enableSorting: false, + enableHiding: false, + cell: (data) => { + const row = data.row.original; + return ( +
+ +
+ ); + } } ], [handleEditDialog, handleDeleteDialog] @@ -156,6 +199,8 @@ const ManageNotifContextProvider = ({ children }: { children: React.ReactNode })
+ +