feat: refactor AttendanceIndex component to improve code organization and enhance badge styling for check-out status

This commit is contained in:
Yoga Pangestu 2026-08-15 15:48:59 +07:00
parent 00ff74bab6
commit de18ac5ce8
2 changed files with 20 additions and 14 deletions

View File

@ -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 (
<Badge
key={emp.id}
variant={late ? 'destructive' : 'default'}
className="w-full justify-center cursor-pointer truncate"
variant={notCheckedOut ? 'outline' : (late ? 'destructive' : 'default')}
className={`w-full justify-center cursor-pointer truncate ${notCheckedOut ? 'border-orange-300 bg-orange-50 text-orange-700 hover:bg-orange-50' : ''}`}
onClick={(e) => {
e.stopPropagation();
setDetailAttendance(att);

View File

@ -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');