feat(i18n): add French language support and enhance localization
All checks were successful
Deploy to production / deploy (push) Successful in 2m48s

- Introduced French as a supported language across the application, updating locale files and adding translations for various components.
- Enhanced language handling logic to accommodate French, ensuring proper detection and fallback mechanisms.
- Updated UI elements to include French language options, improving accessibility for French-speaking users.
- Refactored SEO handling to include French in hreflang links, enhancing search engine indexing for multilingual content.
- Added new scripts for managing French translations and ensuring consistency across language files.
This commit is contained in:
Torsten Schulz (local)
2026-04-07 18:04:03 +02:00
parent f715c6125d
commit f7030bbabe
56 changed files with 5220 additions and 175 deletions

View File

@@ -0,0 +1,249 @@
{
"settings": {
"personal": {
"title": "Données personnelles",
"label": {
"language": "Langue",
"birthdate": "date de naissance",
"gender": "Geschlecht",
"town": "Stadt",
"zip": "Code postal",
"eyecolor": "Couleur des yeux",
"haircolor": "couleur de cheveux",
"hairlength": "longueur des cheveux",
"skincolor": "Couleur de peau",
"freckles": "Taches de rousseur",
"weight": "Poids",
"bodyheight": "Größe",
"piercings": "piercings",
"tattoos": "Tatouages",
"sexualpreference": "Alignement",
"pubichair": "poils pubiens",
"penislength": "Longueur du pénis",
"brasize": "Taille du soutien-gorge",
"willChildren": "je veux des enfants",
"smokes": "Fumée",
"drinks": "je bois de l'alcool",
"hasChildren": "j'ai des enfants",
"interestedInGender": "Intéressé par"
},
"tooltip": {
"language": "Langue",
"birthdate": "date de naissance",
"gender": "Geschlecht",
"town": "Stadt",
"zip": "Code postal",
"eyecolor": "Couleur des yeux",
"haircolor": "couleur de cheveux",
"hairlength": "longueur des cheveux",
"skincolor": "Couleur de peau",
"freckles": "Taches de rousseur",
"weight": "Poids",
"bodyheight": "Größe",
"piercings": "piercings",
"tattoos": "Tatouages",
"sexualpreference": "Alignement",
"pubichair": "poils pubiens",
"penislength": "Longueur du pénis",
"brasize": "Taille du soutien-gorge"
},
"gender": {
"male": "Männlich",
"female": "Weiblich",
"transmale": "Femme trans",
"transfemale": "Homme trans",
"nonbinary": "Non binaire"
},
"language": {
"de": "Allemand",
"en": "Anglais",
"ceb": "Bisaya",
"es": "Espagnol",
"fr": "Français"
},
"eyecolor": {
"blue": "Bleu",
"green": "Vert",
"brown": "Brun",
"black": "Noir",
"grey": "Gris",
"hazel": "noisette",
"amber": "ambre",
"red": "Rouge",
"other": "Autre"
},
"haircolor": {
"black": "Noir",
"brown": "Brun",
"blonde": "Blond",
"red": "Rouge",
"grey": "Gris",
"white": "Blanc",
"other": "Autre"
},
"hairlength": {
"short": "Court",
"medium": "Moyen",
"long": "Long",
"bald": "Chauve",
"other": "Autre"
},
"skincolor": {
"light": "Brillant",
"medium": "Moyen",
"dark": "Sombre",
"other": "Autre"
},
"freckles": {
"much": "Beaucoup",
"medium": "Moyen",
"less": "Peu",
"none": "Non"
},
"sexualpreference": {
"straight": "Hétérosexuel",
"gay": "Gays",
"bi": "Bisexuel",
"asexual": "Asexué",
"pan": "Pansexuel"
},
"pubichair": {
"none": "Non",
"short": "Court",
"medium": "Moyen",
"long": "Long",
"hairy": "Naturellement",
"waxed": "Enlèvement de cire chaude",
"landingstrip": "piste",
"bikinizone": "Zone bikini uniquement",
"other": "Autre"
},
"interestedInGender": {
"male": "Hommes",
"female": "Femmes"
},
"smokes": {
"often": "Souvent",
"socially": "En compagnie",
"daily": "Tous les jours",
"never": "Jamais"
},
"drinks": {
"often": "Souvent",
"socially": "En compagnie",
"daily": "Tous les jours",
"never": "Jamais"
}
},
"view": {
"title": "Regarder"
},
"sexuality": {
"title": "sexualité"
},
"account": {
"title": "compte",
"heroEyebrow": "Paramètres",
"heroIntro": "Conservez le nom dutilisateur, le-mail, le mot de passe et la visibilité en un seul endroit.",
"username": "nom d'utilisateur",
"email": "Adresse email",
"newpassword": "Passwort",
"newpasswordretype": "Répéter le mot de passe",
"deleteAccount": "Supprimer le compte",
"language": "Langue",
"showinsearch": "Afficher dans les recherches des utilisateurs",
"changeaction": "Modifier les données utilisateur",
"oldpassword": "Ancien mot de passe (obligatoire)",
"validation": {
"newPasswordTooShort": "Le nouveau mot de passe doit comporter au moins 8 caractères.",
"passwordMismatch": "Les mots de passe ne correspondent pas.",
"oldPasswordRequired": "Le mot de passe actuel est requis pour modifier le mot de passe."
},
"feedback": {
"saved": "Paramètres du compte enregistrés avec succès.",
"saveError": "Une erreur s'est produite lors de l'enregistrement des paramètres du compte."
},
"adultAccessTitle": "Espace érotique",
"adultAccessIntro": "La zone érotique est uniquement destinée aux utilisateurs majeurs et est également activée par les modérateurs.",
"requestAdultVerification": "Demander l'activation",
"requestAdultVerificationSuccess": "L'activation a été demandée.",
"requestAdultVerificationError": "L'activation n'a pas pu être demandée.",
"adultStatus": {
"ineligible": {
"title": "Pas disponible",
"body": "La zone érotique nest visible que par les utilisateurs majeurs."
},
"none": {
"title": "Pas encore activé",
"body": "La zone est visible mais verrouillée jusqu'à ce qu'elle soit examinée par un modérateur."
},
"pending": {
"title": "L'examen est en cours",
"body": "Votre demande est en cours d'examen pour modération. La zone restera fermée jusqu'à sa libération."
},
"approved": {
"title": "Débloqué",
"body": "L'espace érotique est activé pour votre compte."
},
"rejected": {
"title": "Activation rejetée",
"body": "La dernière demande n'a pas été publiée. Vous pouvez faire une nouvelle demande."
}
}
},
"languageAssistant": {
"eyebrow": "Paramètres",
"title": "Assistant vocal et IA",
"intro": "Ici, vous pouvez stocker votre propre accès API (par exemple OpenAI), que la plateforme peut utiliser pour les fonctions de cours de langue. La clé est stockée cryptée côté serveur ; vous avez besoin d'un compte auprès du fournisseur concerné.",
"linkSignup": "Créer un compte avec OpenAI (nouvelle fenêtre)",
"linkApiKeys": "Gérer les clés API chez OpenAI (nouvelle fenêtre)",
"enabled": "Autoriser l'utilisation des fonctions vocales",
"baseUrl": "URL de base de l'API (facultatif)",
"baseUrlPlaceholder": "Vide = Par défaut (OpenAI). Pour Ollama par ex. Par ex. http://127.0.0.1:11434/v1",
"model": "Nom du modèle",
"apiKey": "Clé API",
"apiKeyHint": "Laissez vide pour conserver la clé enregistrée.",
"apiKeyPlaceholderNew": "Insérer une nouvelle clé",
"apiKeyPlaceholderHasKey": "L'enregistrement se termine dans  {last4}  en laissant ce champ vide, la clé est conservée.",
"apiKeyPlaceholderClear": "La mémoire sera effacée lorsque vous enregistrerez « Supprimer la clé » ci-dessous",
"clearKey": "Supprimer la clé API enregistrée",
"save": "Sauvegarder",
"saved": "Paramètres enregistrés.",
"saveError": "L'enregistrement a échoué.",
"confirmClear": "Vraiment supprimer les clés API ?",
"keyStatusStored": "Clé API enregistrée.",
"keyStatusInvalid": "Une clé API stockée existe mais ne peut pas être lue. Veuillez réenregistrer.",
"keyStatusMissing": "Aucune clé API n'est actuellement stockée."
},
"interests": {
"title": "Interessen",
"new": "Nouvel intérêt",
"add": "Ajouter",
"added": "Le nouvel intérêt a été ajouté et est en cours de modification. Tant qu'il n'est pas terminé, il ne sera pas visible dans la liste d'intérêts.",
"adderror": "Une erreur s'est produite lors de l'ajout des intérêts.",
"errorsetinterest": "Les intérêts n'ont pas pu être réservés pour vous."
},
"visibility": {
"Invisible": "Ne pas montrer",
"OnlyFriends": "Afficher uniquement aux amis",
"FriendsAndAdults": "Montrer aux amis et aux adultes",
"AdultsOnly": "Afficher uniquement pour les adultes",
"All": "Montrer à tout le monde"
},
"feedback": {
"updateError": "La modification n'a pas pu être enregistrée.",
"visibilityUpdateError": "La visibilité n'a pas pu être mise à jour."
},
"flirt": {
"title": "flirter"
},
"immutable": {
"tooltip": "Ce champ ne peut pas être modifié. Pour les modifications, veuillez contacter le support.",
"supportContact": "Contacter l'assistance",
"supportMessage": {
"general": "Bonjour,\n\nJe souhaite demander une modification de mes données de profil non modifiables. \n\nVeuillez me contacter pour plus de détails. \n\nCordialement",
"specific": "Bonjour,\n\nJe souhaite demander une modification des données de profil immuables suivantes : {fields}\n\nVeuillez me contacter pour plus de détails. \n\nCordialement"
}
}
}
}