Implémentation complète du multilingue FR/EN

- Installation vue-i18n v11 et création des fichiers de traduction (fr.json, en.json)
- Création store locale avec détection hiérarchique (URL > localStorage > navigator)
- Modification des routes avec préfixe /:locale? optionnel
- Toggle FR/EN dans Menu.vue avec synchronisation immédiate
- Traduction de ~200 textes dans 27 composants Vue
- Suppression des labels hardcodés en français côté backend
- Ajout route Kirby catch-all en/(:all?) pour /en/ URLs
- Helper addLocalePrefix() pour préserver locale dans liens dialogs
- Traduction pseudo-élément CSS via data attribute

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
isUnknown 2026-02-02 18:21:11 +01:00
parent 3af95b1d20
commit 82eb8d88cc
49 changed files with 1079 additions and 295 deletions

198
src/locales/en.json Normal file
View file

@ -0,0 +1,198 @@
{
"menu": {
"home": "Home",
"notifications": "Notifications",
"meetings": "Meetings",
"designToLight": "Design to Light",
"inspirations": "Inspirations",
"profile": "Profile",
"logout": "Logout",
"currentProjects": "Current projects",
"archivedProjects": "Archived projects",
"news": "New",
"show": "Show menu",
"hide": "Hide menu",
"newModifications": "New modifications"
},
"steps": {
"clientBrief": "Client brief",
"proposal": "Commercial proposal",
"extendedBrief": "Extended brief",
"industrialIdeation": "Industrial ideation",
"virtualSample": "Virtual sample",
"physicalSample": "Physical sample"
},
"dtl": {
"dynamicTrack": "Virtual sample - dynamic track",
"staticTrack": "Virtual sample - static track",
"title": "Design to Light",
"grade": "Design to Light: {grade}",
"globalScore": "Global score",
"positioning": "Positioning",
"design": "Design",
"weight": "Weight",
"indicators": "Component indicators",
"requestOptimization": "Request optimization expertise",
"requestPending": "Expertise request being processed…",
"initialProposal": "Initial proposal",
"alternative": "Alternative {index}",
"proposalBasedOn": "Data based on the proposal"
},
"buttons": {
"edit": "Edit",
"cancel": "Cancel",
"save": "Save",
"delete": "Delete",
"submit": "Submit",
"retry": "Retry",
"add": "Add",
"close": "Close",
"validate": "Validate and send the brief",
"validateMinimum": "Add at least one image",
"showPassword": "Show password",
"hidePassword": "Hide password",
"showProject": "Show project",
"hideProject": "Hide project",
"showComments": "Show comments",
"hideComments": "Hide comments",
"backToProject": "Back to project",
"backToList": "Back to list",
"addComment": "Add a comment",
"reply": "Reply…",
"seeAll": "See all",
"deleteImage": "Delete this image",
"downloadImage": "Download image",
"downloadImages": "Download images",
"downloadPdf": "Download PDF",
"update": "Update",
"requestMeeting": "Request a meeting",
"markAllAsRead": "Mark all as read",
"loopAnimation": "Loop animation",
"stopAnimation": "Stop animation",
"compareTracks": "Compare tracks",
"exitCompare": "Exit compare mode"
},
"forms": {
"email": "Email",
"emailPlaceholder": "email@example.com",
"password": "Password",
"passwordPlaceholder": "Minimum 8 characters",
"newPassword": "New password",
"confirmPassword": "Confirm new password…",
"projectName": "Project name",
"projectDetails": "Project details",
"projectDetailsPlaceholder": "Project details…",
"meetingSubject": "Meeting subject",
"meetingDetails": "Project details",
"meetingDetailsPlaceholder": "Describe your request…",
"description": "Project description",
"descriptionPlaceholder": "Add a general description of your project…",
"imageDescription": "Image description",
"imageDescriptionPlaceholder": "Add a description to the image…",
"commentPlaceholder": "Add a comment…",
"filterByTags": "Filter by tags",
"tags": "Tags",
"selectVariation": "Select a variation",
"uploadedFiles": "Uploaded files",
"addImages": "Add one or more images"
},
"auth": {
"login": "Login",
"passwordShown": "Password shown",
"passwordHidden": "Password hidden",
"fillFields": "Please fill in the fields.",
"inProgress": "In progress…",
"updateSuccess": "Update successful",
"updateInProgress": "in progress…"
},
"account": {
"comments": "Comments",
"noClient": "No associated client",
"managedProjects": "Managed projects",
"myProjects": "My projects",
"currentStep": "Current step:",
"projectCount": "Number of projects",
"clientLogo": "{clientName} logo"
},
"brief": {
"addPlatform": "Add a brief via the platform",
"addPdf": "Add a PDF brief",
"projects": "Projects"
},
"comments": {
"title": "Comments",
"your": "Your comment",
"new": "New comment",
"newInstruction": "In the content area, click where you want to position the comment",
"reply": "reply",
"replies": "replies",
"edit": "Edit",
"inProgress": "In progress",
"emptyMessage": "Share your ideas by adding comments"
},
"dates": {
"today": "Today",
"yesterday": "yesterday",
"updatedOn": "Last updated on"
},
"projects": {
"none": "No projects at the moment",
"current": "Current projects",
"archived": "Archived projects"
},
"notifications": {
"title": "Notifications",
"none": "You have no new notifications",
"noneUnread": "You have no unread notifications",
"all": "All",
"unread": "Unread",
"projectRequest": "Project creation request",
"meetingRequest": "Meeting request",
"content": "Content",
"draft": "(draft)",
"from": "From",
"author": "Author:",
"goToContent": "Go to content"
},
"meetings": {
"none": "You have no scheduled meetings",
"upcoming": "Upcoming",
"past": "Past"
},
"inspirations": {
"title": "Inspirations",
"favorites": "My Favorites",
"addToFavorites": "Add to favorites",
"removeFromFavorites": "Remove from favorites",
"new": "New"
},
"dialogs": {
"requestProject": "Request project creation",
"requestMeeting": "Request a meeting",
"imageDetails": "Image details",
"addImages": "Add images",
"deleteConfirm": "Are you sure you want to delete this image?",
"deleteWarning": "If you delete this image, it will disappear from your brief along with all the information attributed to it.",
"pdfTitle": "PDF title",
"renderTitle": "Render title",
"createWithDTL": "Create with Design to Light",
"learnMore": "Learn more",
"dtlDescription": "Discover the environmental score of your project..."
},
"virtualSample": {
"title": "Virtual sample",
"dynamicPresentation": "Dynamic presentation",
"staticView": "Static view",
"noContent": "Content not available for this track",
"selectToCompare": "Select the track you want to compare"
},
"errors": {
"saveFailed": "Save failed",
"deleteFailed": "Delete failed",
"toggleProjectFailed": "Failed to show/hide project",
"toggleFavoriteFailed": "Failed to toggle favorite",
"readNotificationFailed": "Failed to read notification:",
"readAllNotificationsFailed": "Could not read all notifications",
"markNotificationFailed": "Could not mark notification as read"
}
}

