Compare commits

..

No commits in common. "39bb647b5ccba8d4631aa2cf58a9a06e277b89b1" and "e50187dea1351b234f87356c83096addb09bcb01" have entirely different histories.

3 changed files with 41 additions and 38 deletions

View File

@ -4,19 +4,23 @@ import { z } from 'zod';
import { requestTaylor } from '@/app/api-utlities/clients/taylor.client'; import { requestTaylor } from '@/app/api-utlities/clients/taylor.client';
import { createReviewMutation } from '@/app/api-utlities/requests/common'; import { createReviewMutation } from '@/app/api-utlities/requests/common';
import { reviewSchema } from '@/features/review-form/model/review-form.schema';
export const POST = async (req: NextRequest) => { export const POST = async (req: NextRequest) => {
const body = await req.json(); const body = await req.json();
const validatedRequest = reviewSchema.parse(body); const validatedRequest = z
.object({
name: z.string(),
text: z.string(),
rating: z.number().min(0).max(5),
})
.parse(body);
await requestTaylor( await requestTaylor(
{ mutation: createReviewMutation }, { mutation: createReviewMutation },
{ {
review: { review: {
_name: validatedRequest.name, _name: validatedRequest.name,
_otzyv: validatedRequest.reviewMessage, _otzyv: validatedRequest.text,
_rejting: validatedRequest.rating, _rejting: validatedRequest.rating,
}, },
}, },

View File

@ -5,7 +5,7 @@ export const reviewSchema = z.object({
.string() .string()
.min(2, { message: 'Имя должно содержать не менее 2 символов' }), .min(2, { message: 'Имя должно содержать не менее 2 символов' }),
rating: z.number().min(1, { message: 'Пожалуйста, выберите рейтинг' }).max(5), rating: z.number().min(1, { message: 'Пожалуйста, выберите рейтинг' }).max(5),
reviewMessage: z text: z
.string() .string()
.min(10, { message: 'Отзыв должен содержать не менее 10 символов' }), .min(10, { message: 'Отзыв должен содержать не менее 10 символов' }),
}); });

View File

@ -6,7 +6,6 @@ import { useState } from 'react';
import { useForm } from 'react-hook-form'; import { useForm } from 'react-hook-form';
import { toast } from 'sonner'; import { toast } from 'sonner';
import { useTextController } from '@/shared/language';
import { Button } from '@/shared/shadcn-ui/button'; import { Button } from '@/shared/shadcn-ui/button';
import { import {
Dialog, Dialog,
@ -33,35 +32,45 @@ import { useCreateReviewMutation } from '../api/reviews.api';
import { ReviewFormValues, reviewSchema } from '../model/review-form.schema'; import { ReviewFormValues, reviewSchema } from '../model/review-form.schema';
export function ReviewForm() { export function ReviewForm() {
const { t } = useTextController();
const [openReviewFormDialog, setOpenReviewFormDialog] = useState(false); const [openReviewFormDialog, setOpenReviewFormDialog] = useState(false);
const [isSubmitting, setIsSubmitting] = useState(false);
const [hoveredStar, setHoveredStar] = useState(0); const [hoveredStar, setHoveredStar] = useState(0);
const [createReview, { isLoading: isSubmitting }] = useCreateReviewMutation(); const [createReview] = useCreateReviewMutation();
const form = useForm<ReviewFormValues>({ const form = useForm<ReviewFormValues>({
resolver: zodResolver(reviewSchema), resolver: zodResolver(reviewSchema),
defaultValues: { defaultValues: {
name: '', name: '',
rating: 0, rating: 0,
reviewMessage: '', text: '',
}, },
}); });
const onSubmit = async (data: ReviewFormValues) => { const onSubmit = async (data: ReviewFormValues) => {
setIsSubmitting(true);
try { try {
await createReview(data); await createReview(data);
toast.success(t('about.review-form.dialog.successResponse'), { toast.success(
duration: 5000, 'Спасибо за ваш отзыв! Он будет опубликован после модерации.',
}); {
duration: 5000,
},
);
form.reset(); form.reset();
setOpenReviewFormDialog(false); setOpenReviewFormDialog(false);
} catch (error) { } catch (error) {
toast.error(t('about.review-form.dialog.errorResponse'), { toast.error(
duration: 5000, 'Произошла ошибка при отправке отзыва. Пожалуйста, попробуйте позже.',
}); {
duration: 5000,
},
);
} finally {
setIsSubmitting(false);
} }
}; };
@ -106,17 +115,17 @@ export function ReviewForm() {
<DialogTrigger asChild> <DialogTrigger asChild>
<Button className='flex shadow-lg transition-all duration-300 hover:scale-105'> <Button className='flex shadow-lg transition-all duration-300 hover:scale-105'>
<Plus /> <Plus />
<span>{t('common.buttons.addReview')}</span> <span>Добавить отзыв</span>
</Button> </Button>
</DialogTrigger> </DialogTrigger>
<DialogContent className='overflow-hidden rounded-xl border-none bg-white/95 p-0 shadow-xl backdrop-blur-sm sm:max-w-[500px]'> <DialogContent className='overflow-hidden rounded-xl border-none bg-white/95 p-0 shadow-xl backdrop-blur-sm sm:max-w-[500px]'>
<div className='p-6'> <div className='p-6'>
<DialogHeader className='pb-4'> <DialogHeader className='pb-4'>
<DialogTitle className='text-center text-2xl font-bold'> <DialogTitle className='text-center text-2xl font-bold'>
{t('about.review-form.dialog.title')} Оставьте свой отзыв
</DialogTitle> </DialogTitle>
<DialogDescription className='pt-2 text-center'> <DialogDescription className='pt-2 text-center'>
{t('about.review-form.dialog.description')} Поделитесь своим опытом с нашей компанией
</DialogDescription> </DialogDescription>
</DialogHeader> </DialogHeader>
@ -129,15 +138,11 @@ export function ReviewForm() {
control={form.control} control={form.control}
name='name' name='name'
render={({ field }) => ( render={({ field }) => (
<FormItem className='flex flex-col'> <FormItem>
<FormLabel> <FormLabel>Ваше имя</FormLabel>
{t('about.review-form.dialog.field.name')}
</FormLabel>
<FormControl> <FormControl>
<Input <Input
placeholder={t( placeholder='Введите ваше имя'
'about.review-form.dialog.field.name.placeholder',
)}
{...field} {...field}
className='bg-white/50' className='bg-white/50'
/> />
@ -152,9 +157,7 @@ export function ReviewForm() {
name='rating' name='rating'
render={({ field }) => ( render={({ field }) => (
<FormItem className='space-y-3'> <FormItem className='space-y-3'>
<FormLabel className='block'> <FormLabel className='block'>Ваша оценка</FormLabel>
{t('about.review-form.dialog.field.rating')}
</FormLabel>
<FormControl> <FormControl>
<StarRating <StarRating
value={field.value} value={field.value}
@ -168,23 +171,19 @@ export function ReviewForm() {
<FormField <FormField
control={form.control} control={form.control}
name='reviewMessage' name='text'
render={({ field }) => ( render={({ field }) => (
<FormItem className='flex flex-col'> <FormItem>
<FormLabel> <FormLabel>Ваш отзыв</FormLabel>
{t('about.review-form.dialog.field.reviewMessage')}
</FormLabel>
<FormControl> <FormControl>
<Textarea <Textarea
placeholder={t( placeholder='Расскажите о вашем опыте...'
'about.review-form.dialog.field.reviewMessage.placeholder',
)}
className='min-h-[120px] resize-none bg-white/50' className='min-h-[120px] resize-none bg-white/50'
{...field} {...field}
/> />
</FormControl> </FormControl>
<FormDescription> <FormDescription>
{t('about.review-form.dialog.noteMessage')} Ваш отзыв будет опубликован после модерации.
</FormDescription> </FormDescription>
<FormMessage /> <FormMessage />
</FormItem> </FormItem>
@ -203,7 +202,7 @@ export function ReviewForm() {
Отправка... Отправка...
</> </>
) : ( ) : (
t('common.buttons.sendReview') 'Отправить отзыв'
)} )}
</Button> </Button>
</DialogFooter> </DialogFooter>