import React, { useState, useEffect, useRef } from 'react'; import '../styles/mainslot.css'; import { Header } from '../components/Header'; import Reel from '../components/Reel'; import { GameButton } from '../components/GameButton'; import gameconfig from '../../gameconfig'; import Registration from './Registration'; import spinSound from '../assets/audio/slot.mp3'; import axiosInstance from '../utils/axiosInstance'; interface SlotImage { id: number; image_path: string; section_number: number; } const SlotMachine: React.FC = () => { const [reels, setReels] = useState<string[][]>([]); const [isSoundOn, setIsSoundOn] = useState(true); const [slotImages, setSlotImages] = useState<SlotImage[]>([]); const [error, setError] = useState<string | null>(null); const [isSpinning, setIsSpinning] = useState(false); const [completedReels, setCompletedReels] = useState(0); const [isRegistrationOpen, setIsRegistrationOpen] = useState(false); const [spinCombination, setSpinCombination] = useState<string | null>(null); const [spinKey, setSpinKey] = useState(0); // To force reel re-render with new random images const spinAudioRef = useRef(new Audio(spinSound)); const baseSpinDuration = 2000; const delayBetweenStops = 600; useEffect(() => { spinAudioRef.current.loop = true; const fetchImages = async () => { try { const response = await axiosInstance.get('/api/slot/images'); if (response.data.status && response.data.data.images.length > 0) { setSlotImages(response.data.data.images); console.log('Slot Images:', response.data.data.images); } else { throw new Error(response.data.message || 'Failed to fetch images'); } } catch (error) { console.error('Error fetching slot images:', error); setError('Error fetching slot images'); } }; fetchImages(); if (gameconfig.defaultSlotCount > 0) { setReels(Array.from({ length: gameconfig.defaultSlotCount }, () => [])); } document.documentElement.style.setProperty( '--background-image', `url(${gameconfig.backgroundImage})`, ); document.documentElement.style.setProperty('--spin-btn-color', gameconfig.spinButtonColor); }, []); const handleSpin = () => { if (!isSpinning) { setIsRegistrationOpen(true); } }; const handleRegistrationSubmit = ( username: string, phone: string, eligible: boolean, combination: string, ) => { console.log('Registered Player Data:', { username, phone, eligible, combination }); if (eligible) { setSpinCombination(combination); setIsSpinning(true); setCompletedReels(0); setIsRegistrationOpen(false); setSpinKey((prev) => prev + 1); // Force reels to re-render with new random images if (isSoundOn) spinAudioRef.current.play(); } }; useEffect(() => { if (completedReels === reels.length && isSpinning) { setIsSpinning(false); if (isSoundOn) { spinAudioRef.current.pause(); spinAudioRef.current.currentTime = 0; } setTimeout(() => { setIsRegistrationOpen(true); }, 3500); } }, [completedReels, reels.length, isSpinning, isSoundOn]); const handleReelComplete = () => { setCompletedReels((prev) => prev + 1); }; const toggleSound = () => { setIsSoundOn((prev) => { if (!prev && isSpinning) spinAudioRef.current.play(); else spinAudioRef.current.pause(); return !prev; }); }; return ( <> <div className="slot-machine"> <div id="framework-center" style={{ backgroundImage: gameconfig.backgroundImage }}> <Header /> <div className="control-buttons-container"> <GameButton variant="sound" isActive={isSoundOn} onClick={toggleSound} /> </div> <div className="reels-container"> {reels.map((_, index) => { // Each digit in the combination string represents the section_number for that reel const targetId = spinCombination ? parseInt(spinCombination[index] || '0') : -1; return ( <Reel key={`${index}-${spinKey}`} // Include spinKey to force re-render with new random images slotImages={slotImages} isSpinning={isSpinning} spinDuration={baseSpinDuration + index * delayBetweenStops} onSpinComplete={handleReelComplete} targetId={targetId} // Pass the actual section_number to display /> ); })} </div> <div className="spin-container"> <div className="spin-button-wrapper"> <GameButton variant="spin" onClick={handleSpin} disabled={isSpinning} style={{ backgroundColor: gameconfig.spinButtonColor }} /> </div> </div> {error && <div className="error">{error}</div>} </div> </div> <Registration isOpen={isRegistrationOpen} setIsOpen={setIsRegistrationOpen} onSubmit={handleRegistrationSubmit} spinResult={ completedReels === reels.length && spinCombination ? spinCombination !== '000' ? 'win' : 'loss' : null } /> </> ); }; export default SlotMachine;