"use client";
import { useCallback, useState } from "react";
import { Spinner, Alert, ArchiveButton, ConfirmDialog } from "@/src/Components/UI";
import { CarFormModal,CarDetailPanel } from "@/src/Components/car";
import { ArchivedCarsModal } from "@/src/Components/car/archive/Archivedcarsmodal";
import { CarMaintenanceFormModal } from "@/src/Components/Car_Maintanance/CarMaintananceFormModal";
import { useCars, useCarMutations, useToast } from "@/src/hooks/useCars";
import { useCarMaintenanceMutations } from "@/src/hooks/UseCarsMaintanance";
import { fmtDateShort, isExpiringSoon, STATUS_MAP, INS_MAP } from "@/src/types/car";
import type { Car, CreateCarPayload, ToastMsg, UpdateCarPayload } from "@/src/types/car";
import type { CreateMaintenancePayload, UpdateMaintenancePayload } from "@/src/types/carMaintanance";
// ── Toast ─────────────────────────────────────────────────────────────────────
function CarToast({ notification }: { notification: ToastMsg | null }) {
if (!notification) return null;
const ok = notification.type === "success";
return (
{ok ? "✓" : "⚠"}{notification.message}
);
}
// ── CarCard ───────────────────────────────────────────────────────────────────
// NOTE: hover/lift affordance is implemented via Tailwind `hover:`/`focus-visible:`
// classes instead of onMouseEnter/onMouseLeave DOM mutation, so keyboard users
// (tabbing to this card, which is already role="button" tabIndex={0}) get the
// same visual feedback as mouse users via the native :focus-visible pseudo-class.
function CarCard({
car,
onClick,
onSendToMaintenance,
}: {
car: Car;
onClick: () => void;
onSendToMaintenance: (car: Car) => void;
}) {
const status = STATUS_MAP[car.currentStatus];
const ins = car.insuranceStatus ? INS_MAP[car.insuranceStatus] : null;
const regWarn = isExpiringSoon(car.registrationExpiryDate);
// Maintenance status can ONLY be set via this button's flow (POST
// cars/:carId/maintenance flips it on the backend). Disable rather than
// hide it once the car is already in maintenance or inactive, and explain why.
const maintenanceDisabled = car.currentStatus === "InMaintenance" || car.currentStatus === "Inactive";
const maintenanceDisabledReason =
car.currentStatus === "InMaintenance"
? "المركبة في الصيانة بالفعل"
: car.currentStatus === "Inactive"
? "لا يمكن إرسال مركبة غير نشطة للصيانة"
: undefined;
return (
{ if (e.key === "Enter" || e.key === " ") onClick(); }}
aria-label={`${car.manufacturer} ${car.model} — ${car.plateLetters} ${car.plateNumber}`}
className="rounded-[var(--radius-xl)] border border-[var(--color-border)] bg-[var(--color-surface)] overflow-hidden shadow-[var(--shadow-card)] cursor-pointer outline-none transition-all duration-200 hover:shadow-[0_8px_24px_rgba(37,99,235,.12)] hover:-translate-y-0.5 focus-visible:shadow-[0_8px_24px_rgba(37,99,235,.12)] focus-visible:-translate-y-0.5 focus-visible:ring-2 focus-visible:ring-[var(--color-brand-600)] focus-visible:ring-offset-2"
>
{/* 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 : "—"}
{/* Send to Maintenance quick action */}
{/* Footer CTA hint */}
{search ? `لا توجد مركبات تطابق "${search}"` : "لا توجد مركبات بعد"}
اضغط على "إضافة مركبة" لإضافة أول مركبة في الأسطول.
{!search && (
)}
) : (
/* ── Card grid ── */
{/* PERF NOTE: Cards are rendered inline via .map() below. At the
current pagination size (10-12 items) this is not a bottleneck.
If page size increases (e.g. "show all" mode, a larger
page-size selector, or removal of server-side pagination),
extract is already its own component above — wrap
it in React.memo at that point, and make sure onClick /
onSendToMaintenance passed to it are stable (useCallback)
so memoization is actually effective. */}
{cars.map((car) => (
setDetailId(car.id)}
onSendToMaintenance={(c) => setMaintenanceTarget(c)}
/>
))}