mirror of
https://github.com/Sea-Haven-Industries/proposal-system.git
synced 2026-10-07 16:18:57 +00:00
49 lines
1.8 KiB
TypeScript
49 lines
1.8 KiB
TypeScript
|
|
// Customers domain — contract schema re-exports + customer form schema.
|
||
|
|
import { z } from 'zod';
|
||
|
|
import { createCustomerRequestSchema } from '@proposal-system/api-contracts/schemas';
|
||
|
|
import type { CreateCustomerRequest, UpdateCustomerRequest } from './types';
|
||
|
|
|
||
|
|
export {
|
||
|
|
customerSchema,
|
||
|
|
createCustomerRequestSchema,
|
||
|
|
updateCustomerRequestSchema,
|
||
|
|
} from '@proposal-system/api-contracts/schemas';
|
||
|
|
|
||
|
|
/** Simple email format check (client-side only) — mirrors CustomerManagementPage. */
|
||
|
|
const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Customer create/edit form. Derived from createCustomerRequestSchema — the
|
||
|
|
* form edits a single primary address string (the wire type takes
|
||
|
|
* addresses: string[]); toCustomerRequest() maps to the request shape.
|
||
|
|
*/
|
||
|
|
export const customerFormSchema = createCustomerRequestSchema
|
||
|
|
.pick({ name: true })
|
||
|
|
.extend({
|
||
|
|
name: z.string().trim().min(1, 'Name is required'),
|
||
|
|
address: z.string().trim().min(1, 'Address is required'),
|
||
|
|
contactEmail: z
|
||
|
|
.string()
|
||
|
|
.refine((v) => v.trim() === '' || EMAIL_RE.test(v.trim()), {
|
||
|
|
message: 'Enter a valid email address',
|
||
|
|
}),
|
||
|
|
});
|
||
|
|
|
||
|
|
export type CustomerFormValues = z.infer<typeof customerFormSchema>;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Map validated form values to the create/update request. The form edits the
|
||
|
|
* primary address; any additional existing addresses are preserved
|
||
|
|
* (mirrors the current CustomerManagementPage submit mapping).
|
||
|
|
*/
|
||
|
|
export function toCustomerRequest(
|
||
|
|
values: CustomerFormValues,
|
||
|
|
existingAddresses: string[] = []
|
||
|
|
): CreateCustomerRequest & UpdateCustomerRequest {
|
||
|
|
return {
|
||
|
|
name: values.name.trim(),
|
||
|
|
addresses: [values.address.trim(), ...existingAddresses.slice(1)],
|
||
|
|
...(values.contactEmail.trim() ? { contactEmail: values.contactEmail.trim() } : {}),
|
||
|
|
};
|
||
|
|
}
|