choose api added
This commit is contained in:
parent
229e3de2f2
commit
5530489d41
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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) => {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
export interface GiftsType {
|
||||||
|
data: Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Data {
|
||||||
|
id: number;
|
||||||
|
title: string;
|
||||||
|
image: null;
|
||||||
|
gifts: any[];
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue