From 2d05d3446cbdf17ed3f4d0da97f6b50c20ef772a Mon Sep 17 00:00:00 2001 From: m7amedez5511 Date: Wed, 19 Aug 2026 18:00:55 +0300 Subject: [PATCH] solve problem tree rerender --- app/dashboard/cars/page.tsx | 642 ++++++++++++++++------ app/dashboard/drivers/[driverId]/page.tsx | 557 +++++++++++++++---- app/dashboard/drivers/page.tsx | 167 ++++-- app/dashboard/trips/[tripId]/page.tsx | 294 ++++++++-- app/dashboard/trips/page.tsx | 22 +- app/layout.tsx | 7 +- src/Components/Driver/DriverFormModal.tsx | 125 +++-- src/Components/Trip/Tripformmodal.tsx | 40 +- src/Components/car/CarFormModal.tsx | 54 +- src/hooks/useCurrentUser.ts | 8 +- src/hooks/useUser.ts | 4 +- 11 files changed, 1441 insertions(+), 479 deletions(-) diff --git a/app/dashboard/cars/page.tsx b/app/dashboard/cars/page.tsx index 2e16d8e..b7644fd 100644 --- a/app/dashboard/cars/page.tsx +++ b/app/dashboard/cars/page.tsx @@ -1,16 +1,33 @@ "use client"; - import { useCallback, useState } from "react"; -import { Spinner, Alert, ArchiveButton, ConfirmDialog } from "@/src/Components/UI"; -import { CarFormModal,CarDetailPanel } from "@/src/Components/car"; +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"; +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 ───────────────────────────────────────────────────────────────────── @@ -18,21 +35,35 @@ function CarToast({ notification }: { notification: ToastMsg | null }) { if (!notification) return null; const ok = notification.type === "success"; return ( -
-
+
+
{ok ? "✓" : "⚠"} {notification.message}
@@ -56,13 +87,14 @@ function CarCard({ onSendToMaintenance: (car: Car) => void; }) { const status = STATUS_MAP[car.currentStatus]; - const ins = car.insuranceStatus ? INS_MAP[car.insuranceStatus] : null; + 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 maintenanceDisabled = + car.currentStatus === "InMaintenance" || car.currentStatus === "Inactive"; const maintenanceDisabledReason = car.currentStatus === "InMaintenance" ? "المركبة في الصيانة بالفعل" @@ -75,85 +107,206 @@ function CarCard({ onClick={onClick} role="button" tabIndex={0} - onKeyDown={e => { if (e.key === "Enter" || e.key === " ") onClick(); }} + onKeyDown={(e) => { + 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}` : ""} +

+ {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)} + + انتهاء الاستمارة + + + {regWarn && "⚠ "} + {fmtDateShort(car.registrationExpiryDate)}
- الطاقة - + + الطاقة + + {car.capacity != null ? car.capacity : "—"}
@@ -174,20 +327,38 @@ function CarCard({ height: 34, borderRadius: "var(--radius-md)", border: `1px solid ${maintenanceDisabled ? "var(--color-border)" : "#FDE68A"}`, - background: maintenanceDisabled ? "var(--color-surface-muted)" : "#FFFBEB", - fontSize: 12, fontWeight: 700, + background: maintenanceDisabled + ? "var(--color-surface-muted)" + : "#FFFBEB", + fontSize: 12, + fontWeight: 700, color: maintenanceDisabled ? "var(--color-text-hint)" : "#854D0E", cursor: maintenanceDisabled ? "not-allowed" : "pointer", - display: "flex", alignItems: "center", justifyContent: "center", gap: 6, + display: "flex", + alignItems: "center", + justifyContent: "center", + gap: 6, fontFamily: "var(--font-sans)", }} > -