"use client" // Reserves stock of one item for this project, from one location that has some available. The request // id is minted once per submission, so a retried request reserves once; the service answers a // quantity it cannot hold as `insufficient_stock`, shown here in the kit's words for that refusal. import type { ProjectSlugs } from "@conusai-kit/ui" import { describeError, useWrite } from "@conusai-kit/ui/data" import { FormLayout, type FormValues, PageSection, SelectField, serviceNotice, TextField, usePageNavigation, } from "@conusai-kit/ui/patterns" import { type ReactElement, useState } from "react" export interface ReserveFormLabels { readonly heading: string readonly location: string readonly quantity: string readonly submit: string readonly busy: string readonly nothing: string /** The text of each business refusal by problem code (`businessRefusalNotices` of `@conusai-kit/business/refusals`). */ readonly refusals: Readonly> } export interface ReserveOption { readonly locationId: string /** What a person reads for the location, with what is available there. */ readonly label: string readonly available: number } export function ReserveForm({ slugs, itemId, options, labels, }: { slugs: ProjectSlugs itemId: string options: readonly ReserveOption[] labels: ReserveFormLabels }): ReactElement { const navigation = usePageNavigation() const reserve = useWrite, unknown>("inventory.stock.reserve") const [requestId, setRequestId] = useState(() => crypto.randomUUID()) const open = options.filter((option) => option.available > 0) const submit = async ({ locationId, quantity }: FormValues): Promise => { await reserve.mutate({ ...slugs, itemId, locationId, quantity: Number(quantity), requestId }) setRequestId(crypto.randomUUID()) // The page is rendered on the server: a reload shows the new balance and the reservation. await navigation.refresh() } return ( {open.length === 0 ? (

{labels.nothing}

) : ( serviceNotice(error, labels.refusals)?.text ?? describeError(error)} > ({ value: option.locationId, label: option.label }))} /> )}
) }