lila/apps/web/src/components/game/GameSetup.tsx
lila 3f7bc4111e chore: rename project from glossa to lila
- Update all package names from @glossa/* to @lila/*
- Update all imports, container names, volume names
- Update documentation references
- Recreate database with new credentials
2026-04-13 10:00:52 +02:00

140 lines
3.9 KiB
TypeScript

import { useState } from "react";
import {
SUPPORTED_LANGUAGE_CODES,
SUPPORTED_POS,
DIFFICULTY_LEVELS,
GAME_ROUNDS,
} from "@lila/shared";
import type { GameRequest } from "@lila/shared";
const LABELS: Record<string, string> = {
en: "English",
it: "Italian",
noun: "Nouns",
verb: "Verbs",
easy: "Easy",
intermediate: "Intermediate",
hard: "Hard",
"3": "3 rounds",
"10": "10 rounds",
};
type GameSetupProps = { onStart: (settings: GameRequest) => void };
type SettingGroupProps = {
label: string;
options: readonly string[];
selected: string;
onSelect: (value: string) => void;
};
const SettingGroup = ({
label,
options,
selected,
onSelect,
}: SettingGroupProps) => (
<div className="w-full">
<p className="text-sm font-medium text-purple-400 mb-2">{label}</p>
<div className="flex gap-2 flex-wrap">
{options.map((option) => (
<button
key={option}
onClick={() => onSelect(option)}
className={`py-2 px-5 rounded-xl font-semibold text-sm border-b-4 transition-all duration-200 cursor-pointer ${
selected === option
? "bg-purple-600 text-white border-purple-800"
: "bg-white text-purple-900 border-purple-200 hover:bg-purple-50 hover:border-purple-300"
}`}
>
{LABELS[option] ?? option}
</button>
))}
</div>
</div>
);
export const GameSetup = ({ onStart }: GameSetupProps) => {
const [sourceLanguage, setSourceLanguage] = useState<string>(
SUPPORTED_LANGUAGE_CODES[0],
);
const [targetLanguage, setTargetLanguage] = useState<string>(
SUPPORTED_LANGUAGE_CODES[1],
);
const [pos, setPos] = useState<string>(SUPPORTED_POS[0]);
const [difficulty, setDifficulty] = useState<string>(DIFFICULTY_LEVELS[0]);
const [rounds, setRounds] = useState<string>(GAME_ROUNDS[0]);
const handleSourceLanguage = (value: string) => {
if (value === targetLanguage) {
setTargetLanguage(sourceLanguage);
}
setSourceLanguage(value);
};
const handleTargetLanguage = (value: string) => {
if (value === sourceLanguage) {
setSourceLanguage(targetLanguage);
}
setTargetLanguage(value);
};
const handleStart = () => {
onStart({
source_language: sourceLanguage,
target_language: targetLanguage,
pos,
difficulty,
rounds,
} as GameRequest);
};
return (
<div className="flex flex-col items-center gap-6 w-full max-w-md mx-auto">
<div className="bg-white rounded-3xl shadow-lg p-8 w-full text-center">
<h1 className="text-3xl font-bold text-purple-900 mb-1">lila</h1>
<p className="text-sm text-gray-400">Set up your quiz</p>
</div>
<div className="bg-white rounded-3xl shadow-lg p-6 w-full flex flex-col gap-5">
<SettingGroup
label="I speak"
options={SUPPORTED_LANGUAGE_CODES}
selected={sourceLanguage}
onSelect={handleSourceLanguage}
/>
<SettingGroup
label="I want to learn"
options={SUPPORTED_LANGUAGE_CODES}
selected={targetLanguage}
onSelect={handleTargetLanguage}
/>
<SettingGroup
label="Word type"
options={SUPPORTED_POS}
selected={pos}
onSelect={setPos}
/>
<SettingGroup
label="Difficulty"
options={DIFFICULTY_LEVELS}
selected={difficulty}
onSelect={setDifficulty}
/>
<SettingGroup
label="Rounds"
options={GAME_ROUNDS}
selected={rounds}
onSelect={setRounds}
/>
</div>
<button
onClick={handleStart}
className="w-full py-4 rounded-2xl text-xl font-bold bg-linear-to-r from-pink-400 to-purple-500 text-white border-b-4 border-purple-700 hover:-translate-y-0.5 active:translate-y-0 active:border-b-2 transition-all duration-200 cursor-pointer"
>
Start Quiz
</button>
</div>
);
};