translations
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import React from 'react';
|
||||
import Link from 'next/link';
|
||||
import { useTranslation } from '@/lib/i18n/useTranslation';
|
||||
import { SupportedLanguage } from '@/lib/i18n/translations';
|
||||
|
||||
@@ -14,7 +15,7 @@ export default function Header({ language }: HeaderProps) {
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="flex items-center justify-between h-16">
|
||||
{/* App Title/Branding */}
|
||||
<div className="flex items-center space-x-3">
|
||||
<Link href="/" className="flex items-center space-x-3 hover:opacity-80 transition-opacity cursor-pointer">
|
||||
<div className="text-2xl">♞</div>
|
||||
<h1 className="text-xl font-semibold text-gray-900 dark:text-white">
|
||||
Chess Tutor
|
||||
@@ -22,7 +23,7 @@ export default function Header({ language }: HeaderProps) {
|
||||
<span className="hidden sm:inline-block text-sm text-gray-500 dark:text-gray-400">
|
||||
{t.header.tagline}
|
||||
</span>
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
{/* Action Buttons */}
|
||||
<div className="flex items-center space-x-3">
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
'use client';
|
||||
|
||||
import { useTranslation } from '@/lib/i18n/useTranslation';
|
||||
import { SupportedLanguage } from '@/lib/i18n/translations';
|
||||
|
||||
interface DeviationDialogProps {
|
||||
openingName: string;
|
||||
movesCompleted: number;
|
||||
onUndo: () => void;
|
||||
onStartGame: () => void;
|
||||
onContinueExploring?: () => void;
|
||||
language: SupportedLanguage;
|
||||
}
|
||||
|
||||
export default function DeviationDialog({
|
||||
@@ -14,18 +18,20 @@ export default function DeviationDialog({
|
||||
onUndo,
|
||||
onStartGame,
|
||||
onContinueExploring,
|
||||
language,
|
||||
}: DeviationDialogProps) {
|
||||
const t = useTranslation(language);
|
||||
return (
|
||||
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
|
||||
<div className="bg-white dark:bg-gray-800 rounded-lg shadow-xl p-8 max-w-md mx-4">
|
||||
<div className="text-center mb-6">
|
||||
<div className="text-4xl mb-4">🤔</div>
|
||||
<h2 className="text-2xl font-bold text-gray-900 dark:text-white mb-2">
|
||||
You've Left the Opening!
|
||||
{t.learning.openingTrainer.deviationTitle}
|
||||
</h2>
|
||||
<p className="text-gray-600 dark:text-gray-400">
|
||||
You've studied <span className="font-semibold">{movesCompleted}</span> move
|
||||
{movesCompleted !== 1 ? 's' : ''} of the{' '}
|
||||
{t.learning.openingTrainer.deviationMessage} <span className="font-semibold">{movesCompleted}</span>{' '}
|
||||
{movesCompleted !== 1 ? t.learning.openingTrainer.moves : t.learning.openingTrainer.move} of the{' '}
|
||||
<span className="font-semibold">{openingName}</span>.
|
||||
</p>
|
||||
<p className="text-gray-600 dark:text-gray-400 mt-2">
|
||||
@@ -40,7 +46,7 @@ export default function DeviationDialog({
|
||||
className="w-full px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 font-medium transition-colors flex items-center justify-center gap-2"
|
||||
>
|
||||
<span>♟️</span>
|
||||
<span>Continue Playing (Start Game)</span>
|
||||
<span>{t.learning.openingTrainer.continuePlayingButton}</span>
|
||||
</button>
|
||||
|
||||
{/* Secondary action: Undo */}
|
||||
@@ -49,7 +55,7 @@ export default function DeviationDialog({
|
||||
className="w-full px-6 py-3 bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300 rounded-lg hover:bg-gray-300 dark:hover:bg-gray-600 font-medium transition-colors flex items-center justify-center gap-2"
|
||||
>
|
||||
<span>↩️</span>
|
||||
<span>Undo & Return to Opening</span>
|
||||
<span>{t.learning.openingTrainer.undoReturnButton}</span>
|
||||
</button>
|
||||
|
||||
{/* Optional: Continue exploring */}
|
||||
@@ -59,13 +65,13 @@ export default function DeviationDialog({
|
||||
className="w-full px-6 py-3 bg-gray-100 dark:bg-gray-800 text-gray-600 dark:text-gray-400 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-700 font-medium transition-colors border border-gray-300 dark:border-gray-600 flex items-center justify-center gap-2"
|
||||
>
|
||||
<span>🔍</span>
|
||||
<span>Explore This Variation</span>
|
||||
<span>{t.learning.openingTrainer.exploreVariationButton}</span>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<p className="text-xs text-gray-500 dark:text-gray-500 mt-4 text-center">
|
||||
Tip: You can always navigate back using the move history
|
||||
{t.learning.openingTrainer.deviationTip}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -559,6 +559,7 @@ export default function OpeningTrainer({ opening, personality, apiKey, language
|
||||
<WikipediaSummary
|
||||
openingName={opening.name}
|
||||
wikipediaSlug={opening.wikipediaSlug}
|
||||
language={language}
|
||||
/>
|
||||
|
||||
{/* Session info */}
|
||||
@@ -589,6 +590,7 @@ export default function OpeningTrainer({ opening, personality, apiKey, language
|
||||
onUndo={handleUndoDeviation}
|
||||
onStartGame={handleStartGameFromPosition}
|
||||
onContinueExploring={handleContinueExploring}
|
||||
language={language}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -3,16 +3,20 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { WikipediaSummary as WikipediaSummaryType } from '@/types/openingTraining';
|
||||
import { getWikipediaSummary } from '@/lib/openingTrainer/wikipediaService';
|
||||
import { useTranslation } from '@/lib/i18n/useTranslation';
|
||||
import { SupportedLanguage } from '@/lib/i18n/translations';
|
||||
|
||||
interface WikipediaSummaryProps {
|
||||
openingName: string;
|
||||
wikipediaSlug?: string; // Preferred: direct slug from database
|
||||
language: SupportedLanguage;
|
||||
}
|
||||
|
||||
export default function WikipediaSummary({ openingName, wikipediaSlug }: WikipediaSummaryProps) {
|
||||
export default function WikipediaSummary({ openingName, wikipediaSlug, language }: WikipediaSummaryProps) {
|
||||
const [summary, setSummary] = useState<WikipediaSummaryType | null>(null);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const t = useTranslation(language);
|
||||
|
||||
useEffect(() => {
|
||||
fetchSummary();
|
||||
@@ -46,7 +50,7 @@ export default function WikipediaSummary({ openingName, wikipediaSlug }: Wikiped
|
||||
<div className="bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg p-4">
|
||||
<div className="flex items-center space-x-2">
|
||||
<div className="w-4 h-4 border-2 border-blue-600 dark:border-blue-400 border-t-transparent rounded-full animate-spin"></div>
|
||||
<p className="text-sm text-blue-800 dark:text-blue-300">Loading opening background...</p>
|
||||
<p className="text-sm text-blue-800 dark:text-blue-300">{t.learning.openingTrainer.loadingBackground}</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -56,7 +60,7 @@ export default function WikipediaSummary({ openingName, wikipediaSlug }: Wikiped
|
||||
return (
|
||||
<div className="bg-gray-50 dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg p-4">
|
||||
<p className="text-sm text-gray-600 dark:text-gray-400">
|
||||
No background information available for this opening.
|
||||
{t.learning.openingTrainer.noBackgroundInfo}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
@@ -77,7 +81,7 @@ export default function WikipediaSummary({ openingName, wikipediaSlug }: Wikiped
|
||||
</div>
|
||||
<p className="text-sm text-gray-700 dark:text-gray-300 leading-relaxed">{summary.extract}</p>
|
||||
<p className="text-xs text-gray-500 dark:text-gray-400">
|
||||
Source: Wikipedia (cached {new Date(summary.fetchedAt).toLocaleDateString()})
|
||||
{t.learning.openingTrainer.wikipediaSource} {new Date(summary.fetchedAt).toLocaleDateString()})
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user