Compare commits

..

2 Commits

Author SHA1 Message Date
BunyodL
39bb647b5c update: get all the text from backend 2025-05-08 00:05:45 +05:00
BunyodL
b405fc315b fix: use review-schema and rtk loading-state 2025-05-07 23:40:28 +05:00
3 changed files with 38 additions and 41 deletions

View File

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

View File

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

View File

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