From 504631454a886c8ae6c0fea5d25125583a2609e0 Mon Sep 17 00:00:00 2001 From: chrisschuller Date: Sun, 29 Sep 2024 00:11:30 +0200 Subject: [PATCH] feat: add German language support (#207) * feat: add German language support * fix: translate other locale names to German * chore: integrate recommendations from the PR review * i18n: add translation recommendations from the PR * Fix translations --------- Co-authored-by: Christian Schuller Co-authored-by: Sebastien Castiel --- messages/de-DE.json | 392 ++++++++++++++++++++++++++++++++++++++++++++ messages/en-US.json | 3 +- messages/es.json | 3 +- messages/fi.json | 3 +- src/i18n.ts | 2 +- 5 files changed, 399 insertions(+), 4 deletions(-) create mode 100644 messages/de-DE.json diff --git a/messages/de-DE.json b/messages/de-DE.json new file mode 100644 index 00000000..4e13c80e --- /dev/null +++ b/messages/de-DE.json @@ -0,0 +1,392 @@ +{ + "Homepage": { + "title": "Teile Ausgaben mit Freunden & Familie", + "description": "Willkommen zu deiner neuen Spliit-Instanz!", + "button": { + "groups": "Zu den Gruppen", + "github": "GitHub" + } + }, + "Header": { + "groups": "Gruppen" + }, + "Footer": { + "madeIn": "Entwickelt in Montréal, Québec 🇨🇦", + "builtBy": "Erstellt von Sebastien Castiel und Mitwirkenden" + }, + "Expenses": { + "title": "Ausgaben", + "description": "Hier sind die Ausgaben, die du für deine Gruppe erstellt hast.", + "create": "Ausgabe hinzufügen", + "createFirst": "Erstelle die Erste", + "noExpenses": "Deine Gruppe hat noch keine Ausgaben.", + "exportJson": "Als JSON exportieren", + "searchPlaceholder": "Suche nach einer Ausgabe…", + "ActiveUserModal": { + "title": "Wer bist du?", + "description": "Sag uns, welcher Teilnehmer du bist, um die angezeigten Informationen auf dich anzupassen.", + "nobody": "Ich will niemanden auswählen", + "save": "Änderungen speichern", + "footer": "Diese Einstellung kann später in den Gruppeneinstellungen geändert werden." + }, + "Groups": { + "upcoming": "Bevorstehend", + "thisWeek": "Diese Woche", + "earlierThisMonth": "Diesen Monat", + "lastMonth": "Letzten Monat", + "earlierThisYear": "Dieses Jahr", + "lastYera": "Letztes Jahr", + "older": "Älter" + } + }, + "ExpenseCard": { + "paidBy": "Gezahlt von {paidBy} für ", + "receivedBy": "Empfangen von {paidBy} für ", + "yourBalance": "Deine Bilanz:" + }, + "Groups": { + "myGroups": "Meine Gruppen", + "create": "Erstellen", + "loadingRecent": "Lade letzte Gruppen…", + "NoRecent": { + "description": "Du hast in der letzten Zeit keine Gruppe besucht.", + "create": "Erstelle eine", + "orAsk": "oder bitte einen Freund, dir einen Link zu einer Existierenden zu schicken." + }, + "recent": "Letzte Gruppen", + "starred": "Favorisierte Gruppen", + "archived": "Archivierte Gruppen", + "archive": "Gruppe archivieren", + "unarchive": "Gruppe wiederherstellen", + "removeRecent": "Aus letzten Gruppen entfernen", + "RecentRemovedToast": { + "title": "Gruppe wurde entfernt", + "description": "Die Gruppe wurde von deiner Liste der letzten Gruppen entfernt.", + "undoAlt": "Gruppe entfernen rückgängig machen", + "undo": "Rückgängig machen" + }, + "AddByURL": { + "button": "Mit URL hinzufügen", + "title": "Gruppe mit URL hinzufügen", + "description": "Wenn eine Gruppe mit dir geteilt wurde, kannst du ihre URL hier einfügen, um sie zu deiner Liste hinzuzufügen.", + "error": "Ups, wir können die Gruppe mit der angegebenen URL nicht finden…" + }, + "NotFound": { + "text": "Diese Gruppe existiert nicht.", + "link": "Gehe zu zuletzt besuchten Gruppen" + } + }, + "GroupForm": { + "title": "Gruppeninformationen", + "NameField": { + "label": "Gruppenname", + "placeholder": "Sommerurlaub", + "description": "Gib deiner Gruppe einen Namen." + }, + "InformationField": { + "label": "Gruppeninformationen", + "placeholder": "Welche Informationen sind relevant für Gruppenmitglieder?" + }, + "CurrencyField": { + "label": "Währungssymbol", + "placeholder": "€, $, £…", + "description": "Wir benutzen es, um Beträge anzuzeigen." + }, + "Participants": { + "title": "Mitglieder", + "description": "Füge einen Namen für jedes Gruppenmitglied hinzu.", + "protectedParticipant": "Dieses Mitglied ist Teil der Ausgaben und kann nicht entfernt werden.", + "new": "Neu", + "add": "Mitglied hinzufügen", + "John": "Johannes", + "Jane": "Janina", + "Jack": "Jakob" + }, + "Settings": { + "title": "Lokale Einstellungen", + "description": "Dies sind Einstellungen pro Gerät, die verwendet werden, um deine Benutzererfahrung zu verbessern.", + "ActiveUserField": { + "label": "Aktiver Nutzer", + "placeholder": "Wähle ein Mitglied", + "none": "Keiner", + "description": "Standardnutzer, der die Ausgaben übernimmt." + }, + "save": "Speichern", + "saving": "Speichert…", + "create": "Erstellen", + "creating": "Erstellt…", + "cancel": "Abbrechen" + } + }, + "ExpenseForm": { + "Income": { + "create": "Einnahme erstellen", + "edit": "Einnahme bearbeiten", + "TitleField": { + "label": "Titel der Einnahme", + "placeholder": "Montagabend Restaurant", + "description": "Füge eine Beschreibung für die Einnahme hinzu." + }, + "DateField": { + "label": "Datum der Einnahme", + "description": "Füge ein Datum hinzu für wann die Einnahme erhalten wurde." + }, + "categoryFieldDescription": "Wähle die Kategorie der Einnahme.", + "paidByField": { + "label": "Empfangen von", + "description": "Wähle das Mitglied, das die Einnahme erhalten hat." + }, + "paidFor": { + "title": "Empfangen für", + "description": "Wähle für wen die Einnahme empfangen wurde." + }, + "splitModeDescription": "Wähle, wie die Einnahme aufgeteilt werden soll.", + "attachDescription": "Füge der Einnahme einen Beleg hinzu." + }, + "Expense": { + "create": "Augabe erstellen", + "edit": "Ausgabe bearbeiten", + "TitleField": { + "label": "Titel der Ausgabe", + "placeholder": "Montagabend Restaurant", + "description": "Füge eine Beschreibung für die Ausgabe hinzu." + }, + "DateField": { + "label": "Datum der Ausgabe", + "description": "Füge das Datum ein, zu dem die Ausgabe getätigt wurde." + }, + "categoryFieldDescription": "Wähle eine Kategorie für die Ausgabe.", + "paidByField": { + "label": "Gezahlt von", + "description": "Wähle das Mitglied, das die Ausgabe bezahlt hat." + }, + "paidFor": { + "title": "Gezahlt für", + "description": "Wähle für wen die Ausgabe gezahlt wurde." + }, + "splitModeDescription": "Wähle, wie die Ausgabe aufgeteilt werden soll.", + "attachDescription": "Füge der Ausgabe einen Beleg hinzu." + }, + "amountField": { + "label": "Betrag" + }, + "isReimbursementField": { + "label": "Das ist eine Rückzahlung" + }, + "categoryField": { + "label": "Kategorie" + }, + "notesField": { + "label": "Notizen" + }, + "selectNone": "Keine auswählen", + "selectAll": "Alle auswählen", + "shares": "Anteil(e)", + "advancedOptions": "Fortgeschrittene Aufteilungsoptionen…", + "SplitModeField": { + "label": "Aufteilungsart", + "evenly": "Gleich verteilt", + "byShares": "Ungleich – Nach Anteilen", + "byPercentage": "Ungleich – Prozentual", + "byAmount": "Ungleich – Nach Betrag", + "saveAsDefault": "Als Standardoptionen zur Aufteilung speichern" + }, + "DeletePopup": { + "label": "Löschen", + "title": "Diese Ausgabe löschen?", + "description": "Willst du diese Ausgabe wirklich löschen? Diese Aktion kann nicht rückgängig gemacht werden.", + "yes": "Ja", + "cancel": "Abbrechen" + }, + "attachDocuments": "Dokument hinzufügen", + "create": "Erstellen", + "creating": "Erstellt…", + "save": "Speichern", + "saving": "Speichert…", + "cancel": "Abbrechen" + }, + "ExpenseDocumentsInput": { + "TooBigToast": { + "title": "Die Datei ist zu groß", + "description": "Die maximale Dateigröße ist {maxSize}. Deine ist ${size}." + }, + "ErrorToast": { + "title": "Fehler beim Hochladen der Datei", + "description": "Beim Hochladen der Datei ist etwas schiefgelaufen. Versuche es später nochmal oder wähle eine andere Datei.", + "retry": "Wiederholen" + } + }, + "CreateFromReceipt": { + "Dialog": { + "triggerTitle": "Ausgabe von Rechnungsbeleg erstellen", + "title": "Von Rechnungsbeleg erstellen", + "description": "Ausgabeninformationen von einem Foto einer Rechnung lesen.", + "body": "Lade ein Foto der Rechnung hoch und wir versuchen die Ausgabeinformationen zu extrahieren", + "selectImage": "Bild wählen…", + "titleLabel": "Titel:", + "categoryLabel": "Kategorie:", + "amountLabel": "Betrag:", + "dateLabel": "Datum:", + "editNext": "Als nächstes kannst du die Informationen zur Ausgabe editieren.", + "continue": "Weiter" + }, + "unknown": "Unbekannt", + "TooBigToast": { + "title": "Die Datei ist zu groß", + "description": "Die maximale Dateigröße ist {maxSize}. Deine ist ${size}." + }, + "ErrorToast": { + "title": "Fehler beim Hochladen der Datei", + "description": "Beim Hochladen der Datei ist etwas schiefgelaufen. Versuche es später nochmal oder wähle eine andere Datei.", + "retry": "Wiederholen" + } + }, + "Balances": { + "title": "Bilanz", + "description": "Das sind die Beträge, die jedes Mitglied bezahlt oder empfangen hat.", + "Reimbursements": { + "title": "Vorgeschlagene Rückzahlungen", + "description": "Hier sind Vorschläge für optimierte Rückzahlungen zwischen Mitgliedern.", + "noImbursements": "Es sieht aus, als seien in der Gruppe keine Rückzahlungen nötig 😁", + "owes": "{from} schuldet {to}", + "markAsPaid": "Als gezahlt markieren" + } + }, + "Stats": { + "title": "Statistiken", + "Totals": { + "title": "Gesamtausgaben", + "description": "Zusammenfassung der Ausgaben der gesamten Gruppe.", + "groupSpendings": "Gesamte Ausgaben der Gruppe", + "groupEarnings": "Gesamte Einnahmen der Gruppe", + "yourSpendings": "Deine gesamten Ausgaben", + "yourEarnings": "Deine gesamten Einnahmen", + "yourShare": "Dein gesamter Anteil" + } + }, + "Activity": { + "title": "Aktivitäten", + "description": "Zusammenfassung aller Aktivitäten in dieser Gruppe.", + "noActivity": "Es gab noch keine Aktivität in dieser Gruppe.", + "someone": "Jemand", + "settingsModified": "Die Gruppeneinstellungen wurden von {participant} verändert.", + "expenseCreated": "Augabe {expense} wurde von {participant} erstellt.", + "expenseUpdated": "Ausgabe {expense} wurde von {participant} aktualisiert.", + "expenseDeleted": "Ausgabe {expense} wurde von {participant} gelöscht.", + "Groups": { + "today": "Heute", + "yesterday": "Gestern", + "earlierThisWeek": "Diese Woche", + "lastWeek": "Letze Woche", + "earlierThisMonth": "Diesen Monat", + "lastMonth": "Letzen Monat", + "earlierThisYear": "Dieses Jahr", + "lastYear": "Letztes Jahr", + "older": "Älter" + } + }, + "Information": { + "title": "Informationen", + "description": "Nutze diesen Ort, um Informationen hinzuzufügen, die für die Gruppenmitglieder wichtig sein könnten.", + "empty": "Noch keine Gruppeninformationen vorhanden." + }, + "Settings": { + "title": "Einstellungen" + }, + "Locale": { + "en-US": "Englisch", + "de-DE": "Deutsch", + "fi": "Finnisch" + }, + "Share": { + "title": "Teilen", + "description": "Teile die URL, damit andere Mitglieder die Gruppe sehen und Ausgaben hinzufügen können.", + "warning": "Achtung!", + "warningHelp": "Jede person mit der Gruppen-URL kann Ausgaben sehen und editieren. Teile den Link mit Bedacht!" + }, + "SchemaErrors": { + "min1": "Gib mindestens ein Zeichen ein.", + "min2": "Gib mindestens zwei Zeichen ein.", + "max5": "Gib maximal fünf Zeichen ein.", + "max50": "Gib maximal 50 Zeichen ein.", + "duplicateParticipantName": "Der Name ist bereits an ein anderes Gruppenmitglied vergeben.", + "titleRequired": "Bitte gib einen Titel an.", + "invalidNumber": "Zahl nicht valide.", + "amountRequired": "Du musst einen Betrag angeben.", + "amountNotZero": "Der Betrag darf nicht 0 sein.", + "amountTenMillion": "Der Betrag muss kleiner als 10.000.000 sein", + "paidByRequired": "Du musst ein Mitglied auswählen.", + "paidForMin1": "Die Ausgabe muss mindestens für ein Mitglied bezahlt werden.", + "noZeroShares": "Alle Anteile müssen größer als 0 sein.", + "amountSum": "Die Summe der Beträge muss dem Betrag der Ausgabe entsprechen.", + "percentageSum": "Die Summe der prozentualen Anteile muss 100 ergeben." + }, + "Categories": { + "search": "Nach Kategorie suchen...", + "noCategory": "Keine Kategorie gefunden.", + "Uncategorized": { + "heading": "Nicht kategorisiert", + "General": "Allgemein", + "Payment": "Zahlung" + }, + "Entertainment": { + "heading": "Vergnügen", + "Entertainment": "Vergnügen", + "Games": "Spiele", + "Movies": "Filme", + "Music": "Musik", + "Sports": "Sport" + }, + "Food and Drink": { + "heading": "Essen und Trinken", + "Food and Drink": "Essen und Trinken", + "Dining Out": "Essen gehen", + "Groceries": "Lebensmittel", + "Liquor": "Alkohol" + }, + "Home": { + "heading": "Zuhause", + "Home": "Zuhause", + "Electronics": "Elektronik", + "Furniture": "Möbel", + "Household Supplies": "Haushaltsgegenstände", + "Maintenance": "Wartung", + "Mortgage": "Hypothek", + "Pets": "Haustiere", + "Rent": "Miete", + "Services": "Dienstleistungen" + }, + "Life": { + "heading": "Leben", + "Childcare": "Kinderversorgung", + "Clothing": "Kleidung", + "Education": "Bildung", + "Gifts": "Geschenke", + "Insurance": "Versicherung", + "Medical Expenses": "Medizinische Ausgaben", + "Taxes": "Steuern" + }, + "Transportation": { + "heading": "Transport", + "Transportation": "Transport", + "Bicycle": "Fahrrad", + "Bus/Train": "Bus/Bahn", + "Car": "Auto", + "Gas/Fuel": "Tanken", + "Hotel": "Hotel", + "Parking": "Parken", + "Plane": "Flugzeug", + "Taxi": "Taxi" + }, + "Utilities": { + "heading": "Versorgung", + "Utilities": "Versorgung", + "Cleaning": "Reinigung/Putzen", + "Electricity": "Strom", + "Heat/Gas": "Heizung", + "Trash": "Müll", + "TV/Phone/Internet": "TV/Internet/Telefonie", + "Water": "Wasser" + } + } +} diff --git a/messages/en-US.json b/messages/en-US.json index 3ed3a265..8a7d5cdc 100644 --- a/messages/en-US.json +++ b/messages/en-US.json @@ -297,7 +297,8 @@ "en-US": "English", "fi": "Suomi", "fr-FR": "Français", - "es": "Español" + "es": "Español", + "de-DE": "Deutsch" }, "Share": { "title": "Share", diff --git a/messages/es.json b/messages/es.json index 6626264f..e2422f2b 100644 --- a/messages/es.json +++ b/messages/es.json @@ -297,7 +297,8 @@ "en-US": "English", "fi": "Suomi", "fr-FR": "Français", - "es": "Español" + "es": "Español", + "de-DE": "Deutsch" }, "Share": { "title": "Compartir", diff --git a/messages/fi.json b/messages/fi.json index 264fcb61..6b4784f5 100644 --- a/messages/fi.json +++ b/messages/fi.json @@ -297,7 +297,8 @@ "en-US": "English", "fi": "Suomi", "fr-FR": "Français", - "es": "Español" + "es": "Español", + "de-DE": "Deutsch" }, "Share": { "title": "Jaa", diff --git a/src/i18n.ts b/src/i18n.ts index dbf8cfe9..11ef139c 100644 --- a/src/i18n.ts +++ b/src/i18n.ts @@ -1,7 +1,7 @@ import { getRequestConfig } from 'next-intl/server' import { getUserLocale } from './lib/locale' -export const locales = ['en-US', 'fi', 'fr-FR', 'es'] as const +export const locales = ['en-US', 'fi', 'fr-FR', 'es', 'de-DE'] as const export type Locale = (typeof locales)[number] export type Locales = ReadonlyArray export const defaultLocale: Locale = 'en-US'