From a7dfd208d212aea5db18dadfbdcb60db788278c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?IT=E7=8B=97?= Date: Wed, 22 Jul 2026 10:41:11 +0800 Subject: [PATCH] fix(dashboard): use backend attendance_rate instead of broken client formula MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Old formula: (total - late - abnormal) / total - Did not subtract missing (so 100% with 缺勤 2) - Subtracted abnormal twice (already hidden late/early/ot) - Could never reach 0% New: read backend's pre-computed attendance_rate = (total - missing) / total * 100 Wing Fung (10 rec, 2 missing) now 80% (was 100%) Cindy (10 rec, 4 missing) now 60% (was 90%) --- frontend/src/pages/Dashboard.jsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/frontend/src/pages/Dashboard.jsx b/frontend/src/pages/Dashboard.jsx index c006d79..03ff6e1 100644 --- a/frontend/src/pages/Dashboard.jsx +++ b/frontend/src/pages/Dashboard.jsx @@ -368,10 +368,12 @@ export default function Dashboard() { const otRank = [...byStaff].sort((a, b) => (b.ot_count || 0) - (a.ot_count || 0)) const abnormalRank = [...byStaff].sort((a, b) => (b.abnormal_count || 0) - (a.abnormal_count || 0)) const missingRank = [...byStaff].sort((a, b) => (b.missing_count || 0) - (a.missing_count || 0)) - const attendanceRate = [...byStaff].map(s => ({ - ...s, - rate: (s.total_records || s.total || 0) > 0 ? Math.round(((((s.total_records || s.total || 0) - (s.late_count || 0) - (s.abnormal_count || 0))) / (s.total_records || s.total || 0)) * 100) : 0 - })).sort((a, b) => b.rate - a.rate) + // Use backend's pre-computed attendance_rate = (total - missing) / total * 100 + // (handles missing records correctly; a record can still be late/early/ot + // and count as attended) + const attendanceRate = [...byStaff] + .map(s => ({ ...s, rate: s.attendance_rate ?? 0 })) + .sort((a, b) => b.rate - a.rate) const statCards = summary ? [ { label: '總記錄', value: summary.total_records, icon: Calendar, color: 'bg-blue-50 text-blue-600' },