Files
tests/client/src/components/FormFields.tsx
cracklesparkle 974fc12b34 mantine
2024-10-09 16:51:37 +09:00

94 lines
3.4 KiB
TypeScript

import { SubmitHandler, useForm } from 'react-hook-form'
import { CreateField } from '../interfaces/create'
import { AxiosResponse } from 'axios';
import { Button, Loader, Stack, Text, TextInput } from '@mantine/core';
interface Props {
title?: string;
submitHandler?: (data: any) => Promise<AxiosResponse<any, any>>;
fields: CreateField[];
submitButtonText?: string;
mutateHandler?: any;
defaultValues?: {};
watchValues?: string[];
}
function FormFields({
title = '',
submitHandler,
fields,
submitButtonText = 'Сохранить',
mutateHandler,
defaultValues
}: Props) {
const getDefaultValues = (fields: CreateField[]) => {
let result: { [key: string]: string | boolean } = {}
fields.forEach((field: CreateField) => {
result[field.key] = field.defaultValue || defaultValues?.[field.key as keyof {}]
})
return result
}
const { register, handleSubmit, reset, watch, formState: { errors, isSubmitting, dirtyFields, isValid } } = useForm({
mode: 'onChange',
defaultValues: defaultValues ? getDefaultValues(fields) : {}
})
const onSubmit: SubmitHandler<any> = async (data) => {
fields.forEach((field: CreateField) => {
if (field.include === false) {
delete data[field.key]
}
})
try {
const submitResponse = await submitHandler?.(data)
mutateHandler?.(JSON.stringify(submitResponse?.data))
reset(submitResponse?.data)
} catch (error) {
console.error(error)
}
}
return (
<form onSubmit={handleSubmit(onSubmit)}>
<Stack gap='sm' w='100%'>
{title.length > 0 &&
<Text size="xl" fw={500}>
{title}
</Text>
}
{fields.map((field: CreateField) => {
return (
<TextInput
key={field.key}
label={field.headerName || field.key.charAt(0).toUpperCase() + field.key.slice(1)}
//placeholder="Your name"
type={field.inputType ? field.inputType : 'text'}
{...register(field.key, {
required: field.required ? `${field.headerName} обязателен` : false,
validate: (val: string | boolean) => {
if (field.watch) {
if (watch(field.watch) != val) {
return field.watchMessage || ''
}
}
},
})}
radius="md"
required={field.required || false}
error={errors[field.key]?.message}
errorProps={errors[field.key]}
/>
)
})}
<Button disabled={isSubmitting || Object.keys(dirtyFields).length === 0 || !isValid} type='submit'>
{isSubmitting ? <Loader size={16} /> : submitButtonText}
</Button>
</Stack>
</form>
)
}
export default FormFields