'use client'; import { useState, useEffect, useRef } from 'react'; import { useLotteryAuth } from '@/store/useLotteryAuth'; import { LotteryWinnerDataSimplified } from '@/typings/lottery/lottery.types'; import LotteryWinnersList from './winners/LotteryWinnersList'; import LotterySlotCounter from './slotCounter/LotterySlotCounter'; import ReactConfetti from 'react-confetti'; import { useWindowSize } from 'react-use'; import LotteryCountDownAllert from './countDown/countDownAllert/LotteryCountDownAllert'; import { motion } from 'framer-motion'; import AnimatedText from '@/components/common/AnimatedText'; const WEBSOCKET_URL = 'wss://sms.turkmentv.gov.tm/ws/lottery?dst=0506'; const PING_INTERVAL = 25000; const SLOT_COUNTER_DURATION = 20000; const LotteryWinnersSection = ({ lotteryStatus }: { lotteryStatus: string }) => { // UI States const [winners, setWinners] = useState([]); const [currentNumber, setCurrentNumber] = useState('00-00-00-00-00'); const [isConfettiActive, setIsConfettiActive] = useState(false); const [wsStatus, setWsStatus] = useState<'connecting' | 'connected' | 'error'>('connecting'); const { width, height } = useWindowSize(); const { lotteryData } = useLotteryAuth(); const [isSlotCounterAnimating, setIsSlotCounterAnimating] = useState(false); const [winnerSelectingStatus, setWinnerSelectingStatus] = useState< 'not-selected' | 'is-selecting' | 'selected' >('not-selected'); const [pendingWinner, setPendingWinner] = useState(null); // Refs const wsRef = useRef(null); const pingIntervalRef = useRef(); const mountedRef = useRef(false); // Add new state for display text const [displayText, setDisplayText] = useState('...'); const [winnerText, setWinnerText] = useState(''); // Initialize winners from lottery data useEffect(() => { if (lotteryData?.data.winners) { const simplifiedWinners = lotteryData.data.winners.map((winner) => ({ client: winner.client, winner_no: winner.winner_no, ticket: winner.ticket, })); setWinners(simplifiedWinners); setCurrentNumber(lotteryData.data.winners.at(-1)?.ticket || '00-00-00-00-00'); } }, [lotteryData]); // Handle WebSocket connection useEffect(() => { mountedRef.current = true; const setupWebSocket = () => { try { const socket = new WebSocket(WEBSOCKET_URL); wsRef.current = socket; socket.addEventListener('open', () => { if (!mountedRef.current) return; console.log('WebSocket Connected'); setWsStatus('connected'); pingIntervalRef.current = setInterval(() => { if (socket.readyState === WebSocket.OPEN) { socket.send(JSON.stringify({ type: 'ping' })); } }, PING_INTERVAL); }); socket.addEventListener('message', async (event) => { if (!mountedRef.current) return; console.log('Message received:', event.data); try { const newWinner = JSON.parse(event.data); const winnerData = { client: newWinner.phone, winner_no: newWinner.winner_no, ticket: newWinner.ticket, }; // Set initial animation text setDisplayText(`${winnerData.winner_no}-nji ýeňiji saýlanýar`); // Start the sequence setWinnerSelectingStatus('is-selecting'); setPendingWinner(winnerData); setCurrentNumber(winnerData.ticket); // Wait for slot counter animation await new Promise((resolve) => setTimeout(resolve, SLOT_COUNTER_DURATION)); // Update text to show winner's phone setDisplayText('The winner is'); setWinnerText(winnerData.client); setWinnerSelectingStatus('selected'); setIsConfettiActive(true); setWinners((prev) => [...prev, winnerData]); // Reset everything after 5 seconds setTimeout(() => { if (mountedRef.current) { setIsConfettiActive(false); // setIsSlotCounterAnimating(false); setWinnerSelectingStatus('not-selected'); setPendingWinner(null); setDisplayText('...'); // Reset text setWinnerText(''); } }, 5000); } catch (error) { console.error('Error processing message:', error); setIsSlotCounterAnimating(false); setPendingWinner(null); setDisplayText('...'); // Reset text on error } }); socket.addEventListener('error', (error) => { if (!mountedRef.current) return; console.error('WebSocket Error:', error); setWsStatus('error'); }); socket.addEventListener('close', () => { if (!mountedRef.current) return; console.log('WebSocket Closed'); setWsStatus('error'); if (pingIntervalRef.current) { clearInterval(pingIntervalRef.current); } }); } catch (error) { console.error('Error creating WebSocket:', error); setWsStatus('error'); } }; // Initial connection setupWebSocket(); return () => { mountedRef.current = false; if (pingIntervalRef.current) { clearInterval(pingIntervalRef.current); } if (wsRef.current) { wsRef.current.close(); } }; }, []); return (
{wsStatus === 'error' && (
Connection error. Please refresh the page.
)} {isConfettiActive && (
)}
{winnerSelectingStatus === 'not-selected' || winnerSelectingStatus === 'is-selecting' ? ( ) : (
{winnerText && ( )}
)}
); }; export default LotteryWinnersSection;