From 07e24f7fcbabde10d2d62df3496bb9110376fe40 Mon Sep 17 00:00:00 2001 From: Strekol <40820779+Strekol@users.noreply.github.com> Date: Sat, 28 Sep 2024 23:56:55 +0200 Subject: [PATCH] Add French translation (#196) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Added french version and title/description from json messages * Revert back default language to en-US * Code reviewed with prettier :) * Updated json to add information field * Updated json to add information block (missed on previous) * Reviewed code language * correction traduction "groupes étoilés" en "groupes favoris" --------- Co-authored-by: Andy Trouvé --- messages/en-US.json | 11 +- messages/fi.json | 11 +- messages/fr-FR.json | 392 ++++++++++++++++++++++++++++++++++++++++++++ src/app/page.tsx | 18 +- src/i18n.ts | 2 +- 5 files changed, 424 insertions(+), 10 deletions(-) create mode 100644 messages/fr-FR.json diff --git a/messages/en-US.json b/messages/en-US.json index bce39e9..f1c0aad 100644 --- a/messages/en-US.json +++ b/messages/en-US.json @@ -1,4 +1,12 @@ { + "Homepage": { + "title": "Share Expenses with Friends & Family", + "description": "Welcome to your new Spliit instance !", + "button": { + "groups": "Go to groups", + "github": "GitHub" + } + }, "Header": { "groups": "Groups" }, @@ -287,7 +295,8 @@ }, "Locale": { "en-US": "English", - "fi": "Suomi" + "fi": "Suomi", + "fr-FR": "French" }, "Share": { "title": "Share", diff --git a/messages/fi.json b/messages/fi.json index 5bf45c2..f6cdf3a 100644 --- a/messages/fi.json +++ b/messages/fi.json @@ -1,4 +1,12 @@ { + "Homepage": { + "title": "Jaa kulut ystävien ja perheen kanssa", + "description": "Tervetuloa uuteen Spliit-instanssiisi!", + "button": { + "groups": "Siirry ryhmiin", + "github": "GitHub" + } + }, "Header": { "groups": "Ryhmät" }, @@ -287,7 +295,8 @@ }, "Locale": { "en-US": "English", - "fi": "Suomi" + "fi": "Suomi", + "fr-FR": "French" }, "Share": { "title": "Jaa", diff --git a/messages/fr-FR.json b/messages/fr-FR.json new file mode 100644 index 0000000..36b71da --- /dev/null +++ b/messages/fr-FR.json @@ -0,0 +1,392 @@ +{ + "Homepage": { + "title": "Partagez vos dépenses avec vos amis & votre famille :)", + "description": "Bienvenue sur votre instance Spliit !", + "button": { + "groups": "Accéder aux groupes", + "github": "GitHub" + } + }, + "Header": { + "groups": "Groupes" + }, + "Footer": { + "madeIn": "Made in Montréal, Québec 🇨🇦", + "builtBy": "Développé par Sebastien Castiel et contributeurs" + }, + "Expenses": { + "title": "Dépenses", + "description": "Voici les dépenses que vous avez créées pour votre groupe.", + "create": "Créer une dépense", + "createFirst": "Créer la première :)", + "noExpenses": "Votre groupe n'a effectué aucune dépense pour le moment.", + "exportJson": "Exporter en JSON", + "searchPlaceholder": "Rechercher une dépense…", + "ActiveUserModal": { + "title": "Qui êtes-vous ?", + "description": "Dites-nous quel participant vous êtes pour personnaliser l'affichage des informations.", + "nobody": "Je ne veux sélectionner personne", + "save": "Sauvegarder les modifications", + "footer": "Ce paramètre peut être modifié plus tard dans les paramètres du groupe." + }, + "Groups": { + "upcoming": "À venir", + "thisWeek": "Cette semaine", + "earlierThisMonth": "Plus tôt ce mois-ci", + "lastMonth": "Le mois dernier", + "earlierThisYear": "Plus tôt cette année", + "lastYera": "L'année dernière", + "older": "Plus ancien" + } + }, + "ExpenseCard": { + "paidBy": "Payé par {paidBy} pour ", + "receivedBy": "Reçu par {paidBy} pour ", + "yourBalance": "Votre solde :" + }, + "Groups": { + "myGroups": "Mes groupes", + "create": "Créer", + "loadingRecent": "Chargement des groupes récents…", + "NoRecent": { + "description": "Vous n'avez visité aucun groupe récemment.", + "create": "Créer un groupe", + "orAsk": "ou demandez à un ami de vous envoyer le lien d'un groupe existant." + }, + "recent": "Groupes récents", + "starred": "Groupes favoris", + "archived": "Groupes archivés", + "archive": "Archiver le groupe", + "unarchive": "Désarchiver le groupe", + "removeRecent": "Supprimer des groupes récents", + "RecentRemovedToast": { + "title": "Le groupe a été supprimé", + "description": "Le groupe a été supprimé de votre liste de groupes récents.", + "undoAlt": "Annuler la suppression du groupe", + "undo": "Annuler" + }, + "AddByURL": { + "button": "Ajouter par URL", + "title": "Ajouter un groupe par URL", + "description": "Si un groupe a été partagé avec vous, vous pouvez coller son URL ici pour l'ajouter à votre liste.", + "error": "Oups, nous ne pouvons pas trouver le groupe à partir de l'URL que vous avez fournie…" + }, + "NotFound": { + "text": "Ce groupe n'existe pas.", + "link": "Aller aux groupes récemment visités" + } + }, + "GroupForm": { + "title": "Informations sur le groupe", + "NameField": { + "label": "Nom du groupe", + "placeholder": "Vacances d'été", + "description": "Entrez un nom pour votre groupe." + }, + "InformationField": { + "label": "Informations sur le groupe", + "placeholder": "Quelles informations sont pertinentes pour les participants du groupe ?" + }, + "CurrencyField": { + "label": "Symbole monétaire", + "placeholder": "$, €, £…", + "description": "Nous l'utiliserons pour afficher les montants." + }, + "Participants": { + "title": "Participants", + "description": "Entrez le nom de chaque participant.", + "protectedParticipant": "Ce participant fait partie des dépenses et ne peut pas être supprimé.", + "new": "Nouveau", + "add": "Ajouter un participant", + "John": "John", + "Jane": "Jane", + "Jack": "Jack" + }, + "Settings": { + "title": "Paramètres locaux", + "description": "Ces paramètres sont définis par appareil et sont utilisés pour personnaliser votre expérience.", + "ActiveUserField": { + "label": "Utilisateur actif", + "placeholder": "Sélectionner un participant", + "none": "Aucun", + "description": "Utilisateur utilisé comme défaut pour payer les dépenses." + }, + "save": "Sauvegarder", + "saving": "Sauvegarde…", + "create": "Créer", + "creating": "Création…", + "cancel": "Annuler" + } + }, + "ExpenseForm": { + "Income": { + "create": "Créer un revenu", + "edit": "Modifier le revenu", + "TitleField": { + "label": "Titre du revenu", + "placeholder": "Restaurant du lundi soir", + "description": "Entrez une description pour le revenu." + }, + "DateField": { + "label": "Date du revenu", + "description": "Entrez la date à laquelle le revenu a été reçu." + }, + "categoryFieldDescription": "Sélectionnez la catégorie de revenu.", + "paidByField": { + "label": "Reçu par", + "description": "Sélectionnez le participant qui a reçu le revenu." + }, + "paidFor": { + "title": "Reçu pour", + "description": "Sélectionnez pour qui le revenu a été reçu." + }, + "splitModeDescription": "Sélectionnez comment diviser le revenu.", + "attachDescription": "Voir et joindre des reçus au revenu." + }, + "Expense": { + "create": "Créer une dépense", + "edit": "Modifier la dépense", + "TitleField": { + "label": "Titre de la dépense", + "placeholder": "Restaurant du lundi soir", + "description": "Entrez une description pour la dépense." + }, + "DateField": { + "label": "Date de la dépense", + "description": "Entrez la date à laquelle la dépense a été payée." + }, + "categoryFieldDescription": "Sélectionnez la catégorie de dépense.", + "paidByField": { + "label": "Payé par", + "description": "Sélectionnez le participant qui a réglé la dépense." + }, + "paidFor": { + "title": "Payé pour", + "description": "Sélectionnez les participants concernés" + }, + "splitModeDescription": "Sélectionnez comment diviser la dépense.", + "attachDescription": "Voir et joindre des reçus à la dépense." + }, + "amountField": { + "label": "Montant" + }, + "isReimbursementField": { + "label": "C'est un remboursement" + }, + "categoryField": { + "label": "Catégorie" + }, + "notesField": { + "label": "Notes" + }, + "selectNone": "Tout désélectionner", + "selectAll": "Tout sélectionner", + "shares": "part(s)", + "advancedOptions": "Options de répartition avancées…", + "SplitModeField": { + "label": "Mode de répartition", + "evenly": "Également", + "byShares": "Inégalement – Par parts", + "byPercentage": "Inégalement – Par pourcentage", + "byAmount": "Inégalement – Par montant", + "saveAsDefault": "Enregistrer comme options de répartition par défaut" + }, + "DeletePopup": { + "label": "Supprimer", + "title": "Supprimer cette dépense ?", + "description": "Voulez-vous vraiment supprimer cette dépense ? Cette action est irréversible.", + "yes": "Oui", + "cancel": "Annuler" + }, + "attachDocuments": "Joindre des documents", + "create": "Créer", + "creating": "Création…", + "save": "Sauvegarder", + "saving": "Sauvegarde…", + "cancel": "Annuler" + }, + "ExpenseDocumentsInput": { + "TooBigToast": { + "title": "Le fichier est trop grand", + "description": "La taille maximale du fichier que vous pouvez télécharger est {maxSize}. La vôtre est ${size}." + }, + "ErrorToast": { + "title": "Erreur lors du téléchargement du document", + "description": "Un problème est survenu lors du téléchargement du document. Veuillez réessayer plus tard ou sélectionner un fichier différent.", + "retry": "Réessayer" + } + }, + "CreateFromReceipt": { + "Dialog": { + "triggerTitle": "Créer une dépense à partir du reçu", + "title": "Créer à partir du reçu", + "description": "Extraire les informations de la dépense à partir d'une photo de reçu.", + "body": "Téléchargez la photo d'un reçu, et nous l'analyserons pour extraire les informations de la dépense si possible.", + "selectImage": "Sélectionner une image…", + "titleLabel": "Titre :", + "categoryLabel": "Catégorie :", + "amountLabel": "Montant :", + "dateLabel": "Date :", + "editNext": "Vous pourrez modifier les informations de la dépense ensuite.", + "continue": "Continuer" + }, + "unknown": "Inconnu", + "TooBigToast": { + "title": "Le fichier est trop grand", + "description": "La taille maximale du fichier que vous pouvez télécharger est {maxSize}. La vôtre est ${size}." + }, + "ErrorToast": { + "title": "Erreur lors du téléchargement du document", + "description": "Un problème est survenu lors du téléchargement du document. Veuillez réessayer plus tard ou sélectionner un fichier différent.", + "retry": "Réessayer" + } + }, + "Balances": { + "title": "Équilibres", + "description": "Voici le montant que chaque participant a payé ou a été payé pour.", + "Reimbursements": { + "title": "Remboursements suggérés", + "description": "Voici des suggestions pour des remboursements optimisés entre les participants.", + "noImbursements": "Les dépenses effectuées ne nécessitent pas d'équilibrage 😁", + "owes": "{from} doit à {to}", + "markAsPaid": "Marquer comme payé" + } + }, + "Stats": { + "title": "Statistiques", + "Totals": { + "title": "Totaux", + "description": "Résumé des dépenses du groupe entier.", + "groupSpendings": "Total des dépenses du groupe", + "groupEarnings": "Total des revenus du groupe", + "yourSpendings": "Vos dépenses totales", + "yourEarnings": "Vos revenus totaux", + "yourShare": "Votre part totale" + } + }, + "Activity": { + "title": "Activité", + "description": "Vue d'ensemble de toute l'activité dans ce groupe.", + "noActivity": "Il n'y a pas encore d'activité dans votre groupe.", + "someone": "Quelqu'un", + "settingsModified": "Les paramètres du groupe ont été modifiés par {participant}.", + "expenseCreated": "Dépense {expense} créée par {participant}.", + "expenseUpdated": "Dépense {expense} mise à jour par {participant}.", + "expenseDeleted": "Dépense {expense} supprimée par {participant}.", + "Groups": { + "today": "Aujourd'hui", + "yesterday": "Hier", + "earlierThisWeek": "Plus tôt cette semaine", + "lastWeek": "La semaine dernière", + "earlierThisMonth": "Plus tôt ce mois-ci", + "lastMonth": "Le mois dernier", + "earlierThisYear": "Plus tôt cette année", + "lastYear": "L'année dernière", + "older": "Plus ancien" + } + }, + "Information": { + "title": "Information", + "description": "Utilisez cet espace pour ajouter toute information qui pourrait être pertinente pour les participants du groupe.", + "empty": "Aucune information pour le moment." + }, + "Settings": { + "title": "Paramètres" + }, + "Locale": { + "en-US": "Anglais", + "fi": "Finnois", + "fr-FR": "Français" + }, + "Share": { + "title": "Partager", + "description": "Pour que d'autres participants puissent voir le groupe et ajouter des dépenses, partagez son URL avec eux.", + "warning": "Avertissement !", + "warningHelp": "Toute personne ayant l'URL du groupe pourra voir et modifier les dépenses. Partagez avec prudence !" + }, + "SchemaErrors": { + "min1": "Entrez au moins un caractère.", + "min2": "Entrez au moins deux caractères.", + "max5": "Entrez au maximum cinq caractères.", + "max50": "Entrez au maximum 50 caractères.", + "duplicateParticipantName": "Un autre participant a déjà ce nom.", + "titleRequired": "Veuillez entrer un titre.", + "invalidNumber": "Nombre invalide.", + "amountRequired": "Vous devez entrer un montant.", + "amountNotZero": "Le montant ne doit pas être zéro.", + "amountTenMillion": "Le montant doit être inférieur à 10 000 000.", + "paidByRequired": "Vous devez sélectionner un participant.", + "paidForMin1": "La dépense doit concerner au moins un participant.", + "noZeroShares": "Toutes les parts doivent être supérieures à 0.", + "amountSum": "La somme des montants doit être égale au montant de la dépense.", + "percentageSum": "La somme des pourcentages doit être égale à 100." + }, + "Categories": { + "search": "Rechercher une catégorie…", + "noCategory": "Aucune catégorie trouvée.", + "Uncategorized": { + "heading": "Non classé", + "General": "Général", + "Payment": "Paiement" + }, + "Entertainment": { + "heading": "Divertissement", + "Entertainment": "Divertissement", + "Games": "Jeux", + "Movies": "Films", + "Music": "Musique", + "Sports": "Sports" + }, + "Food and Drink": { + "heading": "Nourriture et boissons", + "Food and Drink": "Nourriture et boissons", + "Dining Out": "Repas au restaurant", + "Groceries": "Épicerie", + "Liquor": "Alcool" + }, + "Home": { + "heading": "Maison", + "Home": "Maison", + "Electronics": "Électronique", + "Furniture": "Mobilier", + "Household Supplies": "Fournitures ménagères", + "Maintenance": "Entretien", + "Mortgage": "Hypothèque", + "Pets": "Animaux", + "Rent": "Loyer", + "Services": "Services" + }, + "Life": { + "heading": "Vie", + "Childcare": "Garde d'enfants", + "Clothing": "Vêtements", + "Education": "Éducation", + "Gifts": "Cadeaux", + "Insurance": "Assurance", + "Medical Expenses": "Dépenses médicales", + "Taxes": "Impôts" + }, + "Transportation": { + "heading": "Transport", + "Transportation": "Transport", + "Bicycle": "Bicyclette", + "Bus/Train": "Bus/Train", + "Car": "Voiture", + "Gas/Fuel": "Essence/Carburant", + "Hotel": "Hôtel", + "Parking": "Parking", + "Plane": "Avion", + "Taxi": "Taxi" + }, + "Utilities": { + "heading": "Services publics", + "Utilities": "Services publics", + "Cleaning": "Nettoyage", + "Electricity": "Électricité", + "Heat/Gas": "Chauffage/Gaz", + "Trash": "Poubelle", + "TV/Phone/Internet": "TV/Téléphone/Internet", + "Water": "Eau" + } + } +} diff --git a/src/app/page.tsx b/src/app/page.tsx index 8aa9bda..b14c12a 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,31 +1,35 @@ import { Button } from '@/components/ui/button' import { Github } from 'lucide-react' +import { useTranslations } from 'next-intl' import Link from 'next/link' // FIX for https://github.com/vercel/next.js/issues/58615 // export const dynamic = 'force-dynamic' export default function HomePage() { + const t = useTranslations() return (
-

- Share Expenses
with Friends{' '} - & Family +

+ {t.rich('Homepage.title', { + strong: (chunks) => {chunks}, + })}

- Welcome to your new Spliit instance!
- Customize this page by editing src/app/page.tsx. + {t.rich('Homepage.description', { + strong: (chunks) => {chunks}, + })}

diff --git a/src/i18n.ts b/src/i18n.ts index 464c83d..2706589 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'] as const +export const locales = ['en-US', 'fi', 'fr-FR'] as const export type Locale = (typeof locales)[number] export type Locales = ReadonlyArray export const defaultLocale: Locale = 'en-US'