172 lines
4.8 KiB
TypeScript
172 lines
4.8 KiB
TypeScript
'use client'
|
||
|
||
//https://codesandbox.io/p/sandbox/react-hook-form-zod-with-array-of-objects-field-array-usefieldarray-8xh3ry?file=%2Fsrc%2FApp.tsx%3A11%2C53
|
||
// https://stackoverflow.com/questions/78004655/how-to-dynamically-add-array-of-objects-to-react-hook-form
|
||
import {zodResolver} from '@hookform/resolvers/zod'
|
||
import {useState} from 'react'
|
||
import {useFieldArray, useForm} from 'react-hook-form'
|
||
import {z} from 'zod'
|
||
|
||
import {onCategoryCreateAction} from '@/actions/admin/category'
|
||
import FormError from '@/components/auth/form-error'
|
||
import {FormSuccess} from '@/components/auth/form-success'
|
||
import {createCategoryFormSchema as validationSchema} from '@/lib/schemas/admin/category'
|
||
import {dump} from '@/lib/utils'
|
||
import {ResourceMessages} from '@/types'
|
||
import {Button} from '@/ui/button'
|
||
import {
|
||
Form,
|
||
FormControl,
|
||
FormDescription,
|
||
FormField,
|
||
FormItem,
|
||
FormLabel,
|
||
FormMessage
|
||
} from '@/ui/form'
|
||
import {Input} from '@/ui/input'
|
||
import {Tabs, TabsContent, TabsList, TabsTrigger} from '@/ui/tabs'
|
||
|
||
export const CreateForm = () => {
|
||
const [loading, setLoading] = useState(false)
|
||
const [error, setError] = useState('')
|
||
const [success, setSuccess] = useState('')
|
||
|
||
const localesValues = {
|
||
title: '',
|
||
short_title: '',
|
||
description: ''
|
||
}
|
||
|
||
const form = useForm<z.infer<typeof validationSchema>>({
|
||
resolver: zodResolver(validationSchema),
|
||
mode: 'onBlur',
|
||
defaultValues: {
|
||
locales: [
|
||
{lang: 'uk', ...localesValues},
|
||
{lang: 'ru', ...localesValues}
|
||
]
|
||
}
|
||
})
|
||
|
||
const {fields, append} = useFieldArray({
|
||
name: 'locales',
|
||
control: form.control
|
||
})
|
||
|
||
const onSubmit = async (data: z.infer<typeof validationSchema>) => {
|
||
setLoading(true)
|
||
onCategoryCreateAction(data).then((res: ResourceMessages) => {
|
||
if (res?.error) {
|
||
setError(res?.error)
|
||
setSuccess('')
|
||
setLoading(false)
|
||
} else {
|
||
setSuccess(res?.success as string)
|
||
setError('')
|
||
setLoading(false)
|
||
}
|
||
})
|
||
}
|
||
|
||
return (
|
||
<Form {...form}>
|
||
<form action='' className='my-8' onSubmit={form.handleSubmit(onSubmit)}>
|
||
<div className='mx-auto w-[400px]'>
|
||
<Tabs defaultValue='uk'>
|
||
<TabsList className='grid w-full grid-cols-2'>
|
||
<TabsTrigger value='uk'>Українська</TabsTrigger>
|
||
<TabsTrigger value='ru'>російська</TabsTrigger>
|
||
</TabsList>
|
||
{fields.map((_, index) => (
|
||
<TabsContent
|
||
value={form.getValues(`locales.${index}.lang`)}
|
||
key={index}
|
||
className='space-y-8'
|
||
>
|
||
<FormField
|
||
control={form.control}
|
||
key={index}
|
||
name={`locales.${index}.lang`}
|
||
render={({field}) => (
|
||
<FormItem className={'w-full'}>
|
||
{/*<FormLabel>Мова</FormLabel>*/}
|
||
<FormControl>
|
||
<Input type='hidden' placeholder='' {...field} />
|
||
</FormControl>
|
||
<FormMessage />
|
||
</FormItem>
|
||
)}
|
||
/>
|
||
<FormField
|
||
control={form.control}
|
||
key={index + 1}
|
||
name={`locales.${index}.title`}
|
||
render={({field}) => (
|
||
<FormItem className={'w-full'}>
|
||
<FormLabel>Назва категорії</FormLabel>
|
||
<FormControl>
|
||
<Input
|
||
lang={form.getValues(`locales.${index}.lang`)}
|
||
placeholder=''
|
||
{...field}
|
||
/>
|
||
</FormControl>
|
||
{/*<FormDescription>
|
||
Select a language between uk or ru
|
||
</FormDescription>*/}
|
||
<FormMessage />
|
||
</FormItem>
|
||
)}
|
||
/>
|
||
<FormField
|
||
control={form.control}
|
||
key={index + 2}
|
||
name={`locales.${index}.short_title`}
|
||
render={({field}) => (
|
||
<FormItem className={'w-full'}>
|
||
<FormLabel>Скорочена назва категорії</FormLabel>
|
||
<FormControl>
|
||
<Input
|
||
lang={form.getValues(`locales.${index}.lang`)}
|
||
placeholder=''
|
||
{...field}
|
||
/>
|
||
</FormControl>
|
||
<FormMessage />
|
||
</FormItem>
|
||
)}
|
||
/>
|
||
<FormField
|
||
control={form.control}
|
||
key={index + 3}
|
||
name={`locales.${index}.description`}
|
||
render={({field}) => (
|
||
<FormItem className={'w-full'}>
|
||
<FormLabel>Опис категорії</FormLabel>
|
||
<FormControl>
|
||
<Input
|
||
lang={form.getValues(`locales.${index}.lang`)}
|
||
placeholder=''
|
||
{...field}
|
||
/>
|
||
</FormControl>
|
||
<FormMessage />
|
||
</FormItem>
|
||
)}
|
||
/>
|
||
</TabsContent>
|
||
))}
|
||
</Tabs>
|
||
<div className='my-8'>
|
||
<FormError message={error} />
|
||
<FormSuccess message={success} />
|
||
<Button type='submit'>
|
||
{loading ? 'Додаємо до бази...' : 'Створити'}
|
||
</Button>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
</Form>
|
||
)
|
||
}
|