SMKBK1 commited on
Commit
5b04450
·
verified ·
1 Parent(s): eaa6dec

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +71 -45
index.html CHANGED
@@ -229,31 +229,37 @@
229
  const formattedDateStr = `${selectedDate.getDate().toString().padStart(2, '0')}/${(selectedDate.getMonth() + 1).toString().padStart(2, '0')}/${selectedDate.getFullYear()}`;
230
  const fallbackDateStr = `${selectedDate.getDate()}/${selectedDate.getMonth() + 1}/${selectedDate.getFullYear()}`;
231
 
232
- let todaysAttendance = attendanceData[formattedDateStr] || attendanceData[fallbackDateStr];
233
- if (!todaysAttendance && isToday && Object.keys(attendanceData).length > 0) {
234
- todaysAttendance = attendanceData[Object.keys(attendanceData)[Object.keys(attendanceData).length - 1]];
235
- }
236
 
237
- const absenteesForClass = todaysAttendance ? (todaysAttendance[selectedClass] || []) : [];
238
  const classStudents = studentsData[selectedClass] || [];
239
- const totalStudents = classStudents.length || 24;
240
- const absentCount = absenteesForClass ? absenteesForClass.length : 0;
241
- const presentCount = totalStudents - absentCount;
242
- const attendancePercentage = totalStudents > 0 ? Math.round((presentCount / totalStudents) * 100) : 100;
 
 
 
243
 
244
  let schoolTotalEnrolled = 0;
245
  let schoolTotalAbsent = 0;
 
246
 
247
  CLASSES.forEach(cls => {
248
  const cStudents = studentsData[cls] || [];
249
- const cAbsents = todaysAttendance ? (todaysAttendance[cls] || []) : [];
250
- schoolTotalEnrolled += (cStudents.length || 24);
251
- schoolTotalAbsent += cAbsents.length;
 
 
 
 
252
  });
253
- const schoolTotalPresent = schoolTotalEnrolled - schoolTotalAbsent;
254
- const schoolAttendancePercentage = schoolTotalEnrolled > 0
255
  ? Math.round((schoolTotalPresent / schoolTotalEnrolled) * 100)
256
- : 100;
257
 
258
  const exitCounts = {};
