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."}
+
+
+
+
+
+
+
+