confetti added. react-confetti & zustand added
This commit is contained in:
parent
a5eb37b26d
commit
2717fbc571
|
|
@ -1,7 +1,7 @@
|
||||||
import CountDown from '@/components/lottery/countDown/CountDown';
|
import LotteryCountDown from "@/components/lottery/countDown/LotteryCountDown";
|
||||||
import SpinWheel from '@/components/lottery/spinWheel/SpinWheel';
|
import SpinWheel from "@/components/lottery/spinWheel/SpinWheel";
|
||||||
import Image from 'next/image';
|
import Image from "next/image";
|
||||||
import React from 'react';
|
import React from "react";
|
||||||
|
|
||||||
const page = () => {
|
const page = () => {
|
||||||
return (
|
return (
|
||||||
|
|
@ -20,7 +20,7 @@ const page = () => {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<CountDown />
|
<LotteryCountDown startDate="2024-11-25" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
@ -32,7 +32,9 @@ const page = () => {
|
||||||
<div className="flex flex-col w-full p-8 gap-4">
|
<div className="flex flex-col w-full p-8 gap-4">
|
||||||
<div className="flex flex-col gap-2 pb-4 border-b border-lightOutlineVariant">
|
<div className="flex flex-col gap-2 pb-4 border-b border-lightOutlineVariant">
|
||||||
<h4 className="font-heading-3-regular">Results</h4>
|
<h4 className="font-heading-3-regular">Results</h4>
|
||||||
<p className="font-base-medium">The results after each stage will be shown here.</p>
|
<p className="font-base-medium">
|
||||||
|
The results after each stage will be shown here.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* {[...Array(5)].map((item, index) => (
|
{/* {[...Array(5)].map((item, index) => (
|
||||||
|
|
@ -60,10 +62,11 @@ const page = () => {
|
||||||
<h3 className="font-heading-5-regular">Umumy düzgünler:</h3>
|
<h3 className="font-heading-5-regular">Umumy düzgünler:</h3>
|
||||||
<ul className="list-disc flex flex-col gap-4 pl-[16px]">
|
<ul className="list-disc flex flex-col gap-4 pl-[16px]">
|
||||||
{Array(5)
|
{Array(5)
|
||||||
.fill(' ')
|
.fill(" ")
|
||||||
.map((item, i) => (
|
.map((item, i) => (
|
||||||
<li className="font-small-regular" key={i}>
|
<li className="font-small-regular" key={i}>
|
||||||
Ilkinji we dogry jogap beren sanawda ilkinji ýeri eýelýär
|
Ilkinji we dogry jogap beren sanawda ilkinji ýeri
|
||||||
|
eýelýär
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
@ -73,7 +76,7 @@ const page = () => {
|
||||||
<h3 className="font-heading-5-regular">Üns beriň:</h3>
|
<h3 className="font-heading-5-regular">Üns beriň:</h3>
|
||||||
<ul className="list-disc flex flex-col gap-4 pl-[16px]">
|
<ul className="list-disc flex flex-col gap-4 pl-[16px]">
|
||||||
{Array(1)
|
{Array(1)
|
||||||
.fill(' ')
|
.fill(" ")
|
||||||
.map((item) => (
|
.map((item) => (
|
||||||
<li className="font-small-regular">SMS = 1 manat</li>
|
<li className="font-small-regular">SMS = 1 manat</li>
|
||||||
))}
|
))}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
'use client';
|
"use client";
|
||||||
|
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from "react";
|
||||||
import { cn } from '@/lib/utils'; // Assuming `cn` is defined in `lib/utils`
|
import { cn } from "@/lib/utils"; // Assuming `cn` is defined in `lib/utils`
|
||||||
|
|
||||||
const Confetti: React.FC = () => {
|
const Confetti: React.FC = () => {
|
||||||
const [confetti, setConfetti] = useState<number[]>([]);
|
const [confetti, setConfetti] = useState<number[]>([]);
|
||||||
|
|
@ -19,11 +19,11 @@ const Confetti: React.FC = () => {
|
||||||
|
|
||||||
const randomColor = () => {
|
const randomColor = () => {
|
||||||
const colors = [
|
const colors = [
|
||||||
'linear-gradient(45deg, #5D5D72, #8589DE)',
|
"linear-gradient(45deg, #5D5D72, #8589DE)",
|
||||||
'linear-gradient(45deg, #E1E0FF, #575992)',
|
"linear-gradient(45deg, #E1E0FF, #575992)",
|
||||||
'#8589DE',
|
"#8589DE",
|
||||||
'#575992',
|
"#575992",
|
||||||
'#E1E0FF',
|
"#E1E0FF",
|
||||||
];
|
];
|
||||||
return colors[Math.floor(Math.random() * colors.length)];
|
return colors[Math.floor(Math.random() * colors.length)];
|
||||||
};
|
};
|
||||||
|
|
@ -44,7 +44,7 @@ const Confetti: React.FC = () => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={i}
|
key={i}
|
||||||
className={cn('absolute', 'confetti-piece')}
|
className={cn("absolute", "confetti-piece")}
|
||||||
style={
|
style={
|
||||||
{
|
{
|
||||||
top: `${randomStartY}%`,
|
top: `${randomStartY}%`,
|
||||||
|
|
@ -55,9 +55,10 @@ const Confetti: React.FC = () => {
|
||||||
animationDuration: `${randomDuration}s`,
|
animationDuration: `${randomDuration}s`,
|
||||||
animationDelay: `${randomDelay}s`,
|
animationDelay: `${randomDelay}s`,
|
||||||
transform: `rotate(${randomRotation}deg)`,
|
transform: `rotate(${randomRotation}deg)`,
|
||||||
'--end-x': `${randomEndX}vw`,
|
"--end-x": `${randomEndX}vw`,
|
||||||
} as React.CSSProperties
|
} as React.CSSProperties
|
||||||
}></div>
|
}
|
||||||
|
></div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,57 +0,0 @@
|
||||||
const CountDown = () => {
|
|
||||||
return (
|
|
||||||
<div className="bg-lightSurfaceContainer pb-8 flex flex-col w-full gap-2 rounded-[12px]">
|
|
||||||
{/* Countdown */}
|
|
||||||
<div className="flex items-center gap-6">
|
|
||||||
{/* {Array(5)
|
|
||||||
.fill(' ')
|
|
||||||
.map((item, index) =>
|
|
||||||
index % 2 === 0 ? (
|
|
||||||
<div className="flex flex-col items-center justify-center flex-1 p-6">
|
|
||||||
<h3 className="text-[80px] leading-[88px] -tracking-[1%]">12</h3>
|
|
||||||
<h4 className="font-medium text-[20px] leading-[28px] -tracking-[1%]">sagat</h4>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<div className="flex flex-col gap-3">
|
|
||||||
<div className="w-3 h-3 rounded-full bg-lightOutlineVariant"></div>
|
|
||||||
<div className="w-3 h-3 rounded-full bg-lightOutlineVariant"></div>
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
)} */}
|
|
||||||
<div className="flex flex-col items-center justify-center flex-1 p-6">
|
|
||||||
<h3 className="text-[80px] leading-[88px] -tracking-[1%]">12</h3>
|
|
||||||
<h4 className="font-medium text-[20px] leading-[28px] -tracking-[1%]">sagat</h4>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex flex-col gap-3">
|
|
||||||
<div className="w-3 h-3 rounded-full bg-lightOutlineVariant"></div>
|
|
||||||
<div className="w-3 h-3 rounded-full bg-lightOutlineVariant"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex flex-col items-center justify-center flex-1 p-6">
|
|
||||||
<h3 className="text-[80px] leading-[88px] -tracking-[1%]">44</h3>
|
|
||||||
<h4 className="font-medium text-[20px] leading-[28px] -tracking-[1%]">minut</h4>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex flex-col gap-3">
|
|
||||||
<div className="w-3 h-3 rounded-full bg-lightOutlineVariant"></div>
|
|
||||||
<div className="w-3 h-3 rounded-full bg-lightOutlineVariant"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex flex-col items-center justify-center flex-1 p-6">
|
|
||||||
<h3 className="text-[80px] leading-[88px] -tracking-[1%]">36</h3>
|
|
||||||
<h4 className="font-medium text-[20px] leading-[28px] -tracking-[1%]">sekund</h4>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Seperator */}
|
|
||||||
<div className="w-full bg-lightOutlineVariant h-[1px]"></div>
|
|
||||||
|
|
||||||
<div className="flex items-center justify-center text-lightOnSurface font-heading-1-regular">
|
|
||||||
<span>-dan başlar</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default CountDown;
|
|
||||||
|
|
@ -0,0 +1,95 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
|
||||||
|
interface LotteryCountDownProps {
|
||||||
|
startDate: string; // Event start date in "YYYY-MM-DD" format
|
||||||
|
}
|
||||||
|
|
||||||
|
const LotteryCountDown: React.FC<LotteryCountDownProps> = ({ startDate }) => {
|
||||||
|
const [timeLeft, setTimeLeft] = useState({
|
||||||
|
hours: 0,
|
||||||
|
minutes: 0,
|
||||||
|
seconds: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
const calculateTimeLeft = () => {
|
||||||
|
const now = new Date();
|
||||||
|
const eventDate = new Date(`${startDate}T00:00:00+05:00`); // Set the time to midnight UTC+5
|
||||||
|
const timeDifference = eventDate.getTime() - now.getTime();
|
||||||
|
|
||||||
|
if (timeDifference <= 0) {
|
||||||
|
return { hours: 0, minutes: 0, seconds: 0 }; // Event has started or passed
|
||||||
|
}
|
||||||
|
|
||||||
|
const hours = Math.floor(timeDifference / (1000 * 60 * 60));
|
||||||
|
const minutes = Math.floor(
|
||||||
|
(timeDifference % (1000 * 60 * 60)) / (1000 * 60)
|
||||||
|
);
|
||||||
|
const seconds = Math.floor((timeDifference % (1000 * 60)) / 1000);
|
||||||
|
|
||||||
|
return { hours, minutes, seconds };
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// Update time left every second
|
||||||
|
const timer = setInterval(() => {
|
||||||
|
setTimeLeft(calculateTimeLeft());
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
return () => clearInterval(timer); // Clean up interval on component unmount
|
||||||
|
}, [startDate]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="bg-lightSurfaceContainer pb-8 flex flex-col w-full gap-2 rounded-[12px]">
|
||||||
|
{/* LotteryCountDown */}
|
||||||
|
<div className="flex items-center gap-6">
|
||||||
|
<div className="flex flex-col items-center justify-center flex-1 p-6">
|
||||||
|
<h3 className="text-[80px] leading-[88px] -tracking-[1%]">
|
||||||
|
{timeLeft.hours}
|
||||||
|
</h3>
|
||||||
|
<h4 className="font-medium text-[20px] leading-[28px] -tracking-[1%]">
|
||||||
|
hours
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-col gap-3">
|
||||||
|
<div className="w-3 h-3 rounded-full bg-lightOutlineVariant"></div>
|
||||||
|
<div className="w-3 h-3 rounded-full bg-lightOutlineVariant"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-col items-center justify-center flex-1 p-6">
|
||||||
|
<h3 className="text-[80px] leading-[88px] -tracking-[1%]">
|
||||||
|
{timeLeft.minutes}
|
||||||
|
</h3>
|
||||||
|
<h4 className="font-medium text-[20px] leading-[28px] -tracking-[1%]">
|
||||||
|
minutes
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-col gap-3">
|
||||||
|
<div className="w-3 h-3 rounded-full bg-lightOutlineVariant"></div>
|
||||||
|
<div className="w-3 h-3 rounded-full bg-lightOutlineVariant"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-col items-center justify-center flex-1 p-6">
|
||||||
|
<h3 className="text-[80px] leading-[88px] -tracking-[1%]">
|
||||||
|
{timeLeft.seconds}
|
||||||
|
</h3>
|
||||||
|
<h4 className="font-medium text-[20px] leading-[28px] -tracking-[1%]">
|
||||||
|
seconds
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Separator */}
|
||||||
|
<div className="w-full bg-lightOutlineVariant h-[1px]"></div>
|
||||||
|
|
||||||
|
<div className="flex items-center justify-center text-lightOnSurface font-heading-1-regular">
|
||||||
|
<span>-dan başlar</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default LotteryCountDown;
|
||||||
|
|
@ -3,13 +3,15 @@ interface IProps {
|
||||||
title: string;
|
title: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CountDownCell = ({ number, title }: IProps) => {
|
const LotteryCountDownCell = ({ number, title }: IProps) => {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col items-center justify-center flex-1 p-6">
|
<div className="flex flex-col items-center justify-center flex-1 p-6">
|
||||||
<h3 className="text-[80px] leading-[88px] -tracking-[1%]">{number}</h3>
|
<h3 className="text-[80px] leading-[88px] -tracking-[1%]">{number}</h3>
|
||||||
<h4 className="font-medium text-[20px] leading-[28px] -tracking-[1%]">{title}</h4>
|
<h4 className="font-medium text-[20px] leading-[28px] -tracking-[1%]">
|
||||||
|
{title}
|
||||||
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default CountDownCell;
|
export default LotteryCountDownCell;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
const CountDownSemicolmn = () => {
|
const LotteryCountDownSemicolmn = () => {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-3">
|
<div className="flex flex-col gap-3">
|
||||||
<div className="w-3 h-3 rounded-full bg-lightOutlineVariant"></div>
|
<div className="w-3 h-3 rounded-full bg-lightOutlineVariant"></div>
|
||||||
|
|
@ -7,4 +7,4 @@ const CountDownSemicolmn = () => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default CountDownSemicolmn;
|
export default LotteryCountDownSemicolmn;
|
||||||
|
|
@ -1,223 +1,85 @@
|
||||||
'use client';
|
"use client";
|
||||||
|
|
||||||
import Image from 'next/image';
|
import Image from "next/image";
|
||||||
// import React, { useRef, useState, useEffect } from "react";
|
import { useState } from "react";
|
||||||
|
import Confetti from "react-confetti";
|
||||||
// const SpinWheel: React.FC = () => {
|
import { useWindowSize } from "react-use";
|
||||||
// const canvasRef = useRef<HTMLCanvasElement | null>(null);
|
|
||||||
// const [isSpinning, setIsSpinning] = useState<boolean>(false);
|
|
||||||
// const [countdown, setCountdown] = useState<number>(5);
|
|
||||||
|
|
||||||
// const totalSize = 554; // Total size including borders
|
|
||||||
// const outerBorderWidth = 12; // Outer border width
|
|
||||||
// const innerBorderWidth = 15; // Inner border width
|
|
||||||
// const wheelSize = totalSize - outerBorderWidth - innerBorderWidth; // Inner wheel size
|
|
||||||
|
|
||||||
// const drawWheel = (angleOffset: number = 0): void => {
|
|
||||||
// const canvas = canvasRef.current;
|
|
||||||
// if (!canvas) return;
|
|
||||||
// const ctx = canvas.getContext("2d");
|
|
||||||
// if (!ctx) return;
|
|
||||||
|
|
||||||
// const radius = wheelSize / 2;
|
|
||||||
|
|
||||||
// // Clear the canvas and set background color
|
|
||||||
// ctx.fillStyle = "#FFF";
|
|
||||||
// ctx.fillRect(0, 0, totalSize, totalSize);
|
|
||||||
|
|
||||||
// // Draw the outermost border
|
|
||||||
// ctx.beginPath();
|
|
||||||
// ctx.arc(totalSize / 2, totalSize / 2, totalSize / 2, 0, 2 * Math.PI);
|
|
||||||
// ctx.fillStyle = "#5D5D72"; // Outer border color
|
|
||||||
// ctx.fill();
|
|
||||||
// ctx.closePath();
|
|
||||||
|
|
||||||
// // Draw the inner border
|
|
||||||
// ctx.beginPath();
|
|
||||||
// ctx.arc(
|
|
||||||
// totalSize / 2,
|
|
||||||
// totalSize / 2,
|
|
||||||
// (totalSize - outerBorderWidth) / 2,
|
|
||||||
// 0,
|
|
||||||
// 2 * Math.PI
|
|
||||||
// );
|
|
||||||
// ctx.fillStyle = "#8589DE"; // Inner border color
|
|
||||||
// ctx.fill();
|
|
||||||
// ctx.closePath();
|
|
||||||
|
|
||||||
// // Draw the wheel
|
|
||||||
// const segmentAngle = (2 * Math.PI) / 24; // 24 segments
|
|
||||||
// for (let i = 0; i < 24; i++) {
|
|
||||||
// ctx.beginPath();
|
|
||||||
// ctx.moveTo(totalSize / 2, totalSize / 2);
|
|
||||||
// ctx.arc(
|
|
||||||
// totalSize / 2,
|
|
||||||
// totalSize / 2,
|
|
||||||
// radius,
|
|
||||||
// segmentAngle * i + angleOffset,
|
|
||||||
// segmentAngle * (i + 1) + angleOffset
|
|
||||||
// );
|
|
||||||
// ctx.fillStyle = i % 2 === 0 ? "#E1E0FF" : "#575992"; // Alternate colors
|
|
||||||
// ctx.fill();
|
|
||||||
// ctx.stroke();
|
|
||||||
// ctx.closePath();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Draw central ellipse
|
|
||||||
// ctx.beginPath();
|
|
||||||
// ctx.ellipse(
|
|
||||||
// totalSize / 2,
|
|
||||||
// totalSize / 2,
|
|
||||||
// 105 / 2,
|
|
||||||
// 105 / 2,
|
|
||||||
// 0,
|
|
||||||
// 0,
|
|
||||||
// 2 * Math.PI
|
|
||||||
// );
|
|
||||||
// ctx.fillStyle = "#FFF";
|
|
||||||
// ctx.fill();
|
|
||||||
// ctx.stroke();
|
|
||||||
|
|
||||||
// // Add countdown text in the ellipse
|
|
||||||
// ctx.fillStyle = "#79536A"; // Text color
|
|
||||||
// ctx.font = "60px Roboto";
|
|
||||||
// ctx.textAlign = "center";
|
|
||||||
// ctx.textBaseline = "middle";
|
|
||||||
// ctx.fillText(countdown.toString(), totalSize / 2, totalSize / 2);
|
|
||||||
// };
|
|
||||||
|
|
||||||
// const spinWheel = (): void => {
|
|
||||||
// if (isSpinning) return;
|
|
||||||
|
|
||||||
// setIsSpinning(true);
|
|
||||||
// setCountdown(5); // Reset countdown
|
|
||||||
|
|
||||||
// let currentAngle = 0;
|
|
||||||
// const spinDuration = 5000; // Spin for 5 seconds
|
|
||||||
// const spinStartTime = Date.now();
|
|
||||||
|
|
||||||
// // Countdown Timer Logic
|
|
||||||
// const countdownInterval = setInterval(() => {
|
|
||||||
// setCountdown((prev) => {
|
|
||||||
// if (prev === 0) {
|
|
||||||
// clearInterval(countdownInterval);
|
|
||||||
// return 0;
|
|
||||||
// }
|
|
||||||
// return prev - 1;
|
|
||||||
// });
|
|
||||||
// }, 1000);
|
|
||||||
|
|
||||||
// // Spinning Logic
|
|
||||||
// const spin = () => {
|
|
||||||
// const elapsedTime = Date.now() - spinStartTime;
|
|
||||||
|
|
||||||
// if (elapsedTime >= spinDuration) {
|
|
||||||
// setIsSpinning(false);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Update angle
|
|
||||||
// const progress = elapsedTime / spinDuration;
|
|
||||||
// const easedProgress = easeOutCubic(progress); // Easing for smooth deceleration
|
|
||||||
// currentAngle = easedProgress * 10 * Math.PI; // Spin multiple times
|
|
||||||
|
|
||||||
// drawWheel(currentAngle);
|
|
||||||
// requestAnimationFrame(spin);
|
|
||||||
// };
|
|
||||||
|
|
||||||
// spin();
|
|
||||||
// };
|
|
||||||
|
|
||||||
// // Easing function for smooth deceleration
|
|
||||||
// const easeOutCubic = (t: number): number => 1 - Math.pow(1 - t, 3);
|
|
||||||
|
|
||||||
// // Initial draw
|
|
||||||
// useEffect(() => {
|
|
||||||
// drawWheel();
|
|
||||||
// }, [countdown]);
|
|
||||||
|
|
||||||
// return (
|
|
||||||
// <div className="flex flex-col items-center justify-center">
|
|
||||||
// <canvas
|
|
||||||
// ref={canvasRef}
|
|
||||||
// width={totalSize}
|
|
||||||
// height={totalSize}
|
|
||||||
// className="rounded-full shadow-lg"
|
|
||||||
// ></canvas>
|
|
||||||
// <button
|
|
||||||
// onClick={spinWheel}
|
|
||||||
// disabled={isSpinning}
|
|
||||||
// className={`mt-4 px-6 py-2 rounded-full text-white font-bold ${
|
|
||||||
// isSpinning
|
|
||||||
// ? "bg-gray-400 cursor-not-allowed"
|
|
||||||
// : "bg-blue-500 hover:bg-blue-700"
|
|
||||||
// }`}
|
|
||||||
// >
|
|
||||||
// {isSpinning ? "Spinning..." : "Spin the Wheel"}
|
|
||||||
// </button>
|
|
||||||
// </div>
|
|
||||||
// );
|
|
||||||
// };
|
|
||||||
|
|
||||||
// export default SpinWheel;
|
|
||||||
|
|
||||||
import { useState } from 'react';
|
|
||||||
import ConfettiExplosion, { ConfettiProps } from 'react-confetti-explosion';
|
|
||||||
|
|
||||||
const largeProps: ConfettiProps = {
|
|
||||||
force: 0.8,
|
|
||||||
duration: 3000,
|
|
||||||
particleCount: 300,
|
|
||||||
width: 1600,
|
|
||||||
colors: ['#041E43', '#1471BF', '#5BB4DC', '#FC027B', '#66D805'],
|
|
||||||
};
|
|
||||||
|
|
||||||
const SpinWheel: React.FC = () => {
|
const SpinWheel: React.FC = () => {
|
||||||
const [isSpinning, setIsSpinning] = useState(false);
|
const [isSpinning, setIsSpinning] = useState(false);
|
||||||
|
const [isCountingDown, setIsCountingDown] = useState(false);
|
||||||
const [countdown, setCountdown] = useState(5);
|
const [countdown, setCountdown] = useState(5);
|
||||||
const [rotation, setRotation] = useState(0);
|
const [rotation, setRotation] = useState(0);
|
||||||
const [showConfetti, setShowConfetti] = useState(false);
|
const [showConfetti, setShowConfetti] = useState(false);
|
||||||
|
|
||||||
|
const { width, height } = useWindowSize();
|
||||||
|
|
||||||
const triggerConfetti = () => {
|
const triggerConfetti = () => {
|
||||||
setShowConfetti(true);
|
setShowConfetti(true);
|
||||||
setTimeout(() => setShowConfetti(false), 5000); // Hide confetti after 5 seconds
|
setTimeout(() => {
|
||||||
|
setShowConfetti(false);
|
||||||
|
setCountdown(5); // Reset countdown after confetti
|
||||||
|
}, 6000); // Hide confetti after 6 seconds
|
||||||
|
};
|
||||||
|
|
||||||
|
const startCountdown = () => {
|
||||||
|
setIsCountingDown(true); // Start countdown state
|
||||||
|
let currentCountdown = 5;
|
||||||
|
const countdownInterval = setInterval(() => {
|
||||||
|
setCountdown(currentCountdown--); // Update countdown
|
||||||
|
if (currentCountdown < 0) {
|
||||||
|
clearInterval(countdownInterval); // Clear countdown interval
|
||||||
|
setIsCountingDown(false); // End countdown
|
||||||
|
spinWheel(); // Trigger spin after countdown
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
};
|
};
|
||||||
|
|
||||||
const spinWheel = () => {
|
const spinWheel = () => {
|
||||||
if (isSpinning) return;
|
if (isSpinning) return;
|
||||||
|
|
||||||
setIsSpinning(true);
|
setIsSpinning(true); // Start spinning
|
||||||
setCountdown(5); // Reset countdown
|
|
||||||
const totalSpin = rotation + 360 * 10 + Math.random() * 360; // 10 full rotations + random offset
|
const totalSpin = rotation + 360 * 10 + Math.random() * 360; // 10 full rotations + random offset
|
||||||
setRotation(totalSpin); // Update rotation to a new value
|
setRotation(totalSpin); // Update rotation to a new value
|
||||||
|
|
||||||
// Countdown logic
|
|
||||||
const countdownInterval = setInterval(() => {
|
|
||||||
setCountdown((prev) => {
|
|
||||||
if (prev === 0) {
|
|
||||||
clearInterval(countdownInterval);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return prev - 1;
|
|
||||||
});
|
|
||||||
}, 1000);
|
|
||||||
|
|
||||||
// Reset everything after the spin duration
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setIsSpinning(false);
|
setIsSpinning(false);
|
||||||
setRotation((prev) => prev % 360); // Normalize the rotation
|
setRotation((prev) => prev % 360); // Normalize the rotation
|
||||||
setCountdown(5); // Reset countdown for the next spin
|
triggerConfetti(); // Show confetti after spinning
|
||||||
triggerConfetti();
|
}, 5000); // Spin duration
|
||||||
}, 6000); // Spin duration
|
};
|
||||||
|
|
||||||
|
const handleSpinClick = () => {
|
||||||
|
if (!isSpinning && !isCountingDown) {
|
||||||
|
startCountdown(); // Start the countdown first
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col items-center">
|
<div className="flex flex-col items-center">
|
||||||
{/* {showConfetti && <ConfettiExplosion {...largeProps} />} */}
|
{showConfetti && (
|
||||||
|
<div className="fixed top-0 left-0 z-50">
|
||||||
|
<Confetti
|
||||||
|
width={width}
|
||||||
|
height={height}
|
||||||
|
recycle={false}
|
||||||
|
numberOfPieces={2000}
|
||||||
|
tweenDuration={10000}
|
||||||
|
run={true}
|
||||||
|
colors={[
|
||||||
|
"linear-gradient(45deg, #5D5D72, #8589DE)",
|
||||||
|
"linear-gradient(45deg, #E1E0FF, #575992)",
|
||||||
|
"#8589DE",
|
||||||
|
"#575992",
|
||||||
|
"#E1E0FF",
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<div className="relative rounded-full w-[554px] h-[554px]">
|
<div className="relative rounded-full w-[554px] h-[554px]">
|
||||||
{/* Wheel triangle */}
|
{/* Wheel triangle */}
|
||||||
<Image
|
<Image
|
||||||
src={'/wheel-triangle.svg'}
|
src={"/wheel-triangle.svg"}
|
||||||
alt="wheel"
|
alt="wheel"
|
||||||
height={34}
|
height={34}
|
||||||
width={35}
|
width={35}
|
||||||
|
|
@ -228,12 +90,13 @@ const SpinWheel: React.FC = () => {
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
transform: `rotate(${rotation}deg)`,
|
transform: `rotate(${rotation}deg)`,
|
||||||
transition: isSpinning ? 'transform 5s ease-out' : '',
|
transition: isSpinning ? "transform 5s ease-out" : "",
|
||||||
}}
|
}}
|
||||||
className="p-3 bg-[#5D5D72] rounded-full overflow-hidden">
|
className="p-3 bg-[#5D5D72] rounded-full overflow-hidden"
|
||||||
|
>
|
||||||
<div className="p-[15px] bg-[#8589DE] rounded-full ">
|
<div className="p-[15px] bg-[#8589DE] rounded-full ">
|
||||||
<Image
|
<Image
|
||||||
src={'/wheel-circle-inner.png'}
|
src={"/wheel-circle-inner.png"}
|
||||||
alt="wheel"
|
alt="wheel"
|
||||||
height={530}
|
height={530}
|
||||||
width={530}
|
width={530}
|
||||||
|
|
@ -252,12 +115,19 @@ const SpinWheel: React.FC = () => {
|
||||||
|
|
||||||
{/* Spin Button */}
|
{/* Spin Button */}
|
||||||
<button
|
<button
|
||||||
onClick={spinWheel}
|
onClick={handleSpinClick}
|
||||||
disabled={isSpinning}
|
disabled={isSpinning || isCountingDown}
|
||||||
className={`mt-6 px-6 py-3 rounded-full text-white font-bold ${
|
className={`mt-6 px-6 py-3 rounded-full text-white font-bold ${
|
||||||
isSpinning ? 'bg-gray-400 cursor-not-allowed' : 'bg-blue-500 hover:bg-blue-700'
|
isSpinning || isCountingDown
|
||||||
}`}>
|
? "bg-gray-400 cursor-not-allowed"
|
||||||
{isSpinning ? 'Spinning...' : 'Spin the Wheel'}
|
: "bg-blue-500 hover:bg-blue-700"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{isCountingDown
|
||||||
|
? `Starting in ${countdown}...`
|
||||||
|
: isSpinning
|
||||||
|
? "Spinning..."
|
||||||
|
: "Spin the Wheel"}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { Dispatch, SetStateAction, useEffect, useState } from 'react';
|
import { Dispatch, SetStateAction, useEffect, useState } from "react";
|
||||||
import { differenceInSeconds, parseISO, addHours } from 'date-fns';
|
import { differenceInSeconds, parseISO, addHours } from "date-fns";
|
||||||
import GradientTitle from './GradientTitle';
|
import GradientTitle from "./GradientTitle";
|
||||||
|
|
||||||
interface CountdownProps {
|
interface CountdownProps {
|
||||||
startsAt: string;
|
startsAt: string;
|
||||||
|
|
@ -17,12 +17,12 @@ const Countdown: React.FC<CountdownProps> = ({
|
||||||
setEventStatus,
|
setEventStatus,
|
||||||
eventStatus,
|
eventStatus,
|
||||||
}) => {
|
}) => {
|
||||||
const [timeLeft, setTimeLeft] = useState<string>('');
|
const [timeLeft, setTimeLeft] = useState<string>("");
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Parsing the start and end times to Date objects in the correct format
|
// Parsing the start and end times to Date objects in the correct format
|
||||||
const startsAtDate = addHours(parseISO(startsAt.replace(' ', 'T')), 5); // Adjusting start time to UTC+5
|
const startsAtDate = addHours(parseISO(startsAt.replace(" ", "T")), 5); // Adjusting start time to UTC+5
|
||||||
const endsAtDate = addHours(parseISO(endsAt.replace(' ', 'T')), 5); // Adjusting end time to UTC+5
|
const endsAtDate = addHours(parseISO(endsAt.replace(" ", "T")), 5); // Adjusting end time to UTC+5
|
||||||
|
|
||||||
// Function to calculate time left
|
// Function to calculate time left
|
||||||
const calculateTimeLeft = () => {
|
const calculateTimeLeft = () => {
|
||||||
|
|
@ -31,14 +31,14 @@ const Countdown: React.FC<CountdownProps> = ({
|
||||||
|
|
||||||
let difference;
|
let difference;
|
||||||
if (nowUTC5 < startsAtDate) {
|
if (nowUTC5 < startsAtDate) {
|
||||||
setEventStatus('Not started');
|
setEventStatus("Not started");
|
||||||
difference = differenceInSeconds(startsAtDate, nowUTC5);
|
difference = differenceInSeconds(startsAtDate, nowUTC5);
|
||||||
} else if (nowUTC5 < endsAtDate) {
|
} else if (nowUTC5 < endsAtDate) {
|
||||||
setEventStatus('Started');
|
setEventStatus("Started");
|
||||||
difference = differenceInSeconds(endsAtDate, nowUTC5);
|
difference = differenceInSeconds(endsAtDate, nowUTC5);
|
||||||
} else {
|
} else {
|
||||||
setEventStatus('Finished');
|
setEventStatus("Finished");
|
||||||
setVoteStatus('closed');
|
setVoteStatus("closed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -47,9 +47,9 @@ const Countdown: React.FC<CountdownProps> = ({
|
||||||
const seconds = difference % 60;
|
const seconds = difference % 60;
|
||||||
|
|
||||||
setTimeLeft(
|
setTimeLeft(
|
||||||
`${hours < 10 ? '0' + hours : hours}:${minutes < 10 ? '0' + minutes : minutes}:${
|
`${hours < 10 ? "0" + hours : hours}:${
|
||||||
seconds < 10 ? '0' + seconds : seconds
|
minutes < 10 ? "0" + minutes : minutes
|
||||||
}`,
|
}:${seconds < 10 ? "0" + seconds : seconds}`
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -60,23 +60,41 @@ const Countdown: React.FC<CountdownProps> = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{eventStatus === 'Finished' ? (
|
{eventStatus === "Finished" ? (
|
||||||
<GradientTitle title={'Netijeler'} size="big" />
|
<GradientTitle title={"Netijeler"} size="big" />
|
||||||
) : eventStatus === 'Started' ? (
|
) : eventStatus === "Started" ? (
|
||||||
<div className="flex flex-col justify-center items-center">
|
<div className="flex flex-col justify-center items-center">
|
||||||
<div className="text-[44px] sm:text-[100px] leading-[100%] flex items-end font-bold bg-fancyTitle bg-clip-text text-transparent text-center">
|
<div className="text-[44px] sm:text-[100px] leading-[100%] flex items-end font-bold bg-fancyTitle bg-clip-text text-transparent text-center">
|
||||||
<h2 className="flex flex-col items-center justify-center">{timeLeft.split(':')[0]}</h2>:
|
<h2 className="flex flex-col items-center justify-center">
|
||||||
<h2 className="flex flex-col items-center justify-center">{timeLeft.split(':')[1]}</h2>:
|
{timeLeft.split(":")[0]}
|
||||||
<h2 className="flex flex-col items-center justify-center">{timeLeft.split(':')[2]}</h2>
|
</h2>
|
||||||
|
:
|
||||||
|
<h2 className="flex flex-col items-center justify-center">
|
||||||
|
{timeLeft.split(":")[1]}
|
||||||
|
</h2>
|
||||||
|
:
|
||||||
|
<h2 className="flex flex-col items-center justify-center">
|
||||||
|
{timeLeft.split(":")[2]}
|
||||||
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : eventStatus === 'Not started' ? (
|
) : eventStatus === "Not started" ? (
|
||||||
<div className="flex flex-col justify-center items-center">
|
<div className="flex flex-col justify-center items-center">
|
||||||
<h1 className="font-semibold text-[24px] uppercase text-fillNavyBlue">Ses bermeklik</h1>
|
<h1 className="font-semibold text-[24px] uppercase text-fillNavyBlue">
|
||||||
|
Ses bermeklik
|
||||||
|
</h1>
|
||||||
<div className="text-[44px] sm:text-[100px] leading-[100%] flex items-end font-bold bg-fancyTitle bg-clip-text text-transparent text-center">
|
<div className="text-[44px] sm:text-[100px] leading-[100%] flex items-end font-bold bg-fancyTitle bg-clip-text text-transparent text-center">
|
||||||
<h2 className="flex flex-col items-center justify-center">{timeLeft.split(':')[0]}</h2>:
|
<h2 className="flex flex-col items-center justify-center">
|
||||||
<h2 className="flex flex-col items-center justify-center">{timeLeft.split(':')[1]}</h2>:
|
{timeLeft.split(":")[0]}
|
||||||
<h2 className="flex flex-col items-center justify-center">{timeLeft.split(':')[2]}</h2>
|
</h2>
|
||||||
|
:
|
||||||
|
<h2 className="flex flex-col items-center justify-center">
|
||||||
|
{timeLeft.split(":")[1]}
|
||||||
|
</h2>
|
||||||
|
:
|
||||||
|
<h2 className="flex flex-col items-center justify-center">
|
||||||
|
{timeLeft.split(":")[2]}
|
||||||
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<h1 className="font-semibold text-[24px] uppercase text-fillNavyBlue mt-[16px]">
|
<h1 className="font-semibold text-[24px] uppercase text-fillNavyBlue mt-[16px]">
|
||||||
sagatdan başlaýar
|
sagatdan başlaýar
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -35,20 +35,22 @@
|
||||||
"next-seo": "^6.0.0",
|
"next-seo": "^6.0.0",
|
||||||
"postcss": "8.4.23",
|
"postcss": "8.4.23",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-confetti-explosion": "^2.1.2",
|
"react-confetti": "^6.1.0",
|
||||||
"react-day-picker": "^8.10.1",
|
"react-day-picker": "^8.10.1",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-fast-marquee": "^1.3.5",
|
"react-fast-marquee": "^1.3.5",
|
||||||
"react-hook-form": "^7.43.9",
|
"react-hook-form": "^7.43.9",
|
||||||
"react-icons": "^4.8.0",
|
"react-icons": "^4.8.0",
|
||||||
"react-player": "^2.12.0",
|
"react-player": "^2.12.0",
|
||||||
|
"react-use": "^17.5.1",
|
||||||
"swiper": "^9.2.4",
|
"swiper": "^9.2.4",
|
||||||
"tailwind-merge": "^2.4.0",
|
"tailwind-merge": "^2.4.0",
|
||||||
"tailwindcss": "3.3.1",
|
"tailwindcss": "3.3.1",
|
||||||
"tailwindcss-animate": "^1.0.7",
|
"tailwindcss-animate": "^1.0.7",
|
||||||
"typescript": "^5.2.2",
|
"typescript": "^5.2.2",
|
||||||
"usehooks-ts": "^2.9.1",
|
"usehooks-ts": "^2.9.1",
|
||||||
"uuid": "^9.0.0"
|
"uuid": "^9.0.0",
|
||||||
|
"zustand": "^5.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/date-fns": "^2.6.0",
|
"@types/date-fns": "^2.6.0",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue