Skip to content

Commit 58eb885

Browse files
authored
fix: move client-side attendance logic to server (#596)
1 parent 2e47213 commit 58eb885

14 files changed

+522
-258
lines changed

src/components/ModalAttendance.tsx

Lines changed: 82 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,18 @@ import { useMutation } from '@apollo/client';
44
import { format } from 'date-fns';
55
import { RECORD_ATTENDANCE } from '../Mutations/Attendance';
66
import AttendanceSymbols from './AttendanceSymbols';
7-
import { AttendanceDataInterface } from '../pages/TraineeAttendanceTracker';
7+
import {
8+
AttendanceDataInterface,
9+
UserInterface,
10+
} from '../pages/TraineeAttendanceTracker';
811

912
interface ModalProps {
1013
isVisible: boolean;
1114
onClose: () => void;
1215
setAttendanceData: React.Dispatch<
1316
React.SetStateAction<AttendanceDataInterface | undefined>
1417
>;
15-
trainees: any;
18+
trainees: UserInterface[];
1619
week: number;
1720
date: string;
1821
dayType: 'today' | 'yesterday' | 'others';
@@ -41,7 +44,7 @@ function ModalAttendance({
4144
team,
4245
teamName,
4346
}: ModalProps) {
44-
const [allTrainees, setAllTrainees] = useState<any[]>([]);
47+
const [allTrainees, setAllTrainees] = useState<(UserInterface & {recorded: boolean})[]>([]);
4548
const [filteredTrainees, setFilteredTrainees] = useState<any[]>([]);
4649
const [searchName, setSearchName] = useState('');
4750
const [inputFocus, setInputFocus] = useState(false);
@@ -88,20 +91,29 @@ function ModalAttendance({
8891

8992
useEffect(() => {
9093
if (trainees) {
91-
const sanitizedTrainees = trainees.filter(
92-
(trainee: any) => trainee.status.status !== 'drop',
93-
);
94+
const sanitizedTrainees = trainees
95+
.map((trainee: UserInterface) => ({ ...trainee, recorded: false }))
96+
.filter((trainee: any) => trainee.status.status !== 'drop');
9497
setAllTrainees(sanitizedTrainees);
9598
}
9699
}, [trainees]);
97100
useEffect(() => {
98101
setFilteredTrainees(
99102
allTrainees.filter((trainee) =>
100-
trainee.profile.name.toLowerCase().includes(searchName.toLowerCase()),
103+
trainee.profile.name
104+
.toLowerCase()
105+
.includes(searchName.trim().toLowerCase()),
101106
),
102107
);
103108
}, [allTrainees, searchName]);
104109

110+
useEffect(() => {
111+
traineesAttendance.length &&
112+
setFilteredTrainees(
113+
allTrainees.sort((a, b) => Number(a.recorded) - Number(b.recorded)),
114+
);
115+
}, [traineesAttendance]);
116+
105117
if (!isVisible) return null;
106118

107119
const handleGiveAttendance = (name: string, score: number, id: string) => {
@@ -117,6 +129,15 @@ function ModalAttendance({
117129
return attendance;
118130
});
119131
} else {
132+
setFilteredTrainees(
133+
allTrainees.map((trainee, index) => {
134+
if (trainee.id === id) {
135+
allTrainees[index].recorded = true;
136+
return { ...trainee, recorded: true };
137+
}
138+
return trainee;
139+
}),
140+
);
120141
updatedAttendance = [...traineesAttendance, { name, score, id }];
121142
}
122143

@@ -137,27 +158,52 @@ function ModalAttendance({
137158
}));
138159

139160
setRecordTrainees(updatedRecords);
161+
setFilteredTrainees(
162+
allTrainees.map((trainee, index) => {
163+
allTrainees[index].recorded = false;
164+
return { ...trainee, recorded: false };
165+
}),
166+
);
140167
};
141168

142169
return (
143170
<div className="fixed inset-0 bg-gray-900 bg-opacity-75 flex justify-center items-center z-50 p-4">
144171
<div className="bg-[#FFFFFF] dark:bg-[#020917] md:w-[500px] rounded-lg w-96 px-5 py-4 xmd:p-6 shadow-lg flex flex-col gap-3 text-[#111827] dark:text-white">
145172
<div className="w-full">
146-
<div className="w-full flex flex-col gap-3">
173+
<div className="w-full flex flex-col gap-4">
147174
<h2 className="text-[1.1rem] xmd:text-xl font-bold text-center text-purple-400 mb-2">
148175
Take Attendance
149176
</h2>
150-
<div className="flex justify-between">
151-
<h3 className="font-semibold text-[.85rem] xmd:text-[.95rem] ">
152-
Week {week}
153-
</h3>
154-
<p className="text-sm">
155-
{format(new Date(date), 'EE, do MMMM yyyy')}
177+
<div className="flex flex-col justify-between text-[.85rem] xmd:text-[.9rem] md:text-[.95rem]">
178+
<p className="">
179+
<span className="font-semibold">Week&nbsp;:&nbsp;</span>
180+
<span className="text-[.82rem] xmd:text-[.86rem] md:text-[.9rem] font-light">
181+
{week}
182+
</span>
183+
</p>
184+
<p className="">
185+
<span className="font-semibold">Team&nbsp;:&nbsp;</span>
186+
<span className="text-[.82rem] xmd:text-[.86rem] md:text-[.9rem] font-light capitalize">
187+
{teamName}
188+
</span>
189+
</p>
190+
<p>
191+
<span className="font-semibold">Date&nbsp;:&nbsp;</span>
192+
<span
193+
className="text-[.82rem] xmd:text-[.86rem] md:text-[.9rem] font-light"
194+
// eslint-disable-next-line react/no-danger
195+
dangerouslySetInnerHTML={{
196+
__html: format(new Date(date), 'EEEE, do MMM yyyy').replace(
197+
/(st|nd|rd|th)\b/,
198+
(match) => `<sup>${match}</sup>`,
199+
),
200+
}}
201+
/>
156202
</p>
157203
</div>
158204

159205
<div className="flex flex-col gap-2">
160-
<p className="font-semibold text-[..84rem] xmd:text-[.95rem]">
206+
<p className="font-semibold text-[..84rem] xmd:text-[.9rem] md:text-[.95rem]">
161207
Trainees:
162208
</p>
163209
<div className="w-full min-h-[40px] max-h-[110px] overflow-auto custom-scrollbar">
@@ -195,15 +241,15 @@ function ModalAttendance({
195241
))}
196242
</div>
197243
) : (
198-
<p className="text-center text-[.83rem] xmd:text-[.9rem] font-medium">
244+
<p className="pl-5 text-[.83rem] xmd:text-[.88rem] font-light">
199245
No trainee given attendance.
200246
</p>
201247
)}
202248
</div>
203249
</div>
204250

205251
<div className="mt-4">
206-
<label className="block text-[.86rem] xmd:text-[.95rem] font-medium">
252+
<label className="block text-[.86rem] xmd:text-[.9rem] md:text-[.95rem] font-medium">
207253
Trainee Name
208254
</label>
209255
<div className="flex">
@@ -216,21 +262,25 @@ function ModalAttendance({
216262
onChange={(e) => {
217263
setSearchName(e.target.value);
218264
}}
219-
className="placeholder:text-neutral-600 dark:placeholder:text-neutral-400 text-[.82rem] xmd:text-sm bg-gray-200 dark:bg-gray-700 w-full py-[5px] px-3 rounded-[2px] focus:outline-none focus:ring-1 focus:ring-purple-500"
265+
className="placeholder:text-neutral-600 dark:placeholder:text-neutral-400 text-[.82rem] xmd:text-[.85rem] bg-gray-300 dark:bg-gray-700 w-full py-[6px] px-3 rounded-[2px] focus:outline-none focus:ring-1 focus:ring-purple-500"
220266
placeholder="Find trainee by name"
221267
/>
222268

223269
<div className="min-h-[100px]">
224270
{inputFocus && (
225-
<div className="bg-[#EDF2EE] dark:bg-[#202B3E] z-20 left-0 right-0 w-full max-h-[100px] overflow-y-auto p-2 flex flex-col gap-1 custom-scrollbar">
226-
{filteredTrainees.length === 0 ? (
227-
<p className="text-[.78rem] xmd:text-sm">{`No trainee found in team ${teamName}.`}</p>
271+
<div className="bg-[#c4c4c4] dark:bg-[#202B3E] z-20 left-0 right-0 w-full max-h-[100px] overflow-y-auto py-1 px-2 flex flex-col gap-1 custom-scrollbar">
272+
{!filteredTrainees.length ? (
273+
<p className="text-[.78rem] xmd:text-[.83rem] py-2 px-1">{`No trainee found in team ${teamName}.`}</p>
228274
) : (
229275
filteredTrainees.map((trainee) => (
230276
<div
231277
key={trainee.email}
232278
onMouseDown={(e) => e.preventDefault()}
233-
className="flex items-center border-[#858585] border-b-[1px] py-[2px] xmd:py-1"
279+
className={`${
280+
trainee.recorded
281+
? 'brightness-[.6] text-neutral-500 dark:text-white'
282+
: ''
283+
} flex items-center border-[#858585] border-b-[1px] py-[2px] xmd:py-1 px-2`}
234284
>
235285
<p className="flex-1 text-[.83rem] xmd:text-sm">
236286
{trainee.profile.name}
@@ -291,24 +341,30 @@ function ModalAttendance({
291341
</div>
292342
</div>
293343

294-
<div className="mt-3 flex justify-between text-[.9rem] xmd:text-[.95rem]">
344+
<div className="mt-3 flex justify-between text-[.92rem] xmd:text-[.95rem] leading-6 font-medium">
295345
<button
296346
type="button"
297347
onClick={() => {
348+
setFilteredTrainees(
349+
allTrainees.map((trainee, index) => {
350+
allTrainees[index].recorded = false;
351+
return { ...trainee, recorded: false };
352+
}),
353+
);
298354
setTraineesAttendance([]);
299355
onClose();
300356
}}
301-
className="bg-gray-500 text-white py-[4px] xmd:py-[6px] px-4 rounded-[4px] hover:bg-gray-600"
357+
className="bg-gray-500 text-white py-[4px] xmd:py-[5px] px-4 rounded-[4px] hover:bg-gray-600"
302358
>
303359
Cancel
304360
</button>
305361
<button
306362
type="submit"
307363
disabled={traineesAttendance.length === 0}
308-
className={`py-[4px] xmd:py-[6px] px-4 rounded-[4px] ${
364+
className={`py-[4px] xmd:py-[5px] px-4 rounded-[4px] ${
309365
traineesAttendance.length === 0 || loadingRecordAttendance
310366
? 'bg-gray-300 text-gray-800 cursor-not-allowed'
311-
: 'bg-purple-500 text-white hover:bg-purple-600'
367+
: 'bg-primary text-white hover:bg-primary/90'
312368
}`}
313369
onClick={() => {
314370
handleSubmitAttendance();

src/containers/admin-dashBoard/Sessions.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,6 @@ function AdminSission() {
158158
getSessionRefetch();
159159
})
160160
.catch((error) => {});
161-
// console.log("------",id)
162161
}
163162
};
164163

src/pages/Organization/Orglogin.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ function Orglogin() {
8888
}
8989
};
9090
const names = name.replace(/ /gi, '').toLowerCase();
91-
// console.log(names)
9291
const completeOrgUrl = `${names}`;
9392

9493
return (

0 commit comments

Comments
 (0)