Compare commits

...

3 Commits

Author SHA1 Message Date
Ilgeldi 7b5db124da new logic in lottery and toss route 2025-02-10 15:36:10 +05:00
Ilgeldi f68e76c4b4 fix build errors 2025-02-08 15:23:37 +05:00
Ilgeldi 228ba3b536 first commit 2025-02-08 15:09:54 +05:00
6 changed files with 16 additions and 173 deletions

View File

@ -1,12 +1,9 @@
"use server";
import baseUrl from "@/baseUrl";
import routes from "@/routes";
import { cookies } from "next/headers";
import { revalidateTag } from "next/cache";
export async function authenticateLottery(
phone: string,
code: string,
) {
export async function authenticateLottery(phone: string, code: string) {
try {
const res = await fetch(`${baseUrl.QUIZ_SRC}${routes.lotteryActive}`, {
method: "POST",
@ -17,6 +14,10 @@ export async function authenticateLottery(
phone: phone,
key: code,
}),
next: {
revalidate: 300,
tags: ["lotteryData"],
},
});
if (!res.ok) {
@ -32,3 +33,7 @@ export async function authenticateLottery(
return undefined;
}
}
export const revalidateTagName = (tag: string) => {
revalidateTag(tag);
};

View File

@ -1,13 +0,0 @@
import LotteryAuthForm from "@/components/lottery/auth/LotteryAuthForm";
const LotteryAuthPage = () => {
return (
<div className="container">
<div className="flex justify-center items-center min-h-[50vh] py-[200px]">
{/* <LotteryAuthForm /> */}
</div>
</div>
);
};
export default LotteryAuthPage;

View File

@ -1,91 +0,0 @@
"use client";
import { useEffect, useState } from "react";
import { useLotteryAuth } from "@/store/useLotteryAuth";
import ProtectedRoute from "@/components/lottery/auth/ProtectedRoute";
import LotteryHeader from "@/components/lottery/LotteryHeader";
import LotteryWinnersSection from "@/components/lottery/LotteryWinnersSection";
import LotteryRulesSection from "@/components/lottery/rules/LotteryRulesSection";
import LotteryCountDown from "@/components/lottery/countDown/LotteryCountDown";
import { Queries } from "@/api/queries";
import Link from "next/link";
import { useRouter } from "next/navigation";
import Loader from "@/components/Loader";
import { authenticateLottery } from "@/api";
import { ILotteryResponse } from "@/models/lottery/lottery.model";
const LotteryPage = () => {
const [lotteryData, setData] = useState<ILotteryResponse>();
const [status, setStatus] = useState<"not-started" | "started" | "ended">(
"not-started"
);
const [isLoading, setIsLoading] = useState(true);
const router = useRouter();
useEffect(() => {
const checkAuth = async () => {
const res = await authenticateLottery();
setData(res);
};
checkAuth();
}, []);
if (isLoading && !lotteryData?.data) {
<div className="flex w-full h-[90vh] justify-center items-center">
<Loader />
</div>;
}
return (
<ProtectedRoute>
{lotteryData?.data && (
<div className="flex flex-col md:gap-[128px] gap-[80px] font-roboto md:pt-[64px] sm:pt-[48px] pt-[40px] ms:pb-[128px] pb-[80px] text-lightOnSurface">
{lotteryData && (
<div className="flex flex-col sm:gap-[64px] gap-[40px]">
<LotteryHeader
title={lotteryData.data.title}
description={lotteryData.data.description}
image={lotteryData.data.image}
smsCode={lotteryData.data.sms_code}
startDate={lotteryData.data.start_time}
/>
{status === "not-started" ? (
<div className="container">
<LotteryCountDown
lotteryStatus={status}
setLotteryStatus={setStatus}
endDate={lotteryData.data.end_time}
startDate={lotteryData.data.start_time}
/>
</div>
) : null}
</div>
)}
<LotteryRulesSection />
<div className="flex flex-col gap-10">
{lotteryData && (status === "ended" || status === "started") && (
<LotteryWinnersSection lotteryStatus={status} />
)}
<div className="w-full">
<div className="container">
<Link
href="/lottery/auth"
className="sm:text-textLarge sm:leading-textLarge text-[16px] rounded-full leading-[24px] sm:py-[12px] py-[8px] w-full flex justify-center items-center border-2 border-lightPrimary hover:bg-lightPrimary font-medium text-lightPrimary hover:text-lightOnPrimary disabled:opacity-50 transition-all duration-300"
>
Çykmak
</Link>
</div>
</div>
</div>
</div>
)}
</ProtectedRoute>
);
};
export default LotteryPage;

View File

@ -4,13 +4,7 @@ import ReactConfetti from "react-confetti";
import { useWindowSize } from "react-use";
import { useMediaQuery } from "usehooks-ts";
const Confetti = ({
numberOfPieces = 200,
showConfetti,
}: {
numberOfPieces?: number;
showConfetti: boolean;
}) => {
const Confetti = () => {
const [recycle, setRecycle] = useState<boolean>(true);
const { width, height } = useWindowSize();
const colors = [
@ -26,7 +20,7 @@ const Confetti = ({
useEffect(() => {
setTimeout(() => setRecycle(false), 30000);
}, []);
}, [recycle]);
return (
<div className="fixed top-0 left-0 z-50">
@ -34,7 +28,7 @@ const Confetti = ({
width={width}
height={height}
recycle={recycle}
numberOfPieces={mobile ? 200 / 3 : 200}
numberOfPieces={mobile ? 300 / 3 : 300}
tweenDuration={500}
colors={colors}
/>

View File

@ -7,6 +7,7 @@ import AnimatedText from "@/components/common/AnimatedText";
import { useWebsocketLottery } from "@/hooks/useWebSocketLottery";
import Confetti from "../common/Confetti";
import { AnimatePresence, motion } from "framer-motion";
import { revalidateTagName } from "@/api";
const WEBSOCKET_URL = "wss://sms.turkmentv.gov.tm/ws/lottery?dst=";
const SLOT_COUNTER_DURATION = 30000;
@ -112,6 +113,7 @@ const LotteryWinnersSection = ({ data }: { data: any }) => {
setWinnerSelectingStatus("selected");
setIsConfettiActive(true);
revalidateTagName("lotteryData");
// Add the winner to the list
setWinners((prevWinners) => [...prevWinners, winner]);
// Wait for the animation duration
@ -125,7 +127,7 @@ const LotteryWinnersSection = ({ data }: { data: any }) => {
Websocket connection error.
</div>
)}
<Confetti showConfetti={isConfettiActive} numberOfPieces={300} />
{isConfettiActive && <Confetti />}
<div className="container">
<div

View File

@ -1,54 +0,0 @@
"use client";
import { useEffect, useState } from "react";
import { useRouter } from "next/navigation";
import { useLotteryAuth } from "@/store/useLotteryAuth";
import { Queries } from "@/api/queries";
const ProtectedRoute = ({ children }: { children: React.ReactNode }) => {
const router = useRouter();
const { setAuth } = useLotteryAuth();
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
const checkAuth = async () => {
// ✅ Check credentials from localStorage
const phone = localStorage.getItem("lotteryPhone");
const code = localStorage.getItem("lotteryCode");
if (phone && code) {
try {
// ✅ Authenticate using stored credentials
const response = await Queries.authenticateLottery(phone, code);
if (response.errorMessage) {
// If authentication fails, redirect to the auth page
console.log("redirecting form protected route");
router.replace("/lottery/auth");
} else {
// ✅ Set the authenticated state
setAuth(response, phone, code);
setIsLoading(false);
}
} catch (err) {
console.error("Authentication failed:", err);
router.replace("/lottery/auth");
}
} else {
// Redirect to the auth page if no credentials are found
router.replace("/lottery/auth");
}
};
checkAuth();
}, [router, setAuth]);
// Show nothing while checking auth
if (isLoading) {
return null;
}
return <>{children}</>;
};
export default ProtectedRoute;