labels added lottery auth form and other fixes

This commit is contained in:
Kakabay 2025-01-08 18:34:51 +05:00
parent 744786ef70
commit 0c9b9224f6
6 changed files with 96 additions and 17 deletions

View File

@ -25,6 +25,7 @@ const LotteryPage = () => {
description={lotteryData.data.description}
image={lotteryData.data.image}
smsCode={lotteryData.data.sms_code}
startDate={lotteryData.data.start_time}
/>
{status === 'not-started' ? (

View File

@ -0,0 +1,60 @@
import { useEffect, useState } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
interface TextMaskRevealProps {
text: string;
className?: string;
duration?: number; // Duration in seconds for each character
startDelay?: number; // Delay before animation starts
}
const TextMaskReveal = ({
text,
className = '',
duration = 0.1,
startDelay = 0,
}: TextMaskRevealProps) => {
const [characters, setCharacters] = useState<string[]>([]);
useEffect(() => {
setCharacters(text.split(''));
}, [text]);
return (
<div
className={`relative overflow-hidden inline-flex ${className}`}
style={{ position: 'relative' }}>
<AnimatePresence>
{characters.map((char, index) => (
<motion.span
key={`${char}-${index}`}
className="inline-block"
initial={{ y: '-100%' }}
animate={{ y: '0%' }}
exit={{ y: '100%' }}
transition={{
duration: duration,
delay: startDelay + index * duration,
ease: 'easeOut',
}}
style={{ display: 'inline-block', overflow: 'hidden' }}>
<motion.span
initial={{ y: '100%' }}
animate={{ y: '0%' }}
exit={{ y: '100%' }}
transition={{
duration: duration,
delay: startDelay + index * duration,
ease: 'easeOut',
}}
className="block">
{char === ' ' ? '\u00A0' : char}
</motion.span>
</motion.span>
))}
</AnimatePresence>
</div>
);
};
export default TextMaskReveal;

View File

@ -1,13 +1,15 @@
import Image from 'next/image';
import InfoDateAllert from '../common/InfoDateAllert';
interface LotteryHeaderProps {
title: string;
description: string;
image: string;
smsCode: string;
startDate: string;
}
const LotteryHeader = ({ title, description, image, smsCode }: LotteryHeaderProps) => {
const LotteryHeader = ({ title, description, image, smsCode, startDate }: LotteryHeaderProps) => {
return (
<section className="container">
<div className="flex flex-col md:gap-[32px] gap-[24px]">
@ -16,6 +18,7 @@ const LotteryHeader = ({ title, description, image, smsCode }: LotteryHeaderProp
{title}
</h1>
<p className="text-center text-textLarge leading-textLarge">{description}</p>
<InfoDateAllert date={startDate} text="Senesi:" />
</div>
{image && (
<div className="md:mb-8 sm:mb-[40px] mb-[16px]">

View File

@ -17,7 +17,6 @@ const LotteryWinnersSection = ({ lotteryStatus }: { lotteryStatus: string }) =>
const [currentNumber, setCurrentNumber] = useState<string>();
const [isConfettiActive, setIsConfettiActive] = useState(false);
const { width, height } = useWindowSize();
const { lotteryData } = useLotteryAuth();
const [winnerSelectingStatus, setWinnerSelectingStatus] = useState<
'not-selected' | 'is-selecting' | 'selected'
@ -29,8 +28,6 @@ const LotteryWinnersSection = ({ lotteryStatus }: { lotteryStatus: string }) =>
// WebSocket Hook
const { wsStatus, subscribeToMessages } = useWebsocketLottery(WEBSOCKET_URL);
console.log(winners);
useEffect(() => {
if (lotteryData) {
if (lotteryData?.data.winners.length > 0) {
@ -42,8 +39,9 @@ const LotteryWinnersSection = ({ lotteryStatus }: { lotteryStatus: string }) =>
setWinners(simplifiedWinners);
setCurrentNumber(lotteryData.data.winners.at(-1)?.ticket || '00-00-00-00-00');
setWinnerSelectingStatus('selected');
setTopText('Ýeniji');
setTopText('Ýeňiji');
setBottomText(lotteryData.data.winners.at(-1)?.client || '');
setIsConfettiActive(true);
}
}
}, [lotteryData]);
@ -62,6 +60,9 @@ const LotteryWinnersSection = ({ lotteryStatus }: { lotteryStatus: string }) =>
ticket: newWinner.ticket,
};
setTimeout(() => {
setIsConfettiActive(false);
}, 1000);
setTopText(`${winnerData.winner_no}-nji(y) ýeňiji saýlanýar`);
setBottomText('...');
setWinnerSelectingStatus('is-selecting');
@ -74,10 +75,6 @@ const LotteryWinnersSection = ({ lotteryStatus }: { lotteryStatus: string }) =>
setWinnerSelectingStatus('selected');
setIsConfettiActive(true);
setWinners((prev) => [...prev, winnerData]);
setTimeout(() => {
setIsConfettiActive(false);
// setPendingWinner(null);
}, 5000);
}, SLOT_COUNTER_DURATION + 500);
});
@ -91,7 +88,7 @@ const LotteryWinnersSection = ({ lotteryStatus }: { lotteryStatus: string }) =>
{wsStatus === 'error' && (
<div className="text-red-500 text-center mb-2">Websocket connection error.</div>
)}
{isConfettiActive && <Confetti infinite={false} numberOfPieces={1000} />}
<Confetti showConfetti={isConfettiActive} numberOfPieces={300} />{' '}
<div className="container">
<div
className="flex flex-col items-center rounded-[32px] gap-[40px]"
@ -100,29 +97,47 @@ const LotteryWinnersSection = ({ lotteryStatus }: { lotteryStatus: string }) =>
}}>
<div className="flex items-center justify-center w-full min-h-[240px]">
{winnerSelectingStatus === 'not-selected' ? (
// <TextMaskReveal
// text={topText}
// className="text-center flex items-center justify-center text-[100px] leading-[108px] text-[#E65E19]"
// duration={0.5}
// />
<AnimatedText
text={topText}
className="text-center flex items-center justify-center text-[100px] leading-[108px] text-[#E65E19]"
duration={0.4}
/>
) : (
<div className="flex flex-col items-center justify-center">
{/* <TextMaskReveal
text={topText}
className="text-center text-[56px] leading-[64px] text-[#E65E19]"
duration={0.4}
/> */}
<AnimatedText
text={topText}
className="text-center text-[56px] leading-[64px] text-[#E65E19]"
duration={0.4}
/>
{bottomText && (
// <TextMaskReveal
// text={bottomText}
// className="text-center text-[80px] leading-[88px] text-[#E65E19]"
// duration={0.4}
// startDelay={3}
// />
<AnimatedText
text={bottomText}
className="text-center text-[80px] leading-[88px] text-[#E65E19]"
duration={0.4}
characterDelay={1.3}
/>
)}
</div>
)}
</div>
<div className="z-10">
{currentNumber && (
<LotterySlotCounter numberString={currentNumber} isAnimating={false} />
)}
{currentNumber && <LotterySlotCounter numberString={currentNumber} />}
</div>
<div className="flex gap-6 rounded-[12px] flex-1 w-full items-center justify-center sm:pb-[62px] pb-[32px] px-4">
<LotteryWinnersList winners={winners} />

View File

@ -6,10 +6,9 @@ import { useMediaQuery } from 'usehooks-ts';
interface LotterySlotCounterProps {
numberString: string;
isAnimating: boolean;
}
const LotterySlotCounter = ({ numberString, isAnimating }: LotterySlotCounterProps) => {
const LotterySlotCounter = ({ numberString }: LotterySlotCounterProps) => {
const [formattedNumber, setFormattedNumber] = useState(numberString);
useEffect(() => {
@ -80,9 +79,9 @@ const LotterySlotCounter = ({ numberString, isAnimating }: LotterySlotCounterPro
startValueOnce
charClassName="rolling-number"
separatorClassName="slot-seperator"
duration={10}
duration={3}
speed={6}
delay={10}
delay={3}
startFromLastDigit
animateUnchanged
animateOnVisible={false}

View File

@ -85,6 +85,7 @@ export const theme = {
lightPrimaryOutline: '#D8D6FF',
// Allert
lightInfoAllertContainer: '#E3F2FD',
lightInfoAllertContainerOutline: '#D4EBFC',
lightOnInfoAllertContainer: '#1E3A5F',
lightOnWarningAllertContainer: '#F57C00',
lightWarningAllertContainer: '#FFF8E1',