import { useState, ReactNode, PropsWithoutRef } from "react"; import { FormProvider, useForm, UseFormProps } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { z } from "zod"; import clsx from "clsx"; import Alert from "app/core/components/alert"; import Logo from "app/core/components/logo"; export interface FormProps> extends Omit, "onSubmit"> { /** All your form fields */ children?: ReactNode; texts: { title: string; subtitle: ReactNode; submit: string; }; schema?: S; onSubmit: (values: z.infer) => Promise; initialValues?: UseFormProps>["defaultValues"]; } interface OnSubmitResult { FORM_ERROR?: string; [prop: string]: any; } export const FORM_ERROR = "FORM_ERROR"; export function AuthForm>({ children, texts, schema, initialValues, onSubmit, ...props }: FormProps) { const ctx = useForm>({ mode: "onBlur", resolver: schema ? zodResolver(schema) : undefined, defaultValues: initialValues, }); const [formError, setFormError] = useState(null); return (

{texts.title}

{texts.subtitle}

{ const result = (await onSubmit(values)) || {}; for (const [key, value] of Object.entries(result)) { if (key === FORM_ERROR) { setFormError(value); } else { ctx.setError(key as any, { type: "submit", message: value, }); } } })} className="form" {...props} > {formError ? (
) : null} {children} {texts.submit ? ( ) : null}
); } export default AuthForm;