Skip to content

Commit adfc2a5

Browse files
Merge pull request #98 from uwblueprint/modalChanges
Confirm Absence Modals and Toasts
2 parents e45b42e + 0a40723 commit adfc2a5

File tree

4 files changed

+170
-31
lines changed

4 files changed

+170
-31
lines changed

src/components/absences/details/AbsenceDetails.tsx

+25-7
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import { FiEdit2, FiMapPin, FiTrash2, FiUser } from 'react-icons/fi';
2323
import { IoEyeOutline } from 'react-icons/io5';
2424
import EditAbsenceForm from '../modals/edit/EditAbsenceForm';
2525
import AbsenceFillThanks from './AbsenceFillThanks';
26+
import ClaimAbsenceToast from './ClaimAbsenceToast';
2627
import AbsenceStatusTag from './AbsenceStatusTag';
2728
import EditableNotes from './EditableNotes';
2829
import LessonPlanView from './LessonPlanView';
@@ -102,6 +103,13 @@ const AbsenceDetails: React.FC<AbsenceDetailsProps> = ({
102103
const handleFillConfirm = async () => {
103104
setIsFilling(true);
104105

106+
const formattedDate = new Date(event.start).toLocaleDateString('en-CA', {
107+
weekday: 'long',
108+
year: 'numeric',
109+
month: 'long',
110+
day: 'numeric',
111+
});
112+
105113
try {
106114
const response = await fetch('/api/editAbsence', {
107115
method: 'PUT',
@@ -126,21 +134,31 @@ const AbsenceDetails: React.FC<AbsenceDetailsProps> = ({
126134
}
127135

128136
toast({
129-
title: 'Absence filled',
130-
description: 'You have successfully filled this absence.',
131-
status: 'success',
132137
isClosable: true,
138+
position: 'bottom-left',
139+
render: () => (
140+
<ClaimAbsenceToast
141+
firstName={event.absentTeacher.firstName}
142+
date={formattedDate}
143+
success={true}
144+
/>
145+
),
133146
});
134147

135148
await fetchAbsences();
136149
setIsFillDialogOpen(false);
137150
setIsFillThanksOpen(true);
138-
} catch (error) {
151+
} catch {
139152
toast({
140-
title: 'Error',
141-
description: error.message || 'Failed to fill absence',
142-
status: 'error',
143153
isClosable: true,
154+
position: 'bottom-left',
155+
render: () => (
156+
<ClaimAbsenceToast
157+
firstName={event.absentTeacher.firstName}
158+
date={formattedDate}
159+
success={false}
160+
/>
161+
),
144162
});
145163
} finally {
146164
setIsFilling(false);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { Box, Text, useTheme } from '@chakra-ui/react';
2+
import { MdCheckCircle, MdError } from 'react-icons/md';
3+
4+
const ClaimAbsenceToast = ({ firstName, date, success }) => {
5+
const theme = useTheme();
6+
7+
const modalColor = success
8+
? theme.colors.positiveGreen[200]
9+
: theme.colors.errorRed[200];
10+
11+
const message = success
12+
? `You have successfully claimed `
13+
: `There was an error in claiming `;
14+
15+
const Icon = success ? MdCheckCircle : MdError;
16+
17+
return (
18+
<Box
19+
bg="white"
20+
width="360px"
21+
height="60px"
22+
border="1px solid"
23+
borderColor={modalColor}
24+
borderRadius="md"
25+
px={3}
26+
py={3}
27+
display="flex"
28+
alignItems="center"
29+
boxShadow="md"
30+
>
31+
<Box mr={4}>
32+
<Icon size="38px" color={modalColor} />
33+
</Box>
34+
<Text fontSize="14px" color="black">
35+
{message}
36+
<Text as="span" fontWeight="bold">
37+
{firstName}&apos;s
38+
</Text>{' '}
39+
absence on{' '}
40+
<Text as="span" fontWeight="bold">
41+
{date}.
42+
</Text>
43+
</Text>
44+
</Box>
45+
);
46+
};
47+
48+
export default ClaimAbsenceToast;

src/components/absences/modals/declare/ConfirmDeclareModal.tsx

+88-21
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,120 @@
1+
import { WarningTwoIcon } from '@chakra-ui/icons';
12
import {
3+
Box,
24
Button,
5+
HStack,
6+
Icon,
37
Modal,
48
ModalBody,
59
ModalContent,
610
ModalFooter,
711
ModalHeader,
812
ModalOverlay,
913
Text,
14+
useTheme,
15+
VStack,
1016
} from '@chakra-ui/react';
1117

12-
interface ConfirmAbsenceModalProps {
18+
interface ConfirmDeclareModalProps {
1319
isOpen: boolean;
1420
onClose: () => void;
1521
onConfirm: () => void;
16-
isSubmitting?: boolean;
22+
isSubmitting: boolean;
1723
lessonDate: string;
24+
hasLessonPlan: boolean;
25+
isWithin14Days: boolean;
1826
}
1927

20-
export const ConfirmAbsenceModal: React.FC<ConfirmAbsenceModalProps> = ({
28+
export const ConfirmDeclareModal: React.FC<ConfirmDeclareModalProps> = ({
2129
isOpen,
2230
onClose,
2331
onConfirm,
24-
isSubmitting = false,
32+
isSubmitting,
2533
lessonDate,
34+
hasLessonPlan,
35+
isWithin14Days,
2636
}) => {
27-
const formattedDate = new Date(lessonDate + 'T00:00:00').toLocaleDateString(
28-
'en-CA',
29-
{
30-
weekday: 'long',
31-
month: 'long',
32-
day: 'numeric',
33-
}
34-
);
37+
const theme = useTheme();
38+
39+
const formattedDate = new Date(lessonDate).toLocaleDateString('en-CA', {
40+
month: 'long',
41+
day: 'numeric',
42+
year: 'numeric',
43+
});
3544

3645
return (
3746
<Modal isOpen={isOpen} onClose={onClose} isCentered>
3847
<ModalOverlay />
39-
<ModalContent>
40-
<ModalHeader>Confirm Absence</ModalHeader>
41-
<ModalBody>
42-
<Text>
43-
Please confirm your absence on <strong>{formattedDate}</strong>.
48+
<ModalContent
49+
maxW="300px"
50+
height={isWithin14Days ? '200px' : '160px'}
51+
borderRadius="lg"
52+
>
53+
<ModalHeader textAlign="center" fontSize="16px" pb={0} pt={5}>
54+
<Text textStyle="h3">
55+
{hasLessonPlan ? 'Confirm Absence' : 'No Lesson Plan Added'}
4456
</Text>
57+
</ModalHeader>
58+
<ModalBody display="flex" justifyContent="center">
59+
<Box maxW="224px" w="100%">
60+
<VStack align="start" pl={1}>
61+
<Text textStyle="subtitle" color="black">
62+
{hasLessonPlan ? (
63+
<>
64+
Please confirm your absence on{' '}
65+
<strong>{formattedDate}.</strong>
66+
</>
67+
) : (
68+
<>
69+
Declare absence on <strong>{formattedDate}</strong> without
70+
adding a lesson plan?
71+
</>
72+
)}
73+
</Text>
74+
{isWithin14Days && (
75+
<HStack align="center" spacing={3}>
76+
<Icon
77+
as={WarningTwoIcon}
78+
boxSize="20px"
79+
color={theme.colors.warningOrange[300]}
80+
/>
81+
82+
<Text
83+
textStyle="body"
84+
color={theme.colors.warningOrange[300]}
85+
>
86+
You are submitting a late report. Please aim to report
87+
absences at least 14 days in advance.
88+
</Text>
89+
</HStack>
90+
)}
91+
</VStack>
92+
</Box>
4593
</ModalBody>
46-
<ModalFooter>
47-
<Button onClick={onClose} mr={3}>
48-
Cancel
94+
<ModalFooter
95+
display="flex"
96+
justifyContent="center"
97+
gap={5}
98+
px={0}
99+
pt={0}
100+
>
101+
<Button
102+
onClick={onClose}
103+
flex="1"
104+
maxW="104px"
105+
h="40px"
106+
variant="outline"
107+
>
108+
Back
49109
</Button>
50-
<Button onClick={onConfirm} isLoading={isSubmitting}>
110+
<Button
111+
colorScheme="blue"
112+
onClick={onConfirm}
113+
isLoading={isSubmitting}
114+
flex="1"
115+
maxW="104px"
116+
h="40px"
117+
>
51118
Confirm
52119
</Button>
53120
</ModalFooter>

src/components/absences/modals/declare/DeclareAbsenceForm.tsx

+9-3
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { FileUpload } from '../../FileUpload';
1919
import { AdminTeacherFields } from '../AdminTeacherFields';
2020
import { DateOfAbsence } from '../DateOfAbsence';
2121
import { InputDropdown } from '../InputDropdown';
22-
import { ConfirmAbsenceModal } from './ConfirmDeclareModal';
22+
import { ConfirmDeclareModal } from './ConfirmDeclareModal';
2323

2424
interface DeclareAbsenceFormProps {
2525
onClose?: () => void;
@@ -170,6 +170,11 @@ const DeclareAbsenceForm: React.FC<DeclareAbsenceFormProps> = ({
170170
}));
171171
};
172172

173+
const selectedDate = new Date(formData.lessonDate + 'T00:00:00');
174+
const now = new Date();
175+
const isWithin14Days =
176+
(selectedDate.getTime() - now.getTime()) / (1000 * 60 * 60 * 24) <= 14;
177+
173178
return (
174179
<Box
175180
as="form"
@@ -297,13 +302,14 @@ const DeclareAbsenceForm: React.FC<DeclareAbsenceFormProps> = ({
297302
Declare Absence
298303
</Button>
299304
</VStack>
300-
301-
<ConfirmAbsenceModal
305+
<ConfirmDeclareModal
302306
isOpen={isOpen}
303307
onClose={closeModal}
304308
onConfirm={handleConfirmSubmit}
305309
isSubmitting={isSubmitting}
306310
lessonDate={formData.lessonDate}
311+
hasLessonPlan={!!lessonPlan}
312+
isWithin14Days={isWithin14Days}
307313
/>
308314
</Box>
309315
);

0 commit comments

Comments
 (0)