Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | import React, { useEffect, useState } from 'react'; import { useNavigate, useParams } from 'react-router-dom'; import AacInterface from '../../aac/AacInterface'; import { useWebSocket } from '../../contexts/WebSocketContext'; import { EventBus } from '../../game/EventBus'; /** * Route parameters from the URL. */ interface RouteParams { sessionId?: string; userId?: string; role?: string; [key: string]: string | undefined; } /** * AacPage component. * * Renders the AAC interface * for selecting food items within a given session. * * @component * @returns {JSX.Element} The AAC interface or a message if sessionId is missing. */ const AacPage: React.FC = () => { /** * Extracts the sessionId, userId, role from the URL parameters. */ const { sessionId, userId, role } = useParams<RouteParams>(); /** * Use the useNavigate hook from react-router-dom to navigate programmatically. */ const navigate = useNavigate(); /** * Get last message and connectedUsers from WebSocket context. */ const { lastMessage, connectedUsers, clearLastMessage } = useWebSocket(); /** * State to hold scores for the game. */ const [scores, setScores] = useState<Record<string, number>>({}); // --- ERROR HANDLING --- useEffect(() => { if (lastMessage?.type === 'ERROR_MESSAGE' && lastMessage?.payload?.code === 'SESSION_NOT_FOUND') { alert(`An error occurred: ${lastMessage.payload.message}`); clearLastMessage?.(); navigate('/'); } }, [lastMessage, navigate, clearLastMessage]); /** * Effect hook to listen for score updates from the EventBus. * Updates the scores state when a 'scoreUpdate' event is emitted. */ useEffect(() => { const handleScoreUpdate = ({ scores }: { scores: Record<string, number> }) => { setScores(scores); }; EventBus.on('scoreUpdate', handleScoreUpdate); return () => { EventBus.off('scoreUpdate', handleScoreUpdate); }; }, []); /** * If GAME_OVER use the navigate function to navigate to different routes. */ useEffect(() => { if (lastMessage?.type === 'GAME_OVER' && sessionId) { console.log('[AacPage] GAME_OVER received. Navigating to Victory screen.'); const colors = Object.fromEntries( connectedUsers .filter(user => user.color) .map(user => [user.userId, user.color]) ); navigate(`/victory/${sessionId}`, { state: { scores, colors, sessionId, userId } }); } }, [lastMessage, sessionId, navigate, scores, connectedUsers]); /** * If sessionId is not present, display an error message. */ if (!sessionId) return <p>Session ID not found</p>; /** * Render the AAC interface with the provided sessionId. */ return ( <div id="aac-page"> <AacInterface sessionId={sessionId} userId={userId} role={role} /> </div> ); }; export default AacPage; |