291 lines
7.3 KiB
TypeScript
291 lines
7.3 KiB
TypeScript
'use client'
|
||
|
||
import {zodResolver} from '@hookform/resolvers/zod'
|
||
import {DeliveryOption} from '@prisma/client'
|
||
import {useLocale} from 'next-intl'
|
||
import React, {useEffect, useState} from 'react'
|
||
import {useForm} from 'react-hook-form'
|
||
import toast from 'react-hot-toast'
|
||
import {z} from 'zod'
|
||
|
||
import {onPlacingOrder} from '@/actions/admin/place-order'
|
||
import NovaPost from '@/app/[locale]/(root)/(shop)/cart/nova-post'
|
||
import SearchAddress from '@/components/pages/cart/search-address'
|
||
import {
|
||
DeliveryOptionTypeDescription,
|
||
createOrderFormSchema
|
||
} from '@/lib/schemas/admin/order'
|
||
import {dump} from '@/lib/utils'
|
||
import useCartStore from '@/store/cart-store'
|
||
import {SessionUser} from '@/types/auth'
|
||
import {Button} from '@/ui/button'
|
||
import {
|
||
Form,
|
||
FormControl,
|
||
FormField,
|
||
FormItem,
|
||
FormLabel,
|
||
FormMessage
|
||
} from '@/ui/form'
|
||
import {Input} from '@/ui/input'
|
||
import {
|
||
Select,
|
||
SelectContent,
|
||
SelectItem,
|
||
SelectTrigger,
|
||
SelectValue
|
||
} from '@/ui/select'
|
||
|
||
export default function RegisteredOrderForm({
|
||
styles,
|
||
user,
|
||
onSubmitHandler
|
||
}: {
|
||
styles: string
|
||
user?: SessionUser | null
|
||
onSubmitHandler: any
|
||
}) {
|
||
const [loading, setLoading] = useState(false)
|
||
const [error, setError] = useState('')
|
||
const [success, setSuccess] = useState('')
|
||
const [deliveryOption, setDeliveryOption] = useState('')
|
||
|
||
const locale = useLocale()
|
||
const [warehouseRef, setWarehouseRef] = useState(JSON.stringify({}))
|
||
|
||
const warehouseSubmit = (warehouse: any) => {
|
||
setWarehouseRef(
|
||
Object.keys(warehouse).length > 0
|
||
? JSON.stringify(warehouse)
|
||
: JSON.stringify({})
|
||
)
|
||
|
||
setValue(
|
||
'address',
|
||
Object.keys(warehouse).length > 0
|
||
? JSON.stringify(warehouse)
|
||
: JSON.stringify({})
|
||
)
|
||
}
|
||
const {cartItems, clearCart} = useCartStore()
|
||
const form = useForm<z.infer<typeof createOrderFormSchema>>({
|
||
resolver: zodResolver(createOrderFormSchema),
|
||
mode: 'onBlur',
|
||
defaultValues: {
|
||
user_id: user ? user.id.toString() : '',
|
||
is_quick: false,
|
||
lang: locale,
|
||
first_name: '',
|
||
surname: '',
|
||
delivery_option: '',
|
||
phone: '',
|
||
email: '',
|
||
address: warehouseRef,
|
||
notes: '',
|
||
details: JSON.stringify(cartItems)
|
||
}
|
||
})
|
||
|
||
const {register, setValue} = form
|
||
|
||
useEffect(() => {
|
||
register('delivery_option')
|
||
register('address')
|
||
register('details')
|
||
}, [register])
|
||
|
||
const deliveryOptionHandler = (value: string) => {
|
||
setDeliveryOption(value)
|
||
setValue('delivery_option', value)
|
||
}
|
||
|
||
const onSubmit = async (values: z.infer<typeof createOrderFormSchema>) => {
|
||
setLoading(true)
|
||
setValue('details', JSON.stringify(cartItems))
|
||
onPlacingOrder(values).then((res: any) => {
|
||
if (res?.error) {
|
||
setError(res?.error)
|
||
setSuccess('')
|
||
setLoading(false)
|
||
toast.error(res?.error)
|
||
} else {
|
||
setSuccess(res?.success as string)
|
||
setError('')
|
||
setLoading(false)
|
||
clearCart()
|
||
toast.success(res?.success)
|
||
}
|
||
|
||
onSubmitHandler(res)
|
||
})
|
||
}
|
||
|
||
return (
|
||
<Form {...form}>
|
||
<form className={styles} action='' onSubmit={form.handleSubmit(onSubmit)}>
|
||
{/*<pre>{dump(user)}</pre>*/}
|
||
<h2>1. {locale !== 'ru' ? 'Особисті дані' : 'Личные данные'}</h2>
|
||
<fieldset>
|
||
<div className='md:w-1/2'>
|
||
<FormField
|
||
control={form.control}
|
||
name='first_name'
|
||
render={({field}) => (
|
||
<FormItem>
|
||
<FormLabel>{locale !== 'ru' ? "Ім'я" : 'Имя'}*</FormLabel>
|
||
<FormControl>
|
||
<Input type='text' placeholder='' {...field} />
|
||
</FormControl>
|
||
<FormMessage />
|
||
</FormItem>
|
||
)}
|
||
/>
|
||
</div>
|
||
<div className='md:w-1/2'>
|
||
<FormField
|
||
control={form.control}
|
||
name='surname'
|
||
render={({field}) => (
|
||
<FormItem>
|
||
<FormLabel>
|
||
{locale !== 'ru' ? 'Прізвище' : 'Фамилия'}*
|
||
</FormLabel>
|
||
<FormControl>
|
||
<Input type='text' placeholder='' {...field} />
|
||
</FormControl>
|
||
<FormMessage />
|
||
</FormItem>
|
||
)}
|
||
/>
|
||
</div>
|
||
</fieldset>
|
||
<fieldset>
|
||
<div className='md:w-1/2'>
|
||
<FormField
|
||
control={form.control}
|
||
name='phone'
|
||
render={({field}) => (
|
||
<FormItem>
|
||
<FormLabel>Телефон*</FormLabel>
|
||
<FormControl>
|
||
<Input type='text' {...field} />
|
||
</FormControl>
|
||
<FormMessage />
|
||
</FormItem>
|
||
)}
|
||
/>
|
||
</div>
|
||
<div className='md:w-1/2'>
|
||
<FormField
|
||
control={form.control}
|
||
name='email'
|
||
render={({field}) => (
|
||
<FormItem>
|
||
<FormLabel>E-mail*</FormLabel>
|
||
<FormControl>
|
||
<Input type='text' {...field} />
|
||
</FormControl>
|
||
<FormMessage />
|
||
</FormItem>
|
||
)}
|
||
/>
|
||
</div>
|
||
</fieldset>
|
||
|
||
<h2>
|
||
2.{' '}
|
||
{locale !== 'ru'
|
||
? 'Інформація про доставку'
|
||
: 'Информация о доставке'}
|
||
</h2>
|
||
<fieldset>
|
||
<FormField
|
||
control={form.control}
|
||
name='delivery_option'
|
||
render={({field}) => (
|
||
<FormItem className='block w-full'>
|
||
<FormLabel>
|
||
{locale !== 'ru'
|
||
? 'Варіанти доставки'
|
||
: 'Варианты доставки'}{' '}
|
||
</FormLabel>
|
||
<Select
|
||
/*onValueChange={field.onChange}*/
|
||
onValueChange={deliveryOptionHandler}
|
||
defaultValue={field.value}
|
||
>
|
||
<FormControl>
|
||
<SelectTrigger>
|
||
<SelectValue
|
||
placeholder={
|
||
locale !== 'ru'
|
||
? 'Оберіть варіант доставки'
|
||
: 'Выберите вариант доставки'
|
||
}
|
||
/>
|
||
</SelectTrigger>
|
||
</FormControl>
|
||
<SelectContent>
|
||
{Object.keys(DeliveryOption).map(
|
||
(option: string, index: number) => (
|
||
<SelectItem key={index} value={option}>
|
||
{DeliveryOptionTypeDescription[option] || option}
|
||
</SelectItem>
|
||
)
|
||
)}
|
||
</SelectContent>
|
||
</Select>
|
||
<FormMessage className='ml-3' />
|
||
</FormItem>
|
||
)}
|
||
/>
|
||
</fieldset>
|
||
|
||
{deliveryOption === 'NP' && (
|
||
<NovaPost onSelectHandler={warehouseSubmit} />
|
||
)}
|
||
|
||
{deliveryOption === 'COURIER' && (
|
||
/*<NovaPost onWarehouseSelect={warehouseSubmit} />*/
|
||
<SearchAddress onSelectHandler={warehouseSubmit} />
|
||
)}
|
||
|
||
{deliveryOption === 'PICKUP' && (
|
||
<div className='py-6 text-lg'>Дані де і коли можна забрати</div>
|
||
)}
|
||
|
||
<fieldset>
|
||
<FormField
|
||
control={form.control}
|
||
name='notes'
|
||
render={({field}) => (
|
||
<FormItem className='block w-full'>
|
||
<FormLabel>
|
||
{locale !== 'ru'
|
||
? 'Додаткова інформація'
|
||
: 'Дополнительная информация'}
|
||
</FormLabel>
|
||
<FormControl>
|
||
<textarea {...field} />
|
||
</FormControl>
|
||
<FormMessage />
|
||
</FormItem>
|
||
)}
|
||
/>
|
||
</fieldset>
|
||
|
||
<fieldset>
|
||
{/*<pre>{warehouseRef}</pre>*/}
|
||
<Button
|
||
type='submit'
|
||
size={'lg'}
|
||
className='float-right mx-auto mb-6 mt-16 h-[unset] w-[200px] py-2 text-xl text-brand-violet'
|
||
>
|
||
{locale !== 'ru' ? 'Оформити замовлення' : 'Оформить заказ'}
|
||
</Button>
|
||
</fieldset>
|
||
</form>
|
||
</Form>
|
||
)
|
||
}
|