diff --git a/src/components/AbsenceClaimThanks.tsx b/src/components/AbsenceClaimThanks.tsx new file mode 100644 index 00000000..07c3734a --- /dev/null +++ b/src/components/AbsenceClaimThanks.tsx @@ -0,0 +1,82 @@ +import { + Button, + Flex, + Modal, + ModalBody, + ModalContent, + ModalFooter, + ModalHeader, + ModalOverlay, + Text, + useTheme, +} from '@chakra-ui/react'; +import { FiCheckCircle } from 'react-icons/fi'; + +const AbsenceClaimThanks = ({ isOpen, onClose, event, absenceDate }) => { + const theme = useTheme(); + + return ( + + + + + + + Thank you! + + + + + You have successfully claimed + + {event?.absentTeacher?.firstName + "'s"} + + {' absence on '} + + {absenceDate + '.'} + + + Make sure to review the lesson plan! + + + Note: + + Please contact admin for any modifications. + + + + + + + + ); +}; + +export default AbsenceClaimThanks; diff --git a/src/components/AbsenceDetails.tsx b/src/components/AbsenceDetails.tsx index 8c6efecf..bf43595d 100644 --- a/src/components/AbsenceDetails.tsx +++ b/src/components/AbsenceDetails.tsx @@ -24,6 +24,7 @@ import { IoEyeOutline } from 'react-icons/io5'; import AbsenceStatusTag from './AbsenceStatusTag'; import EditAbsenceForm from './EditAbsenceForm'; import LessonPlanView from './LessonPlanView'; +import AbsenceClaimThanks from './AbsenceClaimThanks'; interface AbsenceDetailsProps { isOpen: boolean; @@ -47,6 +48,9 @@ const AbsenceDetails: React.FC = ({ const [isDeleting, setIsDeleting] = useState(false); const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false); const [isEditModalOpen, setIsEditModalOpen] = useState(false); + const [isClaiming, setIsClaiming] = useState(false); + const [isClaimDialogOpen, setIsClaimDialogOpen] = useState(false); + const [isClaimThanksOpen, setIsClaimThanksOpen] = useState(false); const toast = useToast(); @@ -57,6 +61,94 @@ const AbsenceDetails: React.FC = ({ const isUserSubstituteTeacher = userId === event.substituteTeacher?.id; const isUserAdmin = userData.role === Role.ADMIN; + const getOrdinalNum = (number) => { + let selector; + + if (number <= 0) { + selector = 4; + } else if ((number > 3 && number < 21) || number % 10 > 3) { + selector = 0; + } else { + selector = number % 10; + } + + return number + ['th', 'st', 'nd', 'rd', ''][selector]; + }; + + const formatDate = (date: Date) => { + const parsedDate = new Date(date); + const weekday = parsedDate.toLocaleDateString('en-CA', { weekday: 'long' }); + const month = parsedDate.toLocaleDateString('en-CA', { month: 'long' }); + const day = parsedDate.getDate(); + + return `${weekday}, ${month} ${getOrdinalNum(day)}`; + }; + + const absenceDate = formatDate(event.start!!); + + const handleClaimThanksDone = () => { + setIsClaimThanksOpen(false); + }; + + const handleClaimAbsenceClick = () => { + setIsClaimDialogOpen(true); + }; + + const handleClaimCancel = () => { + setIsClaimDialogOpen(false); + }; + + const handleClaimConfirm = async () => { + setIsClaiming(true); + + try { + const response = await fetch('/api/editAbsence', { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + id: event.absenceId, + lessonDate: event.start, + reasonOfAbsence: event.reasonOfAbsence, + notes: event.notes, + absentTeacherId: event.absentTeacher.id, + substituteTeacherId: userData.id, + locationId: event.locationId, + subjectId: event.subjectId, + roomNumber: event.roomNumber, + }), + }); + + if (!response.ok) { + throw new Error('Failed to claim absence'); + } + + toast({ + title: 'Absence claimed', + description: 'You have successfully claimed this absence.', + status: 'success', + duration: 5000, + isClosable: true, + }); + + await fetchAbsences(); + setIsClaimDialogOpen(false); + setIsClaimThanksOpen(true); + } catch (error) { + toast({ + title: 'Error', + description: error.message || 'Failed to claim absence', + status: 'error', + duration: 5000, + isClosable: true, + }); + } finally { + setIsClaiming(false); + onClose(); + } + }; + const handleEditClick = () => { setIsEditModalOpen(true); }; @@ -180,13 +272,7 @@ const AbsenceDetails: React.FC = ({ - {event.start - ? new Date(event.start).toLocaleDateString('en-CA', { - weekday: 'long', - month: 'long', - day: 'numeric', - }) - : 'N/A'} + {absenceDate} @@ -335,6 +421,7 @@ const AbsenceDetails: React.FC = ({ height="44px" fontSize="16px" fontWeight="500" + onClick={handleClaimAbsenceClick} > Fill this Absence @@ -343,6 +430,60 @@ const AbsenceDetails: React.FC = ({ + + + + + Are you sure you want to fill this absence? + + + {"You won't be able to undo."} + + + + + + + +