'use client' import { useState, useEffect } from 'react' import { portalAPI } from '@/lib/api/portal' import Modal from '@/components/Modal' import LoadingSpinner from '@/components/LoadingSpinner' import { toast } from 'react-hot-toast' import { Plus } from 'lucide-react' const TIME_OPTIONS = Array.from({ length: 48 }, (_, i) => { const hour = Math.floor(i / 2).toString().padStart(2, '0') const minute = i % 2 === 0 ? '00' : '30' return `${hour}:${minute}` }) const LEAVE_TYPES = [ { value: 'ANNUAL', label: 'إجازة سنوية' }, { value: 'HOURLY', label: 'إجازة ساعية' }, ] const STATUS_MAP: Record = { PENDING: { label: 'قيد المراجعة', color: 'bg-amber-100 text-amber-800' }, APPROVED: { label: 'معتمدة', color: 'bg-green-100 text-green-800' }, REJECTED: { label: 'مرفوضة', color: 'bg-red-100 text-red-800' }, } const COMPANY_TIME_ZONE = 'Asia/Riyadh' const COMPANY_UTC_OFFSET = '+03:00' const toCompanyDateTime = (date: string, time: string) => { return `${date}T${time}:00${COMPANY_UTC_OFFSET}` } const formatCompanyTime = (value: string) => { return new Date(value).toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit', hour12: false, timeZone: COMPANY_TIME_ZONE, }) } const formatCompanyDate = (value: string) => { return new Date(value).toLocaleDateString('ar-SA', { timeZone: COMPANY_TIME_ZONE, }) } export default function PortalLeavePage() { const [leaveBalance, setLeaveBalance] = useState([]) const [leaves, setLeaves] = useState([]) const [loading, setLoading] = useState(true) const [showModal, setShowModal] = useState(false) const [submitting, setSubmitting] = useState(false) const [editingId, setEditingId] = useState(null) const [form, setForm] = useState({ leaveType: 'ANNUAL', startDate: '', endDate: '', leaveDate: '', startTime: '', endTime: '', reason: '', }) const load = () => { setLoading(true) Promise.all([portalAPI.getLeaveBalance(), portalAPI.getLeaves()]) .then(([balance, list]) => { setLeaveBalance(balance) setLeaves(list) }) .catch(() => toast.error('فشل تحميل البيانات')) .finally(() => setLoading(false)) } useEffect(() => load(), []) const resetForm = () => { setForm({ leaveType: 'ANNUAL', startDate: '', endDate: '', leaveDate: '', startTime: '', endTime: '', reason: '', }) setEditingId(null) } const openEdit = (l: any) => { setEditingId(l.id) if (l.leaveType === 'HOURLY') { const start = new Date(l.startDate) const end = new Date(l.endDate) const dateStr = start.toLocaleDateString('en-CA', { timeZone: COMPANY_TIME_ZONE }) const fmt = (d: Date) => d.toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit', hour12: false, timeZone: COMPANY_TIME_ZONE, }) setForm({ leaveType: 'HOURLY', startDate: '', endDate: '', leaveDate: dateStr, startTime: fmt(start), endTime: fmt(end), reason: l.reason || '', }) } else { setForm({ leaveType: 'ANNUAL', startDate: String(l.startDate).split('T')[0], endDate: String(l.endDate).split('T')[0], leaveDate: '', startTime: '', endTime: '', reason: l.reason || '', }) } setShowModal(true) } const handleDelete = async (id: string) => { if (!confirm('حذف طلب الإجازة؟')) return try { await portalAPI.deleteLeaveRequest(id) toast.success('تم حذف الطلب') load() } catch (err: any) { toast.error(err?.response?.data?.message || 'فشل الحذف') } } const handleSubmit = (e: React.FormEvent) => { e.preventDefault() let payload: any = { leaveType: form.leaveType, reason: form.reason || undefined, } if (form.leaveType === 'ANNUAL') { if (!form.startDate || !form.endDate) { toast.error('أدخل تاريخ البداية والنهاية') return } if (new Date(form.endDate) < new Date(form.startDate)) { toast.error('تاريخ النهاية يجب أن يكون بعد البداية') return } payload.startDate = form.startDate payload.endDate = form.endDate } else { if (!form.leaveDate || !form.startTime || !form.endTime) { toast.error('أدخل التاريخ والوقت للإجازة الساعية') return } if (form.startTime >= form.endTime) { toast.error('وقت النهاية يجب أن يكون بعد البداية') return } payload.leaveDate = form.leaveDate payload.startTime = form.startTime payload.endTime = form.endTime payload.startDate = toCompanyDateTime(form.leaveDate, form.startTime) payload.endDate = toCompanyDateTime(form.leaveDate, form.endTime) } setSubmitting(true) const action = editingId ? portalAPI.updateLeaveRequest(editingId, payload) : portalAPI.submitLeaveRequest(payload) action .then(() => { setShowModal(false) resetForm() toast.success(editingId ? 'تم تعديل الطلب' : 'تم إرسال طلب الإجازة') load() }) .catch((err: any) => { const message = err.response?.data?.message || err.response?.data?.error || 'فشل إرسال الطلب' console.error('Leave request error:', err.response?.data || err) toast.error(message) }) .finally(() => setSubmitting(false)) } if (loading) return return (
{/* HEADER */}

إجازاتي

{/* الرصيد */} {leaveBalance.length > 0 && (

رصيد الإجازات

{leaveBalance.map((b) => (

{b.leaveType === 'ANNUAL' ? 'سنوية' : b.leaveType}

{b.available} يوم

))}
)} {/* الطلبات */}

طلباتي

{leaves.length === 0 ? (

لا توجد طلبات

) : (
{leaves.map((l) => { const statusInfo = STATUS_MAP[l.status] || { label: l.status, color: 'bg-gray-100' } return (

{l.leaveType === 'ANNUAL' ? 'سنوية' : 'ساعية'} -{' '} {l.leaveType === 'HOURLY' ? `${formatCompanyTime(l.startDate)} - ${formatCompanyTime(l.endDate)}` : `${l.days} يوم`}

{formatCompanyDate(l.startDate)} - {formatCompanyDate(l.endDate)}

{statusInfo.label} {l.status === 'PENDING' && ( <> )}
) })}
)}
{/* الفورم */} { setShowModal(false); resetForm() }} title={editingId ? 'تعديل طلب الإجازة' : 'طلب إجازة جديد'} >
{/* نوع الإجازة */} {/* سنوية */} {form.leaveType === 'ANNUAL' ? (
setForm(p => ({ ...p, startDate: e.target.value }))} className="border p-2 rounded w-full" />
setForm(p => ({ ...p, endDate: e.target.value }))} className="border p-2 rounded w-full" />
) : ( /* ساعية */
setForm(p => ({ ...p, leaveDate: e.target.value }))} className="border p-2 rounded w-full" />
)} {/* السبب */}