feat(i18n): add German translations and key parity test

- Create all 6 German namespace JSON files (common, collection, threads, setups, onboarding, settings)
- Register German locale in i18n configuration with supportedLngs
- Add key parity test ensuring en/de have identical key structures
- All 19 locale parity tests pass, all 15 formatter tests pass

Phase 34, Plan 05
This commit is contained in:
2026-04-13 18:23:45 +02:00
parent 46715cc793
commit 5e731b436b
8 changed files with 356 additions and 0 deletions

View File

@@ -9,6 +9,13 @@ import enSettings from "../locales/en/settings.json";
import enSetups from "../locales/en/setups.json";
import enThreads from "../locales/en/threads.json";
import deCollection from "../locales/de/collection.json";
import deCommon from "../locales/de/common.json";
import deOnboarding from "../locales/de/onboarding.json";
import deSettings from "../locales/de/settings.json";
import deSetups from "../locales/de/setups.json";
import deThreads from "../locales/de/threads.json";
i18n
.use(LanguageDetector)
.use(initReactI18next)
@@ -22,6 +29,14 @@ i18n
onboarding: enOnboarding,
settings: enSettings,
},
de: {
common: deCommon,
collection: deCollection,
threads: deThreads,
setups: deSetups,
onboarding: deOnboarding,
settings: deSettings,
},
},
supportedLngs: ["en", "de"],
fallbackLng: "en",

View File

@@ -0,0 +1,31 @@
{
"title": "Sammlung",
"gear": "Ausruestung",
"planning": "Planung",
"empty": {
"title": "Ihre Sammlung ist leer",
"description": "Beginnen Sie mit der Katalogisierung Ihrer Ausruestung, indem Sie Ihren ersten Gegenstand hinzufuegen. Verfolgen Sie Gewicht, Preis und organisieren Sie nach Kategorie.",
"addFirst": "Ersten Gegenstand hinzufuegen"
},
"form": {
"name": "Name",
"nameRequired": "Name *",
"namePlaceholder": "z.B. Osprey Talon 22",
"weight": "Gewicht (g)",
"weightPlaceholder": "z.B. 680",
"price": "Preis ($)",
"pricePlaceholder": "z.B. 129,99",
"quantity": "Menge",
"category": "Kategorie",
"notes": "Notizen",
"notesPlaceholder": "Zusaetzliche Notizen...",
"productLink": "Produktlink",
"urlPlaceholder": "https://..."
},
"classification": {
"ultralight": "Ultraleicht",
"light": "Leicht",
"medium": "Mittel",
"heavy": "Schwer"
}
}

View File

