diff --git a/backend/src/tools/schocken/routes.js b/backend/src/tools/schocken/routes.js index d5a2719..ecb00a9 100644 --- a/backend/src/tools/schocken/routes.js +++ b/backend/src/tools/schocken/routes.js @@ -102,7 +102,15 @@ function sendPush(userId, title, message) { }).catch(() => {}); } -const uid = req => req.user.id; +const uid = req => { + // Testmodus: Admin kann als anderen User agieren + const testAs = req.headers['x-schocken-test-as']; + if (testAs && req.user?.role === 'admin') { + const testId = parseInt(testAs); + if (!isNaN(testId)) return testId; + } + return req.user.id; +}; // ── Alle Spiele des Users ───────────────────────────────────────────────────── router.get('/', authenticate, (req, res) => { diff --git a/frontend/src/tools/schocken.jsx b/frontend/src/tools/schocken.jsx index 15508c5..78e4275 100644 --- a/frontend/src/tools/schocken.jsx +++ b/frontend/src/tools/schocken.jsx @@ -1,6 +1,20 @@ import { useState, useEffect, useCallback } from 'react'; import { api, S } from '../lib.js'; +// Testmodus: API-Call als anderer User (nur Admin, nur Schocken) +async function apiAs(userId, path, opts = {}) { + const token = localStorage.getItem('sk_token'); + const headers = { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` }; + if (userId) headers['X-Schocken-Test-As'] = String(userId); + const res = await fetch(`/api${path}`, { + method: opts.method || (opts.body ? 'POST' : 'GET'), + headers, + body: opts.body ? JSON.stringify(opts.body) : undefined, + }); + if (!res.ok) { const e = await res.json().catch(()=>({error:'Fehler'})); throw new Error(e.error||'Fehler'); } + return res.json(); +} + const MY_COLOR = '#4ecdc4'; function getMyId() { @@ -441,7 +455,7 @@ function GameList({ games, myId, onSelect, onNew }) { } // ── Spielansicht ────────────────────────────────────────────────────────────── -function GameView({ game, myId, onRefresh, toast }) { +function GameView({ game, myId, onRefresh, toast, isAdmin=false, onSeatChange }) { const players = game.players; const chips = game.player_chips; const dl = game.drink_losses; @@ -483,6 +497,21 @@ function GameView({ game, myId, onRefresh, toast }) { Runde {game.round_number} + {/* Testmodus-Switcher (nur Admin) */} + {isAdmin && ( +
+
🧪 TESTMODUS — SPIELER WECHSELN
+
+ {players.map(p => ( + + ))} +
+
+ )} + {/* Schockstock */} @@ -544,8 +573,12 @@ export default function Schocken({ toast }) { const [game, setGame] = useState(null); const [showNew, setShowNew] = useState(false); const [loading, setLoading] = useState(true); + const [testSeat, setTestSeat] = useState(null); // null = eigener Account, sonst userId - const myId = getMyId(); + const myRealId = getMyId(); + const isAdmin = getMyRole() === 'admin'; + // Im Testmodus: als anderen Spieler agieren + const myId = (isAdmin && testSeat) ? testSeat : myRealId; const loadGames = useCallback(async () => { try { setGames(await api('/tools/schocken')); } @@ -585,7 +618,7 @@ export default function Schocken({ toast }) { {!activeId ? setShowNew(true)}/> : game && myId - ? + ? {setTestSeat(id);}} /> :
Lade…
}