refactor(forms): migrate form modals to react-hook-form + yupResolver, and adopt shared UI kit components across Role/Order/User/Trip modals and tables
Replace manual useState + validate() wiring with react-hook-form and
yupResolver across CarFormModal, DriverFormModal, Tripformmodal,
OrderFormModal, BranchFormModal, CarMaintananceFormModal, RoleFormModal,
and UserFormModal, following the existing pattern in Addressformmodal.
- Pin yupResolver's generic explicitly (yupResolver<FormValues>(schema as any))
since create/update schemas differ structurally and yup can't unify them
into a single inferred type on its own.
- Replace manual ref-based autofocus (useRef + ref={firstRef}) with
autoFocus/setFocus to avoid ref collisions with register()'s own ref.
- DriverFormModal: bind photo/nationalPhoto/driverCardPhoto file fields via
Controller instead of register.
- Tripformmodal: convert startTime/endTime to ISO-8601 via setValueAs while
keeping the datetime-local input display unaffected.
- OrderFormModal: register nested deliveryAddress/pickupAddress fields via
dot-path syntax; keep pickupMode as local state; preserve conditional
address payload assembly.
- CarMaintananceFormModal: keep toNumberOrUndefined cost coercion and
ISO-8601 date conversion at submit time.
- RoleFormModal: bind permissionIds checkbox group via Controller.
- UserFormModal: add a custom resolver wrapper to preserve the
empty-password-on-edit behavior (skip password validation when editing
with a blank password field).
Also replace raw HTML elements with the shared UI kit components
(Modal, Input, Textarea, Select, Button, Alert, Badge, EmptyState) across
form modals, detail modals, and tables:
- RoleFormModal: Modal, Input, Textarea, Button
- OrderFormModal: Modal, Input, Select, Button
- UserDetailModal / Archiveduserdetailmodal: Modal, Alert, Button
- UserTable / Archivedusertable: Badge, Button, EmptyState
- RoleDetailModal / ArchivedRoleDetailModal: Modal, Alert, Select, Button
- RoleTable / ArchivedRoleTable: Button, EmptyState
- Tripreportpanel: Button with built-in loading state instead of manual
Spinner/disabled/color wiring
StatusBadge, IconBtn, and other per-action custom chips/checkboxes are kept
as-is in every file — the shared Badge/Button components don't support dot
indicators or per-action color-coding, so forcing them in would misshape or
strip semantics from these controls.
Archivedusersmodal, ArchivedRolesModal, and ArchivedTripList required no
changes — already fully compliant with the shared UI kit.
No changes to visual layout, CSS, or Arabic labels/section headings beyond
what's required by the component swaps above.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { useRef, useState } from "react";
|
||||
import { Spinner ,Toast} from "../UI";
|
||||
import { Button, Toast } from "../UI";
|
||||
import { tripService } from "@/src/services/trip.service";
|
||||
import { getStoredToken } from "@/src/lib/auth";
|
||||
import type { TripNotification } from "@/src/hooks/useTrip";
|
||||
@@ -78,30 +78,9 @@ export function TripReportPanel({ tripId }: TripReportPanelProps) {
|
||||
إنشاء تقرير الرحلة
|
||||
</p>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleGenerate}
|
||||
disabled={loading}
|
||||
style={{
|
||||
height: 38,
|
||||
padding: "0 1.25rem",
|
||||
borderRadius: "var(--radius-md)",
|
||||
border: "none",
|
||||
fontSize: 13,
|
||||
fontWeight: 700,
|
||||
color: "#FFF",
|
||||
background: loading ? "var(--color-brand-400)" : "var(--color-brand-600)",
|
||||
cursor: loading ? "not-allowed" : "pointer",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: 8,
|
||||
fontFamily: "var(--font-sans)",
|
||||
whiteSpace: "nowrap",
|
||||
}}
|
||||
>
|
||||
{loading && <Spinner size="sm" className="text-white" />}
|
||||
<Button type="button" onClick={handleGenerate} loading={loading}>
|
||||
{loading ? "جارٍ الإنشاء…" : "إنشاء تقرير البيان"}
|
||||
</button>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<Toast
|
||||
|
||||
Reference in New Issue
Block a user