Enhance new game modal with running game state handling
Introduced functionality to detect and handle ongoing games in the new game modal. The modal now switches between "running" and "choice" modes based on game state, improving clarity for users. Added a dedicated section to display the game code when a game is active.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import React, { useMemo, useState } from "react";
|
||||
import React, { useEffect, useMemo, useState } from "react";
|
||||
import { styles } from "../styles/styles";
|
||||
import { stylesTokens } from "../styles/theme";
|
||||
|
||||
@@ -7,8 +7,14 @@ export default function NewGameModal({
|
||||
onClose,
|
||||
onCreate,
|
||||
onJoin,
|
||||
|
||||
// ✅ neu:
|
||||
currentCode = "",
|
||||
gameFinished = false,
|
||||
hasGame = false,
|
||||
}) {
|
||||
const [mode, setMode] = useState("choice"); // choice | create | join
|
||||
// modes: running | choice | create | join
|
||||
const [mode, setMode] = useState("choice");
|
||||
const [joinCode, setJoinCode] = useState("");
|
||||
const [err, setErr] = useState("");
|
||||
const [created, setCreated] = useState(null); // { code }
|
||||
@@ -16,6 +22,23 @@ export default function NewGameModal({
|
||||
|
||||
const canJoin = useMemo(() => joinCode.trim().length >= 4, [joinCode]);
|
||||
|
||||
// ✅ wichtig: beim Öffnen entscheidet der Modus anhand "läuft vs beendet"
|
||||
useEffect(() => {
|
||||
if (!open) return;
|
||||
|
||||
setErr("");
|
||||
setToast("");
|
||||
setJoinCode("");
|
||||
setCreated(null);
|
||||
|
||||
// Wenn ein Spiel läuft (und nicht finished) -> nur Code anzeigen
|
||||
if (hasGame && !gameFinished) {
|
||||
setMode("running");
|
||||
} else {
|
||||
setMode("choice");
|
||||
}
|
||||
}, [open, hasGame, gameFinished]);
|
||||
|
||||
if (!open) return null;
|
||||
|
||||
const showToast = (msg) => {
|
||||
@@ -44,15 +67,19 @@ export default function NewGameModal({
|
||||
}
|
||||
};
|
||||
|
||||
const copyCode = async () => {
|
||||
const copyText = async (text, okMsg = "✅ Code kopiert") => {
|
||||
try {
|
||||
await navigator.clipboard.writeText(created?.code || "");
|
||||
showToast("✅ Code kopiert");
|
||||
await navigator.clipboard.writeText(text || "");
|
||||
showToast(okMsg);
|
||||
} catch {
|
||||
showToast("❌ Copy nicht möglich");
|
||||
}
|
||||
};
|
||||
|
||||
const codeToShow =
|
||||
(created?.code || "").trim() ||
|
||||
(currentCode || "").trim();
|
||||
|
||||
return (
|
||||
<div style={styles.modalOverlay} onMouseDown={onClose}>
|
||||
<div style={styles.modalCard} onMouseDown={(e) => e.stopPropagation()}>
|
||||
@@ -85,6 +112,63 @@ export default function NewGameModal({
|
||||
)}
|
||||
|
||||
<div style={{ marginTop: 12, display: "grid", gap: 10 }}>
|
||||
{/* ✅ RUNNING: Nur Code anzeigen, keine Choice */}
|
||||
{mode === "running" && (
|
||||
<>
|
||||
<div style={{ color: stylesTokens.textMain, opacity: 0.92 }}>
|
||||
Das Spiel läuft noch. Hier ist der <b>Join-Code</b>:
|
||||
</div>
|
||||
|
||||
<div
|
||||
style={{
|
||||
display: "grid",
|
||||
gap: 8,
|
||||
padding: 12,
|
||||
borderRadius: 16,
|
||||
border: `1px solid ${stylesTokens.panelBorder}`,
|
||||
background: stylesTokens.panelBg,
|
||||
textAlign: "center",
|
||||
}}
|
||||
>
|
||||
<div style={{ fontSize: 12, opacity: 0.8, color: stylesTokens.textDim }}>
|
||||
Spiel-Code
|
||||
</div>
|
||||
|
||||
<div
|
||||
style={{
|
||||
fontSize: 28,
|
||||
fontWeight: 1100,
|
||||
letterSpacing: 2,
|
||||
color: stylesTokens.textGold,
|
||||
fontFamily: '"Cinzel Decorative", "IM Fell English", system-ui',
|
||||
}}
|
||||
>
|
||||
{codeToShow || "—"}
|
||||
</div>
|
||||
|
||||
<button
|
||||
onClick={() => copyText(codeToShow)}
|
||||
style={styles.primaryBtn}
|
||||
disabled={!codeToShow}
|
||||
title={!codeToShow ? "Kein Code verfügbar" : "Code kopieren"}
|
||||
>
|
||||
⧉ Code kopieren
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div style={{ fontSize: 12, opacity: 0.75, color: stylesTokens.textDim }}>
|
||||
Sobald ein Sieger gesetzt wurde, kannst du hier ein neues Spiel erstellen oder beitreten.
|
||||
</div>
|
||||
|
||||
<div style={{ display: "flex", gap: 8, justifyContent: "flex-end" }}>
|
||||
<button onClick={onClose} style={styles.primaryBtn}>
|
||||
Fertig
|
||||
</button>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* ✅ CHOICE: nur wenn Spiel beendet oder kein Spiel selected */}
|
||||
{mode === "choice" && (
|
||||
<>
|
||||
<div style={{ color: stylesTokens.textMain, opacity: 0.92 }}>
|
||||
@@ -159,7 +243,7 @@ export default function NewGameModal({
|
||||
{created.code}
|
||||
</div>
|
||||
|
||||
<button onClick={copyCode} style={styles.primaryBtn}>
|
||||
<button onClick={() => copyText(created?.code || "")} style={styles.primaryBtn}>
|
||||
⧉ Code kopieren
|
||||
</button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user