finsh user,car,driver pages also add validator layer to app build trip page
This commit is contained in:
194
validations/trip.validator.ts
Normal file
194
validations/trip.validator.ts
Normal file
@@ -0,0 +1,194 @@
|
||||
import * as yup from "yup";
|
||||
import type { TripStatus } from "@/types/trip";
|
||||
|
||||
const TRIP_STATUSES: TripStatus[] = [
|
||||
"Scheduled",
|
||||
"InProgress",
|
||||
"Completed",
|
||||
"Cancelled",
|
||||
];
|
||||
|
||||
// NOTE: Unlike driver_validator.ts, there is no actual backend trip validator
|
||||
// file in this handoff. The rules below come from trip_api_reference.html
|
||||
// (marked "// doc") plus a few sensible defaults that are NOT explicitly
|
||||
// stated in the reference (marked "// inferred"). Verify the "inferred" ones
|
||||
// against the real backend validator before relying on them.
|
||||
|
||||
// ── Create schema ─────────────────────────────────────────────────────────────
|
||||
|
||||
export const createTripSchema = yup.object({
|
||||
// Required
|
||||
title: yup
|
||||
.string()
|
||||
.required("عنوان الرحلة مطلوب")
|
||||
.min(3, "عنوان الرحلة يجب أن يكون 3 أحرف على الأقل"), // doc
|
||||
|
||||
driverId: yup
|
||||
.string()
|
||||
.required("السائق مطلوب")
|
||||
.uuid("معرّف السائق غير صالح"), // doc: UUID, driver must be status=Active (enforced server-side)
|
||||
|
||||
carId: yup
|
||||
.string()
|
||||
.required("السيارة مطلوبة")
|
||||
.uuid("معرّف السيارة غير صالح"), // doc: UUID, car must be status=Active (enforced server-side)
|
||||
|
||||
// Optional
|
||||
startTime: yup.string().optional(), // doc: ISO 8601, default now()
|
||||
|
||||
endTime: yup
|
||||
.string()
|
||||
.optional()
|
||||
.test(
|
||||
"after-start",
|
||||
"وقت الانتهاء يجب أن يكون بعد وقت البدء",
|
||||
function (val) {
|
||||
if (!val) return true;
|
||||
const { startTime } = this.parent;
|
||||
if (!startTime) return true;
|
||||
return new Date(val) > new Date(startTime); // inferred
|
||||
},
|
||||
),
|
||||
|
||||
branchId: yup.string().uuid("معرّف الفرع غير صالح").optional(), // doc
|
||||
|
||||
status: yup
|
||||
.mixed<TripStatus>()
|
||||
.oneOf(TRIP_STATUSES, "حالة الرحلة غير صالحة")
|
||||
.optional(), // doc: default Scheduled
|
||||
|
||||
collectedCount: yup
|
||||
.number()
|
||||
.typeError("القيمة يجب أن تكون رقم")
|
||||
.integer("القيمة يجب أن تكون رقم صحيح")
|
||||
.min(0, "القيمة لا يمكن أن تكون سالبة") // inferred
|
||||
.optional(),
|
||||
|
||||
deliveredCount: yup
|
||||
.number()
|
||||
.typeError("القيمة يجب أن تكون رقم")
|
||||
.integer("القيمة يجب أن تكون رقم صحيح")
|
||||
.min(0, "القيمة لا يمكن أن تكون سالبة") // inferred
|
||||
.optional(),
|
||||
|
||||
returnedCount: yup
|
||||
.number()
|
||||
.typeError("القيمة يجب أن تكون رقم")
|
||||
.integer("القيمة يجب أن تكون رقم صحيح")
|
||||
.min(0, "القيمة لا يمكن أن تكون سالبة") // inferred
|
||||
.optional(),
|
||||
|
||||
totalCashCollected: yup
|
||||
.number()
|
||||
.typeError("القيمة يجب أن تكون رقم")
|
||||
.min(0, "القيمة لا يمكن أن تكون سالبة") // inferred
|
||||
.optional(), // doc: number | string -> Decimal server-side
|
||||
|
||||
notes: yup
|
||||
.string()
|
||||
.min(2, "الملاحظات يجب أن تكون حرفين على الأقل") // doc
|
||||
.optional(),
|
||||
|
||||
endReason: yup
|
||||
.string()
|
||||
.min(2, "سبب الانتهاء يجب أن يكون حرفين على الأقل") // doc
|
||||
.optional(),
|
||||
});
|
||||
|
||||
// ── Update schema (same rules, all optional + reason) ─────────────────────────
|
||||
|
||||
export const updateTripSchema = yup.object({
|
||||
title: yup
|
||||
.string()
|
||||
.min(3, "عنوان الرحلة يجب أن يكون 3 أحرف على الأقل")
|
||||
.optional(),
|
||||
|
||||
driverId: yup.string().uuid("معرّف السائق غير صالح").optional(), // doc: must be Active
|
||||
|
||||
carId: yup.string().uuid("معرّف السيارة غير صالح").optional(), // doc: must be Active
|
||||
|
||||
status: yup
|
||||
.mixed<TripStatus>()
|
||||
.oneOf(TRIP_STATUSES, "حالة الرحلة غير صالحة")
|
||||
.optional(),
|
||||
|
||||
startTime: yup.string().optional(),
|
||||
|
||||
endTime: yup
|
||||
.string()
|
||||
.optional()
|
||||
.test(
|
||||
"after-start",
|
||||
"وقت الانتهاء يجب أن يكون بعد وقت البدء",
|
||||
function (val) {
|
||||
if (!val) return true;
|
||||
const { startTime } = this.parent;
|
||||
if (!startTime) return true;
|
||||
return new Date(val) > new Date(startTime); // inferred
|
||||
},
|
||||
),
|
||||
|
||||
branchId: yup.string().uuid("معرّف الفرع غير صالح").optional(),
|
||||
|
||||
collectedCount: yup
|
||||
.number()
|
||||
.typeError("القيمة يجب أن تكون رقم")
|
||||
.integer("القيمة يجب أن تكون رقم صحيح")
|
||||
.min(0, "القيمة لا يمكن أن تكون سالبة")
|
||||
.optional(),
|
||||
|
||||
deliveredCount: yup
|
||||
.number()
|
||||
.typeError("القيمة يجب أن تكون رقم")
|
||||
.integer("القيمة يجب أن تكون رقم صحيح")
|
||||
.min(0, "القيمة لا يمكن أن تكون سالبة")
|
||||
.optional(),
|
||||
|
||||
returnedCount: yup
|
||||
.number()
|
||||
.typeError("القيمة يجب أن تكون رقم")
|
||||
.integer("القيمة يجب أن تكون رقم صحيح")
|
||||
.min(0, "القيمة لا يمكن أن تكون سالبة")
|
||||
.optional(),
|
||||
|
||||
totalCashCollected: yup
|
||||
.number()
|
||||
.typeError("القيمة يجب أن تكون رقم")
|
||||
.min(0, "القيمة لا يمكن أن تكون سالبة")
|
||||
.optional(),
|
||||
|
||||
notes: yup
|
||||
.string()
|
||||
.min(2, "الملاحظات يجب أن تكون حرفين على الأقل")
|
||||
.optional(),
|
||||
|
||||
endReason: yup
|
||||
.string()
|
||||
.min(2, "سبب الانتهاء يجب أن يكون حرفين على الأقل")
|
||||
.optional(),
|
||||
|
||||
// Update-only: reason for reassigning driver/car (recorded in history)
|
||||
reason: yup.string().optional(), // doc: no explicit min length stated
|
||||
});
|
||||
|
||||
// ── Infer form error shape ────────────────────────────────────────────────────
|
||||
|
||||
export type TripSchemaErrors = Partial<
|
||||
Record<
|
||||
| "title"
|
||||
| "driverId"
|
||||
| "carId"
|
||||
| "status"
|
||||
| "startTime"
|
||||
| "endTime"
|
||||
| "branchId"
|
||||
| "collectedCount"
|
||||
| "deliveredCount"
|
||||
| "returnedCount"
|
||||
| "totalCashCollected"
|
||||
| "notes"
|
||||
| "endReason"
|
||||
| "reason",
|
||||
string
|
||||
>
|
||||
>;
|
||||
Reference in New Issue
Block a user