mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-09-30 04:33:11 +00:00
- 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
57 lines
1.8 KiB
TypeScript
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: "",
|
|
};
|