From de18ac5ce83faddf934339530c1c9545e9ddfcde Mon Sep 17 00:00:00 2001 From: Yoga Pangestu Date: Sat, 15 Aug 2026 15:48:59 +0700 Subject: [PATCH] feat: refactor AttendanceIndex component to improve code organization and enhance badge styling for check-out status --- .../js/pages/admin/hr/attendance/index.tsx | 33 +++++++++++-------- routes/web.php | 1 + 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/resources/js/pages/admin/hr/attendance/index.tsx b/resources/js/pages/admin/hr/attendance/index.tsx index d8f4b05..64d4d39 100644 --- a/resources/js/pages/admin/hr/attendance/index.tsx +++ b/resources/js/pages/admin/hr/attendance/index.tsx @@ -1,3 +1,15 @@ +import { Head, router } from '@inertiajs/react'; +import { addMonths, format, subMonths } from 'date-fns'; +import { id } from 'date-fns/locale'; +import { + ChevronLeft, + ChevronRight, + Clock, + LogIn, + LogOut, +} from 'lucide-react'; +import { useMemo, useState, useCallback } from 'react'; +import { toast } from 'sonner'; import { TodayAttendanceAlert } from '@/components/card/today-attendance-alert'; import { CameraCapture, LocationMap } from '@/components/inputs'; import { Badge } from '@/components/ui/badge'; @@ -14,18 +26,6 @@ import { store, update, } from '@/routes/admin/hr/attendances'; -import { Head, router } from '@inertiajs/react'; -import { addMonths, format, subMonths } from 'date-fns'; -import { id } from 'date-fns/locale'; -import { - ChevronLeft, - ChevronRight, - Clock, - LogIn, - LogOut, -} from 'lucide-react'; -import { useMemo, useState, useCallback } from 'react'; -import { toast } from 'sonner'; type Attendance = { id: number; @@ -184,9 +184,11 @@ export default function AttendanceIndex({ const fetchMonthData = useCallback(async (year: number, month: number) => { setLoadingMonth(true); + try { const url = attendanceByMonth.url({ query: { year, month } }); const res = await fetch(url); + if (res.ok) { const data = await res.json(); setAttendances(data.attendances); @@ -215,6 +217,7 @@ export default function AttendanceIndex({ const start = new Date(leave.start_date); const end = new Date(leave.end_date); const current = new Date(start); + while (current <= end) { const dateStr = format(current, 'yyyy-MM-dd'); const existing = map.get(dateStr) ?? []; @@ -538,11 +541,13 @@ export default function AttendanceIndex({ officeHour, officeMinute, ); + const notCheckedOut = !att.check_out_at; + return ( { e.stopPropagation(); setDetailAttendance(att); diff --git a/routes/web.php b/routes/web.php index 90c3bf6..84dc3e2 100644 --- a/routes/web.php +++ b/routes/web.php @@ -116,6 +116,7 @@ Route::post('attendances', [AttendanceController::class, 'store'])->name('attendances.store')->middleware('permission:attendances.create'); Route::put('attendances/{attendance}', [AttendanceController::class, 'update'])->name('attendances.update')->middleware('permission:attendances.create'); Route::get('attendances/by-date', [AttendanceController::class, 'byDate'])->name('attendances.by-date')->middleware('permission:attendances.view'); + Route::get('attendances/by-month', [AttendanceController::class, 'byMonth'])->name('attendances.by-month')->middleware('permission:attendances.view'); Route::resource('leave-requests', LeaveRequestController::class)->except(['show', 'create', 'edit'])->middleware('permission:leave_requests.view|leave_requests.create|leave_requests.update|leave_requests.delete'); Route::post('leave-requests/{leaveRequest}/approve', [LeaveRequestController::class, 'approve'])->name('leave-requests.approve')->middleware('permission:leave_requests.verify');