sendou.ink/app/components/form/MyForm.tsx
Kalle 9312fad90f
Tournament organization page (#1811)
* Initial

* Calendar initial

* Extract EventCalendar

* Events list initial

* Winners

* SQL fixes

* List events by series

* Leaderboards

* Series leaderboard

* Own entry peek

* Edit page skeleton

* RHF initial test

* RHF stuff

* Form etc. progress

* Fix tournament series description

* Fix tabs layout

* Fix socials insert

* Check for not removing admin

* Adding series

* TODOs

* Allow updating org with no series

* FormFieldset

* Allow series without events

* TextAreaFormfield accepting array syntax

* Input form array field

* ToggleFormField

* SelectFormField

* UserSearchFormField

* Fetch badgeOptions

* Badge editing

* Progress

* Use native preventScrollReset

* Rename func

* Fix sticky scroll

* Fix translation

* i18n errors

* handle,meta in edit

* Add ref to user search

* TODOs

* Done
2024-07-25 23:06:29 +03:00

57 lines
1.4 KiB
TypeScript

import { zodResolver } from "@hookform/resolvers/zod";
import { useFetcher } from "@remix-run/react";
import * as React from "react";
import { FormProvider, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import type { z } from "zod";
import type { ActionError } from "~/utils/remix";
import { SubmitButton } from "../SubmitButton";
export function MyForm<T extends z.ZodTypeAny>({
schema,
defaultValues,
title,
children,
}: {
schema: T;
defaultValues?: z.infer<T>;
title?: string;
children: React.ReactNode;
}) {
const { t } = useTranslation(["common"]);
const fetcher = useFetcher<any>();
const methods = useForm<z.infer<T>>({
resolver: zodResolver(schema),
defaultValues,
});
React.useEffect(() => {
if (!fetcher.data?.isError) return;
const error = fetcher.data as ActionError;
methods.setError(error.field as any, {
message: error.msg,
});
}, [fetcher.data, methods.setError]);
const onSubmit = React.useCallback(
methods.handleSubmit((values) =>
fetcher.submit(values, { method: "post", encType: "application/json" }),
),
[],
);
return (
<FormProvider {...methods}>
<fetcher.Form className="stack md-plus items-start" onSubmit={onSubmit}>
{title ? <h1 className="text-lg">{title}</h1> : null}
{children}
<SubmitButton state={fetcher.state} className="mt-6">
{t("common:actions.submit")}
</SubmitButton>
</fetcher.Form>
</FormProvider>
);
}