mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-09-11 05:36:10 -05:00
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
This commit is contained in:
72
app/components/form/TextArrayFormField.tsx
Normal file
72
app/components/form/TextArrayFormField.tsx
Normal file
@@ -0,0 +1,72 @@
|
||||
import { useFieldArray, useFormContext } from "react-hook-form";
|
||||
import type { z } from "zod";
|
||||
import { FormMessage } from "~/components/FormMessage";
|
||||
import { Label } from "~/components/Label";
|
||||
import { AddFieldButton } from "./AddFieldButton";
|
||||
import { RemoveFieldButton } from "./RemoveFieldButton";
|
||||
|
||||
export function TextArrayFormField<T extends z.ZodTypeAny>({
|
||||
label,
|
||||
name,
|
||||
defaultFieldValue,
|
||||
bottomText,
|
||||
}: {
|
||||
label: string;
|
||||
name: keyof z.infer<T> & string;
|
||||
defaultFieldValue: string;
|
||||
bottomText?: string;
|
||||
}) {
|
||||
const {
|
||||
register,
|
||||
formState: { errors },
|
||||
clearErrors,
|
||||
} = useFormContext();
|
||||
const { fields, append, remove } = useFieldArray({
|
||||
name,
|
||||
});
|
||||
|
||||
const rootError = errors[name]?.root;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Label>{label}</Label>
|
||||
<div className="stack md">
|
||||
{fields.map((field, index) => {
|
||||
// @ts-expect-error
|
||||
const error = errors[name]?.[index]?.value;
|
||||
|
||||
return (
|
||||
<div key={field.id}>
|
||||
<div className="stack horizontal md">
|
||||
<input {...register(`${name}.${index}.value`)} />
|
||||
{fields.length > 1 ? (
|
||||
<RemoveFieldButton
|
||||
onClick={() => {
|
||||
remove(index);
|
||||
clearErrors(`${name}.root`);
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
{error && (
|
||||
<FormMessage type="error">
|
||||
{error.message as string}
|
||||
</FormMessage>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
<AddFieldButton
|
||||
// @ts-expect-error
|
||||
onClick={() => append({ value: defaultFieldValue })}
|
||||
/>
|
||||
{rootError && (
|
||||
<FormMessage type="error">{rootError.message as string}</FormMessage>
|
||||
)}
|
||||
{bottomText && !rootError ? (
|
||||
<FormMessage type="info">{bottomText}</FormMessage>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user