Merge branch 'main' of https://git.mdnd-it.cc/Donat/SerpentRace into Backend_Fix
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
import React, { useEffect, useRef, useState } from "react"
|
import React, { useEffect, useRef, useState } from "react"
|
||||||
import { useLocation } from "react-router-dom"
|
import { useLocation } from "react-router-dom"
|
||||||
|
import { useNavigate } from "react-router-dom"
|
||||||
|
import { notifyError, notifyWarning, notifySuccess } from "../../components/Toastify/toastifyServices"
|
||||||
import HandleNavigate from "../../utils/HandleNavigate/HandleNavigate"
|
import HandleNavigate from "../../utils/HandleNavigate/HandleNavigate"
|
||||||
import Navbar from "../../components/Navbar/Navbar.jsx"
|
import Navbar from "../../components/Navbar/Navbar.jsx"
|
||||||
import Background from "../../assets/backgrounds/Background.jsx"
|
import Background from "../../assets/backgrounds/Background.jsx"
|
||||||
@@ -12,6 +14,7 @@ const Lobby = () => {
|
|||||||
const [isStarting, setIsStarting] = useState(false)
|
const [isStarting, setIsStarting] = useState(false)
|
||||||
const sectionRef = useRef(null)
|
const sectionRef = useRef(null)
|
||||||
const { goHome, goGame } = HandleNavigate()
|
const { goHome, goGame } = HandleNavigate()
|
||||||
|
const navigate = useNavigate()
|
||||||
const location = useLocation()
|
const location = useLocation()
|
||||||
|
|
||||||
const [user, setUser] = useRequireAuth()
|
const [user, setUser] = useRequireAuth()
|
||||||
@@ -41,7 +44,7 @@ const Lobby = () => {
|
|||||||
}
|
}
|
||||||
}, [gameToken, connect])
|
}, [gameToken, connect])
|
||||||
|
|
||||||
const gameCode = gameCodeFromState || gameState?.gameCode || 'Loading...'
|
const gameCode = gameCodeFromState || gameState?.gameCode || "Loading..."
|
||||||
|
|
||||||
// Players list - gamemaster is separate, don't filter
|
// Players list - gamemaster is separate, don't filter
|
||||||
// Backend should handle this correctly
|
// Backend should handle this correctly
|
||||||
@@ -50,12 +53,12 @@ const Lobby = () => {
|
|||||||
// Debug logging
|
// Debug logging
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (import.meta.env.DEV) {
|
if (import.meta.env.DEV) {
|
||||||
console.log('🎮 Lobby state update:')
|
console.log("🎮 Lobby state update:")
|
||||||
console.log(' - isGamemaster:', isGamemaster)
|
console.log(" - isGamemaster:", isGamemaster)
|
||||||
console.log(' - gameState:', gameState)
|
console.log(" - gameState:", gameState)
|
||||||
console.log(' - players:', players)
|
console.log(" - players:", players)
|
||||||
console.log(' - currentPlayers:', currentPlayers)
|
console.log(" - currentPlayers:", currentPlayers)
|
||||||
console.log(' - pendingPlayers:', pendingPlayers)
|
console.log(" - pendingPlayers:", pendingPlayers)
|
||||||
}
|
}
|
||||||
}, [isGamemaster, gameState, players, currentPlayers, pendingPlayers])
|
}, [isGamemaster, gameState, players, currentPlayers, pendingPlayers])
|
||||||
|
|
||||||
@@ -73,7 +76,7 @@ const Lobby = () => {
|
|||||||
// Auto-navigate when game starts
|
// Auto-navigate when game starts
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (gameStarted) {
|
if (gameStarted) {
|
||||||
console.log('🎮 Game started, navigating to /game')
|
console.log("🎮 Game started, navigating to /game")
|
||||||
goGame()
|
goGame()
|
||||||
}
|
}
|
||||||
}, [gameStarted, goGame])
|
}, [gameStarted, goGame])
|
||||||
@@ -83,7 +86,7 @@ const Lobby = () => {
|
|||||||
if (approvalStatus === 'denied') {
|
if (approvalStatus === 'denied') {
|
||||||
alert('A gamemaster elutasította a csatlakozási kérelmedet.')
|
alert('A gamemaster elutasította a csatlakozási kérelmedet.')
|
||||||
localStorage.removeItem('gameToken')
|
localStorage.removeItem('gameToken')
|
||||||
goHome()
|
navigate("/home")
|
||||||
} else if (approvalStatus === 'approved') {
|
} else if (approvalStatus === 'approved') {
|
||||||
console.log('✅ Join approved, you can now see the lobby')
|
console.log('✅ Join approved, you can now see the lobby')
|
||||||
}
|
}
|
||||||
@@ -91,7 +94,8 @@ const Lobby = () => {
|
|||||||
|
|
||||||
const handleExit = () => {
|
const handleExit = () => {
|
||||||
if (window.confirm("Biztosan ki szeretnél lépni a lobbyból?")) {
|
if (window.confirm("Biztosan ki szeretnél lépni a lobbyból?")) {
|
||||||
localStorage.removeItem('gameToken')
|
localStorage.removeItem("gameToken")
|
||||||
|
notifyWarning("Kiléptél a lobbyból.")
|
||||||
goHome()
|
goHome()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -99,7 +103,7 @@ const Lobby = () => {
|
|||||||
const handleStartGame = async () => {
|
const handleStartGame = async () => {
|
||||||
// Prevent double-click
|
// Prevent double-click
|
||||||
if (isStarting) {
|
if (isStarting) {
|
||||||
console.log('⚠️ Game start already in progress, ignoring duplicate request')
|
console.log("⚠️ Game start already in progress, ignoring duplicate request")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,34 +113,34 @@ const Lobby = () => {
|
|||||||
// Get gameId from gameState
|
// Get gameId from gameState
|
||||||
const gameId = gameState?.gameId
|
const gameId = gameState?.gameId
|
||||||
if (!gameId) {
|
if (!gameId) {
|
||||||
alert('Hiba: Játék azonosító nem található')
|
notifyError("Hiba: Játék azonosító nem található")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('Starting game with ID:', gameId)
|
console.log("Starting game with ID:", gameId)
|
||||||
const response = await startGame(gameId)
|
const response = await startGame(gameId)
|
||||||
console.log('Game start response:', response)
|
console.log("Game start response:", response)
|
||||||
|
|
||||||
// Store boardData and updated game state for GameScreen
|
// Store boardData and updated game state for GameScreen
|
||||||
if (response.boardData) {
|
if (response.boardData) {
|
||||||
localStorage.setItem('boardData', JSON.stringify(response.boardData))
|
localStorage.setItem("boardData", JSON.stringify(response.boardData))
|
||||||
console.log('✅ boardData stored in localStorage')
|
console.log("✅ boardData stored in localStorage")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Navigate immediately after successful start (don't wait for WebSocket)
|
// Navigate immediately after successful start (don't wait for WebSocket)
|
||||||
console.log('🎮 Navigating to /game...')
|
console.log('🎮 Navigating to /game...')
|
||||||
goGame()
|
navigate('/game')
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to start game:', error)
|
console.error("Failed to start game:", error)
|
||||||
|
|
||||||
// Check if game already started
|
// Check if game already started
|
||||||
if (error.response?.status === 409) {
|
if (error.response?.status === 409) {
|
||||||
console.log('Game already started, navigating to /game...')
|
console.log("Game already started, navigating to /game...")
|
||||||
// Navigate anyway - game is already running
|
// Navigate anyway - game is already running
|
||||||
goGame()
|
navigate('/game')
|
||||||
} else {
|
} else {
|
||||||
alert(`Nem sikerült elindítani a játékot: ${error.response?.data?.error || error.message}`)
|
notifyError(`Nem sikerült elindítani a játékot: ${error.response?.data?.error || error.message}`)
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
setIsStarting(false)
|
setIsStarting(false)
|
||||||
@@ -145,7 +149,7 @@ const Lobby = () => {
|
|||||||
|
|
||||||
const copyGameCode = () => {
|
const copyGameCode = () => {
|
||||||
navigator.clipboard.writeText(gameCode)
|
navigator.clipboard.writeText(gameCode)
|
||||||
alert('Játék kód vágólapra másolva: ' + gameCode)
|
notifySuccess("Játék kód vágólapra másolva: " + gameCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleApprovePlayer = (playerName) => {
|
const handleApprovePlayer = (playerName) => {
|
||||||
@@ -155,8 +159,9 @@ const Lobby = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleRejectPlayer = (playerName) => {
|
const handleRejectPlayer = (playerName) => {
|
||||||
const reason = prompt(`Miért utasítod el ${playerName}-t?`, 'Nincs hely a játékban')
|
const reason = prompt(`Miért utasítod el ${playerName}-t?`, "Nincs hely a játékban")
|
||||||
if (reason !== null) { // User didn't cancel
|
if (reason !== null) {
|
||||||
|
// User didn't cancel
|
||||||
if (rejectPlayer(playerName, reason)) {
|
if (rejectPlayer(playerName, reason)) {
|
||||||
console.log(`❌ Player ${playerName} rejected`)
|
console.log(`❌ Player ${playerName} rejected`)
|
||||||
}
|
}
|
||||||
@@ -183,7 +188,7 @@ const Lobby = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Waiting for Approval Screen (Non-gamemaster, PRIVATE games) */}
|
{/* Waiting for Approval Screen (Non-gamemaster, PRIVATE games) */}
|
||||||
{!isGamemaster && approvalStatus === 'pending' && (
|
{!isGamemaster && approvalStatus === "pending" && (
|
||||||
<div className="flex-1 flex items-center justify-center px-4 py-24">
|
<div className="flex-1 flex items-center justify-center px-4 py-24">
|
||||||
<div className="bg-zinc-900/95 backdrop-blur-sm rounded-3xl p-8 max-w-md w-full border border-yellow-500/50 shadow-2xl">
|
<div className="bg-zinc-900/95 backdrop-blur-sm rounded-3xl p-8 max-w-md w-full border border-yellow-500/50 shadow-2xl">
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
@@ -192,9 +197,7 @@ const Lobby = () => {
|
|||||||
<span className="text-4xl">⏳</span>
|
<span className="text-4xl">⏳</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<h2 className="text-3xl font-bold text-yellow-300 mb-4">
|
<h2 className="text-3xl font-bold text-yellow-300 mb-4">Várakozás jóváhagyásra</h2>
|
||||||
Várakozás jóváhagyásra
|
|
||||||
</h2>
|
|
||||||
<p className="text-zinc-300 text-lg mb-6">
|
<p className="text-zinc-300 text-lg mb-6">
|
||||||
A gamemaster még nem hagyta jóvá a csatlakozásodat.
|
A gamemaster még nem hagyta jóvá a csatlakozásodat.
|
||||||
</p>
|
</p>
|
||||||
@@ -204,9 +207,7 @@ const Lobby = () => {
|
|||||||
<div className="flex flex-col gap-3">
|
<div className="flex flex-col gap-3">
|
||||||
<div className="bg-zinc-800 rounded-lg p-4 border border-zinc-700">
|
<div className="bg-zinc-800 rounded-lg p-4 border border-zinc-700">
|
||||||
<p className="text-zinc-400 text-xs mb-1">Játék kód:</p>
|
<p className="text-zinc-400 text-xs mb-1">Játék kód:</p>
|
||||||
<p className="text-2xl font-mono font-bold text-green-300 tracking-widest">
|
<p className="text-2xl font-mono font-bold text-green-300 tracking-widest">{gameCode}</p>
|
||||||
{gameCode}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
onClick={handleExit}
|
onClick={handleExit}
|
||||||
@@ -221,194 +222,179 @@ const Lobby = () => {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Normal Lobby View (Gamemaster or approved players) */}
|
{/* Normal Lobby View (Gamemaster or approved players) */}
|
||||||
{(isGamemaster || approvalStatus !== 'pending') && (
|
{(isGamemaster || approvalStatus !== "pending") && (
|
||||||
<div className="flex-1 flex items-center justify-center px-4 py-24">
|
<div className="flex-1 flex items-center justify-center px-4 py-24">
|
||||||
<section
|
<section
|
||||||
ref={sectionRef}
|
ref={sectionRef}
|
||||||
className={`w-full max-w-3xl rounded-2xl p-8 md:p-10 transition-all duration-1000 ease-out backdrop-blur-md shadow-2xl ${
|
className={`w-full max-w-3xl rounded-2xl p-8 md:p-10 transition-all duration-1000 ease-out backdrop-blur-md shadow-2xl ${
|
||||||
visible ? "opacity-100 translate-y-0" : "opacity-0 translate-y-10"
|
visible ? "opacity-100 translate-y-0" : "opacity-0 translate-y-10"
|
||||||
}`}
|
}`}
|
||||||
style={{ background: "rgba(0,0,0,0.25)" }}
|
style={{ background: "rgba(0,0,0,0.25)" }}
|
||||||
>
|
>
|
||||||
<h1 className="text-4xl md:text-5xl font-extrabold text-green-300 mb-4 text-center tracking-wide drop-shadow-lg">
|
<h1 className="text-4xl md:text-5xl font-extrabold text-green-300 mb-4 text-center tracking-wide drop-shadow-lg">
|
||||||
Játék Lobby
|
Játék Lobby
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
{/* Game Code Display */}
|
{/* Game Code Display */}
|
||||||
<div className="bg-gradient-to-r from-green-600/20 to-teal-600/20 rounded-xl p-6 mb-6 border-2 border-green-400/50">
|
<div className="bg-gradient-to-r from-green-600/20 to-teal-600/20 rounded-xl p-6 mb-6 border-2 border-green-400/50">
|
||||||
<p className="text-lg text-zinc-300 mb-2 text-center font-semibold">
|
<p className="text-lg text-zinc-300 mb-2 text-center font-semibold">Játék Kód:</p>
|
||||||
Játék Kód:
|
<div className="flex items-center justify-center gap-3">
|
||||||
</p>
|
<p className="text-5xl font-mono font-extrabold text-green-300 tracking-widest drop-shadow-lg">
|
||||||
<div className="flex items-center justify-center gap-3">
|
{gameCode}
|
||||||
<p className="text-5xl font-mono font-extrabold text-green-300 tracking-widest drop-shadow-lg">
|
</p>
|
||||||
{gameCode}
|
<button
|
||||||
|
onClick={copyGameCode}
|
||||||
|
className="bg-green-600 hover:bg-green-500 text-white px-4 py-2 rounded-lg font-semibold transition-all duration-200 hover:scale-105"
|
||||||
|
title="Másolás vágólapra"
|
||||||
|
>
|
||||||
|
📋 Másolás
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<p className="text-sm text-zinc-400 mt-3 text-center">
|
||||||
|
Oszd meg ezt a kódot másokkal, hogy csatlakozhassanak a játékhoz!
|
||||||
</p>
|
</p>
|
||||||
<button
|
|
||||||
onClick={copyGameCode}
|
|
||||||
className="bg-green-600 hover:bg-green-500 text-white px-4 py-2 rounded-lg font-semibold transition-all duration-200 hover:scale-105"
|
|
||||||
title="Másolás vágólapra"
|
|
||||||
>
|
|
||||||
📋 Másolás
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
<p className="text-sm text-zinc-400 mt-3 text-center">
|
|
||||||
Oszd meg ezt a kódot másokkal, hogy csatlakozhassanak a játékhoz!
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Connection Status */}
|
{/* Connection Status */}
|
||||||
<div className="mb-4 text-center">
|
<div className="mb-4 text-center">
|
||||||
<span className={`inline-block px-4 py-2 rounded-full text-sm font-semibold ${
|
<span
|
||||||
isConnected
|
className={`inline-block px-4 py-2 rounded-full text-sm font-semibold ${
|
||||||
? 'bg-green-600/20 text-green-300 border border-green-400'
|
isConnected
|
||||||
: 'bg-red-600/20 text-red-300 border border-red-400'
|
? "bg-green-600/20 text-green-300 border border-green-400"
|
||||||
}`}>
|
: "bg-red-600/20 text-red-300 border border-red-400"
|
||||||
{isConnected ? '🟢 Kapcsolódva' : '🔴 Kapcsolat megszakadt'}
|
}`}
|
||||||
</span>
|
>
|
||||||
</div>
|
{isConnected ? "🟢 Kapcsolódva" : "🔴 Kapcsolat megszakadt"}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<p className="text-lg text-zinc-300 mb-6 text-center">
|
<p className="text-lg text-zinc-300 mb-6 text-center">Játékosok ({currentPlayers.length}):</p>
|
||||||
Játékosok ({currentPlayers.length}):
|
|
||||||
</p>
|
|
||||||
|
|
||||||
{/* Pending Players Section (Gamemaster only, PRIVATE games) */}
|
{/* Pending Players Section (Gamemaster only, PRIVATE games) */}
|
||||||
{isGamemaster && pendingPlayers && pendingPlayers.length > 0 && (
|
{isGamemaster && pendingPlayers && pendingPlayers.length > 0 && (
|
||||||
<div className="bg-yellow-900/20 border-2 border-yellow-500/50 rounded-xl shadow-lg p-6 mb-6">
|
<div className="bg-yellow-900/20 border-2 border-yellow-500/50 rounded-xl shadow-lg p-6 mb-6">
|
||||||
<h3 className="text-xl font-bold text-yellow-300 mb-4 flex items-center gap-2">
|
<h3 className="text-xl font-bold text-yellow-300 mb-4 flex items-center gap-2">
|
||||||
<span>⏳</span>
|
<span>⏳</span>
|
||||||
Jóváhagyásra váró játékosok ({pendingPlayers.length})
|
Jóváhagyásra váró játékosok ({pendingPlayers.length})
|
||||||
</h3>
|
</h3>
|
||||||
<ul className="flex flex-col gap-3">
|
<ul className="flex flex-col gap-3">
|
||||||
{pendingPlayers.map((player, index) => (
|
{pendingPlayers.map((player, index) => (
|
||||||
<li
|
<li key={index} className="bg-zinc-700 py-3 px-4 rounded-xl flex items-center gap-4">
|
||||||
key={index}
|
<div className="w-10 h-10 rounded-full flex items-center justify-center text-sm font-semibold bg-yellow-900/30 text-yellow-300 border border-yellow-500/50">
|
||||||
className="bg-zinc-700 py-3 px-4 rounded-xl flex items-center gap-4"
|
{getInitials(player.playerName)}
|
||||||
>
|
</div>
|
||||||
<div
|
<div className="flex-1">
|
||||||
className="w-10 h-10 rounded-full flex items-center justify-center text-sm font-semibold bg-yellow-900/30 text-yellow-300 border border-yellow-500/50"
|
<span className="text-white text-lg font-semibold">{player.playerName}</span>
|
||||||
|
{player.isAuthenticated && (
|
||||||
|
<span className="ml-2 text-xs bg-green-600/30 text-green-300 px-2 py-0.5 rounded-full border border-green-500/50">
|
||||||
|
✓ Bejelentkezve
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<button
|
||||||
|
onClick={() => handleApprovePlayer(player.playerName)}
|
||||||
|
className="bg-green-600 hover:bg-green-500 text-white px-4 py-2 rounded-lg font-semibold transition-all duration-200 hover:scale-105 flex items-center gap-1"
|
||||||
|
title="Jóváhagyás"
|
||||||
|
>
|
||||||
|
<span>✓</span>
|
||||||
|
<span className="hidden sm:inline">Jóváhagy</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => handleRejectPlayer(player.playerName)}
|
||||||
|
className="bg-red-600 hover:bg-red-500 text-white px-4 py-2 rounded-lg font-semibold transition-all duration-200 hover:scale-105 flex items-center gap-1"
|
||||||
|
title="Elutasítás"
|
||||||
|
>
|
||||||
|
<span>✕</span>
|
||||||
|
<span className="hidden sm:inline">Elutasít</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className="bg-zinc-800/90 rounded-xl shadow-lg p-6 mb-8">
|
||||||
|
<ul className="flex flex-col gap-4">
|
||||||
|
{currentPlayers.length === 0 ? (
|
||||||
|
<li className="text-center text-zinc-400 py-4">Várakozás játékosokra...</li>
|
||||||
|
) : (
|
||||||
|
currentPlayers.map((player, index) => (
|
||||||
|
<li
|
||||||
|
key={player.id || index}
|
||||||
|
className="bg-zinc-700 py-3 px-4 rounded-xl text-green-400 font-semibold flex items-center gap-4 shadow hover:shadow-green-500/20 transition"
|
||||||
>
|
>
|
||||||
{getInitials(player.playerName)}
|
<div
|
||||||
</div>
|
className="w-10 h-10 rounded-full flex items-center justify-center text-sm font-semibold"
|
||||||
<div className="flex-1">
|
style={{ background: "rgba(34,197,94,0.12)", color: "var(--color-mint)" }}
|
||||||
<span className="text-white text-lg font-semibold">
|
>
|
||||||
{player.playerName}
|
{getInitials(player.name || `Player ${index + 1}`)}
|
||||||
|
</div>
|
||||||
|
<span className="text-white text-lg flex-1">
|
||||||
|
{player.name || `Player ${index + 1}`}
|
||||||
</span>
|
</span>
|
||||||
{player.isAuthenticated && (
|
{player.isReady && (
|
||||||
<span className="ml-2 text-xs bg-green-600/30 text-green-300 px-2 py-0.5 rounded-full border border-green-500/50">
|
<span className="bg-green-600 text-white text-xs px-2 py-1 rounded-full">Kész</span>
|
||||||
✓ Bejelentkezve
|
|
||||||
</span>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
{player.isOnline && <span className="text-green-400 text-xs">🟢</span>}
|
||||||
<div className="flex gap-2">
|
</li>
|
||||||
<button
|
))
|
||||||
onClick={() => handleApprovePlayer(player.playerName)}
|
)}
|
||||||
className="bg-green-600 hover:bg-green-500 text-white px-4 py-2 rounded-lg font-semibold transition-all duration-200 hover:scale-105 flex items-center gap-1"
|
|
||||||
title="Jóváhagyás"
|
|
||||||
>
|
|
||||||
<span>✓</span>
|
|
||||||
<span className="hidden sm:inline">Jóváhagy</span>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
onClick={() => handleRejectPlayer(player.playerName)}
|
|
||||||
className="bg-red-600 hover:bg-red-500 text-white px-4 py-2 rounded-lg font-semibold transition-all duration-200 hover:scale-105 flex items-center gap-1"
|
|
||||||
title="Elutasítás"
|
|
||||||
>
|
|
||||||
<span>✕</span>
|
|
||||||
<span className="hidden sm:inline">Elutasít</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
)}
|
|
||||||
|
|
||||||
<div className="bg-zinc-800/90 rounded-xl shadow-lg p-6 mb-8">
|
{/* Role indicator */}
|
||||||
<ul className="flex flex-col gap-4">
|
<div className="mb-6 text-center">
|
||||||
{currentPlayers.length === 0 ? (
|
{isGamemaster ? (
|
||||||
<li className="text-center text-zinc-400 py-4">
|
<div className="bg-yellow-600/20 text-yellow-300 px-4 py-3 rounded-lg border border-yellow-400/50">
|
||||||
Várakozás játékosokra...
|
<p className="font-semibold">👑 Te vagy a Gamemaster!</p>
|
||||||
</li>
|
<p className="text-sm mt-1">Te nem játszol, csak indítod és moderálod a játékot.</p>
|
||||||
|
</div>
|
||||||
) : (
|
) : (
|
||||||
currentPlayers.map((player, index) => (
|
<div className="bg-blue-600/20 text-blue-300 px-4 py-3 rounded-lg border border-blue-400/50">
|
||||||
<li
|
<p className="font-semibold">🎮 Te vagy egy Játékos!</p>
|
||||||
key={player.id || index}
|
<p className="text-sm mt-1">Várj, amíg a gamemaster elindítja a játékot.</p>
|
||||||
className="bg-zinc-700 py-3 px-4 rounded-xl text-green-400 font-semibold flex items-center gap-4 shadow hover:shadow-green-500/20 transition"
|
</div>
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="w-10 h-10 rounded-full flex items-center justify-center text-sm font-semibold"
|
|
||||||
style={{ background: "rgba(34,197,94,0.12)", color: "var(--color-mint)" }}
|
|
||||||
>
|
|
||||||
{getInitials(player.name || `Player ${index + 1}`)}
|
|
||||||
</div>
|
|
||||||
<span className="text-white text-lg flex-1">
|
|
||||||
{player.name || `Player ${index + 1}`}
|
|
||||||
</span>
|
|
||||||
{player.isReady && (
|
|
||||||
<span className="bg-green-600 text-white text-xs px-2 py-1 rounded-full">
|
|
||||||
Kész
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
{player.isOnline && (
|
|
||||||
<span className="text-green-400 text-xs">🟢</span>
|
|
||||||
)}
|
|
||||||
</li>
|
|
||||||
))
|
|
||||||
)}
|
)}
|
||||||
</ul>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Role indicator */}
|
<div className="flex justify-center gap-4">
|
||||||
<div className="mb-6 text-center">
|
{isGamemaster ? (
|
||||||
{isGamemaster ? (
|
/* Gamemaster view - can start game */
|
||||||
<div className="bg-yellow-600/20 text-yellow-300 px-4 py-3 rounded-lg border border-yellow-400/50">
|
<button
|
||||||
<p className="font-semibold">👑 Te vagy a Gamemaster!</p>
|
onClick={handleStartGame}
|
||||||
<p className="text-sm mt-1">Te nem játszol, csak indítod és moderálod a játékot.</p>
|
disabled={currentPlayers.length < 2 || isStarting}
|
||||||
</div>
|
className={`px-8 py-3 rounded-xl font-semibold shadow-lg transition-transform transform hover:scale-105 ${
|
||||||
) : (
|
currentPlayers.length >= 2 && !isStarting
|
||||||
<div className="bg-blue-600/20 text-blue-300 px-4 py-3 rounded-lg border border-blue-400/50">
|
? "bg-gradient-to-r from-green-700 to-green-500 hover:from-green-600 hover:to-green-400 text-white hover:shadow-green-400/30"
|
||||||
<p className="font-semibold">🎮 Te vagy egy Játékos!</p>
|
: "bg-gray-600 text-gray-400 cursor-not-allowed"
|
||||||
<p className="text-sm mt-1">Várj, amíg a gamemaster elindítja a játékot.</p>
|
}`}
|
||||||
</div>
|
title={
|
||||||
)}
|
isStarting
|
||||||
</div>
|
? "Játék indítása folyamatban..."
|
||||||
|
: currentPlayers.length < 2
|
||||||
<div className="flex justify-center gap-4">
|
? "Minimum 2 játékos szükséges"
|
||||||
{isGamemaster ? (
|
: "Játék indítása"
|
||||||
/* Gamemaster view - can start game */
|
}
|
||||||
|
>
|
||||||
|
{isStarting ? "⏳ Indítás..." : "Játék Indítása"}
|
||||||
|
</button>
|
||||||
|
) : (
|
||||||
|
/* Player view - cannot start game, just wait */
|
||||||
|
<div className="text-center text-zinc-400">
|
||||||
|
<p className="text-lg">Várakozás a gamemaster-re...</p>
|
||||||
|
<p className="text-sm mt-2">Csak a gamemaster indíthatja el a játékot</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<button
|
<button
|
||||||
onClick={handleStartGame}
|
onClick={handleExit}
|
||||||
disabled={currentPlayers.length < 2 || isStarting}
|
className="bg-gradient-to-r from-red-700 to-red-500 hover:from-red-600 hover:to-red-400 text-white px-8 py-3 rounded-xl font-semibold shadow-lg hover:shadow-red-400/30 transition-transform transform hover:scale-105"
|
||||||
className={`px-8 py-3 rounded-xl font-semibold shadow-lg transition-transform transform hover:scale-105 ${
|
|
||||||
currentPlayers.length >= 2 && !isStarting
|
|
||||||
? 'bg-gradient-to-r from-green-700 to-green-500 hover:from-green-600 hover:to-green-400 text-white hover:shadow-green-400/30'
|
|
||||||
: 'bg-gray-600 text-gray-400 cursor-not-allowed'
|
|
||||||
}`}
|
|
||||||
title={
|
|
||||||
isStarting
|
|
||||||
? 'Játék indítása folyamatban...'
|
|
||||||
: currentPlayers.length < 2
|
|
||||||
? 'Minimum 2 játékos szükséges'
|
|
||||||
: 'Játék indítása'
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
{isStarting ? '⏳ Indítás...' : 'Játék Indítása'}
|
Kilépés
|
||||||
</button>
|
</button>
|
||||||
) : (
|
</div>
|
||||||
/* Player view - cannot start game, just wait */
|
</section>
|
||||||
<div className="text-center text-zinc-400">
|
|
||||||
<p className="text-lg">Várakozás a gamemaster-re...</p>
|
|
||||||
<p className="text-sm mt-2">Csak a gamemaster indíthatja el a játékot</p>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<button
|
|
||||||
onClick={handleExit}
|
|
||||||
className="bg-gradient-to-r from-red-700 to-red-500 hover:from-red-600 hover:to-red-400 text-white px-8 py-3 rounded-xl font-semibold shadow-lg hover:shadow-red-400/30 transition-transform transform hover:scale-105"
|
|
||||||
>
|
|
||||||
Kilépés
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ const GameLobbySetup = () => {
|
|||||||
const [isPublic, setIsPublic] = useState(true)
|
const [isPublic, setIsPublic] = useState(true)
|
||||||
const [loading, setLoading] = useState(false)
|
const [loading, setLoading] = useState(false)
|
||||||
const [error, setError] = useState(null)
|
const [error, setError] = useState(null)
|
||||||
const [createdGameCode, setCreatedGameCode] = useState('')
|
const [createdGameCode, setCreatedGameCode] = useState("")
|
||||||
const [showSuccess, setShowSuccess] = useState(false)
|
const [showSuccess, setShowSuccess] = useState(false)
|
||||||
|
|
||||||
const handleCreateLobby = async () => {
|
const handleCreateLobby = async () => {
|
||||||
@@ -28,12 +28,12 @@ const GameLobbySetup = () => {
|
|||||||
setError(null)
|
setError(null)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const username = localStorage.getItem('username')
|
const username = localStorage.getItem("username")
|
||||||
|
|
||||||
console.log('Creating game - username:', username)
|
console.log("Creating game - username:", username)
|
||||||
|
|
||||||
if (!username) {
|
if (!username) {
|
||||||
setError('Kérlek jelentkezz be először!')
|
setError("Kérlek jelentkezz be először!")
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -45,12 +45,12 @@ const GameLobbySetup = () => {
|
|||||||
logintype: isPublic ? 0 : 1, // 0=PUBLIC, 1=PRIVATE, 2=ORGANIZATION
|
logintype: isPublic ? 0 : 1, // 0=PUBLIC, 1=PRIVATE, 2=ORGANIZATION
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('Creating game with data:', gameData)
|
console.log("Creating game with data:", gameData)
|
||||||
const response = await createGame(gameData)
|
const response = await createGame(gameData)
|
||||||
console.log('Game created:', response)
|
console.log("Game created:", response)
|
||||||
|
|
||||||
// Verify localStorage still has username
|
// Verify localStorage still has username
|
||||||
console.log('After create - username:', localStorage.getItem('username'))
|
console.log("After create - username:", localStorage.getItem("username"))
|
||||||
|
|
||||||
// Backend returns game object directly
|
// Backend returns game object directly
|
||||||
const code = response.gamecode || response.gameCode
|
const code = response.gamecode || response.gameCode
|
||||||
@@ -62,31 +62,31 @@ const GameLobbySetup = () => {
|
|||||||
// Creator needs to join their own game to get a gameToken
|
// Creator needs to join their own game to get a gameToken
|
||||||
// This allows the WebSocket to recognize them as the gamemaster
|
// This allows the WebSocket to recognize them as the gamemaster
|
||||||
try {
|
try {
|
||||||
const username = localStorage.getItem('username')
|
const username = localStorage.getItem("username")
|
||||||
const joinResponse = await joinGame({
|
const joinResponse = await joinGame({
|
||||||
gameCode: code,
|
gameCode: code,
|
||||||
playerName: username
|
playerName: username,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (joinResponse.gameToken) {
|
if (joinResponse.gameToken) {
|
||||||
localStorage.setItem('gameToken', joinResponse.gameToken)
|
localStorage.setItem("gameToken", joinResponse.gameToken)
|
||||||
console.log('Creator joined game as gamemaster, token stored')
|
console.log("Creator joined game as gamemaster, token stored")
|
||||||
}
|
}
|
||||||
} catch (joinError) {
|
} catch (joinError) {
|
||||||
console.error('Failed to join game as creator:', joinError)
|
console.error("Failed to join game as creator:", joinError)
|
||||||
// Continue anyway - the creator can still try to join manually
|
// Continue anyway - the creator can still try to join manually
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait 3 seconds to show code, then navigate to lobby
|
// Azonnali navigáció a lobbyhoz, amint létrejött a játék
|
||||||
setTimeout(() => {
|
console.log("Navigating to lobby with code:", code)
|
||||||
console.log('Navigating to lobby with code:', code)
|
goLobby({ gameCode: code })
|
||||||
goLobby({ gameCode: code })
|
|
||||||
}, 3000)
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Create game error:', err)
|
console.error("Create game error:", err)
|
||||||
console.error('Error response:', err.response?.data)
|
console.error("Error response:", err.response?.data)
|
||||||
console.error('Error status:', err.response?.status)
|
console.error("Error status:", err.response?.status)
|
||||||
setError(err.response?.data?.message || err.response?.data?.error || 'Nem sikerült létrehozni a játékot')
|
setError(
|
||||||
|
err.response?.data?.message || err.response?.data?.error || "Nem sikerült létrehozni a játékot"
|
||||||
|
)
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
}
|
}
|
||||||
@@ -132,26 +132,9 @@ const GameLobbySetup = () => {
|
|||||||
{deckIds.length} pakli kiválasztva. Add meg a játék részleteit.
|
{deckIds.length} pakli kiválasztva. Add meg a játék részleteit.
|
||||||
</motion.p>
|
</motion.p>
|
||||||
|
|
||||||
{error && (
|
{error && <div className="bg-red-500/20 border border-red-500 rounded-lg p-4 mb-6">{error}</div>}
|
||||||
<div className="bg-red-500/20 border border-red-500 rounded-lg p-4 mb-6">
|
|
||||||
{error}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{createdGameCode && (
|
{/* ...a kód kiírása törölve, lobbyban jelenik meg... */}
|
||||||
<div className="bg-green-500/20 border border-green-500 rounded-lg p-6 mb-6">
|
|
||||||
<p className="font-bold text-xl mb-2">Játék Létrehozva! 🎉</p>
|
|
||||||
<p className="text-3xl font-mono tracking-wider text-green-400 mb-2">
|
|
||||||
{createdGameCode}
|
|
||||||
</p>
|
|
||||||
<p className="text-sm text-gray-300">
|
|
||||||
Oszd meg ezt a kódot más játékosokkal, hogy csatlakozhassanak!
|
|
||||||
</p>
|
|
||||||
<p className="text-sm text-gray-400 mt-2">
|
|
||||||
Átirányítás a lobby-hoz 3 másodperc múlva...
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<div className="bg-[color:var(--color-surface)]/80 backdrop-blur-lg rounded-2xl p-8 shadow-lg space-y-6">
|
<div className="bg-[color:var(--color-surface)]/80 backdrop-blur-lg rounded-2xl p-8 shadow-lg space-y-6">
|
||||||
{/* Max Players */}
|
{/* Max Players */}
|
||||||
|
|||||||
Reference in New Issue
Block a user