{"version":3,"file":"form-BefLrk-v.js","sources":["../../../app/helpers/fetch/form.tsx"],"sourcesContent":["import {\n type Method,\n type PathHelper,\n type ResponseError,\n} from \"@js-from-routes/client\";\nimport {\n useForm,\n type UseFormInput,\n type UseFormReturnType,\n} from \"@mantine/form\";\nimport { type FormEvent } from \"react\";\nimport { startTransition } from \"react\";\nimport { toast } from \"sonner\";\n\nimport { showFormErrorsAlert } from \"~/helpers/form\";\nimport { sentencify } from \"~/helpers/inflect\";\n\ntype FetchPartialForm<\n Values,\n TransformValues extends (values: Values) => unknown,\n> = Omit, \"onSubmit\" | \"onReset\">;\n\nexport interface FetchFormOptions<\n Data extends Record & { error?: never },\n Values,\n TransformValues extends (values: Values) => unknown,\n> extends UseFormInput {\n action: PathHelper;\n descriptor: string;\n params?: {\n query?: Record;\n [key: string]: any;\n };\n method?: Method;\n failSilently?: boolean;\n beforeSubmit?: (form: FetchPartialForm) => void;\n onSubmit?: (\n transformedValues: ReturnType,\n submission: Promise,\n form: FetchPartialForm,\n ) => void;\n onSuccess?: (\n data: Data,\n form: FetchPartialForm,\n ) => void;\n onFailure?: (\n error: Error,\n form: FetchPartialForm,\n ) => void;\n onError?: (form: FetchPartialForm) => void;\n}\n\ntype FetchFormSubmit = (event?: FormEvent) => void;\n\nexport interface FetchForm<\n Data,\n Values,\n TransformValues extends (values: Values) => unknown,\n> extends Omit, \"onSubmit\"> {\n data: Data | undefined;\n error: Error | undefined;\n processing: boolean;\n submit: FetchFormSubmit;\n}\n\ntype _TransformValues = (values: Values) => unknown;\n\nconst NO_BODY_METHODS: Method[] = [\n \"get\",\n \"GET\",\n \"delete\",\n \"DELETE\",\n \"head\",\n \"HEAD\",\n \"options\",\n \"OPTIONS\",\n];\n\n// TODO: Serialize form data.\nexport const useFetchForm = <\n Data extends Record & { error?: never; errors?: never } = {},\n Values extends Record = {},\n TransformValues extends _TransformValues = (values: Values) => Values,\n>(\n options: FetchFormOptions,\n): FetchForm => {\n const {\n action,\n method = action.httpMethod,\n descriptor,\n failSilently,\n beforeSubmit,\n onSubmit,\n onError,\n onFailure,\n onSuccess,\n params,\n transformValues,\n ...otherOptions\n } = options;\n const form = useForm({\n ...otherOptions,\n transformValues,\n });\n const [data, setData] = useState();\n const [error, setError] = useState();\n const [processing, setProcessing] = useState(false);\n const handleSubmit = form.onSubmit(\n transformedValues => {\n setProcessing(true);\n const submission = action<\n Data & { error?: string; errors?: Record }\n >({\n params,\n method,\n data: NO_BODY_METHODS.includes(method) ? undefined : transformedValues,\n })\n .then(\n data => {\n startTransition(() => {\n setData(data);\n });\n onSuccess?.(data, form);\n form.reset();\n return data;\n },\n (responseError: ResponseError) => {\n if (responseError.body) {\n const body = responseError.body as {\n error?: string;\n errors?: Record;\n };\n if (typeof body.error === \"string\") {\n const error = new Error(body.error);\n startTransition(() => {\n setError(error);\n });\n console.error(`Failed to ${descriptor}`, error);\n if (!failSilently) {\n toast.error(`Failed to ${descriptor}`, {\n description: sentencify(\n body.error || \"An unknown error occurred\",\n ),\n });\n }\n onFailure?.(error, form);\n } else if (typeof body.errors === \"object\") {\n form.setErrors(body.errors);\n console.warn(`Couldn't ${descriptor}`, {\n errors: body.errors,\n });\n const formWithErrors = { ...form, errors: body.errors };\n if (!failSilently) {\n showFormErrorsAlert(formWithErrors, `Couldn't ${descriptor}`);\n }\n onError?.(formWithErrors);\n }\n } else {\n console.error(\"Unknown error response\", responseError);\n if (!failSilently) {\n toast.error(`Failed to ${descriptor}`, {\n description: sentencify(\n responseError.message || \"An unknown error occurred\",\n ),\n });\n }\n onFailure?.(responseError, form);\n }\n throw responseError;\n },\n )\n .finally(() => {\n setProcessing(false);\n });\n onSubmit?.(transformedValues, submission, form);\n },\n errors => {\n const formWithErrors = { ...form, errors };\n onError?.(formWithErrors);\n showFormErrorsAlert(formWithErrors, `Couldn't ${descriptor}`);\n },\n );\n const submit = (event?: FormEvent) => {\n beforeSubmit?.(form);\n handleSubmit(event);\n };\n return {\n ...form,\n processing,\n submit,\n data,\n error,\n };\n};\n"],"names":["NO_BODY_METHODS","useFetchForm","options","action","method","descriptor","failSilently","beforeSubmit","onSubmit","onError","onFailure","onSuccess","params","transformValues","otherOptions","form","useForm","data","setData","useState","error","setError","processing","setProcessing","handleSubmit","transformedValues","submission","startTransition","responseError","body","toast","sentencify","formWithErrors","showFormErrorsAlert","errors","event"],"mappings":"gJAmEA,MAAMA,EAA4B,CAChC,MACA,MACA,SACA,SACA,OACA,OACA,UACA,SACF,EAGaC,EAKXC,GAC6C,CACvC,KAAA,CACJ,OAAAC,EACA,OAAAC,EAASD,EAAO,WAChB,WAAAE,EACA,aAAAC,EACA,aAAAC,EACA,SAAAC,EACA,QAAAC,EACA,UAAAC,EACA,UAAAC,EACA,OAAAC,EACA,gBAAAC,EACA,GAAGC,CAAA,EACDZ,EACEa,EAAOC,EAAiC,CAC5C,GAAGF,EACH,gBAAAD,CAAA,CACD,EACK,CAACI,EAAMC,CAAO,EAAIC,WAA2B,EAC7C,CAACC,EAAOC,CAAQ,EAAIF,WAA4B,EAChD,CAACG,EAAYC,CAAa,EAAIJ,EAAAA,SAAS,EAAK,EAC5CK,EAAeT,EAAK,SACHU,GAAA,CACnBF,EAAc,EAAI,EAClB,MAAMG,EAAavB,EAEjB,CACA,OAAAS,EACA,OAAAR,EACA,KAAMJ,EAAgB,SAASI,CAAM,EAAI,OAAYqB,CACtD,CAAA,EACE,KACCR,IACEU,EAAAA,gBAAgB,IAAM,CACpBT,EAAQD,CAAI,CAAA,CACb,EACDN,GAAA,MAAAA,EAAYM,EAAMF,GAClBA,EAAK,MAAM,EACJE,GAERW,GAAiC,CAChC,GAAIA,EAAc,KAAM,CACtB,MAAMC,EAAOD,EAAc,KAIvB,GAAA,OAAOC,EAAK,OAAU,SAAU,CAClC,MAAMT,EAAQ,IAAI,MAAMS,EAAK,KAAK,EAClCF,EAAAA,gBAAgB,IAAM,CACpBN,EAASD,CAAK,CAAA,CACf,EACD,QAAQ,MAAM,aAAaf,CAAU,GAAIe,CAAK,EACzCd,GACGwB,EAAA,MAAM,aAAazB,CAAU,GAAI,CACrC,YAAa0B,EACXF,EAAK,OAAS,2BAAA,CAChB,CACD,EAEHnB,GAAA,MAAAA,EAAYU,EAAOL,EACV,SAAA,OAAOc,EAAK,QAAW,SAAU,CACrCd,EAAA,UAAUc,EAAK,MAAM,EAClB,QAAA,KAAK,YAAYxB,CAAU,GAAI,CACrC,OAAQwB,EAAK,MAAA,CACd,EACD,MAAMG,EAAiB,CAAE,GAAGjB,EAAM,OAAQc,EAAK,MAAO,EACjDvB,GACiB2B,EAAAD,EAAgB,YAAY3B,CAAU,EAAE,EAE9DI,GAAA,MAAAA,EAAUuB,EAAc,CAC1B,MAEQ,QAAA,MAAM,yBAA0BJ,CAAa,EAChDtB,GACGwB,EAAA,MAAM,aAAazB,CAAU,GAAI,CACrC,YAAa0B,EACXH,EAAc,SAAW,2BAAA,CAC3B,CACD,EAEHlB,GAAA,MAAAA,EAAYkB,EAAeb,GAEvB,MAAAa,CAAA,CAEV,EACC,QAAQ,IAAM,CACbL,EAAc,EAAK,CAAA,CACpB,EACQf,GAAA,MAAAA,EAAAiB,EAAmBC,EAAYX,EAC5C,EACUmB,GAAA,CACR,MAAMF,EAAiB,CAAE,GAAGjB,EAAM,OAAAmB,CAAO,EACzCzB,GAAA,MAAAA,EAAUuB,GACUC,EAAAD,EAAgB,YAAY3B,CAAU,EAAE,CAAA,CAEhE,EAKO,MAAA,CACL,GAAGU,EACH,WAAAO,EACA,OAPca,GAAuC,CACrD5B,GAAA,MAAAA,EAAeQ,GACfS,EAAaW,CAAK,CACpB,EAKE,KAAAlB,EACA,MAAAG,CACF,CACF"}