i18n files
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
# Dependencies
|
||||
node_modules
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Build output
|
||||
.next
|
||||
out
|
||||
dist
|
||||
build
|
||||
|
||||
# Testing
|
||||
coverage
|
||||
.nyc_output
|
||||
*.test.ts
|
||||
*.test.tsx
|
||||
*.spec.ts
|
||||
*.spec.tsx
|
||||
__tests__
|
||||
jest.config.ts
|
||||
jest.setup.ts
|
||||
|
||||
# Development files
|
||||
.git
|
||||
.gitignore
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
# IDE
|
||||
.vscode
|
||||
.idea
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
|
||||
# OS files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Documentation
|
||||
README.md
|
||||
screenshots
|
||||
*.md
|
||||
|
||||
# Docker
|
||||
Dockerfile
|
||||
.dockerignore
|
||||
docker-compose.yml
|
||||
|
||||
# Misc
|
||||
.eslintrc.json
|
||||
.prettierrc
|
||||
.editorconfig
|
||||
@@ -0,0 +1,433 @@
|
||||
export type SupportedLanguage = 'en' | 'de' | 'fr' | 'it';
|
||||
|
||||
export interface Translations {
|
||||
// Common
|
||||
common: {
|
||||
close: string;
|
||||
cancel: string;
|
||||
confirm: string;
|
||||
loading: string;
|
||||
error: string;
|
||||
};
|
||||
|
||||
// Header
|
||||
header: {
|
||||
tagline: string;
|
||||
buyMeABeer: string;
|
||||
github: string;
|
||||
};
|
||||
|
||||
// Start Screen
|
||||
start: {
|
||||
title: string;
|
||||
settings: string;
|
||||
language: string;
|
||||
apiKey: string;
|
||||
apiKeyPlaceholder: string;
|
||||
getApiKey: string;
|
||||
startGame: string;
|
||||
resumeGame: string;
|
||||
startNewGame: string;
|
||||
chooseCoach: string;
|
||||
importPosition: string;
|
||||
importPositionPlaceholder: string;
|
||||
apiKeyRequired: string;
|
||||
colorSelection: string;
|
||||
playAsWhite: string;
|
||||
playAsBlack: string;
|
||||
randomColor: string;
|
||||
};
|
||||
|
||||
// Game
|
||||
game: {
|
||||
playingAs: string;
|
||||
vs: string;
|
||||
backToMenu: string;
|
||||
stockfishStrength: string;
|
||||
depth: string;
|
||||
undoMove: string;
|
||||
gameHistory: string;
|
||||
analyze: string;
|
||||
noMovesYet: string;
|
||||
white: string;
|
||||
black: string;
|
||||
};
|
||||
|
||||
// Tutor
|
||||
tutor: {
|
||||
aiCoach: string;
|
||||
askCoach: string;
|
||||
hint: string;
|
||||
bestMove: string;
|
||||
};
|
||||
|
||||
// Game Over
|
||||
gameOver: {
|
||||
title: string;
|
||||
checkmate: string;
|
||||
youWon: string;
|
||||
youLost: string;
|
||||
draw: string;
|
||||
stalemate: string;
|
||||
mistakes: string;
|
||||
aiSummary: string;
|
||||
move: string;
|
||||
evalBefore: string;
|
||||
evalAfter: string;
|
||||
bestMove: string;
|
||||
newGame: string;
|
||||
};
|
||||
|
||||
// Analysis
|
||||
analysis: {
|
||||
title: string;
|
||||
currentPosition: string;
|
||||
evaluation: string;
|
||||
bestMove: string;
|
||||
aiAnalysis: string;
|
||||
};
|
||||
|
||||
// API Key Input
|
||||
apiKeyInput: {
|
||||
title: string;
|
||||
description: string;
|
||||
placeholder: string;
|
||||
submit: string;
|
||||
getKey: string;
|
||||
};
|
||||
}
|
||||
|
||||
const en: Translations = {
|
||||
common: {
|
||||
close: 'Close',
|
||||
cancel: 'Cancel',
|
||||
confirm: 'Confirm',
|
||||
loading: 'Loading...',
|
||||
error: 'Error',
|
||||
},
|
||||
header: {
|
||||
tagline: 'with Gemini & Stockfish',
|
||||
buyMeABeer: 'Buy Me a Beer',
|
||||
github: 'GitHub',
|
||||
},
|
||||
start: {
|
||||
title: 'Chess Tutor AI',
|
||||
settings: '1. Settings',
|
||||
language: 'Language',
|
||||
apiKey: 'Google Gemini API Key',
|
||||
apiKeyPlaceholder: 'AIzaSy...',
|
||||
getApiKey: 'Get free key',
|
||||
startGame: '2. Start Game',
|
||||
resumeGame: 'Resume Previous Game',
|
||||
startNewGame: 'Start New Game instead...',
|
||||
chooseCoach: 'Choose Your Coach:',
|
||||
importPosition: 'Import Position (Optional FEN)',
|
||||
importPositionPlaceholder: 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1',
|
||||
apiKeyRequired: 'Please enter a valid API Key to continue.',
|
||||
colorSelection: 'Choose Your Color:',
|
||||
playAsWhite: 'Play as White',
|
||||
playAsBlack: 'Play as Black',
|
||||
randomColor: 'Random',
|
||||
},
|
||||
game: {
|
||||
playingAs: 'Playing as',
|
||||
vs: 'vs',
|
||||
backToMenu: '← Back to Menu',
|
||||
stockfishStrength: 'Stockfish Strength',
|
||||
depth: 'Depth',
|
||||
undoMove: 'Undo Last Move',
|
||||
gameHistory: 'Game History',
|
||||
analyze: 'Analyze',
|
||||
noMovesYet: 'No moves yet.',
|
||||
white: 'White',
|
||||
black: 'Black',
|
||||
},
|
||||
tutor: {
|
||||
aiCoach: 'AI Coach',
|
||||
askCoach: 'Ask your coach...',
|
||||
hint: 'Hint',
|
||||
bestMove: 'Best Move',
|
||||
},
|
||||
gameOver: {
|
||||
title: 'Game Over',
|
||||
checkmate: 'Checkmate!',
|
||||
youWon: 'You won!',
|
||||
youLost: 'You lost.',
|
||||
draw: 'Draw!',
|
||||
stalemate: 'Stalemate!',
|
||||
mistakes: 'Your Mistakes',
|
||||
aiSummary: 'AI Summary',
|
||||
move: 'Move',
|
||||
evalBefore: 'Eval Before',
|
||||
evalAfter: 'Eval After',
|
||||
bestMove: 'Best Move',
|
||||
newGame: 'New Game',
|
||||
},
|
||||
analysis: {
|
||||
title: 'Position Analysis',
|
||||
currentPosition: 'Current Position',
|
||||
evaluation: 'Evaluation',
|
||||
bestMove: 'Best Move',
|
||||
aiAnalysis: 'AI Analysis',
|
||||
},
|
||||
apiKeyInput: {
|
||||
title: 'API Key Required',
|
||||
description: 'Please enter your Google Gemini API key to continue.',
|
||||
placeholder: 'Enter your API key...',
|
||||
submit: 'Submit',
|
||||
getKey: 'Get a free API key',
|
||||
},
|
||||
};
|
||||
|
||||
const de: Translations = {
|
||||
common: {
|
||||
close: 'Schließen',
|
||||
cancel: 'Abbrechen',
|
||||
confirm: 'Bestätigen',
|
||||
loading: 'Lädt...',
|
||||
error: 'Fehler',
|
||||
},
|
||||
header: {
|
||||
tagline: 'mit Gemini & Stockfish',
|
||||
buyMeABeer: 'Spendier mir ein Bier',
|
||||
github: 'GitHub',
|
||||
},
|
||||
start: {
|
||||
title: 'Chess Tutor AI',
|
||||
settings: '1. Einstellungen',
|
||||
language: 'Sprache',
|
||||
apiKey: 'Google Gemini API-Schlüssel',
|
||||
apiKeyPlaceholder: 'AIzaSy...',
|
||||
getApiKey: 'Kostenlosen Schlüssel erhalten',
|
||||
startGame: '2. Spiel starten',
|
||||
resumeGame: 'Vorheriges Spiel fortsetzen',
|
||||
startNewGame: 'Stattdessen neues Spiel starten...',
|
||||
chooseCoach: 'Wähle deinen Trainer:',
|
||||
importPosition: 'Position importieren (Optional FEN)',
|
||||
importPositionPlaceholder: 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1',
|
||||
apiKeyRequired: 'Bitte geben Sie einen gültigen API-Schlüssel ein, um fortzufahren.',
|
||||
colorSelection: 'Wähle deine Farbe:',
|
||||
playAsWhite: 'Als Weiß spielen',
|
||||
playAsBlack: 'Als Schwarz spielen',
|
||||
randomColor: 'Zufällig',
|
||||
},
|
||||
game: {
|
||||
playingAs: 'Spielst als',
|
||||
vs: 'gegen',
|
||||
backToMenu: '← Zurück zum Menü',
|
||||
stockfishStrength: 'Stockfish-Stärke',
|
||||
depth: 'Tiefe',
|
||||
undoMove: 'Letzten Zug rückgängig',
|
||||
gameHistory: 'Spielverlauf',
|
||||
analyze: 'Analysieren',
|
||||
noMovesYet: 'Noch keine Züge.',
|
||||
white: 'Weiß',
|
||||
black: 'Schwarz',
|
||||
},
|
||||
tutor: {
|
||||
aiCoach: 'KI-Trainer',
|
||||
askCoach: 'Frage deinen Trainer...',
|
||||
hint: 'Hinweis',
|
||||
bestMove: 'Bester Zug',
|
||||
},
|
||||
gameOver: {
|
||||
title: 'Spiel beendet',
|
||||
checkmate: 'Schachmatt!',
|
||||
youWon: 'Du hast gewonnen!',
|
||||
youLost: 'Du hast verloren.',
|
||||
draw: 'Remis!',
|
||||
stalemate: 'Patt!',
|
||||
mistakes: 'Deine Fehler',
|
||||
aiSummary: 'KI-Zusammenfassung',
|
||||
move: 'Zug',
|
||||
evalBefore: 'Bewertung vorher',
|
||||
evalAfter: 'Bewertung nachher',
|
||||
bestMove: 'Bester Zug',
|
||||
newGame: 'Neues Spiel',
|
||||
},
|
||||
analysis: {
|
||||
title: 'Stellungsanalyse',
|
||||
currentPosition: 'Aktuelle Stellung',
|
||||
evaluation: 'Bewertung',
|
||||
bestMove: 'Bester Zug',
|
||||
aiAnalysis: 'KI-Analyse',
|
||||
},
|
||||
apiKeyInput: {
|
||||
title: 'API-Schlüssel erforderlich',
|
||||
description: 'Bitte geben Sie Ihren Google Gemini API-Schlüssel ein, um fortzufahren.',
|
||||
placeholder: 'Geben Sie Ihren API-Schlüssel ein...',
|
||||
submit: 'Absenden',
|
||||
getKey: 'Kostenlosen API-Schlüssel erhalten',
|
||||
},
|
||||
};
|
||||
|
||||
const fr: Translations = {
|
||||
common: {
|
||||
close: 'Fermer',
|
||||
cancel: 'Annuler',
|
||||
confirm: 'Confirmer',
|
||||
loading: 'Chargement...',
|
||||
error: 'Erreur',
|
||||
},
|
||||
header: {
|
||||
tagline: 'avec Gemini & Stockfish',
|
||||
buyMeABeer: 'Offrez-moi une bière',
|
||||
github: 'GitHub',
|
||||
},
|
||||
start: {
|
||||
title: 'Chess Tutor AI',
|
||||
settings: '1. Paramètres',
|
||||
language: 'Langue',
|
||||
apiKey: 'Clé API Google Gemini',
|
||||
apiKeyPlaceholder: 'AIzaSy...',
|
||||
getApiKey: 'Obtenir une clé gratuite',
|
||||
startGame: '2. Démarrer la partie',
|
||||
resumeGame: 'Reprendre la partie précédente',
|
||||
startNewGame: 'Démarrer une nouvelle partie...',
|
||||
chooseCoach: 'Choisissez votre coach :',
|
||||
importPosition: 'Importer une position (FEN optionnel)',
|
||||
importPositionPlaceholder: 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1',
|
||||
apiKeyRequired: 'Veuillez entrer une clé API valide pour continuer.',
|
||||
colorSelection: 'Choisissez votre couleur :',
|
||||
playAsWhite: 'Jouer Blancs',
|
||||
playAsBlack: 'Jouer Noirs',
|
||||
randomColor: 'Aléatoire',
|
||||
},
|
||||
game: {
|
||||
playingAs: 'Jouant',
|
||||
vs: 'contre',
|
||||
backToMenu: '← Retour au menu',
|
||||
stockfishStrength: 'Force de Stockfish',
|
||||
depth: 'Profondeur',
|
||||
undoMove: 'Annuler le dernier coup',
|
||||
gameHistory: 'Historique de la partie',
|
||||
analyze: 'Analyser',
|
||||
noMovesYet: 'Aucun coup pour le moment.',
|
||||
white: 'Blancs',
|
||||
black: 'Noirs',
|
||||
},
|
||||
tutor: {
|
||||
aiCoach: 'Coach IA',
|
||||
askCoach: 'Demandez à votre coach...',
|
||||
hint: 'Indice',
|
||||
bestMove: 'Meilleur coup',
|
||||
},
|
||||
gameOver: {
|
||||
title: 'Partie terminée',
|
||||
checkmate: 'Échec et mat !',
|
||||
youWon: 'Vous avez gagné !',
|
||||
youLost: 'Vous avez perdu.',
|
||||
draw: 'Nulle !',
|
||||
stalemate: 'Pat !',
|
||||
mistakes: 'Vos erreurs',
|
||||
aiSummary: 'Résumé IA',
|
||||
move: 'Coup',
|
||||
evalBefore: 'Éval. avant',
|
||||
evalAfter: 'Éval. après',
|
||||
bestMove: 'Meilleur coup',
|
||||
newGame: 'Nouvelle partie',
|
||||
},
|
||||
analysis: {
|
||||
title: 'Analyse de position',
|
||||
currentPosition: 'Position actuelle',
|
||||
evaluation: 'Évaluation',
|
||||
bestMove: 'Meilleur coup',
|
||||
aiAnalysis: 'Analyse IA',
|
||||
},
|
||||
apiKeyInput: {
|
||||
title: 'Clé API requise',
|
||||
description: 'Veuillez entrer votre clé API Google Gemini pour continuer.',
|
||||
placeholder: 'Entrez votre clé API...',
|
||||
submit: 'Soumettre',
|
||||
getKey: 'Obtenir une clé API gratuite',
|
||||
},
|
||||
};
|
||||
|
||||
const it: Translations = {
|
||||
common: {
|
||||
close: 'Chiudi',
|
||||
cancel: 'Annulla',
|
||||
confirm: 'Conferma',
|
||||
loading: 'Caricamento...',
|
||||
error: 'Errore',
|
||||
},
|
||||
header: {
|
||||
tagline: 'con Gemini & Stockfish',
|
||||
buyMeABeer: 'Offrimi una birra',
|
||||
github: 'GitHub',
|
||||
},
|
||||
start: {
|
||||
title: 'Chess Tutor AI',
|
||||
settings: '1. Impostazioni',
|
||||
language: 'Lingua',
|
||||
apiKey: 'Chiave API Google Gemini',
|
||||
apiKeyPlaceholder: 'AIzaSy...',
|
||||
getApiKey: 'Ottieni chiave gratuita',
|
||||
startGame: '2. Inizia partita',
|
||||
resumeGame: 'Riprendi partita precedente',
|
||||
startNewGame: 'Inizia nuova partita...',
|
||||
chooseCoach: 'Scegli il tuo allenatore:',
|
||||
importPosition: 'Importa posizione (FEN opzionale)',
|
||||
importPositionPlaceholder: 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1',
|
||||
apiKeyRequired: 'Inserisci una chiave API valida per continuare.',
|
||||
colorSelection: 'Scegli il tuo colore:',
|
||||
playAsWhite: 'Gioca Bianco',
|
||||
playAsBlack: 'Gioca Nero',
|
||||
randomColor: 'Casuale',
|
||||
},
|
||||
game: {
|
||||
playingAs: 'Giocando',
|
||||
vs: 'contro',
|
||||
backToMenu: '← Torna al menu',
|
||||
stockfishStrength: 'Forza di Stockfish',
|
||||
depth: 'Profondità',
|
||||
undoMove: 'Annulla ultima mossa',
|
||||
gameHistory: 'Cronologia partita',
|
||||
analyze: 'Analizza',
|
||||
noMovesYet: 'Nessuna mossa ancora.',
|
||||
white: 'Bianco',
|
||||
black: 'Nero',
|
||||
},
|
||||
tutor: {
|
||||
aiCoach: 'Allenatore IA',
|
||||
askCoach: 'Chiedi al tuo allenatore...',
|
||||
hint: 'Suggerimento',
|
||||
bestMove: 'Mossa migliore',
|
||||
},
|
||||
gameOver: {
|
||||
title: 'Partita terminata',
|
||||
checkmate: 'Scacco matto!',
|
||||
youWon: 'Hai vinto!',
|
||||
youLost: 'Hai perso.',
|
||||
draw: 'Patta!',
|
||||
stalemate: 'Stallo!',
|
||||
mistakes: 'I tuoi errori',
|
||||
aiSummary: 'Riepilogo IA',
|
||||
move: 'Mossa',
|
||||
evalBefore: 'Val. prima',
|
||||
evalAfter: 'Val. dopo',
|
||||
bestMove: 'Mossa migliore',
|
||||
newGame: 'Nuova partita',
|
||||
},
|
||||
analysis: {
|
||||
title: 'Analisi posizione',
|
||||
currentPosition: 'Posizione attuale',
|
||||
evaluation: 'Valutazione',
|
||||
bestMove: 'Mossa migliore',
|
||||
aiAnalysis: 'Analisi IA',
|
||||
},
|
||||
apiKeyInput: {
|
||||
title: 'Chiave API richiesta',
|
||||
description: 'Inserisci la tua chiave API Google Gemini per continuare.',
|
||||
placeholder: 'Inserisci la tua chiave API...',
|
||||
submit: 'Invia',
|
||||
getKey: 'Ottieni chiave API gratuita',
|
||||
},
|
||||
};
|
||||
|
||||
export const translations: Record<SupportedLanguage, Translations> = {
|
||||
en,
|
||||
de,
|
||||
fr,
|
||||
it,
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
import { SupportedLanguage, translations, Translations } from './translations';
|
||||
|
||||
export function useTranslation(language: SupportedLanguage): Translations {
|
||||
return translations[language] || translations.en;
|
||||
}
|
||||
|
||||
export function getTranslation(language: SupportedLanguage, key: string): string {
|
||||
const t = useTranslation(language);
|
||||
const keys = key.split('.');
|
||||
let value: any = t;
|
||||
|
||||
for (const k of keys) {
|
||||
value = value?.[k];
|
||||
}
|
||||
|
||||
return value || key;
|
||||
}
|
||||
Reference in New Issue
Block a user