diff --git a/src/components/absences/details/AbsenceDetails.tsx b/src/components/absences/details/AbsenceDetails.tsx index d305e4b7..9e362cfb 100644 --- a/src/components/absences/details/AbsenceDetails.tsx +++ b/src/components/absences/details/AbsenceDetails.tsx @@ -23,6 +23,7 @@ import { FiEdit2, FiMapPin, FiTrash2, FiUser } from 'react-icons/fi'; import { IoEyeOutline } from 'react-icons/io5'; import EditAbsenceForm from '../modals/edit/EditAbsenceForm'; import AbsenceFillThanks from './AbsenceFillThanks'; +import ClaimAbsenceToast from './ClaimAbsenceToast'; import AbsenceStatusTag from './AbsenceStatusTag'; import EditableNotes from './EditableNotes'; import LessonPlanView from './LessonPlanView'; @@ -102,6 +103,13 @@ const AbsenceDetails: React.FC = ({ const handleFillConfirm = async () => { setIsFilling(true); + const formattedDate = new Date(event.start).toLocaleDateString('en-CA', { + weekday: 'long', + year: 'numeric', + month: 'long', + day: 'numeric', + }); + try { const response = await fetch('/api/editAbsence', { method: 'PUT', @@ -126,21 +134,31 @@ const AbsenceDetails: React.FC = ({ } toast({ - title: 'Absence filled', - description: 'You have successfully filled this absence.', - status: 'success', isClosable: true, + position: 'bottom-left', + render: () => ( + + ), }); await fetchAbsences(); setIsFillDialogOpen(false); setIsFillThanksOpen(true); - } catch (error) { + } catch { toast({ - title: 'Error', - description: error.message || 'Failed to fill absence', - status: 'error', isClosable: true, + position: 'bottom-left', + render: () => ( + + ), }); } finally { setIsFilling(false); diff --git a/src/components/absences/details/ClaimAbsenceToast.tsx b/src/components/absences/details/ClaimAbsenceToast.tsx new file mode 100644 index 00000000..a0fa6e6a --- /dev/null +++ b/src/components/absences/details/ClaimAbsenceToast.tsx @@ -0,0 +1,48 @@ +import { Box, Text, useTheme } from '@chakra-ui/react'; +import { MdCheckCircle, MdError } from 'react-icons/md'; + +const ClaimAbsenceToast = ({ firstName, date, success }) => { + const theme = useTheme(); + + const modalColor = success + ? theme.colors.positiveGreen[200] + : theme.colors.errorRed[200]; + + const message = success + ? `You have successfully claimed ` + : `There was an error in claiming `; + + const Icon = success ? MdCheckCircle : MdError; + + return ( + + + + + + {message} + + {firstName}'s + {' '} + absence on{' '} + + {date}. + + + + ); +}; + +export default ClaimAbsenceToast; diff --git a/src/components/absences/modals/declare/ConfirmDeclareModal.tsx b/src/components/absences/modals/declare/ConfirmDeclareModal.tsx index 4de69076..a3391278 100644 --- a/src/components/absences/modals/declare/ConfirmDeclareModal.tsx +++ b/src/components/absences/modals/declare/ConfirmDeclareModal.tsx @@ -1,5 +1,9 @@ +import { WarningTwoIcon } from '@chakra-ui/icons'; import { + Box, Button, + HStack, + Icon, Modal, ModalBody, ModalContent, @@ -7,47 +11,110 @@ import { ModalHeader, ModalOverlay, Text, + useTheme, + VStack, } from '@chakra-ui/react'; -interface ConfirmAbsenceModalProps { +interface ConfirmDeclareModalProps { isOpen: boolean; onClose: () => void; onConfirm: () => void; - isSubmitting?: boolean; + isSubmitting: boolean; lessonDate: string; + hasLessonPlan: boolean; + isWithin14Days: boolean; } -export const ConfirmAbsenceModal: React.FC = ({ +export const ConfirmDeclareModal: React.FC = ({ isOpen, onClose, onConfirm, - isSubmitting = false, + isSubmitting, lessonDate, + hasLessonPlan, + isWithin14Days, }) => { - const formattedDate = new Date(lessonDate + 'T00:00:00').toLocaleDateString( - 'en-CA', - { - weekday: 'long', - month: 'long', - day: 'numeric', - } - ); + const theme = useTheme(); + + const formattedDate = new Date(lessonDate).toLocaleDateString('en-CA', { + month: 'long', + day: 'numeric', + year: 'numeric', + }); return ( - - Confirm Absence - - - Please confirm your absence on {formattedDate}. + + + + {hasLessonPlan ? 'Confirm Absence' : 'No Lesson Plan Added'} + + + + + + {hasLessonPlan ? ( + <> + Please confirm your absence on{' '} + {formattedDate}. + + ) : ( + <> + Declare absence on {formattedDate} without + adding a lesson plan? + + )} + + {isWithin14Days && ( + + + + + You are submitting a late report. Please aim to report + absences at least 14 days in advance. + + + )} + + - - - diff --git a/src/components/absences/modals/declare/DeclareAbsenceForm.tsx b/src/components/absences/modals/declare/DeclareAbsenceForm.tsx index 40b79947..3e395ccf 100644 --- a/src/components/absences/modals/declare/DeclareAbsenceForm.tsx +++ b/src/components/absences/modals/declare/DeclareAbsenceForm.tsx @@ -19,7 +19,7 @@ import { FileUpload } from '../../FileUpload'; import { AdminTeacherFields } from '../AdminTeacherFields'; import { DateOfAbsence } from '../DateOfAbsence'; import { InputDropdown } from '../InputDropdown'; -import { ConfirmAbsenceModal } from './ConfirmDeclareModal'; +import { ConfirmDeclareModal } from './ConfirmDeclareModal'; interface DeclareAbsenceFormProps { onClose?: () => void; @@ -170,6 +170,11 @@ const DeclareAbsenceForm: React.FC = ({ })); }; + const selectedDate = new Date(formData.lessonDate + 'T00:00:00'); + const now = new Date(); + const isWithin14Days = + (selectedDate.getTime() - now.getTime()) / (1000 * 60 * 60 * 24) <= 14; + return ( = ({ Declare Absence - - );