"use client"; import { useState, useCallback } from "react"; import { Alert, Spinner } from "@/Components/UI"; import { DriverFormModal } from "@/Components/Driver/DriverFormModal"; import { DriverDeleteModal } from "@/Components/Driver/DriverDeleteModal"; import { driverService } from "@/services"; import { getStoredToken } from "@/lib/auth"; import { useDrivers } from "@/hooks/useDriver"; import { CreateDriverPayload, Driver, DRIVER_STATUS_MAP, UpdateDriverPayload } from "@/types/driver"; import { DriverDetailPanel } from "@/Components/Driver/DriverDetailPanel"; // ── Helpers ─────────────────────────────────────────────────────────────────── function fmtDate(iso?: string | null): string { if (!iso) return "—"; return new Date(iso).toLocaleDateString("ar-SA", { year: "numeric", month: "short", day: "numeric", }); } function expirySoon(iso?: string | null): boolean { if (!iso) return false; return (new Date(iso).getTime() - Date.now()) / 86_400_000 <= 90; } // ── Styles ──────────────────────────────────────────────────────────────────── const cardStyle: React.CSSProperties = { borderRadius: "var(--radius-xl)", border: "1px solid var(--color-border)", background: "var(--color-surface)", overflow: "hidden", boxShadow: "var(--shadow-card)", }; const thStyle: React.CSSProperties = { padding: "0.75rem 1.5rem", fontSize: 11, fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.2em", color: "var(--color-text-muted)", background: "var(--color-surface-muted)", borderBottom: "1px solid var(--color-border)", }; // ── Page Component ──────────────────────────────────────────────────────────── export default function DriversPage() { const { drivers, loading, error, total, pages, page, search, setPage, handleSearch, clearError, deleteDriver, notification, reload, } = useDrivers(); // ── Panel / modal state ─────────────────────────────────────────────────── const [selectedDriverId, setSelectedDriverId] = useState(null); const [formDriver, setFormDriver] = useState(null); const [deleteTarget, setDeleteTarget] = useState(null); const [deleting, setDeleting] = useState(false); // ── Handlers ────────────────────────────────────────────────────────────── const handleEdit = useCallback((driver: Driver) => { setSelectedDriverId(null); setFormDriver(driver); }, []); const handleDelete = useCallback((driver: Driver) => { setSelectedDriverId(null); setDeleteTarget(driver); }, []); const handleFormSubmit = useCallback( async ( payload: CreateDriverPayload | UpdateDriverPayload, isNew: boolean, ): Promise => { try { const token = getStoredToken(); if (isNew) { // Use multipart if there are file fields const hasFiles = (payload as CreateDriverPayload & { photo?: File }).photo || (payload as CreateDriverPayload & { nationalPhoto?: File }).nationalPhoto || (payload as CreateDriverPayload & { driverCardPhoto?: File }).driverCardPhoto; if (hasFiles) { await driverService.createWithImages( payload as Parameters[0], token, ); } else { await driverService.create(payload as CreateDriverPayload, token); } } else { const id = (formDriver as Driver).id; await driverService.update(id, payload as UpdateDriverPayload, token); } reload(); return true; } catch { return false; } }, [formDriver, reload], ); const handleConfirmDelete = useCallback(async () => { if (!deleteTarget) return; setDeleting(true); const ok = await deleteDriver(deleteTarget.id); setDeleting(false); if (ok) setDeleteTarget(null); }, [deleteTarget, deleteDriver]); // ── Render ──────────────────────────────────────────────────────────────── return ( <>
{/* ── Header ── */}

إدارة الكوادر

السائقون

إجمالي{" "} {total}{" "} سائق مسجل

{/* Search */}
handleSearch(e.target.value)} dir="rtl" style={{ width: "100%", height: 40, paddingRight: 36, paddingLeft: 12, borderRadius: "var(--radius-lg)", border: "1px solid var(--color-border)", background: "var(--color-surface)", fontSize: 13, color: "var(--color-text-primary)", outline: "none", fontFamily: "var(--font-sans)", }} />
{/* Add button */}
{/* ── Notifications ── */} {notification && ( )} {error && ( )} {/* ── Table ── */}
السائق الفرع الجنسية انتهاء الرخصة انتهاء الهوية الحالة
{loading ? (
جارٍ التحميل…
) : drivers.length === 0 ? (

لا توجد نتائج {search && `لـ "${search}"`}

) : (
    {drivers.map((d, i) => { const statusCfg = DRIVER_STATUS_MAP[d.status] ?? DRIVER_STATUS_MAP.Inactive; const licWarn = expirySoon(d.licenseExpiry); const idWarn = expirySoon((d as Driver & { nationalIdExpiry?: string }).nationalIdExpiry); return (
  • setSelectedDriverId(d.id)} style={{ display: "grid", gridTemplateColumns: "2fr 1.2fr 1fr 1.1fr 1.1fr 1fr", alignItems: "center", gap: "0.5rem", padding: "0.875rem 1.5rem", borderBottom: "1px solid var(--color-border)", background: i % 2 !== 0 ? "var(--color-surface-muted)" : "transparent", fontSize: 13, cursor: "pointer", transition: "background 0.15s", }} onMouseEnter={(e) => (e.currentTarget.style.background = "var(--color-surface-hover, #F8FAFC)")} onMouseLeave={(e) => (e.currentTarget.style.background = i % 2 !== 0 ? "var(--color-surface-muted)" : "transparent")} > {/* Name + phone */}

    {d.name}

    {d.phone}

    {/* Branch */} {d.branch?.name ?? "—"} {/* Nationality */} {d.nationality ?? "—"} {/* License expiry */} {licWarn && "⚠ "}{fmtDate(d.licenseExpiry)} {/* National ID expiry */} {idWarn && "⚠ "}{fmtDate((d as Driver & { nationalIdExpiry?: string }).nationalIdExpiry)} {/* Status badge */} {statusCfg.label}
  • ); })}
)} {/* ── Pagination ── */} {pages > 1 && (
صفحة{" "} {page}{" "} من{" "} {pages}
{[ { label: "السابق", action: () => setPage(p => Math.max(1, p - 1)), disabled: page === 1 }, { label: "التالي", action: () => setPage(p => Math.min(pages, p + 1)), disabled: page === pages }, ].map(btn => ( ))}
)}
{/* ── Detail panel ── */} {selectedDriverId && ( setSelectedDriverId(null)} onEdit={handleEdit} onDelete={handleDelete} /> )} {/* ── Form modal ── */} {formDriver !== null && ( setFormDriver(null)} onSubmit={handleFormSubmit} /> )} {/* ── Delete modal ── */} {deleteTarget && ( setDeleteTarget(null)} onConfirm={handleConfirmDelete} /> )} ); }