import { useState, useEffect } from 'react' import { useParams, useNavigate, Link } from 'react-router-dom' import api from '../../api' import toast from 'react-hot-toast' import { ArrowLeft, Save, X } from 'lucide-react' export default function AttendanceDetail() { const { id } = useParams() const navigate = useNavigate() const [record, setRecord] = useState(null) const [loading, setLoading] = useState(true) const [saving, setSaving] = useState(false) const [editMode, setEditMode] = useState(false) const [formData, setFormData] = useState({}) const [error, setError] = useState(null) useEffect(() => { fetchRecord() }, [id]) const fetchRecord = async () => { setLoading(true) setError(null) try { // Fetch all records and find by id const { data } = await api.get('/api/attendance/records?per_page=1000') const found = (data.records || []).find(r => r.id === parseInt(id)) if (found) { setRecord(found) setFormData({ employee_name: found.employee_name || '', company: found.company || '', date: found.date || '', weekday: found.weekday || '', shift_code: found.shift_code || '', status_code: found.status_code || '', status_text: found.status_text || '', late_minutes: found.late_minutes || 0, early_minutes: found.early_minutes || 0, ot_minutes: found.ot_minutes || 0, expected_in: found.expected_in || '', expected_out: found.expected_out || '', actual_in: found.actual_in || '', actual_out: found.actual_out || '', is_manually_edited: found.is_manually_edited || false, }) } else { setError('找不到記錄') } } catch (err) { console.error('Error:', err) setError('載入失敗') } finally { setLoading(false) } } const handleSave = async () => { setSaving(true) try { await api.put(`/api/attendance/${id}`, formData) toast.success('保存成功') setEditMode(false) fetchRecord() } catch (err) { toast.error('保存失敗') } finally { setSaving(false) } } const handleCancel = () => { setEditMode(false) if (record) { setFormData({ employee_name: record.employee_name || '', company: record.company || '', date: record.date || '', weekday: record.weekday || '', shift_code: record.shift_code || '', status_code: record.status_code || '', status_text: record.status_text || '', late_minutes: record.late_minutes || 0, early_minutes: record.early_minutes || 0, ot_minutes: record.ot_minutes || 0, expected_in: record.expected_in || '', expected_out: record.expected_out || '', actual_in: record.actual_in || '', actual_out: record.actual_out || '', }) } } const getStatusBadge = (code, text) => { const badges = { normal: 'bg-green-100 text-green-700', late: 'bg-orange-100 text-orange-700', early: 'bg-blue-100 text-blue-700', ot: 'bg-purple-100 text-purple-700', abnormal: 'bg-red-100 text-red-700', missing: 'bg-gray-200 text-gray-600', late_early: 'bg-orange-100 text-orange-700', late_ot: 'bg-orange-100 text-orange-700', early_ot: 'bg-blue-100 text-blue-700', } return ( {text || code} ) } const displayFields = [ { key: 'employee_name', label: '員工姓名' }, { key: 'company', label: '公司' }, { key: 'date', label: '日期' }, { key: 'weekday', label: '星期' }, { key: 'shift_code', label: '班次' }, { key: 'expected_in', label: '應上班時間' }, { key: 'expected_out', label: '應下班時間' }, { key: 'actual_in', label: '實際上班' }, { key: 'actual_out', label: '實際下班' }, { key: 'late_minutes', label: '遲到分鐘' }, { key: 'early_minutes', label: '早退分鐘' }, { key: 'ot_minutes', label: 'OT分鐘' }, { key: 'status_code', label: '狀態代碼' }, { key: 'status_text', label: '狀態' }, ] if (loading) { return (
載入中...
) } if (error) { return (
返回列表
{error}
) } return (
{/* Header */}
返回

出勤記錄 - {record?.employee_name}

{record && getStatusBadge(record.status_code, record.status_text)} {!editMode ? ( ) : ( <> )}
{/* Manual edit warning */} {record?.is_manually_edited && (
⚠️ 此記錄曾被手動修改,之後重新導入 Excel 不會覆蓋此記錄
)} {/* Record Details */}

記錄詳情

{displayFields.map(({ key, label }) => (
{label}
{editMode && ['status_code', 'late_minutes', 'early_minutes', 'ot_minutes', 'actual_in', 'actual_out', 'shift_code'].includes(key) ? ( setFormData({ ...formData, [key]: e.target.value })} className="w-full px-3 py-1.5 text-sm border border-slate-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" /> ) : ( {record?.[key] !== null && record?.[key] !== undefined ? String(record[key]) : '-'} )}
))}
) }