From 86f18f8140e07194989a5865ab4561bf9eca425f Mon Sep 17 00:00:00 2001 From: Amelia Vance Date: Fri, 12 Apr 2024 16:49:11 -0400 Subject: [PATCH] Update notifications page table and form data and display --- .../src/pages/Notifications/Notifications.tsx | 386 +++++++++++++----- 1 file changed, 280 insertions(+), 106 deletions(-) diff --git a/frontend/src/pages/Notifications/Notifications.tsx b/frontend/src/pages/Notifications/Notifications.tsx index 391bcb18..1ea070ee 100644 --- a/frontend/src/pages/Notifications/Notifications.tsx +++ b/frontend/src/pages/Notifications/Notifications.tsx @@ -1,77 +1,148 @@ import React from 'react'; import { + Box, Button, + Card, + CardActions, + Dialog, + DialogActions, + DialogContent, + DialogTitle, Grid, IconButton, MenuItem, Paper, Select, + Switch, TextField, Typography } from '@mui/material'; import { SelectChangeEvent } from '@mui/material/Select'; -import { Delete } from '@mui/icons-material'; +import { Delete, Edit } from '@mui/icons-material'; import { DataGrid, gridClasses, GridColDef, GridRenderCellParams } from '@mui/x-data-grid'; +import { format } from 'date-fns'; +import { useAuthContext } from 'context'; +import { initialNotificationValues, MaintenanceNotification } from 'types'; -type InputFormValues = { - id: string; - maintenanceType: string; - status: string; - updatedAt: string; - updatedBy: string; - message: string; +const formReadableDate = (date: string) => { + const parsedDate = new Date(date); + return format(parsedDate, 'yyyy-MM-dd HH:mm'); }; -const initialInputFormValues = { - id: '', - maintenanceType: '', - status: '', - updatedAt: '', - updatedBy: '', - message: '' +const humanReadableDate = (date: string) => { + const parsedDate = new Date(date); + return format(parsedDate, 'LLL dd, yyyy hh:mm a'); }; -// Test data. Will be removed once update to backend is added. -const rows = [ - { - id: '1', - maintenanceType: 'minor', - status: 'active', - updatedAt: '12/12/2024', - updatedBy: 'john.smith@test.com', - message: - 'Crossfeed has scheduled minor server maintenance on 3/28/2024 from 8:00AM to 5:00PM. Access to your Crossfeed settings will be limited. We apologize for the inconvenience. For further information, please reach out to admin@crossfeed.com.' - } -]; - export const Notifications: React.FC = () => { - const [values, setValues] = React.useState( - initialInputFormValues + const { apiGet } = useAuthContext(); + const [formValues, setFormValues] = React.useState( + initialNotificationValues + ); + const [activeNotification, setActiveNotification] = React.useState( + initialNotificationValues ); + const [inactiveNotifications, setInactiveNotifications] = React.useState([ + initialNotificationValues + ]); + const [addBtnToggle, setAddBtnToggle] = React.useState(false); + const [dialogToggle, setDialogToggle] = React.useState(false); + const [checked, setChecked] = React.useState(false); + + const tableStyling = { + [`& .${gridClasses.cell}`]: { py: 1 }, + minHeight: { xs: '250px', md: 'unset' } + }; + + const fetchNotifications = React.useCallback(async () => { + try { + const rows = await apiGet('/notifications'); + const activeRow = rows.find( + (row: { status: string }) => row.status === 'active' + ); + const inactiveRows = rows.filter( + (row: MaintenanceNotification) => row.status !== 'active' + ); + setActiveNotification(activeRow); + setInactiveNotifications(inactiveRows); + } catch (e: any) { + console.log(e); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [apiGet]); + + React.useEffect(() => { + fetchNotifications(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); const columns: GridColDef[] = [ - { field: 'id' }, { field: 'maintenanceType', headerName: 'Type', - flex: 1, + flex: 0.5, renderCell: (cellValues: any) => { - console.log(cellValues.value); return <>{cellValues.value.toUpperCase()}; } }, - { field: 'updatedAt', headerName: 'Created Date', flex: 1 }, - { field: 'updatedBy', headerName: 'Admin Email', flex: 1 }, - { field: 'message', headerName: 'Message', flex: 3 }, + { + field: 'timeFrame', + headerName: 'Time Frame', + flex: 1.5, + minWidth: 180, + renderCell: (cellValues: GridRenderCellParams) => { + const startDate = humanReadableDate(cellValues.row.startDatetime); + const endDate = humanReadableDate(cellValues.row.endDatetime); + return ( + <> + {startDate} to +
{endDate} + + ); + } + }, + { field: 'updatedBy', headerName: 'Admin Email', flex: 2 }, + { field: 'message', headerName: 'Message', flex: 3, minWidth: 200 }, + { + field: 'update', + headerName: 'Update', + flex: 0.4, + minWidth: 50, + renderCell: (cellValues: GridRenderCellParams) => { + return ( + { + cellValues.row.startDatetime = formReadableDate( + cellValues.row.startDatetime + ); + cellValues.row.endDatetime = formReadableDate( + cellValues.row.endDatetime + ); + if (cellValues.row.status === 'active') { + setChecked(true); + } else { + setChecked(false); + } + setFormValues(cellValues.row); + setDialogToggle(true); + }} + > + + + ); + } + }, { field: 'delete', headerName: 'Delete', flex: 0.4, + minWidth: 50, renderCell: (cellValues: GridRenderCellParams) => { return ( { } ]; - const onTextChange: React.ChangeEventHandler< - HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement - > = (e) => onChange(e.target.name, e.target.value); - - const onChange = (name: string, value: any) => { - setValues((values) => ({ - ...values, - [name]: value - })); + const handleResetForm = () => { + setDialogToggle(false); + setAddBtnToggle(false); + setFormValues(initialNotificationValues); }; - const handleChange = (event: SelectChangeEvent) => { - setValues((values) => ({ + const handleChange = (event: SelectChangeEvent | any) => { + setFormValues((values) => ({ ...values, [event.target.name]: event.target.value })); }; + const onSwitchChange = (event: React.ChangeEvent) => { + setChecked(event.target.checked); + if (event.target.checked) { + setFormValues((values) => ({ + ...values, + status: 'active' + })); + } else { + setFormValues((values) => ({ + ...values, + status: 'inactive' + })); + } + }; + const formContents = ( + <> + + Maintenance Type + + + + Start Date and Time + + + + End Date and Time + + + + Maintenance Message + + + + Status + + + Active + + * Only one notification can be active at a time. Setting a notification + to active will automatically replace the current active one regardless + of its duration. + + + ); + const createNotificationCard = ( + + + + Create a Notification + + {formContents} + + + + + + + ); + const editNotificationDialog = ( + + + setDialogToggle(false)}> + Update Notification + {formContents} + + + + + + + ); return ( - + Maintenance Notifications - + + + + + + {addBtnToggle && createNotificationCard} + - Active Notifications + Active Notification 'auto'} - sx={{ - [`& .${gridClasses.cell}`]: { - py: 1 - } - }} + sx={tableStyling} hideFooterPagination={true} disableRowSelectionOnClick /> - + - Create a Notification - - - Maintenance Type - - - - Maintenance Message + Inactive Notifications - - + 'auto'} + sx={tableStyling} + disableRowSelectionOnClick + /> + {editNotificationDialog} ); };