choose api added

This commit is contained in:
Kakabay 2024-10-11 19:17:05 +05:00
parent 229e3de2f2
commit 5530489d41
4 changed files with 102 additions and 31 deletions

View File

@ -3,6 +3,8 @@ import PrizeCard from '@/components/prizes/PrizeCard';
import { useState } from 'react'; import { useState } from 'react';
import axios from 'axios'; import axios from 'axios';
import { useQuery, useQueryClient } from '@tanstack/react-query'; import { useQuery, useQueryClient } from '@tanstack/react-query';
import { GiftsType } from '@/typings/gifts/gifts.type';
import { useRouter } from 'next/navigation';
// Define the expected shape of the fetched data // Define the expected shape of the fetched data
interface Prize { interface Prize {
@ -14,29 +16,43 @@ interface Prize {
const PrizesPage = ({ params }: { params: { user_id: string } }) => { const PrizesPage = ({ params }: { params: { user_id: string } }) => {
const [selectedPrize, setSelectedPrize] = useState<null | number>(null); const [selectedPrize, setSelectedPrize] = useState<null | number>(null);
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const router = useRouter();
// Fetching data using TanStack Query // Fetching data using TanStack Query
const { data, isLoading, error } = useQuery<Prize[], Error>( const { data, isLoading, error } = useQuery<GiftsType, Error>(
[`gifts-${params.user_id}`, params.user_id], // Query key using user_id [`gifts-${params.user_id}`, params.user_id, selectedPrize], // Query key using user_id
() => () =>
axios axios
.get(`https://sms.turkmentv.gov.tm/api/gifts/${params.user_id}`) .get(`https://sms.turkmentv.gov.tm/api/gifts/${params.user_id}`)
.then((response) => response.data), .then((response) => response.data),
{ {
staleTime: 60000, // Cache data for 1 minute staleTime: 60000, // Cache data for 1 minute
initialData: () => queryClient.getQueryData([`gifts-${params.user_id}`]), // Handle error with onError callback to trigger the redirect
onError: () => {
router.push('/prizes/auth');
},
}, },
); );
if (isLoading) return <p>Loading...</p>; if (isLoading)
if (error) return <p>Error loading prizes: {error.message}</p>; return (
<div className="flex justify-center items-center h-full text-heading2 leading-heading2 font-medium min-h-[50vh]">
Loading...
</div>
);
// Log the error to the console, even if redirecting
if (error) {
console.error('Error loading prizes:', error.message);
return null; // Return null since the redirect will occur
}
return ( return (
<div className="flex flex-col gap-[32px] md:gap-[64px] items-center"> <div className="flex flex-col gap-[32px] md:gap-[64px] items-center">
<header className="flex flex-col gap-[24px]"> <header className="flex flex-col gap-[24px]">
<div className="flex flex-col gap-[8px] max-w-[639px] w-full"> <div className="flex flex-col gap-[8px] max-w-[639px] w-full">
<h1 className="text-lightOnSurface text-heading1 leading-heading1 md:text-display1 md:leading-display1 tracking-[-1%] text-center font-medium"> <h1 className="text-lightOnSurface text-heading1 leading-heading1 md:text-display1 md:leading-display1 tracking-[-1%] text-center font-medium">
Список подарков {data.data.title}
</h1> </h1>
<p className="text-center text-textSmall leading-textSmall md:text-textBase md:leading-textBase tracking-[-1%] text-lightOnSurface"> <p className="text-center text-textSmall leading-textSmall md:text-textBase md:leading-textBase tracking-[-1%] text-lightOnSurface">
Поздравляю с победой в викторине! Вы стали победителем и получаете возможность выбрать Поздравляю с победой в викторине! Вы стали победителем и получаете возможность выбрать
@ -49,9 +65,9 @@ const PrizesPage = ({ params }: { params: { user_id: string } }) => {
Есть вопросы? Обратись XYXYXY! Есть вопросы? Обратись XYXYXY!
</p> </p>
</header> </header>
<div className="flex flex-col gap-[24px] md:gap-[16px] items-center max-w-[832px]"> <div className="flex flex-col gap-[24px] md:gap-[16px] items-center max-w-[832px] w-full">
{data.length > 0 && {data.data.gifts &&
data.map((prize, i) => ( data.data.gifts.map((prize, i) => (
<PrizeCard <PrizeCard
key={prize.id} key={prize.id}
variant={ variant={
@ -62,7 +78,9 @@ const PrizesPage = ({ params }: { params: { user_id: string } }) => {
: 'disabled' : 'disabled'
} }
setSelectedPrize={setSelectedPrize} setSelectedPrize={setSelectedPrize}
prizeId={prize.id} id={prize.id}
code={params.user_id}
{...prize}
/> />
))} ))}
</div> </div>

View File

@ -10,53 +10,98 @@ import {
DialogTitle, DialogTitle,
DialogTrigger, DialogTrigger,
} from '@/components/ui/dialog'; } from '@/components/ui/dialog';
import { Button } from 'react-day-picker'; import { Dispatch, SetStateAction, useState } from 'react';
import { Dispatch, SetStateAction } from 'react'; import axios from 'axios';
import { ClassNames } from '@emotion/react'; import { useMutation } from '@tanstack/react-query';
interface IProps { interface IProps {
variant: 'default' | 'selected' | 'disabled'; variant: 'default' | 'selected' | 'disabled';
prizeId: number;
setSelectedPrize: Dispatch<SetStateAction<null | number>>; setSelectedPrize: Dispatch<SetStateAction<null | number>>;
className?: string; className?: string;
code: string;
title: string;
description: string;
image: null | string;
id: number;
} }
const PrizeCard = ({ variant, prizeId, setSelectedPrize, className }: IProps) => { const PrizeCard = ({
variant,
setSelectedPrize,
code,
id,
title,
description,
image,
className,
}: IProps) => {
const [dialogOpen, setDialogOpen] = useState<boolean>(false);
const [dialogTitle, setDialogTitle] = useState<string>('Успешно');
// TanStack Query mutation for the API request
const choosePrizeMutation = useMutation({
mutationFn: () =>
axios.post(`https://sms.turkmentv.gov.tm/api/gifts/${id}/choose`, {
code,
}),
onSuccess: () => {
// Set the selected prize on successful API request
setSelectedPrize(id);
setDialogTitle('Успешно');
setDialogOpen(true); // Open the dialog on success
},
onError: () => {
// Set the dialog title to "Ошибка" on error
setDialogTitle('Ошибка');
setDialogOpen(true); // Open the dialog on error
},
});
const handleDialogTriggerClick = () => {
choosePrizeMutation.mutate();
};
return ( return (
<div <div
className={cn( className={cn(
'bg-lightSurfaceContainerHigher flex md:flex-row flex-col rounded-[12px] overflow-hidden', 'bg-lightSurfaceContainerHigher flex md:flex-row flex-col rounded-[12px] overflow-hidden w-full',
className, className,
{ {
'opacity-50': variant === 'disabled', 'opacity-50': variant === 'disabled',
}, },
)}> )}>
<div className="flex-1 overflow-hidden md:h-full h-[186px]"> <div className="flex-1 overflow-hidden md:h-full h-[186px]">
<Image width={416} height={248} src="/prize.jpg" alt="prize" className="h-full w-full" /> <Image
width={416}
height={248}
src={image ? image : '/prize.jpg'}
alt="prize"
className="h-full w-full"
/>
</div> </div>
<div className="flex-1 p-[16px] flex flex-col gap-[16px]"> <div className="flex-1 p-[16px] flex flex-col gap-[16px]">
<h2 className="text-heading5 leading-heading5 -tracking-[-1%] font-medium text-lightOnSurface"> <h2 className="text-heading5 leading-heading5 -tracking-[-1%] font-medium text-lightOnSurface">
Новый Cadillac Escalade 2025 Premium Luxury Platinun {title}
</h2> </h2>
<p className="text-textSmall leading-textSmall -tracking-[-1%] text-lightOnSurfaceVariant"> <p className="text-textSmall leading-textSmall -tracking-[-1%] text-lightOnSurfaceVariant">
Это роскошный полноразмерный SUV, представленный американским производителем Cadillac. {description}
Этот автомобиль отличается высоким уровнем комфорта, стиля и технологий.{' '}
</p> </p>
{variant === 'default' ? ( {variant === 'default' ? (
<Dialog> <Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
<DialogTrigger className="px-[24px] py-[10px] w-full md:w-fit text-textSmall leading-textSmall -tracking-[-1%] font-medium bg-lightPrimary text-lightOnPrimary rounded-[40px]"> <DialogTrigger
Выбрать className="px-[24px] py-[10px] w-full md:w-fit text-textSmall leading-textSmall -tracking-[-1%] font-medium bg-lightPrimary text-lightOnPrimary rounded-[40px]"
onClick={handleDialogTriggerClick}
disabled={choosePrizeMutation.isLoading}>
{choosePrizeMutation.isLoading ? 'Loading...' : 'Выбрать'}
</DialogTrigger> </DialogTrigger>
<DialogContent className="bg-lightSurfaceContainer flex flex-col gap-[8px]"> <DialogContent className="bg-lightSurfaceContainer flex flex-col gap-[8px]">
<DialogHeader className="flex flex-col gap-[8px]"> <DialogHeader className="flex flex-col gap-[8px]">
<DialogTitle>Успешно!</DialogTitle> <DialogTitle>{dialogTitle}</DialogTitle>
<DialogDescription>Все прошло успешно!</DialogDescription> <DialogDescription>Все прошло успешно!</DialogDescription>
</DialogHeader> </DialogHeader>
<DialogFooter> <DialogFooter>
<DialogClose asChild> <DialogClose asChild>
<button <button className="px-[24px] py-[10px] w-full text-textSmall leading-textSmall -tracking-[-1%] font-medium bg-lightPrimary text-lightOnPrimary rounded-[40px]">
className="px-[24px] py-[10px] w-full text-textSmall leading-textSmall -tracking-[-1%] font-medium bg-lightPrimary text-lightOnPrimary rounded-[40px]"
onClick={() => setSelectedPrize(prizeId)}>
Закрыть Закрыть
</button> </button>
</DialogClose> </DialogClose>

View File

@ -4,11 +4,9 @@ import React, { useState, useEffect, FormEvent } from 'react';
import axios from 'axios'; import axios from 'axios';
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import { GiftsType } from '@/typings/gifts/gifts.type';
// Define the expected shape of the API response // Define the expected shape of the API response
interface GiftResponse {
data: any; // Replace 'any' with the actual data type if known
}
const SmsForm: React.FC = () => { const SmsForm: React.FC = () => {
const [inputValue, setInputValue] = useState<string>(''); const [inputValue, setInputValue] = useState<string>('');
@ -17,7 +15,7 @@ const SmsForm: React.FC = () => {
const router = useRouter(); const router = useRouter();
// TanStack Query mutation for the API request // TanStack Query mutation for the API request
const mutation = useMutation<GiftResponse, Error, string>({ const mutation = useMutation<GiftsType, Error, string>({
mutationKey: [`gifts-${inputValue}`], // Using the dynamic query key mutationKey: [`gifts-${inputValue}`], // Using the dynamic query key
mutationFn: (code: string) => axios.get(`https://sms.turkmentv.gov.tm/api/gifts/${code}`), mutationFn: (code: string) => axios.get(`https://sms.turkmentv.gov.tm/api/gifts/${code}`),
onSuccess: (data) => { onSuccess: (data) => {

View File

@ -0,0 +1,10 @@
export interface GiftsType {
data: Data;
}
export interface Data {
id: number;
title: string;
image: null;
gifts: any[];
}