forked from VinokurovVE/tests
94 lines
3.4 KiB
TypeScript
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 |