refactoring ui into separate components, updating ui, adding color scheme

This commit is contained in:
lila 2026-04-11 20:53:10 +02:00
parent ea33b7fcc8
commit b7b1cd383f
4 changed files with 184 additions and 55 deletions

View file

@ -1,6 +1,8 @@
import { createFileRoute } from "@tanstack/react-router";
import { useState, useEffect } from "react";
import type { GameSession, AnswerResult } from "@glossa/shared";
import { QuestionCard } from "../components/game/QuestionCard";
import { ScoreScreen } from "../components/game/ScoreScreen";
const GAME_SETTINGS = {
source_language: "en",
@ -16,16 +18,20 @@ function Play() {
const [results, setResults] = useState<AnswerResult[]>([]);
const [currentResult, setCurrentResult] = useState<AnswerResult | null>(null);
const startGame = async () => {
const response = await fetch("/api/v1/game/start", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(GAME_SETTINGS),
});
const data = await response.json();
setGameSession(data.data);
setCurrentQuestionIndex(0);
setResults([]);
setCurrentResult(null);
};
useEffect(() => {
const startGame = async () => {
const response = await fetch("/api/v1/game/start", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(GAME_SETTINGS),
});
const data = await response.json();
setGameSession(data.data);
};
startGame();
}, []);
@ -57,18 +63,18 @@ function Play() {
// Phase: loading
if (!gameSession) {
return <p>Loading...</p>;
return (
<div className="min-h-screen bg-linear-to-b from-purple-100 to-pink-50 flex items-center justify-center">
<p className="text-purple-400 text-lg font-medium">Loading...</p>
</div>
);
}
// Phase: finished
if (currentQuestionIndex >= gameSession.questions.length) {
const score = results.filter((r) => r.isCorrect).length;
return (
<div>
<h2>
{score} / {results.length}
</h2>
<p>Game over!</p>
<div className="min-h-screen bg-linear-to-b from-purple-100 to-pink-50 flex items-center justify-center p-6">
<ScoreScreen results={results} onPlayAgain={startGame} />
</div>
);
}
@ -77,45 +83,15 @@ function Play() {
const question = gameSession.questions[currentQuestionIndex]!;
return (
<div>
<p>
Question {currentQuestionIndex + 1} / {gameSession.questions.length}
</p>
<h2>{question.prompt}</h2>
{question.gloss && <p>{question.gloss}</p>}
<div>
{question.options.map((option) => {
let style = {};
if (currentResult) {
if (option.optionId === currentResult.correctOptionId) {
style = { backgroundColor: "green", color: "white" };
} else if (option.optionId === currentResult.selectedOptionId) {
style = { backgroundColor: "red", color: "white" };
}
}
return (
<button
key={option.optionId}
onClick={() => handleAnswer(option.optionId)}
disabled={!!currentResult}
style={{
display: "block",
margin: "4px 0",
padding: "8px 16px",
...style,
}}
>
{option.text}
</button>
);
})}
</div>
{currentResult && (
<button onClick={handleNext} style={{ marginTop: "16px" }}>
Next
</button>
)}
<div className="min-h-screen bg-linear-to-b from-purple-100 to-pink-50 flex items-center justify-center p-6">
<QuestionCard
question={question}
questionNumber={currentQuestionIndex + 1}
totalQuestions={gameSession.questions.length}
currentResult={currentResult}
onAnswer={handleAnswer}
onNext={handleNext}
/>
</div>
);
}