@@ -0,0 +1,80 @@
{
"nav": {
"home": "Startseite",
"collection": "Sammlung",
"setups": "Setups",
"discover": "Entdecken",
"settings": "Einstellungen",
"search": "Suchen",
"searchPlaceholder": "Katalog durchsuchen...",
"profile": "Profil"
},
"actions": {
"save": "Speichern",
"cancel": "Abbrechen",
"delete": "Loeschen",
"edit": "Bearbeiten",
"create": "Erstellen",
"close": "Schliessen",
"back": "Zurueck",
"confirm": "Bestaetigen",
"continue": "Weiter",
"tryAgain": "Erneut versuchen",
"dismiss": "Schliessen",
"saving": "Wird gespeichert...",
"deleting": "Wird geloescht...",
"creating": "Wird erstellt...",
"loading": "Laden...",
"addItem": "Gegenstand hinzufuegen",
"saveChanges": "Aenderungen speichern",
"revoke": "Widerrufen",
"skipStep": "Diesen Schritt ueberspringen"
},
"errors": {
"somethingWentWrong": "Etwas ist schiefgelaufen",
"unexpectedError": "Ein unerwarteter Fehler ist aufgetreten",
"nameRequired": "Name ist erforderlich",
"positiveNumber": "Muss eine positive Zahl sein",
"validUrl": "Muss eine gueltige URL sein (https://...)"
},
"auth": {
"signIn": "Anmelden",
"signOut": "Abmelden",
"joinGearBox": "GearBox beitreten",
"signInToGearBox": "Bei GearBox anmelden",
"signInDescription": "Melden Sie sich an oder erstellen Sie ein Konto, um Ihre Sammlung zu verwalten.",
"createAccount": "Konto erstellen",
"redirectDescription": "Sie werden zur Anmeldung weitergeleitet."
},
"confirm": {
"deleteItem": "Gegenstand loeschen",
"deleteItemMessage": "Sind Sie sicher, dass Sie <bold>{{name}}</bold> loeschen moechten? Diese Aktion kann nicht rueckgaengig gemacht werden.",
"deleteCandidate": "Kandidat loeschen",
"deleteCandidateMessage": "Sind Sie sicher, dass Sie <bold>{{name}}</bold> loeschen moechten? Diese Aktion kann nicht rueckgaengig gemacht werden.",
"pickWinner": "Gewinner waehlen",
"pickWinnerMessage": "<bold>{{name}}</bold> als Gewinner waehlen? Der Gegenstand wird Ihrer Sammlung hinzugefuegt und der Thread archiviert."
},
"externalLink": {
"title": "Sie verlassen GearBox",
"redirectMessage": "Sie werden weitergeleitet zu:"
},
"fab": {
"addToCollection": "Zur Sammlung hinzufuegen",
"startNewThread": "Neuen Thread starten",
"newSetup": "Neues Setup"
},
"empty": {
"noResults": "Keine Ergebnisse gefunden",
"noItems": "Keine Gegenstaende gefunden"
},
"stats": {
"items": "Gegenstaende",
"totalWeight": "Gesamtgewicht",
"totalSpent": "Gesamtausgaben"
},
"filter": {
"showing": "{{filtered}} von {{total}} Gegenstaenden",
"searchItems": "Gegenstaende suchen...",
"allCategories": "Alle Kategorien"
}
}

View File

@@ -0,0 +1,34 @@
{
"welcome": {
"title": "Willkommen bei GearBox",
"subtitle": "Sagen Sie uns, was Sie interessiert, und wir helfen Ihnen, Ihre Sammlung mit Ausruestung einzurichten, die wirklich genutzt wird.",
"cta": "Los geht's"
},
"hobby": {
"title": "Was interessiert Sie?",
"subtitle": "Waehlen Sie eins oder mehrere — wir zeigen Ihnen beliebte Ausruestung fuer jedes.",
"continue": "Weiter"
},
"items": {
"title": "Beliebte Ausruestung fuer {{hobby}}",
"titleMultiple": "Beliebte Ausruestung fuer Ihre Hobbys",
"subtitle": "Tippen Sie auf Gegenstaende, die Sie bereits besitzen. Wir fuegen sie Ihrer Sammlung hinzu.",
"noCatalog": "Noch keine Ausruestung katalogisiert",
"noCatalogDescription": "Wir bauen unseren Katalog fuer dieses Hobby noch auf. Sie koennen diesen Schritt ueberspringen und spaeter manuell Ausruestung hinzufuegen.",
"reviewCount": "{{count}} Gegenstaende pruefen",
"reviewCount_one": "{{count}} Gegenstand pruefen"
},
"review": {
"title": "Ihre Startsammlung",
"itemsReady": "{{count}} Gegenstaende bereit zum Hinzufuegen",
"itemsReady_one": "{{count}} Gegenstand bereit zum Hinzufuegen",
"noItemsSelected": "Keine Gegenstaende ausgewaehlt — Sie koennen jederzeit spaeter Ausruestung aus dem Katalog hinzufuegen.",
"addToCollection": "Zu meiner Sammlung hinzufuegen",
"adding": "Wird hinzugefuegt..."
},
"done": {
"title": "Alles bereit!",
"subtitle": "Ihre Sammlung ist fertig. Durchstoebern Sie jederzeit den Katalog, um mehr Ausruestung zu entdecken.",
"cta": "Jetzt entdecken"
}
}

View File

