mirror of
https://github.com/TheRealOwenRees/echecsfrance.git
synced 2026-07-22 20:16:57 +00:00
126 lines
3.9 KiB
TypeScript
126 lines
3.9 KiB
TypeScript
"use client";
|
|
|
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
import { useTranslations } from "next-intl";
|
|
import { FormProvider, useForm } from "react-hook-form";
|
|
import { z } from "zod";
|
|
|
|
import { Button } from "@/components/Button";
|
|
import { InlineSwitchField } from "@/components/form/InlineSwitchField";
|
|
import { Label } from "@/components/form/Label";
|
|
import { TextField } from "@/components/form/TextField";
|
|
import { ZoneEditorField } from "@/components/form/ZoneEditorField";
|
|
import { zoneSchema } from "@/schemas";
|
|
import { Zone } from "@/server/myZones";
|
|
import { TimeControl } from "@/types";
|
|
|
|
export type ZoneFormValues = z.infer<typeof zoneSchema>;
|
|
|
|
type ZoneFormProps = {
|
|
zone?: Zone;
|
|
onSubmit: (data: ZoneFormValues) => Promise<void>;
|
|
onCancel: () => void;
|
|
submitTitle?: string;
|
|
cancelTitle?: string;
|
|
};
|
|
|
|
export const ZoneForm = ({
|
|
zone,
|
|
onSubmit,
|
|
onCancel,
|
|
submitTitle,
|
|
cancelTitle,
|
|
}: ZoneFormProps) => {
|
|
const t = useTranslations("Zones");
|
|
const at = useTranslations("App");
|
|
|
|
// @ts-ignore - Type instantiation is excessively deep and possibly infinite
|
|
const form = useForm<ZoneFormValues>({
|
|
resolver: zodResolver(zoneSchema),
|
|
defaultValues: zone
|
|
? {
|
|
name: zone.name,
|
|
classicNotifications: zone.classicNotifications,
|
|
rapidNotifications: zone.rapidNotifications,
|
|
blitzNotifications: zone.blitzNotifications,
|
|
otherNotifications: zone.otherNotifications,
|
|
features: zone.features as ZoneFormValues["features"],
|
|
}
|
|
: {
|
|
classicNotifications: false,
|
|
rapidNotifications: false,
|
|
blitzNotifications: false,
|
|
otherNotifications: false,
|
|
features: {
|
|
type: "FeatureCollection",
|
|
features: [],
|
|
},
|
|
},
|
|
});
|
|
|
|
const features = form.watch("features");
|
|
console.log(features);
|
|
|
|
return (
|
|
<FormProvider {...form}>
|
|
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
|
|
<div className="grid grid-cols-4 items-start gap-6">
|
|
<div className="col-span-4">
|
|
<TextField
|
|
name="name"
|
|
control={form.control}
|
|
label={t("zoneNameLabel")}
|
|
placeholder={t("zoneNamePlaceholder")}
|
|
required
|
|
/>
|
|
</div>
|
|
|
|
<div className="col-span-4">
|
|
<div className="flex flex-col gap-4">
|
|
<Label>{t("notificationsLabel")}</Label>
|
|
<div className="font-light text-gray-500 dark:text-gray-400">
|
|
{t("notificationsInfo")}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<InlineSwitchField
|
|
name="classicNotifications"
|
|
control={form.control}
|
|
label={at("timeControlEnum", { tc: TimeControl.Classic })}
|
|
/>
|
|
<InlineSwitchField
|
|
name="rapidNotifications"
|
|
control={form.control}
|
|
label={at("timeControlEnum", { tc: TimeControl.Rapid })}
|
|
/>
|
|
<InlineSwitchField
|
|
name="blitzNotifications"
|
|
control={form.control}
|
|
label={at("timeControlEnum", { tc: TimeControl.Blitz })}
|
|
/>
|
|
<InlineSwitchField
|
|
name="otherNotifications"
|
|
control={form.control}
|
|
label={at("timeControlEnum", { tc: TimeControl.Other })}
|
|
/>
|
|
|
|
<section id="map" className="z-0 col-span-4 flex h-auto">
|
|
<ZoneEditorField name="features" control={form.control} />
|
|
</section>
|
|
</div>
|
|
|
|
<div className="flex justify-end gap-4">
|
|
<Button intent="secondary" onClick={onCancel}>
|
|
{cancelTitle ?? at("cancelButton")}
|
|
</Button>
|
|
|
|
<Button disabled={form.formState.isSubmitting} type="submit">
|
|
{submitTitle ?? at("saveButton")}
|
|
</Button>
|
|
</div>
|
|
</form>
|
|
</FormProvider>
|
|
);
|
|
};
|