import React, { createContext, useContext, useEffect, useMemo, useState } from "react"; const STORAGE_KEY = "hpLanguage"; const LanguageContext = createContext(null); const entryLabels = { "Schlaftrunk": "Sleeping Potion", "Verschwindekabinett": "Vanishing Cabinet", "Portschlüssel": "Portkey", "Impedimenta": "Impedimenta", "Petrificus Totalus": "Petrificus Totalus", "Alraune": "Mandrake", "Große Halle": "Great Hall", "Krankenflügel": "Hospital Wing", "Raum der Wünsche": "Room of Requirement", "Klassenzimmer für Zaubertränke": "Potions Classroom", "Pokalszimmer": "Trophy Room", "Klassenzimmer für Wahrsagen": "Divination Classroom", "Eulerei": "Owlery", "Bibliothek": "Library", "Verteidigung gegen die dunklen Künste": "Defence Against the Dark Arts", }; export function translateEntryLabel(label, language) { return language === "en" ? (entryLabels[label] || label) : label; } export const translations = { de: { language: "Deutsch", changeLanguage: "Sprache ändern", switchTo: "English", statistics: "Statistik", adminDashboard: "Admin Dashboard", adminSettings: "Admin Settings", setPassword: "Passwort setzen", changeDesign: "Design ändern", logout: "Logout", newGame: "New Game", user: "User", admin: "Admin", help: "Hilfe", game: "Spiel", players: "Spieler", suspects: "Verdächtige Personen", items: "Gegenstände", locations: "Orte", winner: "Sieger", started: "Spiel läuft", finished: "Spiel beendet", lobby: "Lobby", startGame: "Spiel starten", waitingForHost: "Warte, bis der Host das Spiel startet.", chipsCreated: "Spieler-Chips erstellt", atLeastTwoPlayers: "Mindestens 2 Spieler werden benötigt.", chipsOnStart: "Beim Start werden die Spieler-Chips erstellt.", noPlayersYet: "Noch keine Spieler beigetreten.", close: "Schließen", cancel: "Abbrechen", save: "Speichern", create: "Erstellen", edit: "Bearbeiten", delete: "Löschen", disable: "Deaktivieren", active: "aktiv", disabled: "deaktiviert", loading: "Laden …", email: "E-Mail", password: "Passwort", confirmPassword: "Passwort bestätigen", role: "Rolle", displayName: "Anzeigename", name: "Name", createUser: "User anlegen", editUser: "User bearbeiten", newUser: "Neuen User anlegen", existingUsers: "Vorhandene User", accountActive: "Konto ist aktiv", optional: "optional", inviteHint: "Leer lassen = Einladung senden", inviteNotice: "Ohne Passwort wird automatisch eine einmalige Einladung per SMTP verschickt.", adminDashboardSubtitle: "Benutzer, Rollen und Zugangsdaten verwalten", adminSettingsSubtitle: "SMTP und Einladungen konfigurieren", smtpServer: "SMTP-Server", port: "Port", smtpUsername: "SMTP-Benutzername", senderEmail: "Absender-E-Mail", senderName: "Absendername", appUrl: "App-URL für Einladungslinks", useTls: "STARTTLS verwenden (empfohlen)", testEmail: "Test-E-Mail", sendTest: "Test senden", saveSettings: "Einstellungen speichern", setupAdmin: "Admin einrichten", login: "Anmelden", logout: "Logout", enterEmail: "E-Mail eingeben", passwordMin: "Mindestens 8 Zeichen", passwordAgain: "Passwort wiederholen", acceptInvite: "Einladung annehmen", invite: "Deine Einladung", setPasswordTitle: "Passwort setzen", design: "Design ändern", joinGame: "Spiel beitreten", newGameTitle: "Neues Spiel", gameCode: "Spiel-Code", copy: "Kopieren", copied: "Kopiert", createGame: "Spiel erstellen", join: "Beitreten", chooseAction: "Was möchtest du tun?", helpTitle: "Hilfe & Spielablauf", notes: "Notizen", playerChips: "Spieler-Chips", whoHasCard: "Wer hat die Karte?", selectChip: "Chip auswählen", readOnly: "Spiel beendet – Notizzettel ist schreibgeschützt", cycleStatus: "Klick: Grün → Rot → Grau → Leer", cycleNote: "— → i → m → s.(Chip) → —", gameStarted: "Spiel gestartet", investigationsBegin: "Die Ermittlungen beginnen", bestDetective: "Möge der beste Detektiv gewinnen.", }, en: { language: "English", changeLanguage: "Change language", switchTo: "Deutsch", statistics: "Statistics", adminDashboard: "Admin Dashboard", adminSettings: "Admin Settings", setPassword: "Set password", changeDesign: "Change design", logout: "Logout", newGame: "New Game", user: "User", admin: "Admin", help: "Help", game: "Game", players: "Players", suspects: "Suspects", items: "Items", locations: "Locations", winner: "Winner", started: "Game in progress", finished: "Game finished", lobby: "Lobby", startGame: "Start game", waitingForHost: "Wait for the host to start the game.", chipsCreated: "player chips created", atLeastTwoPlayers: "At least 2 players are required.", chipsOnStart: "Player chips will be created when the game starts.", noPlayersYet: "No players have joined yet.", close: "Close", cancel: "Cancel", save: "Save", create: "Create", edit: "Edit", delete: "Delete", disable: "Disable", active: "active", disabled: "disabled", loading: "Loading …", email: "Email", password: "Password", confirmPassword: "Confirm password", role: "Role", displayName: "Display name", name: "Name", createUser: "Create user", editUser: "Edit user", newUser: "Create new user", existingUsers: "Existing users", accountActive: "Account is active", optional: "optional", inviteHint: "Leave blank = send invitation", inviteNotice: "Without a password, a one-time invitation is sent via SMTP.", adminDashboardSubtitle: "Manage users, roles and credentials", adminSettingsSubtitle: "Configure SMTP and invitations", smtpServer: "SMTP server", port: "Port", smtpUsername: "SMTP username", senderEmail: "Sender email", senderName: "Sender name", appUrl: "App URL for invitation links", useTls: "Use STARTTLS (recommended)", testEmail: "Test email", sendTest: "Send test", saveSettings: "Save settings", setupAdmin: "Set up admin", login: "Log in", enterEmail: "Enter email", passwordMin: "At least 8 characters", passwordAgain: "Repeat password", acceptInvite: "Accept invitation", invite: "Your invitation", setPasswordTitle: "Set password", design: "Change design", joinGame: "Join game", newGameTitle: "New game", gameCode: "Game code", copy: "Copy", copied: "Copied", createGame: "Create game", join: "Join", chooseAction: "What would you like to do?", helpTitle: "Help & game guide", notes: "Notes", playerChips: "Player chips", whoHasCard: "Who has the card?", selectChip: "Select chip", readOnly: "Game finished – note sheet is read-only", cycleStatus: "Click: Green → Red → Grey → Empty", cycleNote: "— → i → m → s.(chip) → —", gameStarted: "Game started", investigationsBegin: "The investigation begins", bestDetective: "May the best detective win.", }, }; export function LanguageProvider({ children }) { const [language, setLanguage] = useState(() => { try { return localStorage.getItem(STORAGE_KEY) === "en" ? "en" : "de"; } catch { return "de"; } }); useEffect(() => { try { localStorage.setItem(STORAGE_KEY, language); } catch {} document.documentElement.lang = language; }, [language]); const value = useMemo(() => ({ language, setLanguage, toggleLanguage: () => setLanguage((current) => current === "de" ? "en" : "de"), t: (key, values = {}) => { let value = translations[language][key] || key; Object.entries(values).forEach(([name, replacement]) => { value = value.replaceAll(`{${name}}`, replacement); }); return value; }, }), [language]); return {children}; } export function useLanguage() { return useContext(LanguageContext) || { language: "de", toggleLanguage: () => {}, t: (key) => key }; }