diff --git a/scripts/find-missing-translations.ts b/scripts/find-missing-translations.ts new file mode 100644 index 0000000000..fb9e488ee7 --- /dev/null +++ b/scripts/find-missing-translations.ts @@ -0,0 +1,87 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ + +// npx tsx scripts/find-missing-translations.ts + +import fs from 'fs'; +import path from 'path'; + +function extractKeys(obj: any, prefix = ''): string[] { + let keys: string[] = []; + + for (const key in obj) { + const currentKey = prefix ? `${prefix}.${key}` : key; + + if (typeof obj[key] === 'object' && obj[key] !== null) { + keys = [...keys, ...extractKeys(obj[key], currentKey)]; + } else { + keys.push(currentKey); + } + } + + return keys; +} + +async function main() { + const rootDir = path.resolve(__dirname, '..'); + const localesDir = path.join('src', 'i18n', 'locales'); + + const files = fs + .readdirSync(path.join(rootDir, localesDir)) + .filter((file) => file.endsWith('.json')) + .map((file) => path.join(rootDir, localesDir, file)); + + const localeKeys: { [locale: string]: Set } = {}; + const allKeys = new Set(); + + for (const file of files) { + const keys = extractKeys(JSON.parse(fs.readFileSync(file, 'utf8'))); + const relativePath = path.join(localesDir, path.basename(file)); + localeKeys[relativePath] = new Set(keys); + + for (const key of keys) { + allKeys.add(key); + } + } + + Object.entries(localeKeys).forEach(([locale, keys]) => { + const missingKeys = Array.from(allKeys).filter((key) => !keys.has(key)); + + if (missingKeys.length > 0) { + console.log( + `\n[${locale}] Missing ${missingKeys.length} translation(s):`, + ); + + const groupedMissing = new Map(); + + for (const key of missingKeys) { + const parts = key.split('.'); + + if (parts.length >= 2) { + const namespace = parts[0]; + const subKey = parts.slice(1).join('.'); + + if (namespace && subKey) { + if (!groupedMissing.has(namespace)) { + groupedMissing.set(namespace, []); + } + + const group = groupedMissing.get(namespace); + + if (group) { + group.push(subKey); + } + } + } + } + + for (const [namespace, keys] of groupedMissing.entries()) { + console.log(`${namespace}`); + keys.forEach((key) => console.log(`\t${key}`)); + } + } else { + console.log(`\n[${locale}] No missing translations`); + } + }); +} + +main(); diff --git a/src/actions/locale.ts b/src/actions/locale.ts index c5c5649b44..922d01fc4e 100644 --- a/src/actions/locale.ts +++ b/src/actions/locale.ts @@ -1,6 +1,6 @@ 'use server'; -import type { Locale } from '@/lib/locale'; +import type { Locale } from '@/i18n/locale'; import { cookies } from 'next/headers'; export const setLocale = async (locale: Locale) => { diff --git a/src/app/(authenticated)/dashboard/layout.tsx b/src/app/(authenticated)/dashboard/layout.tsx index 978b53eea6..92c48bf18b 100644 --- a/src/app/(authenticated)/dashboard/layout.tsx +++ b/src/app/(authenticated)/dashboard/layout.tsx @@ -1,13 +1,5 @@ -import { getLocale, getTranslations } from 'next-intl/server'; - import { DashboardHeader } from '@/components/dashboard/DashboardHeader'; -export async function generateMetadata() { - const locale = await getLocale(); - const t = await getTranslations({ locale, namespace: 'Dashboard' }); - return { title: t('meta_title'), description: t('meta_description') }; -} - export default function DashboardLayout({ children, }: { diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 4298cbc84d..98126527b3 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -5,7 +5,7 @@ import { NextIntlClientProvider } from 'next-intl'; import { getLocale, getTranslations, setRequestLocale } from 'next-intl/server'; import { ClerkProvider } from '@clerk/nextjs'; -import { getClerkLocale } from '@/lib/locale'; +import { getClerkLocale } from '@/i18n/locale'; import { ThemeProvider } from '@/components/layout'; import { ToastProvider, ToastViewport } from '@/components/ui/toast'; import { ToastProvider as ToastContextProvider } from '@/components/ui/toast-context'; diff --git a/src/app/onboarding/create-org/page.tsx b/src/app/onboarding/create-org/page.tsx index e37ad9bb07..a77dc2ba19 100644 --- a/src/app/onboarding/create-org/page.tsx +++ b/src/app/onboarding/create-org/page.tsx @@ -1,13 +1,5 @@ -import { getLocale, getTranslations } from 'next-intl/server'; - import { CreateOrg } from './CreateOrg'; -export async function generateMetadata() { - const locale = await getLocale(); - const t = await getTranslations({ locale, namespace: 'Dashboard' }); - return { title: t('meta_title'), description: t('meta_description') }; -} - export const dynamic = 'force-dynamic'; export default async function Page() { diff --git a/src/app/onboarding/select-org/page.tsx b/src/app/onboarding/select-org/page.tsx index fd9ef9fdb8..55f9e416d2 100644 --- a/src/app/onboarding/select-org/page.tsx +++ b/src/app/onboarding/select-org/page.tsx @@ -1,13 +1,5 @@ -import { getLocale, getTranslations } from 'next-intl/server'; - import { SelectOrg } from './SelectOrg'; -export async function generateMetadata() { - const locale = await getLocale(); - const t = await getTranslations({ locale, namespace: 'Dashboard' }); - return { title: t('meta_title'), description: t('meta_description') }; -} - export const dynamic = 'force-dynamic'; export default async function Page() { diff --git a/src/app/robots.ts b/src/app/robots.ts index c1807a9ddc..f0895a48d6 100644 --- a/src/app/robots.ts +++ b/src/app/robots.ts @@ -1,6 +1,6 @@ import type { MetadataRoute } from 'next'; -import { getBaseUrl } from '@/lib/getBaseUrl'; +import { getBaseUrl } from '@/lib/metadata'; export default function robots(): MetadataRoute.Robots { return { diff --git a/src/app/sign-in/[[...sign-in]]/page.tsx b/src/app/sign-in/[[...sign-in]]/page.tsx index e84bb8bfda..ce5806e022 100644 --- a/src/app/sign-in/[[...sign-in]]/page.tsx +++ b/src/app/sign-in/[[...sign-in]]/page.tsx @@ -1,13 +1,5 @@ -import { getLocale, getTranslations } from 'next-intl/server'; - import { SignIn } from './SignIn'; -export async function generateMetadata() { - const locale = await getLocale(); - const t = await getTranslations({ locale, namespace: 'SignIn' }); - return { title: t('meta_title'), description: t('meta_description') }; -} - export default function Page() { return ; } diff --git a/src/app/sign-up/[[...sign-up]]/page.tsx b/src/app/sign-up/[[...sign-up]]/page.tsx index 038a2156ab..8ba5958761 100644 --- a/src/app/sign-up/[[...sign-up]]/page.tsx +++ b/src/app/sign-up/[[...sign-up]]/page.tsx @@ -1,13 +1,5 @@ -import { getLocale, getTranslations } from 'next-intl/server'; - import { SignUp } from './SignUp'; -export async function generateMetadata() { - const locale = await getLocale(); - const t = await getTranslations({ locale, namespace: 'SignUp' }); - return { title: t('meta_title'), description: t('meta_description') }; -} - export default function Page() { return ; } diff --git a/src/app/sitemap.ts b/src/app/sitemap.ts index 2b48226917..2e265493d5 100644 --- a/src/app/sitemap.ts +++ b/src/app/sitemap.ts @@ -1,6 +1,6 @@ import type { MetadataRoute } from 'next'; -import { getBaseUrl } from '@/lib/getBaseUrl'; +import { getBaseUrl } from '@/lib/metadata'; export default function sitemap(): MetadataRoute.Sitemap { return [ diff --git a/src/components/dashboard/DefaultParametersPage.tsx b/src/components/dashboard/DefaultParametersPage.tsx index d962c250d9..1bc3bb4917 100644 --- a/src/components/dashboard/DefaultParametersPage.tsx +++ b/src/components/dashboard/DefaultParametersPage.tsx @@ -20,7 +20,6 @@ import { Input } from '@/components/ui/input'; import { Slider } from '@/components/ui/slider'; import { useToast } from '@/components/ui/toast-context'; -// Default parameters form type type DefaultParamsFormValues = { experimentalPowerSteering: boolean; terminalOutputLimit: number; @@ -52,7 +51,6 @@ const DefaultParametersPage = () => { const [isSaving, setIsSaving] = useState(false); - // Form for default parameters const form = useForm({ defaultValues: { experimentalPowerSteering: true, diff --git a/src/components/dashboard/UsageAnalyticsCard.tsx b/src/components/dashboard/UsageAnalyticsCard.tsx index c12383437e..433b0e8600 100644 --- a/src/components/dashboard/UsageAnalyticsCard.tsx +++ b/src/components/dashboard/UsageAnalyticsCard.tsx @@ -1,10 +1,10 @@ 'use client'; +import React, { useMemo, useState } from 'react'; import Link from 'next/link'; import { useTranslations } from 'next-intl'; -import React, { useMemo, useState } from 'react'; -import { Button } from '@/components/ui/button'; +import { Button } from '@/components/ui'; type TimePeriod = '7' | '30' | '90'; @@ -20,9 +20,7 @@ export const UsageAnalyticsCard = () => { const t = useTranslations('DashboardIndex'); const [timePeriod, setTimePeriod] = useState('7'); - // Mock data based on selected time period const analyticsData = useMemo(() => { - // Return different data based on timePeriod switch (timePeriod) { case '7': return { @@ -59,8 +57,6 @@ export const UsageAnalyticsCard = () => { {t('analytics_description')}

