import { useEffect, useState } from 'react';
import { Link, useNavigate, useParams } from 'react-router-dom';
import { api } from '../lib/api.js';
import { getAccess, setAccess, setPlayerToken } from '../lib/session.js';
function useCode() {
const { code } = useParams();
const [info, setInfo] = useState(null);
const [error, setError] = useState(null);
useEffect(() => {
api('/access', { method: 'POST', body: { code } }).then(setInfo).catch((e) => setError(e.message));
}, [code]);
return { code, info, error };
}
function alreadyPlayer(access) {
if (!access) return false;
if (access.kind === 'organizer') return Boolean(access.playerToken);
return access.kind === 'player';
}
export function JoinPage() {
const { code, info, error } = useCode();
const navigate = useNavigate();
const [nickname, setNickname] = useState('');
const [steamId, setSteamId] = useState('');
const [submitError, setSubmitError] = useState(null);
const [busy, setBusy] = useState(false);
useEffect(() => {
if (!info) return;
if (info.access === 'spectator') navigate(`/watch/${code}`, { replace: true });
// Schon als Spieler dabei? Dann direkt zur Lobby. Organisator ohne Team und Zuschauer dürfen beitreten.
else if (alreadyPlayer(getAccess(info.matchId))) navigate(`/m/${info.matchId}`, { replace: true });
}, [info, code, navigate]);
if (error) return
Prüfe Code …
; const submit = async (e) => { e.preventDefault(); setBusy(true); setSubmitError(null); try { const res = await api(`/matches/${info.matchId}/join`, { method: 'POST', body: { code, nickname, steamId } }); const existing = getAccess(info.matchId); // Der Organisator behält seinen Zugang und bekommt den Spieler-Zugang dazu. if (existing?.kind === 'organizer') setPlayerToken(info.matchId, res.playerToken); else setAccess(info.matchId, { token: res.playerToken, kind: 'player' }); navigate(`/m/${info.matchId}`); } catch (err) { setSubmitError(err.message); setBusy(false); } }; return ( ); } export function WatchPage() { const { code, info, error } = useCode(); const navigate = useNavigate(); useEffect(() => { if (!info) return; if (info.access !== 'spectator') { navigate(`/join/${code}`, { replace: true }); return; } // Spieler oder Organisator behalten ihren stärkeren Zugang. if (!getAccess(info.matchId)) setAccess(info.matchId, { token: code, kind: 'spectator' }); navigate(`/m/${info.matchId}`, { replace: true }); }, [info, code, navigate]); if (error) returnÖffne Zuschauerzugang …
; } function AccessError({ message }) { return ({message}. Prüfe den Link oder frag den Organisator nach einem neuen Code.
Zur Übersicht