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) => {
|
export const requestTaylor = async (query: object, variables?: object) => {
|
||||||
const body = JSON.stringify({
|
const body = JSON.stringify({
|
||||||
query: jsonToGraphQLQuery({ query }),
|
query: jsonToGraphQLQuery(query),
|
||||||
variables,
|
variables,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { EnumType } from 'json-to-graphql-query';
|
import { EnumType, VariableType } from 'json-to-graphql-query';
|
||||||
|
|
||||||
export const stationsRequest = {
|
export const stationsRequest = {
|
||||||
_azs: {
|
_azs: {
|
||||||
@ -146,6 +146,18 @@ export const historyRequest = {
|
|||||||
|
|
||||||
export const reviewsRequest = {
|
export const reviewsRequest = {
|
||||||
_otzyvy: {
|
_otzyvy: {
|
||||||
|
__args: {
|
||||||
|
filtersSet: {
|
||||||
|
conjunction: new EnumType('and'),
|
||||||
|
filtersSet: [
|
||||||
|
{
|
||||||
|
field: new EnumType('_status'),
|
||||||
|
operator: 'contains',
|
||||||
|
value: 'Опубликовано',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
records: {
|
records: {
|
||||||
id: true,
|
id: true,
|
||||||
_name: 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 {
|
export interface Transaction {
|
||||||
id: number;
|
id: number;
|
||||||
date_create: string;
|
date_create: string;
|
||||||
station: string;
|
station?: string;
|
||||||
|
station_name?: string;
|
||||||
product_name: string;
|
product_name: string;
|
||||||
amount: string;
|
amount: string;
|
||||||
price_real: 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';
|
} from '@/shared/shadcn-ui/form';
|
||||||
import { Input } from '@/shared/shadcn-ui/input';
|
import { Input } from '@/shared/shadcn-ui/input';
|
||||||
import { Textarea } from '@/shared/shadcn-ui/textarea';
|
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';
|
import { ReviewFormValues, reviewSchema } from '../model/review-form.schema';
|
||||||
|
|
||||||
export function ReviewForm() {
|
export function ReviewForm() {
|
||||||
@ -40,6 +36,8 @@ export function ReviewForm() {
|
|||||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||||
const [hoveredStar, setHoveredStar] = useState(0);
|
const [hoveredStar, setHoveredStar] = useState(0);
|
||||||
|
|
||||||
|
const [createReview] = useCreateReviewMutation();
|
||||||
|
|
||||||
const form = useForm<ReviewFormValues>({
|
const form = useForm<ReviewFormValues>({
|
||||||
resolver: zodResolver(reviewSchema),
|
resolver: zodResolver(reviewSchema),
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
@ -53,7 +51,7 @@ export function ReviewForm() {
|
|||||||
setIsSubmitting(true);
|
setIsSubmitting(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await new Promise((resolve) => setTimeout(resolve, 1500));
|
await createReview(data);
|
||||||
|
|
||||||
toast.success(
|
toast.success(
|
||||||
'Спасибо за ваш отзыв! Он будет опубликован после модерации.',
|
'Спасибо за ваш отзыв! Он будет опубликован после модерации.',
|
||||||
|
|||||||
@ -4,14 +4,12 @@ import { Fuel, History, MapPin, Star, Target, Users } from 'lucide-react';
|
|||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
|
||||||
import { Reviews } from '@/app/api-utlities/@types';
|
|
||||||
import { AboutUsPageData } from '@/app/api-utlities/@types/pages';
|
import { AboutUsPageData } from '@/app/api-utlities/@types/pages';
|
||||||
|
|
||||||
import { ReviewForm } from '@/features/review-form/ui';
|
import { ReviewForm } from '@/features/review-form/ui';
|
||||||
|
|
||||||
import AnimatedCounter from '@/shared/components/animated-counter';
|
import AnimatedCounter from '@/shared/components/animated-counter';
|
||||||
import { Container } from '@/shared/components/container';
|
import { Container } from '@/shared/components/container';
|
||||||
import { Rating } from '@/shared/components/rating';
|
|
||||||
import { Review } from '@/shared/components/review';
|
import { Review } from '@/shared/components/review';
|
||||||
import { useTextController } from '@/shared/language/hooks/use-text-controller';
|
import { useTextController } from '@/shared/language/hooks/use-text-controller';
|
||||||
import { Button } from '@/shared/shadcn-ui/button';
|
import { Button } from '@/shared/shadcn-ui/button';
|
||||||
@ -296,7 +294,7 @@ export default function AboutPage({ content }: AboutPageProps) {
|
|||||||
<Review key={review.id} review={review} />
|
<Review key={review.id} review={review} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<div className='mt-4 flex w-full justify-end'>
|
<div className='mt-4 flex w-full justify-center'>
|
||||||
<ReviewForm />
|
<ReviewForm />
|
||||||
</div>
|
</div>
|
||||||
</Container>
|
</Container>
|
||||||
|
|||||||
@ -199,7 +199,9 @@ export const TransactionsTable = ({
|
|||||||
<TableCell>
|
<TableCell>
|
||||||
{format(new Date(transaction.date_create), 'dd.MM.yyyy')}
|
{format(new Date(transaction.date_create), 'dd.MM.yyyy')}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell>{transaction.station}</TableCell>
|
<TableCell>
|
||||||
|
{transaction.station || transaction.station_name}
|
||||||
|
</TableCell>
|
||||||
<TableCell>{transaction.product_name}</TableCell>
|
<TableCell>{transaction.product_name}</TableCell>
|
||||||
<TableCell className='text-right'>
|
<TableCell className='text-right'>
|
||||||
{transaction.price_real}
|
{transaction.price_real}
|
||||||
@ -268,7 +270,9 @@ export const TransactionsTable = ({
|
|||||||
</Pagination>
|
</Pagination>
|
||||||
|
|
||||||
<div className='flex items-center gap-2'>
|
<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
|
<select
|
||||||
className='rounded border p-1 text-sm'
|
className='rounded border p-1 text-sm'
|
||||||
value={itemsPerPage}
|
value={itemsPerPage}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user