feat: implement comprehensive i18n system with German and English support
- Created type-safe i18n system with TranslationKeys interface - Added German (de) and English (en) translations with 160+ keys - Implemented I18nContext provider and useI18n hook - Added LanguageSwitcher component for language selection - Refactored all major components to use translations: * Home page, StatsDashboard, DramOfTheDay * BottleGrid, EditBottleForm, CameraCapture * BuddyList, SessionList, TastingNoteForm * StatusSwitcher and bottle management features - Implemented locale-aware currency formatting (EUR) - Implemented locale-aware date formatting - Added localStorage persistence for language preference - Added automatic browser language detection - Organized translations into 8 main categories - System is extensible for additional languages
This commit is contained in:
@@ -9,6 +9,8 @@ import BuddyList from "@/components/BuddyList";
|
||||
import SessionList from "@/components/SessionList";
|
||||
import StatsDashboard from "@/components/StatsDashboard";
|
||||
import DramOfTheDay from "@/components/DramOfTheDay";
|
||||
import LanguageSwitcher from "@/components/LanguageSwitcher";
|
||||
import { useI18n } from "@/i18n/I18nContext";
|
||||
|
||||
export default function Home() {
|
||||
const supabase = createClientComponentClient();
|
||||
@@ -16,6 +18,7 @@ export default function Home() {
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [user, setUser] = useState<any>(null);
|
||||
const [fetchError, setFetchError] = useState<string | null>(null);
|
||||
const { t } = useI18n();
|
||||
|
||||
useEffect(() => {
|
||||
// Check session
|
||||
@@ -111,7 +114,12 @@ export default function Home() {
|
||||
<h1 className="text-5xl font-black text-zinc-900 dark:text-white tracking-tighter mb-4">
|
||||
WHISKY<span className="text-amber-600">VAULT</span>
|
||||
</h1>
|
||||
<p className="text-zinc-500 max-w-sm mx-auto">Scanne deine Flaschen, tracke deine Tastings und verwalte deinen Keller.</p>
|
||||
<p className="text-zinc-500 max-w-sm mx-auto">
|
||||
{t('home.searchPlaceholder').replace('...', '')}
|
||||
</p>
|
||||
<div className="mt-8">
|
||||
<LanguageSwitcher />
|
||||
</div>
|
||||
</div>
|
||||
<AuthForm />
|
||||
</main>
|
||||
@@ -126,12 +134,13 @@ export default function Home() {
|
||||
WHISKY<span className="text-amber-600">VAULT</span>
|
||||
</h1>
|
||||
<div className="flex items-center gap-4">
|
||||
<LanguageSwitcher />
|
||||
<DramOfTheDay bottles={bottles} />
|
||||
<button
|
||||
onClick={handleLogout}
|
||||
className="text-sm font-medium text-zinc-500 hover:text-zinc-800 dark:hover:text-zinc-300 transition-colors"
|
||||
>
|
||||
Abmelden
|
||||
{t('home.logout')}
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
@@ -152,7 +161,7 @@ export default function Home() {
|
||||
|
||||
<div className="w-full mt-12">
|
||||
<h2 className="text-2xl font-bold mb-6 text-zinc-800 dark:text-zinc-100 flex items-center gap-3">
|
||||
Deine Sammlung
|
||||
{t('home.collection')}
|
||||
<span className="text-sm font-normal text-zinc-500 bg-zinc-100 dark:bg-zinc-800 px-3 py-1 rounded-full">
|
||||
{bottles.length}
|
||||
</span>
|
||||
@@ -164,13 +173,13 @@ export default function Home() {
|
||||
</div>
|
||||
) : fetchError ? (
|
||||
<div className="p-8 bg-zinc-100 dark:bg-zinc-900/50 border border-zinc-200 dark:border-zinc-800 rounded-3xl text-center">
|
||||
<p className="text-zinc-800 dark:text-zinc-200 font-bold mb-2">Die Sammlung konnte nicht geladen werden</p>
|
||||
<p className="text-zinc-500 text-sm italic mb-4">Ein technischer Fehler ist aufgetreten.</p>
|
||||
<p className="text-zinc-800 dark:text-zinc-200 font-bold mb-2">{t('common.error')}</p>
|
||||
<p className="text-zinc-500 text-sm italic mb-4">{fetchError}</p>
|
||||
<button
|
||||
onClick={fetchCollection}
|
||||
className="px-6 py-2 bg-amber-600 hover:bg-amber-700 text-white rounded-xl text-xs font-bold uppercase tracking-widest transition-all"
|
||||
>
|
||||
Erneut versuchen
|
||||
{t('home.reTry')}
|
||||
</button>
|
||||
</div>
|
||||
) : (
|
||||
|
||||
Reference in New Issue
Block a user