Initial commit
This commit is contained in:
143
client/src/App.jsx
Normal file
143
client/src/App.jsx
Normal file
@@ -0,0 +1,143 @@
|
||||
import React, { useState, useEffect, useCallback } from 'react';
|
||||
import socket from './socket';
|
||||
import Lobby from './components/Lobby';
|
||||
import GameBoard from './components/GameBoard';
|
||||
|
||||
const SCREENS = { NAME: 'name', LOBBY: 'lobby', ROOM: 'room', GAME: 'game' };
|
||||
|
||||
export default function App() {
|
||||
const [screen, setScreen] = useState(SCREENS.NAME);
|
||||
const [playerName, setPlayerName] = useState('');
|
||||
const [playerId, setPlayerId] = useState(null);
|
||||
const [rooms, setRooms] = useState([]);
|
||||
const [currentRoom, setCurrentRoom] = useState(null);
|
||||
const [gameState, setGameState] = useState(null);
|
||||
const [gameId, setGameId] = useState(null);
|
||||
const [error, setError] = useState(null);
|
||||
const [connected, setConnected] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
socket.connect();
|
||||
|
||||
socket.on('connect', () => {
|
||||
setConnected(true);
|
||||
setPlayerId(socket.id);
|
||||
});
|
||||
|
||||
socket.on('disconnect', () => setConnected(false));
|
||||
|
||||
socket.on('nameSet', (data) => {
|
||||
setPlayerId(data.id);
|
||||
setScreen(SCREENS.LOBBY);
|
||||
});
|
||||
|
||||
socket.on('roomsUpdated', (data) => setRooms(data));
|
||||
socket.on('roomCreated', (room) => {
|
||||
setCurrentRoom(room);
|
||||
setScreen(SCREENS.ROOM);
|
||||
});
|
||||
socket.on('roomJoined', (room) => {
|
||||
setCurrentRoom(room);
|
||||
setScreen(SCREENS.ROOM);
|
||||
});
|
||||
socket.on('roomUpdated', (room) => setCurrentRoom(room));
|
||||
|
||||
socket.on('gameStarted', (data) => {
|
||||
setGameId(data.gameId);
|
||||
setGameState(data.state);
|
||||
setScreen(SCREENS.GAME);
|
||||
});
|
||||
|
||||
socket.on('gameStateUpdated', (state) => setGameState(state));
|
||||
|
||||
socket.on('error', (data) => {
|
||||
setError(data.message);
|
||||
setTimeout(() => setError(null), 3000);
|
||||
});
|
||||
|
||||
socket.on('actionError', (data) => {
|
||||
setError(data.message);
|
||||
setTimeout(() => setError(null), 3000);
|
||||
});
|
||||
|
||||
socket.on('playerDisconnected', (data) => {
|
||||
setError(`${data.playerName} disconnected`);
|
||||
setTimeout(() => setError(null), 3000);
|
||||
});
|
||||
|
||||
socket.on('needsResponse', () => {});
|
||||
|
||||
return () => {
|
||||
socket.removeAllListeners();
|
||||
socket.disconnect();
|
||||
};
|
||||
}, []);
|
||||
|
||||
const handleSetName = useCallback((e) => {
|
||||
e.preventDefault();
|
||||
if (!playerName.trim()) return;
|
||||
socket.emit('setName', playerName.trim());
|
||||
}, [playerName]);
|
||||
|
||||
const handleBackToLobby = useCallback(() => {
|
||||
socket.emit('leaveRoom');
|
||||
setCurrentRoom(null);
|
||||
setGameState(null);
|
||||
setGameId(null);
|
||||
setScreen(SCREENS.LOBBY);
|
||||
socket.emit('getRooms');
|
||||
}, []);
|
||||
|
||||
if (screen === SCREENS.NAME) {
|
||||
return (
|
||||
<div className="app">
|
||||
<div className="title-screen">
|
||||
<h1 className="game-title">Arcane Duels</h1>
|
||||
<p className="game-subtitle">A game of strategy, mana, and might</p>
|
||||
<form onSubmit={handleSetName} className="name-form">
|
||||
<input
|
||||
type="text"
|
||||
value={playerName}
|
||||
onChange={(e) => setPlayerName(e.target.value)}
|
||||
placeholder="Enter your name..."
|
||||
className="name-input"
|
||||
maxLength={20}
|
||||
autoFocus
|
||||
/>
|
||||
<button type="submit" className="btn btn-primary" disabled={!connected}>
|
||||
{connected ? 'Enter the Arena' : 'Connecting...'}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
{error && <div className="error-toast">{error}</div>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (screen === SCREENS.GAME && gameState) {
|
||||
return (
|
||||
<div className="app">
|
||||
<GameBoard
|
||||
gameState={gameState}
|
||||
playerId={playerId}
|
||||
onLeave={handleBackToLobby}
|
||||
/>
|
||||
{error && <div className="error-toast">{error}</div>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="app">
|
||||
<Lobby
|
||||
playerId={playerId}
|
||||
playerName={playerName}
|
||||
rooms={rooms}
|
||||
currentRoom={currentRoom}
|
||||
screen={screen}
|
||||
onBackToLobby={handleBackToLobby}
|
||||
/>
|
||||
{error && <div className="error-toast">{error}</div>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user