@extends('layouts.app') @section('title', '⏰ 簽到退') @push('styles') @endpush @section('content')
{{-- 簽到退成功提示 --}} @if(session('punch_success')) @php $ps = session('punch_success'); @endphp @endif {{-- IP 錯誤提示 --}} @if(session('punch_error')) @endif {{-- 免打卡提示 --}} @if($attendanceExempt)
您已設定為免打卡人員,不列入出缺席統計與工時計算。仍可視需要自行簽到退作為記錄。
@endif {{-- IP 限制警告(可見但尚未簽到退) --}} @if($ipRestrict && !$ipAllowed)
IP 限制:您目前的 IP {{ $clientIp }} 不在允許的簽到退範圍內,簽到退按鈕已停用。
@endif {{-- 時鐘區 --}}
00:00:00
{{-- 三個簽到退按鈕 --}}
@foreach(\App\Models\Attendance::TYPES as $typeKey => $typeMeta) @php $records = $todayRecords->where('type', $typeKey); $last = $todayMap[$typeKey] ?? null; $count = $records->count(); $color = $typeMeta['color']; $isPunched = $last !== null; $btnClass = $isPunched ? "punched punched-{$color}" : "outline-{$color}"; @endphp
{{-- 非公出:直接送出表單;公出:開 modal 填備註 --}} @php $disabled = ($ipRestrict && !$ipAllowed) ? 'disabled' : ''; @endphp @if($typeKey !== 'business_out') @php $hasClockIn = isset($todayMap['clock_in']); @endphp
@csrf
@else @endif {{-- 最後簽到退時間 --}}
@if($last) {{ $last->clocked_at->format('H:i') }} @if($count > 1)(共 {{ $count }} 次)@endif @else 尚未簽到退 @endif
@endforeach
{{-- 遲到補請假提示 --}} @if($showLeaveLinkButton)
您今天遲到約 {{ $lateLinkMinutes }} 分鐘,超過設定閾值。
如需以請假補充遲到時數,可點右側按鈕申請今天的請假。
補請假
@endif {{-- 公出 Modal --}} {{-- 行事曆點擊詳情 Modal --}} {{-- 本月工時摘要 --}}
{{ $monthlyStats['work_days'] }}
出勤天數
{{ $monthlyStats['total_hours'] }}小時
累計工時
{{ $monthlyStats['missing_out'] }}
漏打下班
{{-- Tabs --}}
{{-- 今日紀錄 Tab --}}
@if($todayRecords->isEmpty())

今天還沒有簽到退紀錄

@else
@foreach($todayRecords as $r)
{{ $r->typeLabel() }}
{{ $r->clocked_at->format('H:i:s') }}
@if($r->note)
{{ $r->note }}
@endif
@endforeach
@endif
{{-- 歷史查詢 Tab --}}
{{-- 月份篩選 + 檢視切換 --}}
{{-- 切換按鈕 --}}
@if($historyByDay->isEmpty())

該月份無簽到退紀錄

@else {{-- ── 條列 View ── --}}
@foreach($historyByDay as $date => $dayRecords) @php $d = \Carbon\Carbon::parse($date); $isToday = ($date === now()->toDateString()); @endphp

@foreach($dayRecords->sortBy('clocked_at') as $r) @endforeach
{{ $r->typeLabel() }} {{ $r->clocked_at->format('H:i:s') }} {{ $r->note ?? '—' }}
@endforeach
{{-- /history-list-view --}} {{-- ── 行事曆 View ── --}} @php $calMonth = \Carbon\Carbon::parse($month . '-01'); $startOfCal = $calMonth->copy()->startOfWeek(\Carbon\Carbon::SUNDAY); $endOfCal = $calMonth->copy()->endOfMonth()->endOfWeek(\Carbon\Carbon::SATURDAY); $todayStr = now()->toDateString(); // 把 $historyByDay 轉成 date => records 的普通陣列 $dayMap = $historyByDay->all(); $typeConfig = \App\Models\Attendance::TYPES; @endphp
{{-- 星期標題 --}}
@foreach(['日','一','二','三','四','五','六'] as $wd)
{{ $wd }}
@endforeach
@php $cursor = $startOfCal->copy(); @endphp @while($cursor->lte($endOfCal)) @php $dateStr = $cursor->toDateString(); $inMonth = $cursor->month === $calMonth->month; $isToday = ($dateStr === $todayStr); $records = $dayMap[$dateStr] ?? collect(); $isSun = $cursor->dayOfWeek === 0; $isSat = $cursor->dayOfWeek === 6; // 取各類型第一筆時間 $clockIn = $records->where('type','clock_in')->sortBy('clocked_at')->first(); $clockOut = $records->where('type','clock_out')->sortBy('clocked_at')->last(); $bizOut = $records->where('type','business_out')->sortBy('clocked_at')->first(); @endphp
isNotEmpty()) data-date="{{ $dateStr }}" onclick="showDayDetail('{{ $dateStr }}')" @endif>
{{ $cursor->day }}
@if($clockIn)
{{ $clockIn->clocked_at->format('H:i') }}
@endif @if($clockOut)
{{ $clockOut->clocked_at->format('H:i') }}
@endif @if($bizOut)
{{ $bizOut->clocked_at->format('H:i') }}
@endif
@php $cursor->addDay(); @endphp @endwhile
{{-- 圖例 --}}
上班簽到 下班簽退 公出
{{-- /history-cal-view --}} @endif
{{-- tab-content --}}
@endsection @push('scripts') @endpush