shoc-frontend-new/src/domain/locations/schemas/location-schema.ts
Alexandre Brandizzi a75b9c8be6 feat(sites): Add Site modal and site detail panel with in-place edit
- Sites page: Add Site modal with Site Code, Client, address, State/Area, optional Site Phone and Email, points of contact
- Duplicate Site Code shows inline under the field and keeps the modal open
- Row opens a non-modal detail panel; Street Address links to Google Maps; key-less map preview
- Edit switches the panel in place with Site Code read-only; Save needs a valid change, Cancel makes no call
- Site Phone is sent independently of the contacts; zip and title are carried through edits
- Retire the separate new/edit location pages
2026-09-25 11:43:30 -03:00

57 lines
1.8 KiB
TypeScript

import { z } from "zod";
import { US_STATE_CODES } from "@/data/areas";
export const locationContactSchema = z.object({
id: z.number().int().positive().optional(),
name: z
.string()
.trim()
.min(1, "Contact name is required")
.max(100, "Contact name cannot exceed 100 characters"),
phone: z
.string()
.trim()
.min(1, "Contact phone is required")
.max(20, "Contact phone cannot exceed 20 characters"),
});
/** Add Site / Site detail edit form. `zipCode` and `title` are carried through, not edited. */
export const locationSchema = z.object({
name: z
.string()
.trim()
.min(1, "Site Code is required")
.max(50, "Site Code cannot exceed 50 characters"),
accountId: z.string().min(1, "Client is required"),
address: z.string().trim().min(1, "Street Address is required"),
city: z.string().trim().min(1, "City is required"),
state: z
.union([z.enum(US_STATE_CODES), z.literal("")])
.refine((state): boolean => state !== "", { message: "State is required" }),
sitePhone: z.string().trim().max(20, "Site Phone cannot exceed 20 characters"),
contactEmail: z
.string()
.trim()
.refine((value) => value === "" || z.email().safeParse(value).success, {
message: "Invalid email address",
}),
contacts: z.array(locationContactSchema).min(1, "At least one contact is required"),
zipCode: z.string(),
title: z.string(),
});
export type LocationFormValues = z.infer<typeof locationSchema>;
export type LocationContactFormValues = z.infer<typeof locationContactSchema>;
export const locationDefaultValues: LocationFormValues = {
name: "",
accountId: "",
address: "",
city: "",
state: "",
sitePhone: "",
contactEmail: "",
contacts: [{ name: "", phone: "" }],
zipCode: "",
title: "",
};