From 6acc7ecc1c7013a31f3471f32b2157be8ae39784 Mon Sep 17 00:00:00 2001 From: Stefan Date: Mon, 1 Dec 2025 11:49:12 +0100 Subject: [PATCH] Fix homepage layout and add Polish language support - Reorganize StartScreen: Start New Game button always visible at top - Move unfinished games section below the start button - Remove '2.' prefix from startGame translations (all languages) - Update startNewGame translations to be button-appropriate - Fix TypeScript errors: Update GameImportModal, GameAnalysisModal, and GameOverModal to use SupportedLanguage type instead of hardcoded language union - Delete local branches: codex/add-polish-as-ui-language and codex/add-option-to-continue-game-from-position --- src/components/GameAnalysisModal.tsx | 3 +- src/components/GameImportModal.tsx | 3 +- src/components/GameOverModal.tsx | 3 +- src/components/StartScreen.tsx | 42 ++++++++++++++-------------- src/lib/i18n/translations.ts | 20 ++++++------- 5 files changed, 37 insertions(+), 34 deletions(-) diff --git a/src/components/GameAnalysisModal.tsx b/src/components/GameAnalysisModal.tsx index 5592f18..cbce918 100644 --- a/src/components/GameAnalysisModal.tsx +++ b/src/components/GameAnalysisModal.tsx @@ -5,12 +5,13 @@ import { Stockfish, StockfishEvaluation } from "@/lib/stockfish"; import { OpeningMetadata, lookupOpening } from "@/lib/openings"; import { getGenAIModel } from "@/lib/gemini"; import { Loader2, X, Brain, Trophy, AlertTriangle } from "lucide-react"; +import { SupportedLanguage } from "@/lib/i18n/translations"; interface GameAnalysisModalProps { fen: string; stockfish: Stockfish | null; apiKey: string | null; - language: 'en' | 'de' | 'fr' | 'it'; + language: SupportedLanguage; onClose: () => void; } diff --git a/src/components/GameImportModal.tsx b/src/components/GameImportModal.tsx index 0b9961f..361a329 100644 --- a/src/components/GameImportModal.tsx +++ b/src/components/GameImportModal.tsx @@ -4,11 +4,12 @@ import { useState, useEffect } from "react"; import { Chessboard } from "react-chessboard"; import { X, Loader2, Download, ExternalLink } from "lucide-react"; import { fetchChessComGames, fetchLichessGames, GameMetadata, Platform } from "@/lib/gameImport"; +import { SupportedLanguage } from "@/lib/i18n/translations"; interface GameImportModalProps { onClose: () => void; onSelectGame: (pgn: string) => void; - language: 'en' | 'de' | 'fr' | 'it'; + language: SupportedLanguage; } export function GameImportModal({ onClose, onSelectGame, language }: GameImportModalProps) { diff --git a/src/components/GameOverModal.tsx b/src/components/GameOverModal.tsx index 9c4ed20..1a4896b 100644 --- a/src/components/GameOverModal.tsx +++ b/src/components/GameOverModal.tsx @@ -6,6 +6,7 @@ import { Loader2, X, Trophy, AlertTriangle, RefreshCw } from "lucide-react"; import { StockfishEvaluation } from "@/lib/stockfish"; import { DetectedTactic } from "@/lib/tacticDetection"; import ReactMarkdown from "react-markdown"; +import { SupportedLanguage } from "@/lib/i18n/translations"; export interface MoveHistoryItem { moveNumber: number; @@ -50,7 +51,7 @@ interface GameOverModalProps { winner: "White" | "Black" | "Draw"; history: MoveHistoryItem[]; apiKey: string | null; - language: 'en' | 'de' | 'fr' | 'it'; + language: SupportedLanguage; onClose: () => void; onNewGame: () => void; } diff --git a/src/components/StartScreen.tsx b/src/components/StartScreen.tsx index 4842a41..f90013c 100644 --- a/src/components/StartScreen.tsx +++ b/src/components/StartScreen.tsx @@ -85,11 +85,7 @@ export default function StartScreen({ onStartGame, onResumeGame, savedGames, onD return t.start.noEvaluation; }; - useEffect(() => { - if (!hasSavedGames) { - setShowNewGameOptions(true); - } - }, [hasSavedGames]); + if (!mounted) return null; @@ -118,18 +114,24 @@ export default function StartScreen({ onStartGame, onResumeGame, savedGames, onD
- {hasSavedGames && ( + {/* Start New Game Button - Always visible at top */} +
+ +
+ + {/* Unfinished Games Section */} + {hasSavedGames && !showNewGameOptions && (

{t.start.savedGamesTitle}

-
{sortedSavedGames.length === 0 && ( @@ -210,7 +212,7 @@ export default function StartScreen({ onStartGame, onResumeGame, savedGames, onD )} {/* New Game Options */} - {(!hasSavedGames || showNewGameOptions) && ( + {showNewGameOptions && (
{/* Color Selection */}
@@ -326,14 +328,12 @@ export default function StartScreen({ onStartGame, onResumeGame, savedGames, onD )}
- {hasSavedGames && ( - - )} +
)} diff --git a/src/lib/i18n/translations.ts b/src/lib/i18n/translations.ts index ccfc518..ac7f603 100644 --- a/src/lib/i18n/translations.ts +++ b/src/lib/i18n/translations.ts @@ -194,9 +194,9 @@ const en: Translations = { apiKey: 'Google Gemini API Key', apiKeyPlaceholder: 'AIzaSy...', getApiKey: 'Get free key', - startGame: '2. Start Game', + startGame: 'Start Game', resumeGame: 'Resume Previous Game', - startNewGame: 'Start New Game instead...', + startNewGame: 'Start New Game', chooseCoach: 'Choose Your Coach:', importPosition: 'Import Position or Game (FEN or PGN)', importPositionPlaceholder: 'Paste FEN position or PGN game here...', @@ -355,9 +355,9 @@ const de: Translations = { apiKey: 'Google Gemini API-Schlüssel', apiKeyPlaceholder: 'AIzaSy...', getApiKey: 'Kostenlosen Schlüssel erhalten', - startGame: '2. Spiel starten', + startGame: 'Spiel starten', resumeGame: 'Vorheriges Spiel fortsetzen', - startNewGame: 'Stattdessen neues Spiel starten...', + startNewGame: 'Neues Spiel starten', chooseCoach: 'Wähle deinen Trainer:', importPosition: 'Position oder Partie importieren (FEN oder PGN)', importPositionPlaceholder: 'FEN-Position oder PGN-Partie hier einfügen...', @@ -516,9 +516,9 @@ const fr: Translations = { apiKey: 'Clé API Google Gemini', apiKeyPlaceholder: 'AIzaSy...', getApiKey: 'Obtenir une clé gratuite', - startGame: '2. Démarrer la partie', + startGame: 'Démarrer la partie', resumeGame: 'Reprendre la partie précédente', - startNewGame: 'Démarrer une nouvelle partie...', + startNewGame: 'Démarrer une nouvelle partie', chooseCoach: 'Choisissez votre coach :', importPosition: 'Importer une position ou partie (FEN ou PGN)', importPositionPlaceholder: 'Collez une position FEN ou partie PGN ici...', @@ -677,9 +677,9 @@ const it: Translations = { apiKey: 'Chiave API Google Gemini', apiKeyPlaceholder: 'AIzaSy...', getApiKey: 'Ottieni chiave gratuita', - startGame: '2. Inizia partita', + startGame: 'Inizia partita', resumeGame: 'Riprendi partita precedente', - startNewGame: 'Inizia nuova partita...', + startNewGame: 'Inizia nuova partita', chooseCoach: 'Scegli il tuo allenatore:', importPosition: 'Importa posizione o partita (FEN o PGN)', importPositionPlaceholder: 'Incolla posizione FEN o partita PGN qui...', @@ -838,9 +838,9 @@ const pl: Translations = { apiKey: 'Klucz API Google Gemini', apiKeyPlaceholder: 'AIzaSy...', getApiKey: 'Zdobądź darmowy klucz', - startGame: '2. Rozpocznij grę', + startGame: 'Rozpocznij grę', resumeGame: 'Wznów poprzednią partię', - startNewGame: 'Zacznij nową partię...', + startNewGame: 'Rozpocznij nową partię', chooseCoach: 'Wybierz swojego trenera:', importPosition: 'Importuj pozycję lub partię (FEN lub PGN)', importPositionPlaceholder: 'Wklej tutaj pozycję FEN lub partię PGN...',