259
  Object.values(studentLogs).forEach(slotLogs => {
@@ -311,11 +317,13 @@
311
  }
312
 
313
  const cStudents = studentsData[cls] || [];
314
- const cAbsents = todaysAttendance ? (todaysAttendance[cls] || []) : [];
315
  const cEnrolled = cStudents.length || 24;
316
- const cAbsentCount = cAbsents.length;
317
- const cPresentCount = cEnrolled - cAbsentCount;
318
- const cPercentage = cEnrolled > 0 ? Math.round((cPresentCount / cEnrolled) * 100) : 100;
 
 
319
 
320
  return {
321
  className: cls,
@@ -517,34 +525,33 @@
517
  </div>
518
 
519
  <div className="flex flex-col sm:flex-row items-stretch sm:items-center gap-3 text-sm">
520
- <div className="bg-indigo-800/60 backdrop-blur-md px-3 py-2 rounded-lg border border-indigo-500/30 flex items-center gap-2 justify-center relative">
521
  <Calendar className="w-4 h-4 text-indigo-300 flex-shrink-0" />
522
- <label className="cursor-pointer flex items-center gap-2">
523
- <span className="whitespace-nowrap">
524
- {selectedDate.toLocaleDateString('ms-MY', { weekday: 'long', day: 'numeric', month: 'short', year: 'numeric' })}
525
- </span>
526
- <input
527
- type="date"
528
- value={selectedDateInputValue}
529
- onChange={(e) => {
530
- if (!e.target.value) return;
531
- const [y, m, d] = e.target.value.split('-').map(Number);
532
- const newDate = new Date(y, m - 1, d);
533
- newDate.setHours(0, 0, 0, 0);
534
- setSelectedDate(newDate);
535
- }}
536
- className="absolute inset-0 opacity-0 cursor-pointer w-full h-full"
537
- title="Pilih tarikh"
538
- />
539
- </label>
540
  {!isToday && (
541
  <button
 
542
  onClick={() => {
543
  const d = new Date();
544
  d.setHours(0, 0, 0, 0);
545
  setSelectedDate(d);
546
  }}
547
- className="ml-1 text-[10px] font-bold bg-white/20 hover:bg-white/30 px-1.5 py-0.5 rounded text-white whitespace-nowrap"
548
  title="Kembali ke hari ini"
549
  >
550
  Hari Ini
@@ -857,7 +864,9 @@
857
  <>
858
  <div className="p-4 md:p-6 grid grid-cols-1 lg:grid-cols-2 gap-6 border-b border-slate-100 bg-white">
859
  <div className="space-y-3">
860
- <h2 className="text-xs font-bold uppercase tracking-wider text-slate-500">Kehadiran Hari Ini ({selectedClass})</h2>
 
 
861
  <div className="grid grid-cols-2 gap-3">
862
  <div className="bg-slate-50 p-3 rounded-xl border border-slate-200 flex items-center justify-between">
863
  <span className="text-xs md:text-sm font-medium text-slate-600">Hadir:</span>
@@ -872,6 +881,9 @@
872
  <span className="text-xs md:text-sm font-medium text-slate-600">Jumlah Daftar:</span>
873
  <span className="text-base md:text-lg font-bold text-slate-800">{totalStudents}</span>
874
  </div>
 
 
 
875
  </div>
876
 
877
  <div>
@@ -879,6 +891,11 @@
879
  <div className="bg-slate-50 p-4 rounded-xl border border-slate-200 min-h-[120px] flex flex-col justify-center">
880
  {isLoading ? (
881
  <div className="text-center text-slate-400 text-sm italic">Memuatkan data...</div>
 
 
 
 
 
882
  ) : absenteesForClass && absenteesForClass.length > 0 ? (
883
  <ul className="text-sm space-y-1.5 max-h-32 overflow-y-auto pr-1">
884
  {absenteesForClass.map((student, idx) => (
@@ -904,18 +921,27 @@
904
  <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4">
905
 
906
  <div className="bg-white p-4 rounded-xl border border-slate-200 shadow-sm">
907
- <div className="text-xs font-bold text-slate-500 mb-1">Kadar Kehadiran ({presentCount}/{totalStudents})</div>
 
 
908
  <div className="flex items-baseline gap-2 mb-2">
909
- <span className={`text-2xl md:text-3xl font-black ${attendancePercentage < 80 ? 'text-orange-500' : 'text-emerald-500'}`}>
910
- {attendancePercentage}%
 
 
911
  </span>
912
  </div>
913
  <div className="w-full bg-slate-100 rounded-full h-2.5">
914
  <div
915
- className={`h-2.5 rounded-full ${attendancePercentage < 80 ? 'bg-orange-500' : 'bg-emerald-500'}`}
916
- style={{ width: `${attendancePercentage}%` }}
 
 
917
  ></div>
918
  </div>
 
 
 
919
  </div>
920
 
921
  <div className="bg-white p-4 rounded-xl border border-slate-200 shadow-sm">
 
229
  const formattedDateStr = `${selectedDate.getDate().toString().padStart(2, '0')}/${(selectedDate.getMonth() + 1).toString().padStart(2, '0')}/${selectedDate.getFullYear()}`;
230
  const fallbackDateStr = `${selectedDate.getDate()}/${selectedDate.getMonth() + 1}/${selectedDate.getFullYear()}`;
231
 
232
+ // Only use attendance data that matches the selected date — no fallback to other days
233
+ const todaysAttendance = attendanceData[formattedDateStr] || attendanceData[fallbackDateStr] || null;
234
+ const hasAttendanceData = !!todaysAttendance;
 
235
 
236
+ const absenteesForClass = hasAttendanceData ? (todaysAttendance[selectedClass] || []) : [];
237
  const classStudents = studentsData[selectedClass] || [];
238
+ const totalStudents = classStudents.length || 24;
239
+ // If no attendance record for this date (e.g. Saturday / public holiday), show 0 present & 0 absent
240
+ const absentCount = hasAttendanceData ? absenteesForClass.length : 0;
241
+ const presentCount = hasAttendanceData ? (totalStudents - absentCount) : 0;
242
+ const attendancePercentage = hasAttendanceData && totalStudents > 0
243
+ ? Math.round((presentCount / totalStudents) * 100)
244
+ : 0;
245
 
246
  let schoolTotalEnrolled = 0;
247
  let schoolTotalAbsent = 0;
248
+ let schoolTotalPresent = 0;
249
 
250
  CLASSES.forEach(cls => {
251
  const cStudents = studentsData[cls] || [];
252
+ const cEnrolled = cStudents.length || 24;
253
+ schoolTotalEnrolled += cEnrolled;
254
+ if (hasAttendanceData) {
255
+ const cAbsents = todaysAttendance[cls] || [];
256
+ schoolTotalAbsent += cAbsents.length;
257
+ schoolTotalPresent += (cEnrolled - cAbsents.length);
258
+ }
259
  });
260
+ const schoolAttendancePercentage = hasAttendanceData && schoolTotalEnrolled > 0
 
261
  ? Math.round((schoolTotalPresent / schoolTotalEnrolled) * 100)
262
+ : 0;
263
 
264
  const exitCounts = {};
265
  Object.values(studentLogs).forEach(slotLogs => {
 
317
  }
318
 
319
  const cStudents = studentsData[cls] || [];
320
+ const cAbsents = hasAttendanceData ? (todaysAttendance[cls] || []) : [];
321
  const cEnrolled = cStudents.length || 24;
322
+ const cAbsentCount = hasAttendanceData ? cAbsents.length : 0;
323
+ const cPresentCount = hasAttendanceData ? (cEnrolled - cAbsentCount) : 0;
324
+ const cPercentage = hasAttendanceData && cEnrolled > 0
325
+ ? Math.round((cPresentCount / cEnrolled) * 100)
326
+ : 0;
327
 
328
  return {
329
  className: cls,
 
525
  </div>
526
 
527
  <div className="flex flex-col sm:flex-row items-stretch sm:items-center gap-3 text-sm">
528
+ <div className="bg-indigo-800/60 backdrop-blur-md px-3 py-2 rounded-lg border border-indigo-500/30 flex items-center gap-2 justify-center flex-wrap">
529
  <Calendar className="w-4 h-4 text-indigo-300 flex-shrink-0" />
530
+ <input
531
+ type="date"
532
+ value={selectedDateInputValue}
533
+ onChange={(e) => {
534
+ if (!e.target.value) return;
535
+ const [y, m, d] = e.target.value.split('-').map(Number);
536
+ const newDate = new Date(y, m - 1, d);
537
+ newDate.setHours(0, 0, 0, 0);
538
+ setSelectedDate(newDate);
539
+ }}
540
+ className="bg-indigo-900 border border-indigo-400/40 rounded px-2 py-1 text-white font-bold focus:outline-none cursor-pointer text-sm [color-scheme:dark]"
541
+ title="Pilih tarikh"
542
+ />
543
+ <span className="text-indigo-200 text-xs hidden sm:inline whitespace-nowrap">
544
+ {selectedDate.toLocaleDateString('ms-MY', { weekday: 'long' })}
545
+ </span>
 
 
546
  {!isToday && (
547
  <button
548
+ type="button"
549
  onClick={() => {
550
  const d = new Date();
551
  d.setHours(0, 0, 0, 0);
552
  setSelectedDate(d);
553
  }}
554
+ className="text-[10px] font-bold bg-white/20 hover:bg-white/30 px-1.5 py-0.5 rounded text-white whitespace-nowrap"
555
  title="Kembali ke hari ini"
556
  >
557
  Hari Ini
 
864
  <>
865
  <div className="p-4 md:p-6 grid grid-cols-1 lg:grid-cols-2 gap-6 border-b border-slate-100 bg-white">
866
  <div className="space-y-3">
867
+ <h2 className="text-xs font-bold uppercase tracking-wider text-slate-500">
868
+ Kehadiran {isToday ? 'Hari Ini' : 'Tarikh Dipilih'} ({selectedClass})
869
+ </h2>
870
  <div className="grid grid-cols-2 gap-3">
871
  <div className="bg-slate-50 p-3 rounded-xl border border-slate-200 flex items-center justify-between">
872
  <span className="text-xs md:text-sm font-medium text-slate-600">Hadir:</span>
 
881
  <span className="text-xs md:text-sm font-medium text-slate-600">Jumlah Daftar:</span>
882
  <span className="text-base md:text-lg font-bold text-slate-800">{totalStudents}</span>
883
  </div>
884
+ {!hasAttendanceData && (
885
+ <p className="text-[11px] text-amber-600 font-medium italic">Tiada data kehadiran untuk tarikh ini</p>
886
+ )}
887
  </div>
888
 
889
  <div>
 
891
  <div className="bg-slate-50 p-4 rounded-xl border border-slate-200 min-h-[120px] flex flex-col justify-center">
892
  {isLoading ? (
893
  <div className="text-center text-slate-400 text-sm italic">Memuatkan data...</div>
894
+ ) : !hasAttendanceData ? (
895
+ <div className="flex flex-col items-center justify-center text-slate-400 italic">
896
+ <span className="text-sm">Tiada data kehadiran</span>
897
+ <span className="text-[11px] mt-1">(contoh: hari cuti / hujung minggu)</span>
898
+ </div>
899
  ) : absenteesForClass && absenteesForClass.length > 0 ? (
900
  <ul className="text-sm space-y-1.5 max-h-32 overflow-y-auto pr-1">
901
  {absenteesForClass.map((student, idx) => (
 
921
  <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4">
922
 
923
  <div className="bg-white p-4 rounded-xl border border-slate-200 shadow-sm">
924
+ <div className="text-xs font-bold text-slate-500 mb-1">
925
+ Kadar Kehadiran {hasAttendanceData ? `(${presentCount}/${totalStudents})` : ''}
926
+ </div>
927
  <div className="flex items-baseline gap-2 mb-2">
928
+ <span className={`text-2xl md:text-3xl font-black ${
929
+ !hasAttendanceData ? 'text-slate-400' : attendancePercentage < 80 ? 'text-orange-500' : 'text-emerald-500'
930
+ }`}>
931
+ {hasAttendanceData ? `${attendancePercentage}%` : '—'}
932
  </span>
933
  </div>
934
  <div className="w-full bg-slate-100 rounded-full h-2.5">
935
  <div
936
+ className={`h-2.5 rounded-full ${
937
+ !hasAttendanceData ? 'bg-slate-300' : attendancePercentage < 80 ? 'bg-orange-500' : 'bg-emerald-500'
938
+ }`}
939
+ style={{ width: `${hasAttendanceData ? attendancePercentage : 0}%` }}
940
  ></div>
941
  </div>
942
+ {!hasAttendanceData && (
943
+ <p className="text-[10px] text-slate-400 italic mt-1">Tiada data</p>
944
+ )}
945
  </div>
946
 
947
  <div className="bg-white p-4 rounded-xl border border-slate-200 shadow-sm">