import { useState, useRef, useEffect } from 'react'; import VisibilityIcon from '@mui/icons-material/Visibility'; import ContentCopyIcon from '@mui/icons-material/ContentCopy'; import CancelIcon from '@mui/icons-material/Cancel'; import RefreshIcon from '@mui/icons-material/Refresh'; import { Box, useTheme, useMediaQuery, CircularProgress, IconButton, List, Card, CardContent, Typography } from '@mui/material'; import { DataGrid, GridColDef, GridRenderCellParams, GridToolbarContainer, GridToolbarQuickFilter, GridToolbarExport, GridToolbarDensitySelector, GridToolbarColumnsButton } from '@mui/x-data-grid'; import Mailing from '@/types/mailing'; import MailingEdit from "@/components/modals/MailingEdit"; import MailingView from "@/components/modals/MailingView"; // Assume this is a new read-only view component import ConfirmationDialog from "@/components/modals/ConfirmationDialog"; function ScheduleMailings() { const theme = useTheme(); const isMobile = useMediaQuery(theme.breakpoints.down("sm")); const gridContainerRef = useRef(null); const [mailingsLoading, setMailingsLoading] = useState(false); const [mailings, setMailings] = useState([]); const [selectedRow, setSelectedRow] = useState(null); const [viewOpen, setViewOpen] = useState(false); const [editOpen, setEditOpen] = useState(false); const [confirmDialogOpen, setConfirmDialogOpen] = useState(false); const [mailingToCancel, setMailingToCancel] = useState(null); const [forceRender, setForceRender] = useState(false); const formatRecurringString = (typeCode: string, startDate: string): string => { const date = new Date(startDate); switch (typeCode.toUpperCase()) { case 'D': return `Daily at ${date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}`; case 'W': return `Weekly on ${date.toLocaleDateString('en-US', { weekday: 'long' })} at ${date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}`; case 'M': return `Monthly on day ${date.getDate()} at ${date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}`; default: return 'Custom recurring schedule'; } }; const columns: GridColDef[] = [ { field: "actions", headerName: "", sortable: false, width: 140, renderCell: (params: GridRenderCellParams) => ( <> { e.stopPropagation(); handleView(params.row); }}> { e.stopPropagation(); handleCopy(params.row); }}> { e.stopPropagation(); handleCancelClick(params.row); }}> ), }, { field: "name", headerName: "Name", flex: 1, minWidth: 160 }, { field: "scheduleDate", headerName: "Schedule Date", flex: 1, minWidth: 200, valueGetter: (_: any, row: Mailing) => row.scheduleDate ? new Date(row.scheduleDate).toLocaleString() : 'N/A' }, { field: "recurring", headerName: "Recurring", flex: 1, minWidth: 200, valueGetter: (_: any, mailing: Mailing) => mailing.recurringTypeCode && mailing.recurringStartDate ? formatRecurringString(mailing.recurringTypeCode, mailing.recurringStartDate) : '' }, ]; const reloadMailings = async () => { setMailingsLoading(true); const mailingsResponse = await fetch("/api/mailings/status/sc"); // Adjust endpoint as needed const mailingsData = await mailingsResponse.json(); if (mailingsData) { setMailings(mailingsData); setMailingsLoading(false); setForceRender(true); } else { console.error("Failed to fetch scheduled mailings"); setMailingsLoading(false); } }; const handleView = (row: Mailing) => { setSelectedRow(row); setViewOpen(true); }; const handleCopy = (row: Mailing) => { const newMailing = { ...row, id: 0 }; // Copy all fields except ID setSelectedRow(newMailing); setEditOpen(true); }; const handleCancelClick = (row: Mailing) => { setMailingToCancel(row); setConfirmDialogOpen(true); }; const handleCancelConfirm = async () => { if (!mailingToCancel) return; try { const response = await fetch(`/api/mailings/${mailingToCancel.id}/cancel`, { method: 'POST' }); if (response.ok) { setMailings((prev) => prev.filter(m => m.id !== mailingToCancel.id)); } else { console.error("Failed to cancel mailing"); } } catch (error) { console.error("Error cancelling mailing:", error); } finally { setConfirmDialogOpen(false); setMailingToCancel(null); } }; const handleCancelDialogClose = () => { setConfirmDialogOpen(false); setMailingToCancel(null); }; const handleUpdateRow = (updatedRow: Mailing) => { setMailings((prev) => [...prev, updatedRow]); }; useEffect(() => { reloadMailings(); }, []); useEffect(() => { if (forceRender) { setForceRender(false); } }, [forceRender]); return ( {isMobile ? ( mailingsLoading ? ( ) : ( {mailings.map((mailing) => ( {mailing.name} Schedule Date: {mailing.scheduleDate ? new Date(mailing.scheduleDate).toLocaleString() : 'N/A'} Recurring: {mailing.recurringTypeCode && mailing.recurringStartDate ? formatRecurringString(mailing.recurringTypeCode, mailing.recurringStartDate) : 'None'} handleView(mailing)}> handleCopy(mailing)}> handleCancelClick(mailing)}> ))} )) : ( ( reloadMailings()} sx={{ marginLeft: 1 }}> {mailingsLoading ? : } ), }} slotProps={{ toolbar: { showQuickFilter: true, }, }} initialState={{ pagination: { paginationModel: { pageSize: 20, }, }, sorting: { sortModel: [{ field: 'scheduleDate', sort: 'asc' }], // Default sort by scheduleDate, descending }, }} pageSizeOptions={[10, 20, 50, 100]} /> )} {viewOpen && ( setViewOpen(false)} /> )} {editOpen && ( { if (reason !== 'backdropClick') setEditOpen(false) }} onSave={handleUpdateRow} /> )} {confirmDialogOpen && ( )} ); } export default ScheduleMailings;