diff --git a/api/queries.ts b/api/queries.ts index 1050706..5d84da5 100644 --- a/api/queries.ts +++ b/api/queries.ts @@ -1,39 +1,39 @@ -import baseUrl from '@/baseUrl'; -import { AddPostModel } from '@/models/add.post.model'; -import { IAllVotes } from '@/models/allVotes.model'; -import { BannerModel } from '@/models/banner.model'; -import { CategoriesModel } from '@/models/categories.model'; -import { ChannelsModel } from '@/models/channels.model'; -import { HomeModel } from '@/models/home.model'; -import { LiveDescriptionModel } from '@/models/liveDescription.model'; -import { ILottery } from '@/models/lottery/lottery.model'; -import { MarqueeModel } from '@/models/marquee.model'; -import { NewsModel, NewsType } from '@/models/news.model'; -import { NewsItemModel } from '@/models/newsItem.model'; -import { PageItemModel } from '@/models/pageItem.model'; -import { PlansModel } from '@/models/plans.model'; -import { PropertiesModel } from '@/models/properties.model'; -import { IQuizQuestionsHistory } from '@/models/quizQuestionHistory.model'; -import { IQuizQuestions } from '@/models/quizQuestions.model'; -import { IQuizQuestionsWinners } from '@/models/quizQuestionsWinners.model'; -import { MessagesByTvAdmin } from '@/models/sms/messagesByTvAdmis.model'; -import { IMyTvAdmins } from '@/models/sms/my.tv.admins.model'; -import { VideoModel } from '@/models/video.model'; -import { VideosModel } from '@/models/videos.model'; -import { IVote } from '@/models/vote.model'; -import routes from '@/routes'; -import { CloudFog } from 'lucide-react'; +import baseUrl from "@/baseUrl"; +import { AddPostModel } from "@/models/add.post.model"; +import { IAllVotes } from "@/models/allVotes.model"; +import { BannerModel } from "@/models/banner.model"; +import { CategoriesModel } from "@/models/categories.model"; +import { ChannelsModel } from "@/models/channels.model"; +import { HomeModel } from "@/models/home.model"; +import { LiveDescriptionModel } from "@/models/liveDescription.model"; +import { ILotteryResponse } from "@/models/lottery/lottery.model"; +import { MarqueeModel } from "@/models/marquee.model"; +import { NewsModel, NewsType } from "@/models/news.model"; +import { NewsItemModel } from "@/models/newsItem.model"; +import { PageItemModel } from "@/models/pageItem.model"; +import { PlansModel } from "@/models/plans.model"; +import { PropertiesModel } from "@/models/properties.model"; +import { IQuizQuestionsHistory } from "@/models/quizQuestionHistory.model"; +import { IQuizQuestions } from "@/models/quizQuestions.model"; +import { IQuizQuestionsWinners } from "@/models/quizQuestionsWinners.model"; +import { MessagesByTvAdmin } from "@/models/sms/messagesByTvAdmis.model"; +import { IMyTvAdmins } from "@/models/sms/my.tv.admins.model"; +import { VideoModel } from "@/models/video.model"; +import { VideosModel } from "@/models/videos.model"; +import { IVote } from "@/models/vote.model"; +import routes from "@/routes"; +import { CloudFog } from "lucide-react"; export class Queries { public static async getNews( page: number, - { perPage = 8 }: { perPage?: number }, + { perPage = 8 }: { perPage?: number } ): Promise { return await fetch( `${baseUrl.NEWS_SRC}${routes.news}?locale=tm&count=${perPage}&page=${page}`, { next: { revalidate: 3600 }, - }, + } ).then((res) => res.json().then((res) => res as NewsModel)); } @@ -50,9 +50,12 @@ export class Queries { } public static async getHomeBannerSingle3(id: string): Promise { - return await fetch(`https://turkmentv.gov.tm/v2/api/slider?type=small3/${id}`, { - next: { revalidate: 3600 }, - }).then((res) => res.json().then((res) => res as NewsType)); + return await fetch( + `https://turkmentv.gov.tm/v2/api/slider?type=small3/${id}`, + { + next: { revalidate: 3600 }, + } + ).then((res) => res.json().then((res) => res as NewsType)); } public static async getNewsItem(id: string): Promise { @@ -86,8 +89,8 @@ export class Queries { } public static async getVideo(id: number): Promise { - return await fetch(`${baseUrl.MATERIALS_SRC}${routes.video(id)}`).then((res) => - res.json().then((res) => res as VideoModel), + return await fetch(`${baseUrl.MATERIALS_SRC}${routes.video(id)}`).then( + (res) => res.json().then((res) => res as VideoModel) ); } @@ -125,9 +128,12 @@ export class Queries { } public static async getMarquee(): Promise { - return await fetch(`${baseUrl.MATERIALS_SRC}${routes.marquee}?on_morquee=1`, { - next: { revalidate: 3600 }, - }).then((res) => res.json().then((res) => res as MarqueeModel)); + return await fetch( + `${baseUrl.MATERIALS_SRC}${routes.marquee}?on_morquee=1`, + { + next: { revalidate: 3600 }, + } + ).then((res) => res.json().then((res) => res as MarqueeModel)); } public static async getBanner(): Promise { @@ -136,10 +142,15 @@ export class Queries { }).then((res) => res.json().then((res) => res as BannerModel)); } - public static async getLiveDescription(channel: number): Promise { - return await fetch(`${baseUrl.MATERIALS_SRC}${routes.channelItem(channel)}`, { - next: { revalidate: 3600 }, - }).then((res) => res.json().then((res) => res as LiveDescriptionModel)); + public static async getLiveDescription( + channel: number + ): Promise { + return await fetch( + `${baseUrl.MATERIALS_SRC}${routes.channelItem(channel)}`, + { + next: { revalidate: 3600 }, + } + ).then((res) => res.json().then((res) => res as LiveDescriptionModel)); } public static async getProperties(): Promise { @@ -149,17 +160,20 @@ export class Queries { } public static async getPlans(property_id: number): Promise { - return await fetch(`${baseUrl.API_SRC}${routes.plans(String(property_id))}`, { - next: { revalidate: 3600 }, - }).then((res) => res.json().then((res) => res as PlansModel)); + return await fetch( + `${baseUrl.API_SRC}${routes.plans(String(property_id))}`, + { + next: { revalidate: 3600 }, + } + ).then((res) => res.json().then((res) => res as PlansModel)); } public static async postAdvert(data: AddPostModel): Promise { return await fetch(`${baseUrl.API_SRC}${routes.addPost}`, { - headers: { 'Content-Type': 'application/json' }, - cache: 'no-cache', + headers: { "Content-Type": "application/json" }, + cache: "no-cache", body: JSON.stringify(data), - method: 'POST', + method: "POST", }); } @@ -176,16 +190,26 @@ export class Queries { }).then((res) => res.json().then((res) => res as IQuizQuestions)); } - public static async getQuizHistory(id: number): Promise { - return await fetch(`${baseUrl.QUIZ_SRC}${routes.getQuizQuestionHistory(id)}`, { - next: { revalidate: 3600 }, - }).then((res) => res.json().then((res) => res as any)); + public static async getQuizHistory( + id: number + ): Promise { + return await fetch( + `${baseUrl.QUIZ_SRC}${routes.getQuizQuestionHistory(id)}`, + { + next: { revalidate: 3600 }, + } + ).then((res) => res.json().then((res) => res as any)); } - public static async getQuizWinners(id: number): Promise { - return await fetch(`${baseUrl.QUIZ_SRC}${routes.getQuizQuestionsWinners(id)}`, { - next: { revalidate: 3600 }, - }).then((res) => res.json().then((res) => res as IQuizQuestionsWinners)); + public static async getQuizWinners( + id: number + ): Promise { + return await fetch( + `${baseUrl.QUIZ_SRC}${routes.getQuizQuestionsWinners(id)}`, + { + next: { revalidate: 3600 }, + } + ).then((res) => res.json().then((res) => res as IQuizQuestionsWinners)); } // ====================================================================================== @@ -207,7 +231,7 @@ export class Queries { // Sms ======================================================================================== public static async getAdmins(): Promise { - const token = localStorage.getItem('access_token'); + const token = localStorage.getItem("access_token"); return await fetch(`${baseUrl.SMS_SRC}${routes.myTvAdmins}`, { headers: { Authorization: `Bearer ${token}` }, @@ -219,31 +243,43 @@ export class Queries { current_page: number, dateValue: string, activeSort: string, - searchFetch: string, + searchFetch: string ): Promise { - const token = localStorage.getItem('access_token'); + const token = localStorage.getItem("access_token"); return await fetch( - `${baseUrl.SMS_SRC}${routes.messagesByTvAdmin(id)}?per_page=60&page=${current_page}${ - dateValue ? '&filter_by_date=' + dateValue.toString() : '' - }${searchFetch ? '&search=' + searchFetch : ''}&order=${activeSort}`, + `${baseUrl.SMS_SRC}${routes.messagesByTvAdmin( + id + )}?per_page=60&page=${current_page}${ + dateValue ? "&filter_by_date=" + dateValue.toString() : "" + }${searchFetch ? "&search=" + searchFetch : ""}&order=${activeSort}`, { headers: { Authorization: `Bearer ${token}` }, - }, + } ).then((res) => res.json().then((res) => res as MessagesByTvAdmin)); } // Lottery ================================================================================ - public static async getLottery(): Promise { - return await fetch(`${baseUrl.QUIZ_SRC}${routes.lotteryActive}`, { - next: { revalidate: 3600 }, - }).then((res) => res.json().then((res) => res as ILottery)); - } - public static async getLotteryById(lottery_id: string): Promise { - return await fetch(`${baseUrl.QUIZ_SRC}${routes.lotteryId(lottery_id)}`, { - next: { revalidate: 3600 }, - }).then((res) => res.json().then((res) => res as ILottery)); + public static async authenticateLottery( + phone: string, + code: string + ): Promise { + return await fetch(`${baseUrl.QUIZ_SRC}${routes.lotteryActive}`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + phone: phone, + key: code, + }), + }).then((res) => { + if (!res.ok) { + throw new Error("Authentication failed"); + } + return res.json(); + }); } // ============================================================================================ diff --git a/app/(main)/lottery/active/page.tsx b/app/(main)/lottery/active/page.tsx deleted file mode 100644 index 18cd3a7..0000000 --- a/app/(main)/lottery/active/page.tsx +++ /dev/null @@ -1,138 +0,0 @@ -'use client'; - -import { Queries } from '@/api/queries'; -import Loader from '@/components/Loader'; -import LotteryWinnersSection from '@/components/lottery/LotteryWinnersSection'; -import RollingCounter from '@/components/lottery/RollingCounter/RollingCounter'; -import RollingCounterWorking from '@/components/lottery/RollingCounter/RollingCounterWorking'; -import LotteryCountDown from '@/components/lottery/countDown/LotteryCountDown'; -import LotteryCountDownAllert from '@/components/lottery/countDown/countDownAllert/LotteryCountDownAllert'; -import LotteryForm from '@/components/lottery/form/LotteryForm'; -import LotteryRulesSection from '@/components/lottery/rules/LotteryRulesSection'; -import { ILottery } from '@/models/lottery/lottery.model'; -import Image from 'next/image'; -import { useEffect, useState } from 'react'; - -const page = () => { - const [isLoading, setIsLoading] = useState(true); - const [data, setData] = useState(); - const [lotteryStatus, setLotteryStatus] = useState<'not-started' | 'started' | 'ended'>( - 'not-started', - ); - const [currentNumber, setCurrentNumber] = useState('22-22-22-22-22'); - - // useEffect(() => { - // Queries.getLottery() - // .then((res) => { - // setData(res); - // }) - // .finally(() => setIsLoading(false)); - // }, []); - - // useEffect(() => { - // const timer = setTimeout(() => { - // setCurrentNumber('81-34-52-35-61'); - // }, 10000); // 15 seconds - - // return () => clearTimeout(timer); // Cleanup on unmount - // }, []); - - // if (isLoading) { - // return ( - //
- // - //
- // ); - // } - - return ( -
- {/* */} - - - {data && ( -
-
-
-
- {data.data.title && ( -

- {data.data.title} -

- )} - {data.data.description && ( -

- {data.data.description} -

- )} - {data.data.sms_code && ( -
- - - - SMS-kod: {data.data.sms_code} -
- )} -
- {data.data.image && ( -
- banner -
- )} - -
- - -
-
-
-
- )} - -
- {lotteryStatus === 'not-started' && ( -
- -
- )} - - -
- - -
- ); -}; - -export default page; diff --git a/app/(main)/lottery/auth/page.tsx b/app/(main)/lottery/auth/page.tsx new file mode 100644 index 0000000..37a2bf6 --- /dev/null +++ b/app/(main)/lottery/auth/page.tsx @@ -0,0 +1,31 @@ +"use client"; + +import LotteryAuthForm from "@/components/lottery/auth/LotteryAuthForm"; +import { useEffect } from "react"; +import { useRouter } from "next/navigation"; +import { useLotteryAuth } from "@/store/useLotteryAuth"; + +const LotteryAuthPage = () => { + const router = useRouter(); + const { isAuthenticated, logout } = useLotteryAuth(); + + useEffect(() => { + console.log("Auth page - Authentication state:", isAuthenticated); + if (isAuthenticated) { + console.log("Auth page - Redirecting to lottery..."); + router.push("/lottery"); + } + }, [isAuthenticated, router]); + + useEffect(() => { + logout(); + }, [logout]); + + return ( +
+ +
+ ); +}; + +export default LotteryAuthPage; diff --git a/app/(main)/lottery/page.tsx b/app/(main)/lottery/page.tsx new file mode 100644 index 0000000..9b5ad10 --- /dev/null +++ b/app/(main)/lottery/page.tsx @@ -0,0 +1,103 @@ +"use client"; + +import { useState } from "react"; +import { useLotteryAuth } from "@/store/useLotteryAuth"; +import ProtectedRoute from "@/components/lottery/auth/ProtectedRoute"; +import { Queries } from "@/api/queries"; +import Loader from "@/components/Loader"; +import LotteryWinnersSection from "@/components/lottery/LotteryWinnersSection"; +import RollingCounter from "@/components/lottery/RollingCounter/RollingCounter"; +import RollingCounterWorking from "@/components/lottery/RollingCounter/RollingCounterWorking"; +import LotteryCountDown from "@/components/lottery/countDown/LotteryCountDown"; +import LotteryCountDownAllert from "@/components/lottery/countDown/countDownAllert/LotteryCountDownAllert"; +import LotteryForm from "@/components/lottery/form/LotteryForm"; +import LotteryRulesSection from "@/components/lottery/rules/LotteryRulesSection"; +import Image from "next/image"; +import { useRouter } from "next/navigation"; +import { useEffect } from "react"; + +const Page = () => { + const { lotteryData } = useLotteryAuth(); + const [lotteryStatus, setLotteryStatus] = useState< + "not-started" | "started" | "ended" + >("not-started"); + const [currentNumber, setCurrentNumber] = useState("22-22-22-22-22"); + + return ( + +
+ + + {lotteryData && ( +
+
+
+
+ {lotteryData.data.title && ( +

+ {lotteryData.data.title} +

+ )} + {lotteryData.data.description && ( +

+ {lotteryData.data.description} +

+ )} + {lotteryData.data.sms_code && ( +
+ + + + SMS-kod: {lotteryData.data.sms_code} +
+ )} +
+ {lotteryData.data.image && ( +
+ banner +
+ )} + + {lotteryStatus === "not-started" && ( + + )} +
+
+
+ )} + + + +
+ {lotteryStatus === "ended" || lotteryStatus === "started" ? ( + + ) : null} +
+
+
+ ); +}; + +export default Page; diff --git a/app/(prizes)/prizes/auth/page.tsx b/app/(prizes)/prizes/auth/page.tsx index 38764e7..3428814 100644 --- a/app/(prizes)/prizes/auth/page.tsx +++ b/app/(prizes)/prizes/auth/page.tsx @@ -1,10 +1,10 @@ -import SmsForm from '@/components/prizes/SmsForm'; -import React from 'react'; +import SmsForm from "@/components/prizes/SmsForm"; +import React from "react"; const page = () => { return (
-
+
diff --git a/components/lottery/auth/LotteryAuthForm.tsx b/components/lottery/auth/LotteryAuthForm.tsx new file mode 100644 index 0000000..9dbca8f --- /dev/null +++ b/components/lottery/auth/LotteryAuthForm.tsx @@ -0,0 +1,132 @@ +"use client"; + +import { Queries } from "@/api/queries"; +import { useState, FormEvent, useEffect } from "react"; +import { useRouter } from "next/navigation"; +import { useLotteryAuth } from "@/store/useLotteryAuth"; + +const LotteryAuthForm = () => { + const [phone, setPhone] = useState(""); + const [code, setCode] = useState(""); + const [error, setError] = useState(null); + const [isLoading, setIsLoading] = useState(false); + const [shouldRedirect, setShouldRedirect] = useState(false); + const router = useRouter(); + const setAuth = useLotteryAuth((state) => state.setAuth); + + // Phone validation function + const validatePhone = (value: string) => { + const phoneRegex = /^99363\d{6}$/; + return phoneRegex.test(value); + }; + + // Code validation function + const validateCode = (value: string) => { + const codeRegex = /^\d-\d{10}$/; + return codeRegex.test(value); + }; + + const handleSubmit = async (e: FormEvent) => { + e.preventDefault(); + setError(null); + console.log("Form submitted"); + + if (!validatePhone(phone)) { + setError("Telefon belgisi nädogry formatda"); + return; + } + + if (!validateCode(code)) { + setError("Kod nädogry formatda"); + return; + } + + setIsLoading(true); + + try { + console.log("Making API request..."); + const response = await Queries.authenticateLottery(phone, code); + console.log("API Response:", response); + + setAuth(response); + console.log("Auth state set"); + + router.replace("/lottery"); + } catch (err) { + console.error("Authentication error:", err); + setError("Telefon belgisi ýa-da kod nädogry"); + } finally { + setIsLoading(false); + } + }; + + useEffect(() => { + if (shouldRedirect) { + console.log("Redirect effect triggered"); + router.push("/lottery"); + } + }, [shouldRedirect, router]); + + const handlePhoneChange = (e: React.ChangeEvent) => { + const value = e.target.value.replace(/\D/g, ""); // Remove non-digits + if (value.length <= 11) { + // Limit to 11 digits (99363 + 6 digits) + setPhone(value); + } + }; + + const handleCodeChange = (e: React.ChangeEvent) => { + const value = e.target.value; + if (value.length <= 12) { + // Limit to 12 characters (X-XXXXXXXXXX) + setCode(value); + } + }; + + return ( +
+

+ Lotereýa giriş +

+
+
+ +
+
+ +
+ {error && ( +

+ {error} +

+ )} +
+ +
+ ); +}; + +export default LotteryAuthForm; diff --git a/components/lottery/auth/ProtectedRoute.tsx b/components/lottery/auth/ProtectedRoute.tsx new file mode 100644 index 0000000..376e580 --- /dev/null +++ b/components/lottery/auth/ProtectedRoute.tsx @@ -0,0 +1,46 @@ +"use client"; + +import { useEffect, useState } from "react"; +import { useRouter } from "next/navigation"; +import { useLotteryAuth } from "@/store/useLotteryAuth"; +import Loader from "@/components/Loader"; + +interface ProtectedRouteProps { + children: React.ReactNode; +} + +const ProtectedRoute = ({ children }: ProtectedRouteProps) => { + const router = useRouter(); + const { isAuthenticated } = useLotteryAuth(); + const [isHydrated, setIsHydrated] = useState(false); + + useEffect(() => { + setIsHydrated(true); + }, []); + + useEffect(() => { + if (isHydrated && !isAuthenticated) { + router.replace("/lottery/auth"); + } + }, [isHydrated, isAuthenticated, router]); + + if (!isHydrated) { + return ( +
+ +
+ ); + } + + if (!isAuthenticated) { + return ( +
+ +
+ ); + } + + return <>{children}; +}; + +export default ProtectedRoute; diff --git a/components/lottery/countDown/LotteryCountDown.tsx b/components/lottery/countDown/LotteryCountDown.tsx index 0fe4473..e8189bd 100644 --- a/components/lottery/countDown/LotteryCountDown.tsx +++ b/components/lottery/countDown/LotteryCountDown.tsx @@ -1,13 +1,15 @@ -'use client'; +"use client"; -import { calculateTimeLeft } from '@/lib/hooks/useCalculateTimeLeft'; -import React, { useState, useEffect, Dispatch, SetStateAction } from 'react'; +import { calculateTimeLeft } from "@/lib/hooks/useCalculateTimeLeft"; +import React, { useState, useEffect, Dispatch, SetStateAction } from "react"; interface LotteryCountDownProps { startDate: string; // Event start date in "YYYY-MM-DD HH:mm:ss" format endDate: string; // Event end date in "YYYY-MM-DD HH:mm:ss" format lotteryStatus: string; - setLotteryStatus: Dispatch>; + setLotteryStatus: Dispatch< + SetStateAction<"not-started" | "started" | "ended"> + >; } const LotteryCountDown: React.FC = ({ @@ -24,19 +26,27 @@ const LotteryCountDown: React.FC = ({ useEffect(() => { const timer = setInterval(() => { - if (lotteryStatus === 'not-started') { + if (lotteryStatus === "not-started") { const timeToStart = calculateTimeLeft(startDate); setTimeLeft(timeToStart); - if (timeToStart.hours === 0 && timeToStart.minutes === 0 && timeToStart.seconds === 0) { - setLotteryStatus('started'); // Update status to "started" + if ( + timeToStart.hours === 0 && + timeToStart.minutes === 0 && + timeToStart.seconds === 0 + ) { + setLotteryStatus("started"); // Update status to "started" } - } else if (lotteryStatus === 'started') { + } else if (lotteryStatus === "started") { const timeToEnd = calculateTimeLeft(endDate); setTimeLeft(timeToEnd); - if (timeToEnd.hours === 0 && timeToEnd.minutes === 0 && timeToEnd.seconds === 0) { - setLotteryStatus('ended'); // Update status to "finished" + if ( + timeToEnd.hours === 0 && + timeToEnd.minutes === 0 && + timeToEnd.seconds === 0 + ) { + setLotteryStatus("ended"); // Update status to "finished" } } }, 1000); @@ -49,14 +59,14 @@ const LotteryCountDown: React.FC = ({ return (

- {lotteryStatus === 'started' - ? 'Bije dowam edýär' - : lotteryStatus === 'ended' - ? 'Bije tamamlandy' - : 'Bije'} + {lotteryStatus === "started" + ? "Bije dowam edýär" + : lotteryStatus === "ended" + ? "Bije tamamlandy" + : "Bije"}

{/* LotteryCountDown */} - {lotteryStatus === 'not-started' && ( + {lotteryStatus === "not-started" && (

@@ -99,11 +109,11 @@ const LotteryCountDown: React.FC = ({
- {lotteryStatus === 'not-started' - ? '- den başlar' - : lotteryStatus === 'started' - ? 'girmek üçin aşakda kodyňyzy giriziň' - : 'netijeleri görmek üçin aşakda kodyňyzy giriziň'} + {lotteryStatus === "not-started" + ? "- den başlar" + : lotteryStatus === "started" + ? "girmek üçin aşakda kodyňyzy giriziň" + : "netijeleri görmek üçin aşakda kodyňyzy giriziň"}

diff --git a/components/lottery/rules/LotteryRulesSection.tsx b/components/lottery/rules/LotteryRulesSection.tsx index 8fc2bd8..a53aeab 100644 --- a/components/lottery/rules/LotteryRulesSection.tsx +++ b/components/lottery/rules/LotteryRulesSection.tsx @@ -1,4 +1,8 @@ +import { useLotteryAuth } from "@/store/useLotteryAuth"; + const LotteryRulesSection = () => { + const { lotteryData } = useLotteryAuth(); + return (
@@ -13,7 +17,7 @@ const LotteryRulesSection = () => {
    {Array(5) - .fill(' ') + .fill(" ") .map((item, i) => (
  • Ilkinji we dogry jogap beren sanawda ilkinji ýeri eýelýär @@ -23,10 +27,12 @@ const LotteryRulesSection = () => {
-

Üns beriň:

+

+ Üns beriň: +

    {Array(1) - .fill(' ') + .fill(" ") .map((item, i) => (
  • SMS = 1 manat diff --git a/models/lottery/lottery.model.ts b/models/lottery/lottery.model.ts index e260c11..c516cf6 100644 --- a/models/lottery/lottery.model.ts +++ b/models/lottery/lottery.model.ts @@ -1,8 +1,12 @@ -export interface ILottery { - data: Data; +export interface ILotteryWinner { + no: number; + client: string; + dt: string; + winner_no: number; + ticket: string; } -export interface Data { +export interface ILotteryData { id: number; title: string; description: string; @@ -10,12 +14,10 @@ export interface Data { start_time: string; end_time: string; sms_code: string; - winners: Winner[]; + winners: ILotteryWinner[]; } -export interface Winner { - no: number; - client: string; - dt: string; - winner_no: number; +export interface ILotteryResponse { + data: ILotteryData; + user_lottery_numbers: string[]; } diff --git a/store/useLotteryAuth.ts b/store/useLotteryAuth.ts new file mode 100644 index 0000000..bd3e2fb --- /dev/null +++ b/store/useLotteryAuth.ts @@ -0,0 +1,35 @@ +import { create } from "zustand"; +import { persist, createJSONStorage } from "zustand/middleware"; +import { ILotteryResponse } from "@/models/lottery/lottery.model"; + +interface LotteryAuthState { + isAuthenticated: boolean; + lotteryData: ILotteryResponse | null; + setAuth: (data: ILotteryResponse) => void; + clearAuth: () => void; + logout: () => void; +} + +export const useLotteryAuth = create()( + persist( + (set) => ({ + isAuthenticated: false, + lotteryData: null, + setAuth: (data) => set({ isAuthenticated: true, lotteryData: data }), + clearAuth: () => set({ isAuthenticated: false, lotteryData: null }), + logout: () => { + console.log("Logging out from lottery..."); + set({ isAuthenticated: false, lotteryData: null }); + // Could add additional cleanup here if needed + }, + }), + { + name: "lottery-auth-storage", + storage: createJSONStorage(() => localStorage), + partialize: (state) => ({ + isAuthenticated: state.isAuthenticated, + lotteryData: state.lotteryData, + }), + } + ) +);