Added create review endpoint
This commit is contained in:
parent
2872d6c1dd
commit
54dc9c243b
@ -2,7 +2,7 @@ import { jsonToGraphQLQuery } from 'json-to-graphql-query';
|
||||
|
||||
export const requestTaylor = async (query: object, variables?: object) => {
|
||||
const body = JSON.stringify({
|
||||
query: jsonToGraphQLQuery({ query }),
|
||||
query: jsonToGraphQLQuery(query),
|
||||
variables,
|
||||
});
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { EnumType } from 'json-to-graphql-query';
|
||||
import { EnumType, VariableType } from 'json-to-graphql-query';
|
||||
|
||||
export const stationsRequest = {
|
||||
_azs: {
|
||||
@ -146,6 +146,18 @@ export const historyRequest = {
|
||||
|
||||
export const reviewsRequest = {
|
||||
_otzyvy: {
|
||||
__args: {
|
||||
filtersSet: {
|
||||
conjunction: new EnumType('and'),
|
||||
filtersSet: [
|
||||
{
|
||||
field: new EnumType('_status'),
|
||||
operator: 'contains',
|
||||
value: 'Опубликовано',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
records: {
|
||||
id: true,
|
||||
_name: true,
|
||||
@ -182,3 +194,17 @@ export const certificatesRequest = {
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const createReviewMutation = {
|
||||
__variables: {
|
||||
review: 'TableOtzyvyMutationParameters',
|
||||
},
|
||||
_otzyvy: {
|
||||
createRecord: {
|
||||
__args: {
|
||||
records: [new VariableType('review')],
|
||||
},
|
||||
id: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
32
src/app/api/reviews/create/route.ts
Normal file
32
src/app/api/reviews/create/route.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import { NextRequest } from 'next/server';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { requestTaylor } from '@/app/api-utlities/clients/taylor.client';
|
||||
import { createReviewMutation } from '@/app/api-utlities/requests/common';
|
||||
|
||||
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);
|
||||
|
||||
await requestTaylor(
|
||||
{ mutation: createReviewMutation },
|
||||
{
|
||||
review: {
|
||||
_name: validatedRequest.name,
|
||||
_otzyv: validatedRequest.text,
|
||||
_rejting: validatedRequest.rating,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
return new Response(JSON.stringify({ success: true }), {
|
||||
status: 201,
|
||||
});
|
||||
};
|
||||
@ -10,7 +10,8 @@ export interface TransactionResponse {
|
||||
export interface Transaction {
|
||||
id: number;
|
||||
date_create: string;
|
||||
station: string;
|
||||
station?: string;
|
||||
station_name?: string;
|
||||
product_name: string;
|
||||
amount: string;
|
||||
price_real: string;
|
||||
|
||||
17
src/features/review-form/api/reviews.api.ts
Normal file
17
src/features/review-form/api/reviews.api.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import { baseAPI } from '@/shared/api/base-api';
|
||||
|
||||
import { ReviewFormValues } from '../model/review-form.schema';
|
||||
|
||||
export const reviewsAPI = baseAPI.injectEndpoints({
|
||||
endpoints: (build) => ({
|
||||
createReview: build.mutation<void, ReviewFormValues>({
|
||||
query: (body) => ({
|
||||
url: 'reviews/create',
|
||||
method: 'POST',
|
||||
body,
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
export const { useCreateReviewMutation } = reviewsAPI;
|
||||
@ -27,12 +27,8 @@ import {
|
||||
} from '@/shared/shadcn-ui/form';
|
||||
import { Input } from '@/shared/shadcn-ui/input';
|
||||
import { Textarea } from '@/shared/shadcn-ui/textarea';
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipTrigger,
|
||||
} from '@/shared/shadcn-ui/tooltip';
|
||||
|
||||
import { useCreateReviewMutation } from '../api/reviews.api';
|
||||
import { ReviewFormValues, reviewSchema } from '../model/review-form.schema';
|
||||
|
||||
export function ReviewForm() {
|
||||
@ -40,6 +36,8 @@ export function ReviewForm() {
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
const [hoveredStar, setHoveredStar] = useState(0);
|
||||
|
||||
const [createReview] = useCreateReviewMutation();
|
||||
|
||||
const form = useForm<ReviewFormValues>({
|
||||
resolver: zodResolver(reviewSchema),
|
||||
defaultValues: {
|
||||
@ -53,7 +51,7 @@ export function ReviewForm() {
|
||||
setIsSubmitting(true);
|
||||
|
||||
try {
|
||||
await new Promise((resolve) => setTimeout(resolve, 1500));
|
||||
await createReview(data);
|
||||
|
||||
toast.success(
|
||||
'Спасибо за ваш отзыв! Он будет опубликован после модерации.',
|
||||
|
||||
@ -4,14 +4,12 @@ import { Fuel, History, MapPin, Star, Target, Users } from 'lucide-react';
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
|
||||
import { Reviews } from '@/app/api-utlities/@types';
|
||||
import { AboutUsPageData } from '@/app/api-utlities/@types/pages';
|
||||
|
||||
import { ReviewForm } from '@/features/review-form/ui';
|
||||
|
||||
import AnimatedCounter from '@/shared/components/animated-counter';
|
||||
import { Container } from '@/shared/components/container';
|
||||
import { Rating } from '@/shared/components/rating';
|
||||
import { Review } from '@/shared/components/review';
|
||||
import { useTextController } from '@/shared/language/hooks/use-text-controller';
|
||||
import { Button } from '@/shared/shadcn-ui/button';
|
||||
@ -296,7 +294,7 @@ export default function AboutPage({ content }: AboutPageProps) {
|
||||
<Review key={review.id} review={review} />
|
||||
))}
|
||||
</div>
|
||||
<div className='mt-4 flex w-full justify-end'>
|
||||
<div className='mt-4 flex w-full justify-center'>
|
||||
<ReviewForm />
|
||||
</div>
|
||||
</Container>
|
||||
|
||||
@ -199,7 +199,9 @@ export const TransactionsTable = ({
|
||||
<TableCell>
|
||||
{format(new Date(transaction.date_create), 'dd.MM.yyyy')}
|
||||
</TableCell>
|
||||
<TableCell>{transaction.station}</TableCell>
|
||||
<TableCell>
|
||||
{transaction.station || transaction.station_name}
|
||||
</TableCell>
|
||||
<TableCell>{transaction.product_name}</TableCell>
|
||||
<TableCell className='text-right'>
|
||||
{transaction.price_real}
|
||||
@ -268,7 +270,9 @@ export const TransactionsTable = ({
|
||||
</Pagination>
|
||||
|
||||
<div className='flex items-center gap-2'>
|
||||
<span className='text-sm text-gray-500'>{t('transactions.entries')}</span>
|
||||
<span className='text-sm text-gray-500'>
|
||||
{t('transactions.entries')}
|
||||
</span>
|
||||
<select
|
||||
className='rounded border p-1 text-sm'
|
||||
value={itemsPerPage}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user