@@ -0,0 +1,32 @@
{
"title": "Einstellungen",
"language": {
"title": "Sprache",
"description": "Aendern Sie die Anzeigesprache der App"
},
"weightUnit": {
"title": "Gewichtseinheit",
"description": "Waehlen Sie die Einheit fuer die Gewichtsanzeige in der App"
},
"currency": {
"title": "Waehrung",
"description": "Aendert das angezeigte Waehrungssymbol. Werte werden nicht umgerechnet."
},
"apiKeys": {
"title": "API-Schluessel",
"description": "API-Schluessel ermoeglichen programmatischen Zugriff auf GearBox (z.B. von Claude Desktop oder Skripten).",
"copyWarning": "Kopieren Sie diesen Schluessel jetzt — er wird nicht erneut angezeigt:",
"namePlaceholder": "Schluesselname (z.B. claude-desktop)"
},
"importExport": {
"title": "Import / Export",
"description": "Exportieren Sie Ihre Ausruestungssammlung als CSV-Datei oder importieren Sie Gegenstaende aus einer CSV.",
"export": "CSV exportieren",
"import": "CSV importieren",
"importing": "Wird importiert...",
"imported": "{{count}} Gegenstaende importiert.",
"imported_one": "{{count}} Gegenstand importiert.",
"newCategories": "Neue Kategorien: {{categories}}",
"noItemsFound": "Keine Gegenstaende in der CSV gefunden."
}
}

View File

@@ -0,0 +1,43 @@
{
"title": "Setups",
"create": "Neues Setup",
"empty": {
"title": "Noch keine Setups",
"description": "Erstellen Sie ein Setup, um Ausruestung fuer bestimmte Reisen oder Aktivitaeten zu organisieren."
},
"card": {
"items": "{{count}} Gegenstaende",
"items_one": "{{count}} Gegenstand",
"weight": "Gewicht",
"price": "Preis"
},
"share": {
"title": "Setup teilen",
"shareLinks": "Freigabelinks",
"createLink": "Link erstellen",
"noLinks": "Noch keine Freigabelinks",
"copyLink": "Link kopieren",
"revokeLink": "Link widerrufen",
"copied": "Kopiert!",
"noExpiration": "Kein Ablaufdatum",
"expired": "Abgelaufen",
"expiresToday": "Laeuft heute ab",
"expiresTomorrow": "Laeuft morgen ab",
"expiresInDays": "Laeuft in {{days}} Tagen ab",
"daysOption": "{{days}} Tage",
"deactivateWarning": "Bei Umstellung auf Privat werden alle Freigabelinks deaktiviert. Sie koennen durch Zurueckschalten reaktiviert werden."
},
"visibility": {
"private": "Privat",
"privateDescription": "Nur Sie haben Zugriff",
"link": "Link-Freigabe",
"linkDescription": "Jeder mit dem Link",
"public": "Oeffentlich",
"publicDescription": "Sichtbar auf Ihrem Profil"
},
"impact": {
"title": "Auswirkungsvorschau",
"adding": "Hinzufuegen",
"removing": "Entfernen"
}
}

View File

@@ -0,0 +1,45 @@
{
"title": "Recherche-Threads",
"create": {
"title": "Neuer Thread",
"threadName": "Thread-Name",
"namePlaceholder": "z.B. Leichter Schlafsack",
"category": "Kategorie",
"nameRequired": "Thread-Name ist erforderlich",
"selectCategory": "Bitte waehlen Sie eine Kategorie",
"createFailed": "Thread konnte nicht erstellt werden",
"createThread": "Thread erstellen"
},
"status": {
"active": "Aktiv",
"researching": "Recherche",
"ordered": "Bestellt",
"arrived": "Angekommen",
"resolved": "Abgeschlossen",
"archived": "Archiviert"
},
"candidate": {
"name": "Name",
"price": "Preis",
"weight": "Gewicht",
"url": "URL",
"pros": "Vorteile",
"cons": "Nachteile",
"notes": "Notizen",
"addCandidate": "Kandidat hinzufuegen"
},
"comparison": {
"weight": "Gewicht",
"price": "Preis",
"pros": "Vorteile",
"cons": "Nachteile"
},
"resolve": {
"title": "Gewinner waehlen",
"message": "<bold>{{name}}</bold> als Gewinner waehlen? Der Gegenstand wird Ihrer Sammlung hinzugefuegt und der Thread archiviert."
},
"empty": {
"noThreads": "Noch keine Recherche-Threads",
"noCandidates": "Noch keine Kandidaten"
}
}