- - {/* Time period toggle */}
- - {/* Metrics grid */}
- {/* Active Developers */}
{t('analytics_active_developers')} @@ -96,8 +89,6 @@ export const UsageAnalyticsCard = () => { {analyticsData.activeDevelopers}
- - {/* Tasks Started */}
{t('analytics_tasks_started')} @@ -106,8 +97,6 @@ export const UsageAnalyticsCard = () => { {analyticsData.tasksStarted}
- - {/* Tasks Completed */}
{t('analytics_tasks_completed')} @@ -116,8 +105,6 @@ export const UsageAnalyticsCard = () => { {analyticsData.tasksCompleted}
- - {/* Tokens Consumed */}
{t('analytics_tokens_consumed')} @@ -126,8 +113,6 @@ export const UsageAnalyticsCard = () => { {analyticsData.tokensConsumed}
- - {/* LLM Model Costs */}
{t('analytics_llm_costs')} @@ -137,8 +122,6 @@ export const UsageAnalyticsCard = () => {
- - {/* Link to detailed analytics */}
SaaS template to build and scale your business with ease.", - "description": "A free and open-source landing page template for your SaaS business, built with React, TypeScript, Shadcn UI, and Tailwind CSS.", - "primary_button": "Get Started", - "secondary_button": "Star on GitHub" - }, - "Sponsors": { - "title": "Sponsored by" - }, - "Features": { - "section_subtitle": "Features", - "section_title": "Unlock the Full Potential of the SaaS Template", - "section_description": "A free and open-source landing page template for your SaaS business, built with React, TypeScript, Shadcn UI, and Tailwind CSS.", - "feature1_title": "Node.js", - "feature2_title": "React", - "feature3_title": "Tailwind CSS", - "feature4_title": "TypeScript", - "feature5_title": "Shadcn UI", - "feature6_title": "ESLint", - "feature_description": "A free and open-source landing page template for your SaaS business, built with React, TypeScript, Shadcn UI, and Tailwind CSS." - }, - "Pricing": { - "section_subtitle": "Features", - "section_title": "Unlock the Full Potential of the SaaS Template", - "section_description": "A free and open-source landing page template for your SaaS business, built with React, TypeScript, Shadcn UI, and Tailwind CSS.", - "button_text": "Get Started" - }, - "PricingPlan": { - "free_plan_name": "Free", - "premium_plan_name": "Premium", - "enterprise_plan_name": "Enterprise", - "free_plan_description": "For individuals", - "premium_plan_description": "For small teams", - "enterprise_plan_description": "For industry leaders", - "feature_team_member": "{number} Team Members", - "feature_website": "{number} Websites", - "feature_storage": "{number} GB Storage", - "feature_transfer": "{number} TB Transfer", - "feature_email_support": "Email Support", - "plan_interval_month": "month", - "plan_interval_year": "year", - "next_renew_date": "Your subscription renews on {date}" - }, - "FAQ": { - "question": "Lorem ipsum dolor sit amet, consectetur adipiscing elit?", - "answer": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam aliquam enim dui, id consequat turpis ullamcorper ac. Mauris id quam dolor. Nullam eu egestas turpis. Proin risus elit, sollicitudin in mi a, accumsan euismod turpis. In euismod mi sed diam tristique hendrerit." - }, - "CTA": { - "title": "You are ready?", - "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", - "button_text": "Star on GitHub" + "sign_up": "Sign Up" }, "Footer": { - "product": "Product", - "docs": "Docs", - "blog": "Blog", - "community": "Community", - "company": "Company", "terms_of_service": "Terms Of Service", - "privacy_policy": "Privacy Policy", - "designed_by": "Designed by ." - }, - "ProtectFallback": { - "not_enough_permission": "You do not have the permissions to perform this action" - }, - "SignIn": { - "meta_title": "Sign in", - "meta_description": "Seamlessly sign in to your account with our user-friendly login process." - }, - "SignUp": { - "meta_title": "Sign up", - "meta_description": "Effortlessly create an account through our intuitive sign-up process." + "privacy_policy": "Privacy Policy" }, "DashboardLayout": { "home": "Home", "analytics": "Analytics", - "todos": "Todos", "members": "Members", "audit_logs": "Audit Logs", - "billing": "Billing", "settings": "Settings", "provider_whitelist": "Provider Whitelist" }, - "Dashboard": { - "meta_title": "SaaS Template Dashboard", - "meta_description": "A free and open-source landing page template for your SaaS business, built with Next.js, TypeScript, Shadcn UI, and Tailwind CSS." - }, "DashboardIndex": { "title_bar": "Dashboard", "title_bar_description": "Welcome to your dashboard", @@ -138,56 +57,6 @@ "parameters_section_title": "Default Parameters", "parameters_section_description": "Set global default parameters for AI model calls" }, - "Billing": { - "title_bar": "Billing", - "title_bar_description": "Manage your billing and subscription", - "current_section_title": "Current Plan", - "current_section_description": "Adjust your payment plan to best suit your requirements", - "manage_subscription_button": "Manage Subscription" - }, - "BillingOptions": { - "current_plan": "Current Plan", - "upgrade_plan": "Get Started" - }, - "CheckoutConfirmation": { - "title_bar": "Payment Confirmation", - "message_state_title": "Payment successful", - "message_state_description": "Your payment has been successfully processed. Thank you for your purchase!", - "message_state_button": "Go back to Billing" - }, - "DataTable": { - "no_results": "No results." - }, - "Todos": { - "title_bar": "Todo List", - "title_bar_description": "View and manage your todo list", - "add_todo_button": "New todo" - }, - "TodoTableColumns": { - "open_menu": "Open menu", - "edit": "Edit", - "delete": "Delete", - "title_header": "Title", - "message_header": "Message", - "created_at_header": "Created at" - }, - "AddTodo": { - "title_bar": "Add Todo", - "add_todo_section_title": "Create a new todo", - "add_todo_section_description": "Fill in the form below to create a new todo" - }, - "EditTodo": { - "title_bar": "Edit todo", - "edit_todo_section_title": "Modify todo", - "edit_todo_section_description": "Fill in the form below to edit the todo" - }, - "TodoForm": { - "title_label": "Title", - "title_description": "Enter a descriptive title for your todo.", - "message_title": "Message", - "message_description": "Enter a detailed message for your todo.", - "submit_button": "Submit" - }, "Analytics": { "title_bar": "Usage Analytics", "title_bar_description": "Detailed analytics for your organization", diff --git a/src/i18n/locales/fr.json b/src/i18n/locales/fr.json index 101df9caf5..a1a70f51ce 100644 --- a/src/i18n/locales/fr.json +++ b/src/i18n/locales/fr.json @@ -1,102 +1,23 @@ { "Index": { - "meta_title": "SaaS Template - Le template SaaS parfait pour construire et mettre à l'échelle votre entreprise en toute simplicité.", - "meta_description": "Un template gratuit et open-source de landing page pour votre entreprise SaaS, construit avec React, TypeScript, Shadcn UI et Tailwind CSS." + "meta_title": "Roo Code Cloud", + "meta_description": "Gestion cloud pour Roo Code." }, "Navbar": { "sign_in": "Se connecter", - "sign_up": "S'inscrire", - "product": "Produit", - "docs": "Docs", - "blog": "Blog", - "community": "Communauté", - "company": "Entreprise" - }, - "Hero": { - "follow_twitter": "Suivez @Ixartz sur Twitter", - "title": "Le parfait SaaS template pour construire et mettre à l'échelle votre entreprise en toute simplicité.", - "description": "Un template gratuit et open-source de landing page pour votre entreprise SaaS, construit avec React, TypeScript, Shadcn UI et Tailwind CSS.", - "primary_button": "Démarrer", - "secondary_button": "Mettez une étoile sur GitHub" - }, - "Sponsors": { - "title": "Sponsorisé par" - }, - "Features": { - "section_subtitle": "Fonctionnalités", - "section_title": "Débloquer le plein potentiel du SaaS Template", - "section_description": "Un template gratuit et open-source de landing page pour votre entreprise SaaS, construit avec React, TypeScript, Shadcn UI et Tailwind CSS.", - "feature1_title": "Node.js", - "feature2_title": "React", - "feature3_title": "Tailwind CSS", - "feature4_title": "TypeScript", - "feature5_title": "Shadcn UI", - "feature6_title": "ESLint", - "feature_description": "Un template gratuit et open-source de landing page pour votre entreprise SaaS, construit avec React, TypeScript, Shadcn UI et Tailwind CSS." - }, - "Pricing": { - "section_subtitle": "Fonctionnalités", - "section_title": "Débloquer le plein potentiel du SaaS Template", - "section_description": "Un template gratuit et open-source de landing page pour votre entreprise SaaS, construit avec React, TypeScript, Shadcn UI et Tailwind CSS.", - "button_text": "Démarrer" - }, - "PricingPlan": { - "free_plan_name": "Gratuit", - "premium_plan_name": "Premium", - "enterprise_plan_name": "Enterprise", - "free_plan_description": "Pour les particuliers", - "premium_plan_description": "Pour les petites équipes", - "enterprise_plan_description": "Pour les leaders de l'industrie", - "feature_team_member": "{number} membres", - "feature_website": "{number} sites internet", - "feature_storage": "{number} Go de stockage", - "feature_transfer": "{number} TB de transfert", - "feature_email_support": "Support par e-mail", - "plan_interval_month": "mois", - "plan_interval_year": "année", - "next_renew_date": "Votre abonnement sera renouvelé le {date}" - }, - "FAQ": { - "question": "Lorem ipsum dolor sit amet, consectetur adipiscing elit?", - "answer": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam aliquam enim dui, id consequat turpis ullamcorper ac. Mauris id quam dolor. Nullam eu egestas turpis. Proin risus elit, sollicitudin in mi a, accumsan euismod turpis. In euismod mi sed diam tristique hendrerit." - }, - "CTA": { - "title": "Vous êtes prêt?", - "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", - "button_text": "Mettez une étoile sur GitHub" + "sign_up": "S'inscrire" }, "Footer": { - "product": "Produit", - "docs": "Docs", - "blog": "Blog", - "community": "Communauté", - "company": "Entreprise", "terms_of_service": "Conditions d'utilisation", - "privacy_policy": "Politique de confidentialité", - "designed_by": "Designé by ." - }, - "ProtectFallback": { - "not_enough_permission": "Vous n'avez pas les permissions pour effectuer cette action" - }, - "SignIn": { - "meta_title": "Se connecter", - "meta_description": "Connectez-vous à votre compte avec facilité." - }, - "SignUp": { - "meta_title": "S'inscrire", - "meta_description": "Créez un compte sans effort grâce à notre processus d'inscription intuitif." + "privacy_policy": "Politique de confidentialité" }, "DashboardLayout": { "home": "Accueil", "analytics": "Analytiques", - "todos": "Todos", "members": "Membres", - "billing": "Facturation", - "settings": "Réglages" - }, - "Dashboard": { - "meta_title": "Tableau de bord du SaaS Template", - "meta_description": "Un template gratuit et open-source de landing page pour votre entreprise SaaS, construit avec Next.js, TypeScript, Shadcn UI et Tailwind CSS." + "audit_logs": "Journaux d'audit", + "settings": "Réglages", + "provider_whitelist": "Liste blanche des fournisseurs" }, "DashboardIndex": { "title_bar": "Tableau de bord", @@ -105,17 +26,17 @@ "message_state_description": "Vous pouvez personnaliser cette page en modifiant le fichier dans dashboard/page.tsx", "message_state_button": "Mettez une étoile sur GitHub", "message_state_alternative": "Vous voulez plus de fonctionnalités en utilisant la même stack ? Essayez .", - "analytics_title": "Analytique d'Utilisation", + "analytics_title": "Analytiques d'utilisation", "analytics_description": "Métriques et statistiques d'utilisation de l'organisation", "analytics_period_7_days": "7 derniers jours", "analytics_period_30_days": "30 derniers jours", "analytics_period_90_days": "90 derniers jours", - "analytics_tasks_started": "Tâches Commencées", - "analytics_tasks_completed": "Tâches Terminées", - "analytics_tokens_consumed": "Tokens Consommés", + "analytics_tasks_started": "Tâches commencées", + "analytics_tasks_completed": "Tâches terminées", + "analytics_tokens_consumed": "Tokens consommés", "analytics_costs": "Coûts (USD)", - "analytics_llm_costs": "Coûts des Modèles LLM (USD)", - "analytics_active_developers": "Développeurs Actifs", + "analytics_llm_costs": "Coûts des modèles LLM (USD)", + "analytics_active_developers": "Développeurs actifs", "analytics_view_details": "Voir les analytiques détaillées" }, "UserProfile": { @@ -123,71 +44,31 @@ "title_bar_description": "Afficher et gérer votre profil utilisateur" }, "OrganizationProfile": { - "title_bar": "Gestion de l’organisation", - "title_bar_description": "Gérer votre organisation" + "title_bar": "Gestion de l'organisation", + "title_bar_description": "Gérer votre organisation", + "provider_whitelist": "Liste blanche des fournisseurs", + "default_parameters": "Paramètres par défaut" }, - "Billing": { - "title_bar": "Facturation", - "title_bar_description": "Gérer votre facturation et votre abonnement", - "current_section_title": "Plan actuel", - "current_section_description": "Ajuster votre plan de paiement pour le mieux répondre à vos besoins", - "manage_subscription_button": "Gérer l'abonnement" - }, - "BillingOptions": { - "current_plan": "Plan actuel", - "upgrade_plan": "Démarrer" - }, - "CheckoutConfirmation": { - "title_bar": "Confirmation du paiement", - "message_state_title": "Paiement accepté", - "message_state_description": "Votre paiement a été traité avec succès. Merci pour votre achat !", - "message_state_button": "Revenir à la facturation" - }, - "DataTable": { - "no_results": "Aucun résultat." - }, - "Todos": { - "title_bar": "Liste de Todos", - "title_bar_description": "Afficher et gérer votre liste de todos", - "add_todo_button": "Nouveau todo" - }, - "TodoTableColumns": { - "open_menu": "Ouvrir le menu", - "edit": "Modifier", - "delete": "Supprimer", - "title_header": "Titre", - "message_header": "Message", - "created_at_header": "Créé le" - }, - "AddTodo": { - "title_bar": "Ajouter une todo", - "add_todo_section_title": "Créer une nouvelle todo", - "add_todo_section_description": "Remplissez le formulaire ci-dessous pour créer une nouvelle todo" - }, - "EditTodo": { - "title_bar": "Editer le todo", - "edit_todo_section_title": "Modifier le todo", - "edit_todo_section_description": "Remplissez le formulaire ci-dessous pour modifier la todo" - }, - "TodoForm": { - "title_label": "Titre", - "title_description": "Entrez un titre descriptif pour votre todo.", - "message_title": "Message", - "message_description": "Entrez un message détaillé pour votre todo.", - "submit_button": "Envoyer" + "ProviderWhitelist": { + "title": "Liste blanche des fournisseurs et paramètres par défaut", + "description": "Contrôlez quels fournisseurs d'IA sont autorisés et définissez les paramètres par défaut pour votre organisation", + "providers_section_title": "Fournisseurs autorisés", + "providers_section_description": "Sélectionnez quels fournisseurs et modèles d'IA sont autorisés à être utilisés", + "parameters_section_title": "Paramètres par défaut", + "parameters_section_description": "Définissez les paramètres par défaut globaux pour les appels aux modèles d'IA" }, "Analytics": { - "title_bar": "Analytique d'Utilisation", + "title_bar": "Analytiques d'utilisation", "title_bar_description": "Analytiques détaillées pour votre organisation", - "summary_title": "Résumé d'Utilisation", + "summary_title": "Résumé d'utilisation", "period_7_days": "7 derniers jours", "period_30_days": "30 derniers jours", "period_90_days": "90 derniers jours", - "active_developers": "Développeurs Actifs", - "tasks_started": "Tâches Commencées", - "tasks_completed": "Tâches Terminées", - "tokens_consumed": "Tokens Consommés", - "llm_costs": "Coûts des Modèles LLM (USD)", + "active_developers": "Développeurs actifs", + "tasks_started": "Tâches commencées", + "tasks_completed": "Tâches terminées", + "tokens_consumed": "Tokens consommés", + "llm_costs": "Coûts des modèles LLM (USD)", "view_mode_title": "Afficher Par", "view_mode_developers": "Développeurs", "view_mode_models": "Modèles", @@ -195,12 +76,12 @@ "filter_title": "Filtres", "filter_developer": "Développeur", "filter_model": "Modèle", - "filter_clear_all": "Effacer Tout", - "task_details_title": "Détails de la Tâche", + "filter_clear_all": "Effacer tout", + "task_details_title": "Détails de la tâche", "task_details_close": "Fermer", "pagination_prev": "Précédent", "pagination_next": "Suivant", - "pagination_of": "de", + "pagination_of": "sur", "pagination_page_size": "Taille de page", "no_data": "Aucune donnée disponible", "loading": "Chargement des données..." diff --git a/src/i18n/request.ts b/src/i18n/request.ts index db49c6243d..bec73800ca 100644 --- a/src/i18n/request.ts +++ b/src/i18n/request.ts @@ -1,5 +1,5 @@ import { cookies } from 'next/headers'; -import { isLocale } from '@/lib/locale'; +import { isLocale } from '@/i18n/locale'; import { getRequestConfig } from 'next-intl/server'; export default getRequestConfig(async (params) => { diff --git a/src/lib/getBaseUrl.ts b/src/lib/metadata.ts similarity index 100% rename from src/lib/getBaseUrl.ts rename to src/lib/metadata.ts