Branding & Code Refresh: Reverted to image assets (logo.png/bg.png) and applied consistent formatting

This commit is contained in:
2026-04-16 18:39:32 +02:00
parent fe3c45b8bf
commit 34153c3c15
6 changed files with 44 additions and 107 deletions
+24 -71
View File
@@ -21,71 +21,33 @@ function PresentApp() {
useEffect(() => {
const code = location.hash.replace('#', '');
const params = new URLSearchParams(location.search);
// Accept both ?pt= (present token) and ?token= (legacy/admin password)
const token = params.get('pt') || params.get('token');
if (!code || !token) {
setPhase('need-config');
return;
}
if (!code || !token) { setPhase('need-config'); return; }
const ws = new WebSocket(wsUrl());
ws.onopen = () => {
ws.send(JSON.stringify({ type: 'present-join', token, code }));
};
ws.onopen = () => { ws.send(JSON.stringify({ type: 'present-join', token, code })); };
ws.onmessage = (e) => {
const msg = JSON.parse(e.data);
switch (msg.type) {
case 'present-joined':
setSession(msg.session);
setLeaderboard(msg.session.leaderboard || []);
setPhase('waiting');
break;
case 'player-joined':
case 'player-left':
setSession((s) => s ? { ...s, players: msg.players, playerCount: msg.playerCount } : s);
break;
case 'game-start':
setQTotal(msg.totalQuestions);
break;
case 'present-joined': setSession(msg.session); setLeaderboard(msg.session.leaderboard || []); setPhase('waiting'); break;
case 'player-joined': case 'player-left':
setSession((s) => s ? { ...s, players: msg.players, playerCount: msg.playerCount } : s); break;
case 'game-start': setQTotal(msg.totalQuestions); break;
case 'question':
setQuestion(msg.question);
setQIndex(msg.index);
setQTotal(msg.total);
setTimeLimit(msg.timeLimit);
setTimeLeft(msg.timeLimit);
setAnswerCount(0);
setResult(null);
setPhase('question');
break;
case 'answer-count':
setAnswerCount(msg.count);
break;
case 'time-up':
clearInterval(timerRef.current);
break;
setQuestion(msg.question); setQIndex(msg.index); setQTotal(msg.total);
setTimeLimit(msg.timeLimit); setTimeLeft(msg.timeLimit);
setAnswerCount(0); setResult(null); setPhase('question'); break;
case 'answer-count': setAnswerCount(msg.count); break;
case 'time-up': clearInterval(timerRef.current); break;
case 'question-result':
setResult(msg);
setLeaderboard(msg.leaderboard);
setPhase('result');
clearInterval(timerRef.current);
break;
setResult(msg); setLeaderboard(msg.leaderboard); setPhase('result'); clearInterval(timerRef.current); break;
case 'game-end':
setLeaderboard(msg.leaderboard);
setPhase('final');
clearInterval(timerRef.current);
break;
case 'error':
setError(msg.message);
setPhase('error');
break;
setLeaderboard(msg.leaderboard); setPhase('final'); clearInterval(timerRef.current); break;
case 'error': setError(msg.message); setPhase('error'); break;
}
};
ws.onerror = () => setPhase('error');
return () => ws.close();
}, []);
@@ -99,15 +61,13 @@ function PresentApp() {
}
}, [phase, timeLimit]);
if (phase === 'need-config') {
return (
<div className="min-h-screen flex flex-col items-center justify-center p-8">
<div className="text-6xl mb-4">🚨</div>
<h1 className="text-3xl font-bold mb-4 fire-gradient">Quizalarm Präsentation</h1>
<p className="text-gray-400 mb-4 text-center">Öffne diesen Link aus dem Admin-Panel.</p>
</div>
);
}
if (phase === 'need-config') return (
<div className="min-h-screen flex flex-col items-center justify-center p-8">
<img src="/img/logo.png" alt="Quizalarm" className="w-24 h-24 mb-4" />
<h1 className="text-3xl font-bold mb-4 fire-gradient">Quizalarm Präsentation</h1>
<p className="text-gray-400 mb-4 text-center">Öffne diesen Link aus dem Admin-Panel.</p>
</div>
);
if (phase === 'error') return (
<div className="min-h-screen flex flex-col items-center justify-center text-red-400 text-3xl">
@@ -120,7 +80,7 @@ function PresentApp() {
if (phase === 'waiting') return (
<div className="min-h-screen flex flex-col items-center justify-center p-8">
<div className="text-6xl mb-4">🚨</div>
<img src="/img/logo.png" alt="Quizalarm" className="w-24 h-24 mb-4" />
<h1 className="text-4xl font-extrabold mb-4 fire-gradient">Quizalarm</h1>
<p className="text-gray-400 text-xl mb-6">{session?.setName}</p>
<div className="text-8xl font-mono font-extrabold tracking-widest text-red-500 mb-8">{session?.code}</div>
@@ -155,9 +115,7 @@ function PresentApp() {
{(question?.antworten || []).map((a) => {
const colors = { A: 'bg-red-600', B: 'bg-blue-600', C: 'bg-amber-600', D: 'bg-green-600' };
return (
<div key={a.key} className={`${colors[a.key] || 'bg-gray-600'} rounded-2xl flex items-center justify-center p-6 text-2xl font-bold`}>
{a.text}
</div>
<div key={a.key} className={`${colors[a.key] || 'bg-gray-600'} rounded-2xl flex items-center justify-center p-6 text-2xl font-bold`}>{a.text}</div>
);
})}
</div>
@@ -176,7 +134,6 @@ function PresentApp() {
<h2 className="text-2xl text-gray-400 text-center mb-2">Frage {qIndex + 1} / {qTotal}</h2>
<h2 className="text-3xl font-bold text-center mb-6">{question?.frage}</h2>
{question?.bild && <img src={question.bild} className="max-h-48 mx-auto rounded-xl mb-6" alt="" />}
{question?.typ?.toLowerCase() !== 'freitext' && (
<div className="grid grid-cols-2 gap-4 mb-8">
{(question?.antworten || []).map((a) => {
@@ -192,15 +149,11 @@ function PresentApp() {
})}
</div>
)}
{question?.typ?.toLowerCase() === 'freitext' && (
<div className="text-center mb-8">
<div className="inline-block bg-green-600 ring-4 ring-green-400 rounded-2xl px-8 py-4 text-2xl font-bold">
{result?.correctAnswer?.[0]}
</div>
<div className="inline-block bg-green-600 ring-4 ring-green-400 rounded-2xl px-8 py-4 text-2xl font-bold"> {result?.correctAnswer?.[0]}</div>
</div>
)}
<div className="flex-1">
<h3 className="text-2xl font-bold text-center mb-4">🏆 Leaderboard</h3>
<div className="max-w-xl mx-auto">