198
src/locales/fr.json Normal file
View file

@ -0,0 +1,198 @@
{
"menu": {
"home": "Home",
"notifications": "Notifications",
"meetings": "Réunions",
"designToLight": "Design to Light",
"inspirations": "Inspirations",
"profile": "Profil",
"logout": "Déconnexion",
"currentProjects": "Projets en cours",
"archivedProjects": "Projets archivés",
"news": "Nouveautés",
"show": "Afficher le menu",
"hide": "Masquer le menu",
"newModifications": "Nouvelles modifications"
},
"steps": {
"clientBrief": "Brief client",
"proposal": "Proposition commerciale",
"extendedBrief": "Brief enrichi",
"industrialIdeation": "Idéation industrielle",
"virtualSample": "Échantillon virtuel",
"physicalSample": "Échantillon physique"
},
"dtl": {
"dynamicTrack": "Échantillon virtuel - piste dynamique",
"staticTrack": "Échantillon virtuel - piste statique",
"title": "Design to Light",
"grade": "Design to Light: {grade}",
"globalScore": "Note globale",
"positioning": "Positionnement",
"design": "Design",
"weight": "Poids",
"indicators": "Indicateur des composants impliqués",
"requestOptimization": "Demander une expertise d'optimisation",
"requestPending": "Demande d'expertise en cours de traitement…",
"initialProposal": "Proposition initiale",
"alternative": "Alternative {index}",
"proposalBasedOn": "Données basées sur la proposition"
},
"buttons": {
"edit": "Modifier",
"cancel": "Annuler",
"save": "Sauvegarder",
"delete": "Supprimer",
"submit": "Soumettre",
"retry": "Réessayer",
"add": "Ajouter",
"close": "Fermer",
"validate": "Valider et envoyer le brief",
"validateMinimum": "Ajoutez au moins une image",
"showPassword": "Afficher le mot de passe",
"hidePassword": "Masquer le mot de passe",
"showProject": "Afficher le projet",
"hideProject": "Masquer le projet",
"showComments": "Afficher les commentaires",
"hideComments": "Masquer les commentaires",
"backToProject": "Retour au projet",
"backToList": "Retour à la liste",
"addComment": "Ajouter un commentaire",
"reply": "Répondre…",
"seeAll": "Voir tout",
"deleteImage": "Supprimer cette image",
"downloadImage": "Télécharger l'image",
"downloadImages": "Télécharger les images",
"downloadPdf": "Télécharger le PDF",
"update": "Mettre à jour",
"requestMeeting": "Demander un RDV",
"markAllAsRead": "Marquer tout comme lu",
"loopAnimation": "Animation en boucle",
"stopAnimation": "Arrêter l'animation",
"compareTracks": "Comparer les pistes",
"exitCompare": "Quitter le mode comparer"
},
"forms": {
"email": "Email",
"emailPlaceholder": "mail@exemple.com",
"password": "Mot de passe",
"passwordPlaceholder": "Minimum 8 caractères",
"newPassword": "Nouveau mot de passe",
"confirmPassword": "Confirmez le nouveau mot de passe…",
"projectName": "Nom du projet",
"projectDetails": "Détails du projet",
"projectDetailsPlaceholder": "Détails du projet…",
"meetingSubject": "Objet du rendez-vous",
"meetingDetails": "Détails du projet",
"meetingDetailsPlaceholder": "Décrivez votre demande…",
"description": "Description du projet",
"descriptionPlaceholder": "Ajoutez une description générale de votre projet…",
"imageDescription": "Description de l'image",
"imageDescriptionPlaceholder": "Ajoutez une description à l'image…",
"commentPlaceholder": "Ajouter un commentaire…",
"filterByTags": "Filtrer par tags",
"tags": "Tags",
"selectVariation": "Sélectionnez une déclinaison",
"uploadedFiles": "Fichiers importés",
"addImages": "Ajouter une ou plusieurs images"
},
"auth": {
"login": "Connexion",
"passwordShown": "Mot de passe affiché",
"passwordHidden": "Mot de passe masqué",
"fillFields": "Veuillez remplir les champs.",
"inProgress": "En cours…",
"updateSuccess": "Mise à jour réussie",
"updateInProgress": "en cours…"
},
"account": {
"comments": "Commentaires",
"noClient": "Pas de client associé",
"managedProjects": "Projets managés",
"myProjects": "Mes projets",
"currentStep": "Étape en cours :",
"projectCount": "Nombre de projets",
"clientLogo": "logo {clientName}"
},
"brief": {
"addPlatform": "Ajouter un brief via la plateforme",
"addPdf": "Ajouter un brief PDF",
"projects": "Projets"
},
"comments": {
"title": "Commentaires",
"your": "Votre commentaire",
"new": "Nouveau commentaire",
"newInstruction": "Dans la zone du contenu, cliquez où vous souhaitez positionner le commentaire",
"reply": "réponse",
"replies": "réponses",
"edit": "Éditer",
"inProgress": "En cours",
"emptyMessage": "Partagez vos idées en ajoutant des commentaires"
},
"dates": {
"today": "Aujourd'hui",
"yesterday": "hier",
"updatedOn": "Dernière mise à jour le"
},
"projects": {
"none": "Aucun projet pour le moment",
"current": "Projets en cours",
"archived": "Projets archivés"
},
"notifications": {
"title": "Notifications",
"none": "Vous n'avez pas de nouvelles notifications",
"noneUnread": "Vous n'avez pas de notifications non lues",
"all": "Tout",
"unread": "Non lu",
"projectRequest": "Demande de création de projet",
"meetingRequest": "Demande de rendez-vous",
"content": "Contenu",
"draft": "(brouillon)",
"from": "De la part de",
"author": "Auteur :",
"goToContent": "Aller au contenu"
},
"meetings": {
"none": "Vous n'avez aucune réunion programmée",
"upcoming": "À venir",
"past": "Passées"
},
"inspirations": {
"title": "Les Inspirations",
"favorites": "Mes Favoris",
"addToFavorites": "Ajouter aux favoris",
"removeFromFavorites": "Retirer des favoris",
"new": "Nouveauté"
},
"dialogs": {
"requestProject": "Demander la création d'un projet",
"requestMeeting": "Demander un rendez-vous",
"imageDetails": "Détails de l'image",
"addImages": "Ajouter des images",
"deleteConfirm": "Êtes-vous sûr de vouloir supprimer cette image ?",
"deleteWarning": "Si vous supprimez cette image, celle-ci disparaîtra de votre brief ainsi que toutes les informations qui lui sont attribuées.",
"pdfTitle": "Titre du PDF",
"renderTitle": "Titre du rendu",
"createWithDTL": "Créer avec Design to Light",
"learnMore": "En savoir plus",
"dtlDescription": "Découvrez la note environnementale de votre projet..."
},
"virtualSample": {
"title": "Échantillon virtuel",
"dynamicPresentation": "Présentation dynamique",
"staticView": "Vue statique",
"noContent": "Contenu non disponible pour cette piste",
"selectToCompare": "Sélectionnez sur la piste que vous souhaitez comparer"
},
"errors": {
"saveFailed": "Erreur lors de la sauvegarde",
"deleteFailed": "Erreur lors de la suppression",
"toggleProjectFailed": "Erreur lors du masquage/affichage du projet",
"toggleFavoriteFailed": "Failed to toggle favorite",
"readNotificationFailed": "Erreur lors de la lecture de la notification :",
"readAllNotificationsFailed": "Could not read all notifications",
"markNotificationFailed": "Could not mark notification as read"
}
}