"use client" // Adds a contact point (an e-mail address, a phone number, a web address) to a party. The service // checks the value against its kind and answers a malformed one in its own words. import type { ProjectSlugs } from "@conusai-kit/ui" import { describeError, useWrite } from "@conusai-kit/ui/data" import { CheckField, FormLayout, type FormValues, PageSection, SelectField, serviceNotice, TextField, usePageNavigation, } from "@conusai-kit/ui/patterns" import { FieldGroup, FieldLegend, FieldSet } from "@conusai-kit/ui/primitives" import { type ReactElement, useState } from "react" import { CONTACT_KINDS, CONTACT_PURPOSES } from "../contract/constants.js" export interface ContactFormLabels { readonly heading: string readonly kind: string readonly value: string readonly purposes: string readonly primary: string readonly submit: string readonly busy: string readonly kinds: Readonly> readonly purposeNames: Readonly> /** The text of each business refusal by problem code (`businessRefusalNotices` of `@conusai-kit/business/refusals`). */ readonly refusals: Readonly> } const INPUT_TYPE = { email: "email", phone: "tel", web: "url" } as const export function ContactForm({ slugs, partyId, labels, }: { slugs: ProjectSlugs partyId: string labels: ContactFormLabels }): ReactElement { const navigation = usePageNavigation() const add = useWrite, unknown>("crm.contact.add") const [requestId, setRequestId] = useState(() => crypto.randomUUID()) const [kind, setKind] = useState<(typeof CONTACT_KINDS)[number]>("email") const submit = async (values: FormValues): Promise => { await add.mutate({ ...slugs, partyId, kind, value: values.value, purposes: CONTACT_PURPOSES.filter((purpose) => values[`purpose-${purpose}`] === "on"), isPrimary: values.isPrimary === "on", requestId, }) setRequestId(crypto.randomUUID()) // The page is rendered on the server: a reload lists the new contact point. await navigation.refresh() } return ( serviceNotice(error, labels.refusals)?.text ?? describeError(error)} > setKind(CONTACT_KINDS.find((option) => option === value) ?? "email")} options={CONTACT_KINDS.map((option) => ({ value: option, label: labels.kinds[option] }))} />
{labels.purposes} {CONTACT_PURPOSES.map((purpose) => ( ))}
) }