ERP-System fdce301495 fix(dashboard): resolve tutorial QA notes (clips 2–6)
- settings/company: show success toast on save (2.1)
- inspection templates: add explicit Save button (2.6)
- parts: label price fields with AED currency (3.1)
- service groups: add parts/services picker to packages (3.3)
- vehicles: add insurance (has_insurance + insurance type) field (4.2)
- appointments: add calendar view with list/calendar toggle (5.1)
- job card check-in: require department (5.4)
- job card payments: refresh job card/invoice queries so PAID shows (5.6)
- vendors: add phone + address fields (6.1)
- bill payments: surface real vendor/employee validation errors (6.4)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 11:39:07 +04:00

44 lines
1.8 KiB
TypeScript

import { z } from "zod"
const optionalStringMaxSchema = (max: number) =>
z.preprocess(
(value) => (value === "" || value == null ? undefined : value),
z.string().max(max, `Must be at most ${max} characters`).optional(),
)
const optionalNumberSchema = z.preprocess(
(value) => (value === "" || value == null ? undefined : value),
z.coerce.number().int().optional(),
)
const relationFieldSchema = z
.object({ value: z.string(), label: z.string() })
.nullable()
.optional()
const vendorFormSchema = z.object({
first_name: z.string().trim().min(1, "First name is required").max(50, "First name must be at most 50 characters"),
last_name: z.string().trim().min(1, "Last name is required").max(50, "Last name must be at most 50 characters"),
company_name: z.string().trim().min(1, "Company name is required").max(50, "Company name must be at most 50 characters"),
email: z.string().trim().min(1, "Email is required").email("Enter a valid email address").max(100, "Email must be at most 100 characters"),
salutation: optionalStringMaxSchema(50),
phone: optionalStringMaxSchema(20),
alternate_phone: optionalStringMaxSchema(20),
opening_balance: optionalNumberSchema,
credit_limit: optionalNumberSchema,
website: optionalStringMaxSchema(255),
// ── Address (optional). Persisted by the backend store endpoint when
// address_line_1 + country + state are provided. ──
address_line_1: optionalStringMaxSchema(255),
address_line_2: optionalStringMaxSchema(255),
city: optionalStringMaxSchema(100),
zip_code: optionalStringMaxSchema(20),
country: relationFieldSchema,
state: relationFieldSchema,
})
type VendorFormValues = z.infer<typeof vendorFormSchema>
export { vendorFormSchema }
export type { VendorFormValues }