"use client";
// app/(dashboard)/cars/page.tsx
import { useCallback, useState } from "react";
import { Spinner, Alert } from "@/Components/UI";
import { CarFormModal } from "@/Components/car/CarFormModal";
import { CarDetailPanel } from "@/Components/car/CarDetailPanel";
import { CarDeleteModal } from "@/Components/car/CarDeleteModal";
import { useCars, useCarMutations, useToast } from "@/hooks/useCars";
import { fmtDateShort, isExpiringSoon, STATUS_MAP, INS_MAP } from "@/types/car";
import type { Car, CreateCarPayload, ToastMsg, UpdateCarPayload } from "@/types/car";
// ── Toast ─────────────────────────────────────────────────────────────────────
function CarToast({ notification }: { notification: ToastMsg | null }) {
if (!notification) return null;
const ok = notification.type === "success";
return (
{ok ? "✓" : "⚠"}
{notification.message}
);
}
// ── CarCard ───────────────────────────────────────────────────────────────────
function CarCard({ car, onClick }: { car: Car; onClick: () => void }) {
const status = STATUS_MAP[car.currentStatus];
const ins = car.insuranceStatus ? INS_MAP[car.insuranceStatus] : null;
const regWarn = isExpiringSoon(car.registrationExpiryDate);
return (
{ if (e.key === "Enter" || e.key === " ") onClick(); }}
aria-label={`${car.manufacturer} ${car.model} — ${car.plateLetters} ${car.plateNumber}`}
style={{
borderRadius: "var(--radius-xl)",
border: "1px solid var(--color-border)",
background: "var(--color-surface)",
overflow: "hidden",
boxShadow: "var(--shadow-card)",
cursor: "pointer",
transition: "box-shadow 200ms, transform 200ms",
}}
onMouseEnter={e => {
(e.currentTarget as HTMLElement).style.boxShadow = "0 8px 24px rgba(37,99,235,.12)";
(e.currentTarget as HTMLElement).style.transform = "translateY(-2px)";
}}
onMouseLeave={e => {
(e.currentTarget as HTMLElement).style.boxShadow = "var(--shadow-card)";
(e.currentTarget as HTMLElement).style.transform = "translateY(0)";
}}
>
{/* Colour accent bar by status */}
{/* Manufacturer + model */}
{car.manufacturer} {car.model}
{car.year}{car.color ? ` · ${car.color}` : ""}
{/* Status badge */}
{status.label}
{/* Plate number */}
رقم اللوحة
{car.plateLetters} {car.plateNumber}
{/* Key attributes grid */}
الفرع
{car.branch?.name ?? "—"}
التأمين
{ins?.label ?? "—"}
انتهاء الاستمارة
{regWarn && "⚠ "}{fmtDateShort(car.registrationExpiryDate)}
الطاقة
{car.capacity != null ? car.capacity : "—"}
{/* Footer CTA hint */}
اضغط لعرض التفاصيل ←
);
}
// ── Page ──────────────────────────────────────────────────────────────────────
export default function CarsPage() {
const [search, setSearch] = useState("");
const [page, setPage] = useState(1);
// Modal state
const [detailId, setDetailId] = useState(null);
const [formTarget, setFormTarget] = useState(false); // false = closed
const [deleteTarget, setDeleteTarget] = useState(null);
const { toast, notify } = useToast();
const { cars, loading, error, total, pages, loadCars, removeCar, setError } =
useCars(page, search);
// Need a stable ref to the current edit target for the mutation hook
const getEditTarget = useCallback(() =>
formTarget instanceof Object && formTarget !== null ? formTarget as Car : null,
[formTarget]);
const { deleting, handleFormSubmit, handleDeleteConfirm } = useCarMutations({
onSuccess: (msg) => { notify({ type: "success", message: msg }); loadCars(); },
onError: (msg) => notify({ type: "error", message: msg }),
onDeleted: (id) => { removeCar(id); setDeleteTarget(null); },
getEditTarget,
});
const handleDelete = async () => {
if (!deleteTarget) return;
await handleDeleteConfirm(deleteTarget);
};
// ── Render ──────────────────────────────────────────────────────────────────
return (
<>
{detailId && (
setDetailId(null)}
onEdit={(car) => { setDetailId(null); setFormTarget(car); }}
onDelete={(car) => { setDetailId(null); setDeleteTarget(car); }}
/>
)}
{formTarget !== false && (
setFormTarget(false)}
onSubmit={(payload: CreateCarPayload | UpdateCarPayload, isNew: boolean) =>
handleFormSubmit(payload, isNew).then((ok) => { if (ok) setFormTarget(false); return ok; })
}
/>
)}
{deleteTarget && (
setDeleteTarget(null)}
onConfirm={handleDelete}
/>
)}
{/* ── Header ── */}
إدارة الأسطول
المركبات
إجمالي {total} مركبة في الأسطول
{/* Search */}
{ setSearch(e.target.value); setPage(1); }}
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 */}
{/* Error alert */}
{error && setError(null)} />}
{/* ── Loading ── */}
{loading ? (
جارٍ تحميل المركبات…
) : cars.length === 0 ? (
🚗
{search ? `لا توجد مركبات تطابق "${search}"` : "لا توجد مركبات بعد"}
اضغط على "إضافة مركبة" لإضافة أول مركبة في الأسطول.
{!search && (
)}
) : (
/* ── Card grid ── */
{cars.map((car) => (
setDetailId(car.id)}
/>
))}
)}
{/* ── Pagination ── */}
{pages > 1 && (
صفحة {page} من{" "}
{pages}
{" · "}
{total} مركبة
{[
{ 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) => (
))}
)}
>
);
}