@lastbrain/app 2.0.15 → 2.0.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app-shell/not-found.js +2 -2
- package/dist/components/LanguageSwitcher.d.ts +7 -0
- package/dist/components/LanguageSwitcher.d.ts.map +1 -0
- package/dist/components/LanguageSwitcher.js +62 -0
- package/dist/config/version.d.ts.map +1 -1
- package/dist/config/version.js +19 -21
- package/dist/i18n/LanguageProvider.d.ts +4 -0
- package/dist/i18n/LanguageProvider.d.ts.map +1 -0
- package/dist/i18n/LanguageProvider.js +6 -0
- package/dist/i18n/TranslationsScript.d.ts +8 -0
- package/dist/i18n/TranslationsScript.d.ts.map +1 -0
- package/dist/i18n/TranslationsScript.js +10 -0
- package/dist/i18n/cookies.d.ts +6 -0
- package/dist/i18n/cookies.d.ts.map +1 -0
- package/dist/i18n/cookies.js +24 -0
- package/dist/i18n/langHrefHelper.d.ts +36 -0
- package/dist/i18n/langHrefHelper.d.ts.map +1 -0
- package/dist/i18n/langHrefHelper.js +41 -0
- package/dist/i18n/server-helpers.d.ts +33 -0
- package/dist/i18n/server-helpers.d.ts.map +1 -0
- package/dist/i18n/server-helpers.js +39 -0
- package/dist/i18n/server-lang.d.ts +10 -0
- package/dist/i18n/server-lang.d.ts.map +1 -0
- package/dist/i18n/server-lang.js +42 -0
- package/dist/i18n/server.d.ts +10 -0
- package/dist/i18n/server.d.ts.map +1 -0
- package/dist/i18n/server.js +8 -0
- package/dist/i18n/types.d.ts +38 -0
- package/dist/i18n/types.d.ts.map +1 -0
- package/dist/i18n/types.js +4 -0
- package/dist/i18n/useLangRouter.d.ts +12 -0
- package/dist/i18n/useLangRouter.d.ts.map +1 -0
- package/dist/i18n/useLangRouter.js +18 -0
- package/dist/i18n/useLink.d.ts +34 -0
- package/dist/i18n/useLink.d.ts.map +1 -0
- package/dist/i18n/useLink.js +58 -0
- package/dist/i18n/useModuleTranslation.d.ts +11 -0
- package/dist/i18n/useModuleTranslation.d.ts.map +1 -0
- package/dist/i18n/useModuleTranslation.js +23 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/layouts/AdminLayout.js +1 -1
- package/dist/layouts/AppProviders.d.ts +4 -1
- package/dist/layouts/AppProviders.d.ts.map +1 -1
- package/dist/layouts/AppProviders.js +18 -8
- package/dist/layouts/AuthLayout.js +1 -1
- package/dist/layouts/AuthLayoutWithSidebar.d.ts.map +1 -1
- package/dist/layouts/AuthLayoutWithSidebar.js +5 -3
- package/dist/layouts/PublicLayout.d.ts.map +1 -1
- package/dist/layouts/PublicLayout.js +1 -1
- package/dist/layouts/RootLayout.d.ts +4 -1
- package/dist/layouts/RootLayout.d.ts.map +1 -1
- package/dist/layouts/RootLayout.js +2 -2
- package/dist/scripts/i18n-build.d.ts +7 -0
- package/dist/scripts/i18n-build.d.ts.map +1 -0
- package/dist/scripts/i18n-build.js +100 -0
- package/dist/scripts/init-app.js +12 -12
- package/dist/scripts/module-build.d.ts.map +1 -1
- package/dist/scripts/module-build.js +390 -83
- package/dist/styles.css +1 -1
- package/dist/templates/DefaultDoc.d.ts.map +1 -1
- package/dist/templates/DefaultDoc.js +90 -2
- package/dist/templates/middleware-i18n.example.d.ts +16 -0
- package/dist/templates/middleware-i18n.example.d.ts.map +1 -0
- package/dist/templates/middleware-i18n.example.js +72 -0
- package/package.json +14 -3
- package/src/app-shell/not-found.tsx +2 -2
- package/src/components/LanguageSwitcher.tsx +156 -0
- package/src/config/version.ts +19 -21
- package/src/i18n/LanguageProvider.tsx +7 -0
- package/src/i18n/README_LANG_HELPERS.md +187 -0
- package/src/i18n/TranslationsScript.tsx +17 -0
- package/src/i18n/cookies.ts +24 -0
- package/src/i18n/langHrefHelper.ts +51 -0
- package/src/i18n/server-helpers.ts +48 -0
- package/src/i18n/server-lang.ts +51 -0
- package/src/i18n/server.ts +13 -0
- package/src/i18n/types.ts +39 -0
- package/src/i18n/useLangRouter.ts +21 -0
- package/src/i18n/useLink.ts +60 -0
- package/src/i18n/useModuleTranslation.ts +27 -0
- package/src/index.ts +20 -0
- package/src/layouts/AdminLayout.tsx +1 -1
- package/src/layouts/AppProviders.tsx +35 -16
- package/src/layouts/AuthLayout.tsx +1 -1
- package/src/layouts/AuthLayoutWithSidebar.tsx +5 -3
- package/src/layouts/PublicLayout.tsx +3 -1
- package/src/layouts/RootLayout.tsx +13 -6
- package/src/scripts/i18n-build.ts +122 -0
- package/src/scripts/init-app.ts +12 -12
- package/src/scripts/module-build.ts +483 -96
- package/src/templates/DefaultDoc.tsx +511 -1
- package/src/templates/middleware-i18n.example.ts +92 -0
- package/dist/app-shell/(admin)/dashboard/page.d.ts +0 -2
- package/dist/app-shell/(admin)/dashboard/page.d.ts.map +0 -1
- package/dist/app-shell/(admin)/dashboard/page.js +0 -5
- package/dist/app-shell/(admin)/page.d.ts +0 -2
- package/dist/app-shell/(admin)/page.d.ts.map +0 -1
- package/dist/app-shell/(admin)/page.js +0 -5
- package/dist/app-shell/(auth)/dashboard/page.d.ts +0 -2
- package/dist/app-shell/(auth)/dashboard/page.d.ts.map +0 -1
- package/dist/app-shell/(auth)/dashboard/page.js +0 -5
- package/dist/app-shell/(auth)/page.d.ts +0 -2
- package/dist/app-shell/(auth)/page.d.ts.map +0 -1
- package/dist/app-shell/(auth)/page.js +0 -5
- package/dist/components/TableStructure.d.ts +0 -8
- package/dist/components/TableStructure.d.ts.map +0 -1
- package/dist/components/TableStructure.js +0 -37
- package/dist/hooks/useNotificationsSimple.d.ts +0 -20
- package/dist/hooks/useNotificationsSimple.d.ts.map +0 -1
- package/dist/hooks/useNotificationsSimple.js +0 -37
- package/dist/module-build.d.ts +0 -2
- package/dist/module-build.d.ts.map +0 -1
- package/dist/module-build.js +0 -50
- package/dist/modules/index.d.ts +0 -3
- package/dist/modules/index.d.ts.map +0 -1
- package/dist/modules/index.js +0 -2
- package/dist/src/__tests__/module-registry.test.d.ts +0 -2
- package/dist/src/__tests__/module-registry.test.d.ts.map +0 -1
- package/dist/src/__tests__/module-registry.test.js +0 -53
- package/dist/src/app-shell/(admin)/layout.d.ts +0 -4
- package/dist/src/app-shell/(admin)/layout.d.ts.map +0 -1
- package/dist/src/app-shell/(admin)/layout.js +0 -5
- package/dist/src/app-shell/(auth)/layout.d.ts +0 -4
- package/dist/src/app-shell/(auth)/layout.d.ts.map +0 -1
- package/dist/src/app-shell/(auth)/layout.js +0 -5
- package/dist/src/app-shell/(public)/page.d.ts +0 -2
- package/dist/src/app-shell/(public)/page.d.ts.map +0 -1
- package/dist/src/app-shell/(public)/page.js +0 -5
- package/dist/src/app-shell/layout.d.ts +0 -3
- package/dist/src/app-shell/layout.d.ts.map +0 -1
- package/dist/src/app-shell/layout.js +0 -3
- package/dist/src/app-shell/not-found.d.ts +0 -2
- package/dist/src/app-shell/not-found.d.ts.map +0 -1
- package/dist/src/app-shell/not-found.js +0 -10
- package/dist/src/auth/authHelpers.d.ts +0 -7
- package/dist/src/auth/authHelpers.d.ts.map +0 -1
- package/dist/src/auth/authHelpers.js +0 -19
- package/dist/src/auth/useAuthSession.d.ts +0 -7
- package/dist/src/auth/useAuthSession.d.ts.map +0 -1
- package/dist/src/auth/useAuthSession.js +0 -49
- package/dist/src/cli.d.ts +0 -3
- package/dist/src/cli.d.ts.map +0 -1
- package/dist/src/cli.js +0 -143
- package/dist/src/components/NotificationContainer.d.ts +0 -2
- package/dist/src/components/NotificationContainer.d.ts.map +0 -1
- package/dist/src/components/NotificationContainer.js +0 -8
- package/dist/src/hooks/useNotifications.d.ts +0 -30
- package/dist/src/hooks/useNotifications.d.ts.map +0 -1
- package/dist/src/hooks/useNotifications.js +0 -165
- package/dist/src/index.d.ts +0 -22
- package/dist/src/index.d.ts.map +0 -1
- package/dist/src/index.js +0 -22
- package/dist/src/layouts/AdminLayout.d.ts +0 -4
- package/dist/src/layouts/AdminLayout.d.ts.map +0 -1
- package/dist/src/layouts/AdminLayout.js +0 -4
- package/dist/src/layouts/AdminLayoutWithSidebar.d.ts +0 -10
- package/dist/src/layouts/AdminLayoutWithSidebar.d.ts.map +0 -1
- package/dist/src/layouts/AdminLayoutWithSidebar.js +0 -62
- package/dist/src/layouts/AppProviders.d.ts +0 -27
- package/dist/src/layouts/AppProviders.d.ts.map +0 -1
- package/dist/src/layouts/AppProviders.js +0 -48
- package/dist/src/layouts/AuthLayout.d.ts +0 -4
- package/dist/src/layouts/AuthLayout.d.ts.map +0 -1
- package/dist/src/layouts/AuthLayout.js +0 -4
- package/dist/src/layouts/AuthLayoutWithSidebar.d.ts +0 -12
- package/dist/src/layouts/AuthLayoutWithSidebar.d.ts.map +0 -1
- package/dist/src/layouts/AuthLayoutWithSidebar.js +0 -60
- package/dist/src/layouts/PublicLayout.d.ts +0 -8
- package/dist/src/layouts/PublicLayout.d.ts.map +0 -1
- package/dist/src/layouts/PublicLayout.js +0 -6
- package/dist/src/layouts/PublicLayoutWithSidebar.d.ts +0 -9
- package/dist/src/layouts/PublicLayoutWithSidebar.d.ts.map +0 -1
- package/dist/src/layouts/PublicLayoutWithSidebar.js +0 -60
- package/dist/src/layouts/RootLayout.d.ts +0 -6
- package/dist/src/layouts/RootLayout.d.ts.map +0 -1
- package/dist/src/layouts/RootLayout.js +0 -9
- package/dist/src/modules/module-loader.d.ts +0 -5
- package/dist/src/modules/module-loader.d.ts.map +0 -1
- package/dist/src/modules/module-loader.js +0 -10
- package/dist/src/scripts/db-init.d.ts +0 -2
- package/dist/src/scripts/db-init.d.ts.map +0 -1
- package/dist/src/scripts/db-init.js +0 -300
- package/dist/src/scripts/db-migrations-sync.d.ts +0 -2
- package/dist/src/scripts/db-migrations-sync.d.ts.map +0 -1
- package/dist/src/scripts/db-migrations-sync.js +0 -84
- package/dist/src/scripts/dev-sync.d.ts +0 -2
- package/dist/src/scripts/dev-sync.d.ts.map +0 -1
- package/dist/src/scripts/dev-sync.js +0 -194
- package/dist/src/scripts/init-app.d.ts +0 -12
- package/dist/src/scripts/init-app.d.ts.map +0 -1
- package/dist/src/scripts/init-app.js +0 -2175
- package/dist/src/scripts/module-add.d.ts +0 -2
- package/dist/src/scripts/module-add.d.ts.map +0 -1
- package/dist/src/scripts/module-add.js +0 -232
- package/dist/src/scripts/module-build.d.ts +0 -2
- package/dist/src/scripts/module-build.d.ts.map +0 -1
- package/dist/src/scripts/module-build.js +0 -1280
- package/dist/src/scripts/module-create.d.ts +0 -28
- package/dist/src/scripts/module-create.d.ts.map +0 -1
- package/dist/src/scripts/module-create.js +0 -1429
- package/dist/src/scripts/module-delete.d.ts +0 -6
- package/dist/src/scripts/module-delete.d.ts.map +0 -1
- package/dist/src/scripts/module-delete.js +0 -147
- package/dist/src/scripts/module-list.d.ts +0 -2
- package/dist/src/scripts/module-list.d.ts.map +0 -1
- package/dist/src/scripts/module-list.js +0 -61
- package/dist/src/scripts/module-remove.d.ts +0 -2
- package/dist/src/scripts/module-remove.d.ts.map +0 -1
- package/dist/src/scripts/module-remove.js +0 -311
- package/dist/src/scripts/readme-build.d.ts +0 -2
- package/dist/src/scripts/readme-build.d.ts.map +0 -1
- package/dist/src/scripts/readme-build.js +0 -39
- package/dist/src/scripts/script-runner.d.ts +0 -5
- package/dist/src/scripts/script-runner.d.ts.map +0 -1
- package/dist/src/scripts/script-runner.js +0 -25
- package/dist/src/templates/AuthGuidePage.d.ts +0 -2
- package/dist/src/templates/AuthGuidePage.d.ts.map +0 -1
- package/dist/src/templates/AuthGuidePage.js +0 -9
- package/dist/src/templates/DefaultDoc.d.ts +0 -2
- package/dist/src/templates/DefaultDoc.d.ts.map +0 -1
- package/dist/src/templates/DefaultDoc.js +0 -240
- package/dist/src/templates/DocPage.d.ts +0 -17
- package/dist/src/templates/DocPage.d.ts.map +0 -1
- package/dist/src/templates/DocPage.js +0 -193
- package/dist/src/templates/DocsPageWithModules.d.ts +0 -2
- package/dist/src/templates/DocsPageWithModules.d.ts.map +0 -1
- package/dist/src/templates/DocsPageWithModules.js +0 -8
- package/dist/src/templates/MigrationsGuidePage.d.ts +0 -2
- package/dist/src/templates/MigrationsGuidePage.d.ts.map +0 -1
- package/dist/src/templates/MigrationsGuidePage.js +0 -11
- package/dist/src/templates/ModuleGuidePage.d.ts +0 -2
- package/dist/src/templates/ModuleGuidePage.d.ts.map +0 -1
- package/dist/src/templates/ModuleGuidePage.js +0 -14
- package/dist/src/templates/SimpleDocPage.d.ts +0 -2
- package/dist/src/templates/SimpleDocPage.d.ts.map +0 -1
- package/dist/src/templates/SimpleDocPage.js +0 -28
- package/dist/src/templates/SimpleHomePage.d.ts +0 -6
- package/dist/src/templates/SimpleHomePage.d.ts.map +0 -1
- package/dist/src/templates/SimpleHomePage.js +0 -7
- package/dist/src/types/menu.d.ts +0 -23
- package/dist/src/types/menu.d.ts.map +0 -1
- package/dist/src/types/menu.js +0 -1
- package/dist/templates/HomePage.d.ts +0 -6
- package/dist/templates/HomePage.d.ts.map +0 -1
- package/dist/templates/HomePage.js +0 -6
- package/dist/templates/components/AppAside.d.ts +0 -6
- package/dist/templates/components/AppAside.d.ts.map +0 -1
- package/dist/templates/components/AppAside.js +0 -9
- package/dist/templates/layouts/admin-layout.d.ts +0 -4
- package/dist/templates/layouts/admin-layout.d.ts.map +0 -1
- package/dist/templates/layouts/admin-layout.js +0 -6
- package/dist/templates/layouts/auth-layout.d.ts +0 -4
- package/dist/templates/layouts/auth-layout.d.ts.map +0 -1
- package/dist/templates/layouts/auth-layout.js +0 -6
- package/dist/templates/migrations/20201010100000_init.sql +0 -123
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useLanguage } from "./LanguageProvider";
|
|
3
|
+
/**
|
|
4
|
+
* Helper pour transformer un URL avec le paramètre [lang]
|
|
5
|
+
* Utile pour les transformations statiques avant le rendu React
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```tsx
|
|
9
|
+
* const href = langHref("/settings", "fr"); // "/fr/settings"
|
|
10
|
+
* const href = langHref("/api/users", "en"); // "/api/users" (API non modifiée)
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
export function langHref(href, lang) {
|
|
14
|
+
const normalizedHref = String(href);
|
|
15
|
+
const isAbsolute = normalizedHref.startsWith("http");
|
|
16
|
+
const hasLangPrefix = normalizedHref.startsWith(`/${lang}/`);
|
|
17
|
+
if (isAbsolute) {
|
|
18
|
+
return normalizedHref;
|
|
19
|
+
}
|
|
20
|
+
else if (hasLangPrefix) {
|
|
21
|
+
return normalizedHref;
|
|
22
|
+
}
|
|
23
|
+
else if (normalizedHref === "/") {
|
|
24
|
+
return `/${lang}`;
|
|
25
|
+
}
|
|
26
|
+
else if (normalizedHref.startsWith("/api/")) {
|
|
27
|
+
return normalizedHref;
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
return `/${lang}${normalizedHref}`;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Hook pour générer des URLs avec le paramètre [lang] injecté automatiquement
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```tsx
|
|
38
|
+
* "use client";
|
|
39
|
+
* import { useLink } from "@lastbrain/app";
|
|
40
|
+
*
|
|
41
|
+
* export function MyComponent() {
|
|
42
|
+
* const link = useLink();
|
|
43
|
+
*
|
|
44
|
+
* return (
|
|
45
|
+
* <>
|
|
46
|
+
* <img src={link("/api/storage/avatar.jpg")} />
|
|
47
|
+
* <a href={link("/recipes")}>Recettes</a>
|
|
48
|
+
* </>
|
|
49
|
+
* );
|
|
50
|
+
* }
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export function useLink() {
|
|
54
|
+
const { lang } = useLanguage();
|
|
55
|
+
return (href) => {
|
|
56
|
+
return langHref(href, lang);
|
|
57
|
+
};
|
|
58
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook pour utiliser les traductions d'un module spécifique
|
|
3
|
+
* Préfixe automatiquement les clés avec le nom du module
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* const t = useModuleTranslation("auth");
|
|
7
|
+
* t("hello") // -> cherche "module-auth.hello"
|
|
8
|
+
* t("hello", "Hello") // -> cherche "module-auth.hello", fallback à "Hello"
|
|
9
|
+
*/
|
|
10
|
+
export declare function useModuleTranslation(moduleName: string): (key: string, defaultValue?: string) => string;
|
|
11
|
+
//# sourceMappingURL=useModuleTranslation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useModuleTranslation.d.ts","sourceRoot":"","sources":["../../src/i18n/useModuleTranslation.ts"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,IAG7C,KAAK,MAAM,EAAE,eAAe,MAAM,KAAG,MAAM,CAUpD"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useLanguage } from "./LanguageProvider";
|
|
3
|
+
/**
|
|
4
|
+
* Hook pour utiliser les traductions d'un module spécifique
|
|
5
|
+
* Préfixe automatiquement les clés avec le nom du module
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* const t = useModuleTranslation("auth");
|
|
9
|
+
* t("hello") // -> cherche "module-auth.hello"
|
|
10
|
+
* t("hello", "Hello") // -> cherche "module-auth.hello", fallback à "Hello"
|
|
11
|
+
*/
|
|
12
|
+
export function useModuleTranslation(moduleName) {
|
|
13
|
+
const { t: globalT } = useLanguage();
|
|
14
|
+
return (key, defaultValue) => {
|
|
15
|
+
const prefixedKey = `module-${moduleName}.${key}`;
|
|
16
|
+
const translation = globalT(prefixedKey);
|
|
17
|
+
// Si la traduction retourne exactement la clé (non trouvée), utiliser le fallback
|
|
18
|
+
if (translation === prefixedKey && defaultValue !== undefined) {
|
|
19
|
+
return defaultValue;
|
|
20
|
+
}
|
|
21
|
+
return translation;
|
|
22
|
+
};
|
|
23
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -11,6 +11,13 @@ export { AuthLayoutWithSidebar, type AuthLayoutWithSidebarProps, type MenuIgnore
|
|
|
11
11
|
export { AdminLayout } from "./layouts/AdminLayout";
|
|
12
12
|
export { AdminLayoutWithSidebar } from "./layouts/AdminLayoutWithSidebar";
|
|
13
13
|
export { getModuleConfigs } from "./modules/module-loader";
|
|
14
|
+
export { LanguageProvider, useLanguage, type Language, } from "./i18n/LanguageProvider";
|
|
15
|
+
export { useLink, langHref } from "./i18n/useLink";
|
|
16
|
+
export { useLangRouter } from "./i18n/useLangRouter";
|
|
17
|
+
export { useModuleTranslation } from "@lastbrain/core";
|
|
18
|
+
export { transformLangHrefs, transformLangHref } from "./i18n/langHrefHelper";
|
|
19
|
+
export { LanguageSwitcher } from "./components/LanguageSwitcher";
|
|
20
|
+
export type { TranslationKey, Translations, I18nConfig, LangParams, LangIdParams, ModuleTranslations, } from "./i18n/types";
|
|
14
21
|
export { AppAside } from "@lastbrain/ui";
|
|
15
22
|
export type { AppAsideMenuItem, AppAsideMenuConfig } from "@lastbrain/ui";
|
|
16
23
|
export { SimpleHomePage } from "./templates/SimpleHomePage";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,OAAO,EACP,UAAU,EACV,gBAAgB,IAAI,uBAAuB,GAC5C,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,mCAAmC,CAAC;AAC5E,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EACL,qBAAqB,EACrB,KAAK,0BAA0B,EAC/B,KAAK,WAAW,EAChB,KAAK,UAAU,GAChB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAG3D,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,YAAY,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAG1E,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,OAAO,EACP,UAAU,EACV,gBAAgB,IAAI,uBAAuB,GAC5C,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,mCAAmC,CAAC;AAC5E,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EACL,qBAAqB,EACrB,KAAK,0BAA0B,EAC/B,KAAK,WAAW,EAChB,KAAK,UAAU,GAChB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAG3D,OAAO,EACL,gBAAgB,EAChB,WAAW,EACX,KAAK,QAAQ,GACd,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC9E,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,YAAY,EACV,cAAc,EACd,YAAY,EACZ,UAAU,EACV,UAAU,EACV,YAAY,EACZ,kBAAkB,GACnB,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,YAAY,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAG1E,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -11,6 +11,13 @@ export { AuthLayoutWithSidebar, } from "./layouts/AuthLayoutWithSidebar";
|
|
|
11
11
|
export { AdminLayout } from "./layouts/AdminLayout";
|
|
12
12
|
export { AdminLayoutWithSidebar } from "./layouts/AdminLayoutWithSidebar";
|
|
13
13
|
export { getModuleConfigs } from "./modules/module-loader";
|
|
14
|
+
// i18n
|
|
15
|
+
export { LanguageProvider, useLanguage, } from "./i18n/LanguageProvider";
|
|
16
|
+
export { useLink, langHref } from "./i18n/useLink";
|
|
17
|
+
export { useLangRouter } from "./i18n/useLangRouter";
|
|
18
|
+
export { useModuleTranslation } from "@lastbrain/core";
|
|
19
|
+
export { transformLangHrefs, transformLangHref } from "./i18n/langHrefHelper";
|
|
20
|
+
export { LanguageSwitcher } from "./components/LanguageSwitcher";
|
|
14
21
|
// Components
|
|
15
22
|
export { AppAside } from "@lastbrain/ui";
|
|
16
23
|
// Templates de pages (starter + docs)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
export function AdminLayout({ children }) {
|
|
3
|
-
return _jsx("div", { className: "max-w-screen
|
|
3
|
+
return _jsx("div", { className: "max-w-screen px-2 md:px-5", children: children });
|
|
4
4
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type Language } from "../i18n/LanguageProvider";
|
|
1
2
|
import type { User } from "@supabase/supabase-js";
|
|
2
3
|
import type { ModuleRealtimeConfig } from "@lastbrain/core";
|
|
3
4
|
import type { NotificationsData } from "../hooks/useNotifications";
|
|
@@ -20,8 +21,10 @@ export declare function useAuth(): {
|
|
|
20
21
|
loading: boolean;
|
|
21
22
|
isSuperAdmin: boolean;
|
|
22
23
|
};
|
|
23
|
-
export declare function AppProviders({ children, realtimeConfig, }: {
|
|
24
|
+
export declare function AppProviders({ children, realtimeConfig, lang, translations, }: {
|
|
24
25
|
children: React.ReactNode;
|
|
25
26
|
realtimeConfig?: ModuleRealtimeConfig[];
|
|
27
|
+
lang?: Language;
|
|
28
|
+
translations?: Record<string, string>;
|
|
26
29
|
}): import("react/jsx-runtime").JSX.Element;
|
|
27
30
|
//# sourceMappingURL=AppProviders.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppProviders.d.ts","sourceRoot":"","sources":["../../src/layouts/AppProviders.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAuCnE,wBAAgB,UAAU,kDAEzB;AAED,wBAAgB,gBAAgB;UAvCxB,iBAAiB;aACd,OAAO;WACT,MAAM,GAAG,IAAI;aACX,MAAM,OAAO,CAAC,IAAI,CAAC;gBAChB,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC;mBAC1B,MAAM,OAAO,CAAC,IAAI,CAAC;wBACd,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC;aACxC,OAAO;eACL,OAAO;oBACF,OAAO;yBACF,OAAO;EA+B7B;AAED,wBAAgB,OAAO;UAjBf,IAAI,GAAG,IAAI;aACR,OAAO;kBACF,OAAO;EAiBtB;AAED,wBAAgB,YAAY,CAAC,EAC3B,QAAQ,EACR,cAAmB,
|
|
1
|
+
{"version":3,"file":"AppProviders.d.ts","sourceRoot":"","sources":["../../src/layouts/AppProviders.tsx"],"names":[],"mappings":"AAQA,OAAO,EAAoB,KAAK,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAC3E,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAuCnE,wBAAgB,UAAU,kDAEzB;AAED,wBAAgB,gBAAgB;UAvCxB,iBAAiB;aACd,OAAO;WACT,MAAM,GAAG,IAAI;aACX,MAAM,OAAO,CAAC,IAAI,CAAC;gBAChB,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC;mBAC1B,MAAM,OAAO,CAAC,IAAI,CAAC;wBACd,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC;aACxC,OAAO;eACL,OAAO;oBACF,OAAO;yBACF,OAAO;EA+B7B;AAED,wBAAgB,OAAO;UAjBf,IAAI,GAAG,IAAI;aACR,OAAO;kBACF,OAAO;EAiBtB;AAED,wBAAgB,YAAY,CAAC,EAC3B,QAAQ,EACR,cAAmB,EACnB,IAAW,EACX,YAAiB,GAClB,EAAE;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,cAAc,CAAC,EAAE,oBAAoB,EAAE,CAAC;IACxC,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACvC,2CA0CA"}
|
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { createContext, useContext, useMemo } from "react";
|
|
4
4
|
import { getModuleConfigs } from "../modules/module-loader";
|
|
5
|
-
import { ToastProvider } from "@lastbrain/ui";
|
|
5
|
+
import { ToastProvider, AppLinkProvider } from "@lastbrain/ui";
|
|
6
6
|
import { RealtimeProvider } from "@lastbrain/core";
|
|
7
7
|
import { useAuthSession } from "../auth/useAuthSession";
|
|
8
8
|
import { useNotifications as useNotificationsHook } from "../hooks/useNotifications";
|
|
9
|
+
import { LanguageProvider } from "../i18n/LanguageProvider";
|
|
9
10
|
const ModuleContext = createContext(getModuleConfigs());
|
|
10
11
|
const NotificationContext = createContext({
|
|
11
12
|
data: { notifications: [], unreadCount: 0 },
|
|
@@ -34,15 +35,24 @@ export function useNotifications() {
|
|
|
34
35
|
export function useAuth() {
|
|
35
36
|
return useContext(AuthContext);
|
|
36
37
|
}
|
|
37
|
-
export function AppProviders({ children, realtimeConfig = [], }) {
|
|
38
|
+
export function AppProviders({ children, realtimeConfig = [], lang = "fr", translations = {}, }) {
|
|
38
39
|
const modules = useMemo(() => getModuleConfigs(), []);
|
|
39
40
|
const { user, loading: authLoading, isSuperAdmin } = useAuthSession();
|
|
40
41
|
// Hook de notifications seulement quand l'auth est prête
|
|
41
42
|
const notificationsData = useNotificationsHook(user);
|
|
42
|
-
const authValue = useMemo(() => ({ user, loading: authLoading, isSuperAdmin }), [user, authLoading, isSuperAdmin]);
|
|
43
|
-
//
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
43
|
+
const authValue = useMemo(() => ({ user, loading: authLoading, isSuperAdmin }), [user, authLoading, isSuperAdmin]);
|
|
44
|
+
// Mémoriser les traductions pour éviter les changements
|
|
45
|
+
const memoizedTranslations = useMemo(() => {
|
|
46
|
+
// Si des traductions non-vides sont fournies, les utiliser
|
|
47
|
+
if (Object.keys(translations).length > 0) {
|
|
48
|
+
return translations;
|
|
49
|
+
}
|
|
50
|
+
// Sinon, tenter de récupérer celles du script injecté côté client
|
|
51
|
+
if (typeof window !== "undefined" && window.__TRANSLATIONS__) {
|
|
52
|
+
return window.__TRANSLATIONS__;
|
|
53
|
+
}
|
|
54
|
+
// Ne retourner un objet vide que si vraiment rien n'est disponible
|
|
55
|
+
return {};
|
|
56
|
+
}, [translations]);
|
|
57
|
+
return (_jsx(LanguageProvider, { initialLang: lang, translations: memoizedTranslations, children: _jsx(AppLinkProvider, { lang: lang || "fr", children: _jsx(AuthContext.Provider, { value: authValue, children: _jsx(ModuleContext.Provider, { value: modules, children: _jsx(NotificationContext.Provider, { value: notificationsData, children: _jsxs(RealtimeProvider, { userId: user?.id, config: realtimeConfig, children: [children, _jsx(ToastProvider, { placement: "bottom-right", toastOffset: 5 })] }) }) }) }) }) }));
|
|
48
58
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthLayoutWithSidebar.d.ts","sourceRoot":"","sources":["../../src/layouts/AuthLayoutWithSidebar.tsx"],"names":[],"mappings":"AAGA,OAAO,EAGL,KAAK,UAAU,EACf,KAAK,QAAQ,EACd,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"AuthLayoutWithSidebar.d.ts","sourceRoot":"","sources":["../../src/layouts/AuthLayoutWithSidebar.tsx"],"names":[],"mappings":"AAGA,OAAO,EAGL,KAAK,UAAU,EACf,KAAK,QAAQ,EACd,MAAM,eAAe,CAAC;AAGvB,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAG7D,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;AAExC,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,UAAU,CAAC,EAAE,QAAQ,EAAE,CAAC;CACzB;AAED,wBAAgB,qBAAqB,CAAC,EACpC,QAAQ,EACR,UAAU,EACV,SAAc,EACd,WAAW,EACX,UAAU,GACX,EAAE,0BAA0B,2CAkG5B"}
|
|
@@ -3,9 +3,11 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { AuthLayout } from "./AuthLayout";
|
|
4
4
|
import { AppAside, AppAsideSkeleton, } from "@lastbrain/ui";
|
|
5
5
|
import { useAuthSession } from "../auth/useAuthSession";
|
|
6
|
+
import { usePathname } from "next/navigation";
|
|
6
7
|
import { useEffect, useState } from "react";
|
|
7
8
|
export function AuthLayoutWithSidebar({ children, menuConfig, className = "", menuIgnored, menuCustom, }) {
|
|
8
9
|
const { isSuperAdmin, loading, user } = useAuthSession();
|
|
10
|
+
const pathname = usePathname();
|
|
9
11
|
const [isCollapsed, setIsCollapsed] = useState(() => {
|
|
10
12
|
if (typeof window !== "undefined") {
|
|
11
13
|
const savedState = localStorage.getItem("aside-collapsed");
|
|
@@ -40,8 +42,8 @@ export function AuthLayoutWithSidebar({ children, menuConfig, className = "", me
|
|
|
40
42
|
};
|
|
41
43
|
}
|
|
42
44
|
}, []);
|
|
43
|
-
//
|
|
44
|
-
const
|
|
45
|
+
// Détecter si on est dans la section auth pour le skeleton (avec support [lang])
|
|
46
|
+
const isAuthSection = pathname.includes("/auth");
|
|
45
47
|
// Créer un menuConfig sûr avec des valeurs par défaut
|
|
46
48
|
const safeMenuConfig = {
|
|
47
49
|
public: menuConfig?.public || [],
|
|
@@ -56,5 +58,5 @@ export function AuthLayoutWithSidebar({ children, menuConfig, className = "", me
|
|
|
56
58
|
safeMenuConfig.public.length > 0);
|
|
57
59
|
// Afficher le skeleton pendant le chargement de la session ou si pas de menuConfig valide
|
|
58
60
|
const shouldShowSkeleton = loading || !hasValidMenuConfig;
|
|
59
|
-
return (_jsxs("div", { className: "flex min-h-screen", children: [shouldShowSkeleton ? (_jsx(AppAsideSkeleton, { className: className, isAdminSection:
|
|
61
|
+
return (_jsxs("div", { className: "flex min-h-screen", children: [shouldShowSkeleton ? (_jsx(AppAsideSkeleton, { className: className, isAdminSection: isAuthSection })) : (_jsx(AppAside, { menuConfig: safeMenuConfig, isSuperAdmin: isSuperAdmin, isAuthenticated: !!user, className: className, ...(menuIgnored ? { menuIgnored } : {}), ...(menuCustom ? { menuCustom } : {}) })), _jsx("div", { className: `flex-1 transition-all duration-300 ${!mounted ? "lg:ml-72" : isCollapsed ? "lg:ml-20" : "lg:ml-72"}`, children: _jsx(AuthLayout, { children: children }) })] }));
|
|
60
62
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PublicLayout.d.ts","sourceRoot":"","sources":["../../src/layouts/PublicLayout.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAU,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAE1D,UAAU,iBAAiB;IACzB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AAED,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"PublicLayout.d.ts","sourceRoot":"","sources":["../../src/layouts/PublicLayout.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAU,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAE1D,UAAU,iBAAiB;IACzB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AAED,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,iBAAiB,2CASzE"}
|
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { Footer } from "@lastbrain/ui";
|
|
4
4
|
export function PublicLayout({ children, footerConfig }) {
|
|
5
|
-
return (_jsxs(_Fragment, { children: [_jsx("section", { className: "pt-16 min-h-[calc(100vh)]", children: children }), footerConfig && _jsx(Footer, { config: footerConfig })] }));
|
|
5
|
+
return (_jsxs(_Fragment, { children: [_jsx("section", { className: "pt-16 min-h-[calc(100vh)] max-w-screen", children: children }), footerConfig && _jsx(Footer, { config: footerConfig })] }));
|
|
6
6
|
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { ModuleRealtimeConfig } from "@lastbrain/core";
|
|
2
|
-
|
|
2
|
+
import type { Language } from "../i18n/LanguageProvider";
|
|
3
|
+
export declare function RootLayout({ children, realtimeConfig, lang, translations, }: {
|
|
3
4
|
children: React.ReactNode;
|
|
4
5
|
realtimeConfig?: ModuleRealtimeConfig[];
|
|
6
|
+
lang?: Language;
|
|
7
|
+
translations?: Record<string, string>;
|
|
5
8
|
}): import("react/jsx-runtime").JSX.Element;
|
|
6
9
|
//# sourceMappingURL=RootLayout.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RootLayout.d.ts","sourceRoot":"","sources":["../../src/layouts/RootLayout.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"RootLayout.d.ts","sourceRoot":"","sources":["../../src/layouts/RootLayout.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAIzD,wBAAgB,UAAU,CAAC,EACzB,QAAQ,EACR,cAAmB,EACnB,IAAW,EACX,YAAiB,GAClB,EAAE;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,cAAc,CAAC,EAAE,oBAAoB,EAAE,CAAC;IACxC,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACvC,2CAqBA"}
|
|
@@ -4,6 +4,6 @@ import { ThemeProvider } from "next-themes";
|
|
|
4
4
|
import { AppProviders } from "./AppProviders";
|
|
5
5
|
// Note: L'app Next.js doit importer son propre globals.css dans son layout
|
|
6
6
|
// Note: La configuration realtime doit être fournie par l'app qui utilise ce layout
|
|
7
|
-
export function RootLayout({ children, realtimeConfig = [], }) {
|
|
8
|
-
return (_jsx("html", { lang:
|
|
7
|
+
export function RootLayout({ children, realtimeConfig = [], lang = "fr", translations = {}, }) {
|
|
8
|
+
return (_jsx("html", { lang: lang, suppressHydrationWarning: true, children: _jsx("body", { className: "min-h-screen max-w-screen", children: _jsx(ThemeProvider, { attribute: "class", defaultTheme: "light", enableSystem: false, storageKey: "lastbrain-theme", children: _jsx(AppProviders, { realtimeConfig: realtimeConfig, lang: lang, translations: translations, children: _jsx("div", { className: " min-h-screen pt-12", children: children }) }) }) }) }));
|
|
9
9
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i18n-build.d.ts","sourceRoot":"","sources":["../../src/scripts/i18n-build.ts"],"names":[],"mappings":";AACA;;;GAGG"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Script pour collecter tous les fichiers i18n des modules et les concaténer
|
|
4
|
+
* dans le dossier i18n de l'application
|
|
5
|
+
*/
|
|
6
|
+
import fs from "node:fs";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
const projectRoot = process.env.PROJECT_ROOT || process.cwd();
|
|
9
|
+
const monorepoRoot = projectRoot.includes("/apps/")
|
|
10
|
+
? path.resolve(projectRoot, "..", "..")
|
|
11
|
+
: projectRoot;
|
|
12
|
+
const packagesDir = path.join(monorepoRoot, "packages");
|
|
13
|
+
const appI18nDir = path.join(projectRoot, "i18n");
|
|
14
|
+
/**
|
|
15
|
+
* Collecte tous les fichiers i18n des modules
|
|
16
|
+
*/
|
|
17
|
+
async function collectTranslations() {
|
|
18
|
+
const translations = {
|
|
19
|
+
fr: {},
|
|
20
|
+
en: {},
|
|
21
|
+
};
|
|
22
|
+
try {
|
|
23
|
+
// Importer glob dynamiquement
|
|
24
|
+
const { glob } = await import("glob");
|
|
25
|
+
// Rechercher tous les fichiers i18n dans packages/**/src/i18n/*.json
|
|
26
|
+
const pattern = path.join(packagesDir, "**/src/i18n/*.json");
|
|
27
|
+
const files = await glob(pattern, {
|
|
28
|
+
ignore: ["**/node_modules/**", "**/dist/**"],
|
|
29
|
+
});
|
|
30
|
+
console.log(`\n🔍 Found ${files.length} i18n files\n`);
|
|
31
|
+
for (const file of files) {
|
|
32
|
+
const fileName = path.basename(file, ".json");
|
|
33
|
+
const lang = fileName; // fr.json -> fr, en.json -> en
|
|
34
|
+
if (!translations[lang]) {
|
|
35
|
+
translations[lang] = {};
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
const content = JSON.parse(fs.readFileSync(file, "utf-8"));
|
|
39
|
+
const moduleName = extractModuleName(file);
|
|
40
|
+
console.log(` ✓ ${moduleName} (${lang})`);
|
|
41
|
+
// Préfixer les clés avec le nom du module pour éviter les collisions
|
|
42
|
+
for (const [key, value] of Object.entries(content)) {
|
|
43
|
+
const prefixedKey = `${moduleName}.${key}`;
|
|
44
|
+
translations[lang][prefixedKey] = value;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
console.warn(` ⚠️ Error reading ${file}:`, error);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
console.error("❌ Error collecting translations:", error);
|
|
54
|
+
}
|
|
55
|
+
return translations;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Extrait le nom du module depuis le chemin du fichier
|
|
59
|
+
*/
|
|
60
|
+
function extractModuleName(filePath) {
|
|
61
|
+
// packages/module-auth/src/i18n/fr.json -> module-auth
|
|
62
|
+
const parts = filePath.split(path.sep);
|
|
63
|
+
const packagesIndex = parts.indexOf("packages");
|
|
64
|
+
if (packagesIndex !== -1 && packagesIndex < parts.length - 1) {
|
|
65
|
+
return parts[packagesIndex + 1];
|
|
66
|
+
}
|
|
67
|
+
return "unknown";
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Écrit les traductions concaténées dans le dossier i18n de l'app
|
|
71
|
+
*/
|
|
72
|
+
function writeTranslations(translations) {
|
|
73
|
+
// Créer le dossier i18n s'il n'existe pas
|
|
74
|
+
if (!fs.existsSync(appI18nDir)) {
|
|
75
|
+
fs.mkdirSync(appI18nDir, { recursive: true });
|
|
76
|
+
}
|
|
77
|
+
for (const [lang, content] of Object.entries(translations)) {
|
|
78
|
+
const filePath = path.join(appI18nDir, `${lang}.json`);
|
|
79
|
+
fs.writeFileSync(filePath, JSON.stringify(content, null, 2), "utf-8");
|
|
80
|
+
const keyCount = Object.keys(content).length;
|
|
81
|
+
console.log(`\n✅ Generated ${filePath} (${keyCount} keys)`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Point d'entrée principal
|
|
86
|
+
*/
|
|
87
|
+
async function buildI18n() {
|
|
88
|
+
console.log("🌍 Building i18n files...\n");
|
|
89
|
+
console.log(`📁 Project root: ${projectRoot}`);
|
|
90
|
+
console.log(`📦 Packages dir: ${packagesDir}`);
|
|
91
|
+
console.log(`🎯 App i18n dir: ${appI18nDir}\n`);
|
|
92
|
+
const translations = await collectTranslations();
|
|
93
|
+
writeTranslations(translations);
|
|
94
|
+
console.log("\n✨ i18n build complete!\n");
|
|
95
|
+
}
|
|
96
|
+
// Exécuter
|
|
97
|
+
buildI18n().catch((error) => {
|
|
98
|
+
console.error("\n❌ Error:", error);
|
|
99
|
+
process.exit(1);
|
|
100
|
+
});
|
package/dist/scripts/init-app.js
CHANGED
|
@@ -368,19 +368,18 @@ async function createNextStructure(targetDir, force, useHeroUI, withAuth) {
|
|
|
368
368
|
if (!fs.existsSync(layoutDest) || force) {
|
|
369
369
|
let layoutContent = "";
|
|
370
370
|
if (useHeroUI) {
|
|
371
|
-
// Layout avec HeroUI - Server Component
|
|
371
|
+
// Layout avec HeroUI - Server Component (juste HTML, providers gérés par [lang]/layout.tsx)
|
|
372
372
|
layoutContent = `// GENERATED BY LASTBRAIN APP-SHELL
|
|
373
373
|
// Server Component pour permettre le SSR des pages enfants
|
|
374
374
|
|
|
375
375
|
import "../styles/globals.css";
|
|
376
|
-
import { ClientLayout } from "../components/ClientLayout";
|
|
377
376
|
import type { PropsWithChildren } from "react";
|
|
378
377
|
|
|
379
378
|
export default function RootLayout({ children }: PropsWithChildren<{}>) {
|
|
380
379
|
return (
|
|
381
380
|
<html lang="fr" suppressHydrationWarning>
|
|
382
381
|
<body className="min-h-screen">
|
|
383
|
-
|
|
382
|
+
{children}
|
|
384
383
|
</body>
|
|
385
384
|
</html>
|
|
386
385
|
);
|
|
@@ -388,19 +387,18 @@ export default function RootLayout({ children }: PropsWithChildren<{}>) {
|
|
|
388
387
|
`;
|
|
389
388
|
}
|
|
390
389
|
else {
|
|
391
|
-
// Layout Tailwind CSS uniquement - Server Component
|
|
390
|
+
// Layout Tailwind CSS uniquement - Server Component (juste HTML, providers gérés par [lang]/layout.tsx)
|
|
392
391
|
layoutContent = `// GENERATED BY LASTBRAIN APP-SHELL
|
|
393
392
|
// Server Component pour permettre le SSR des pages enfants
|
|
394
393
|
|
|
395
394
|
import "../styles/globals.css";
|
|
396
|
-
import { ClientLayout } from "../components/ClientLayout";
|
|
397
395
|
import type { PropsWithChildren } from "react";
|
|
398
396
|
|
|
399
397
|
export default function RootLayout({ children }: PropsWithChildren<{}>) {
|
|
400
398
|
return (
|
|
401
399
|
<html lang="fr" suppressHydrationWarning>
|
|
402
400
|
<body className="min-h-screen">
|
|
403
|
-
|
|
401
|
+
{children}
|
|
404
402
|
</body>
|
|
405
403
|
</html>
|
|
406
404
|
);
|
|
@@ -424,7 +422,7 @@ export default function RootLayout({ children }: PropsWithChildren<{}>) {
|
|
|
424
422
|
console.log(chalk.green("✓ styles/globals.css créé"));
|
|
425
423
|
}
|
|
426
424
|
// Créer la page d'accueil publique (racine)
|
|
427
|
-
const homePagePath = path.join(appDir, "page.tsx");
|
|
425
|
+
const homePagePath = path.join(appDir, "[lang]", "page.tsx");
|
|
428
426
|
if (!fs.existsSync(homePagePath) || force) {
|
|
429
427
|
const homePageContent = `// GENERATED BY LASTBRAIN APP-SHELL
|
|
430
428
|
|
|
@@ -449,10 +447,10 @@ export default function RootPage() {
|
|
|
449
447
|
if (!fs.existsSync(notFoundPath) || force) {
|
|
450
448
|
const notFoundContent = `"use client";
|
|
451
449
|
import { Button } from "@lastbrain/ui";
|
|
452
|
-
import {
|
|
450
|
+
import { useLocalizedRouter } from "@lastbrain/core";
|
|
453
451
|
|
|
454
452
|
export default function NotFound() {
|
|
455
|
-
const router =
|
|
453
|
+
const router = useLocalizedRouter();
|
|
456
454
|
return (
|
|
457
455
|
<div className="flex min-h-screen items-center justify-center bg-background">
|
|
458
456
|
<div className="mx-auto max-w-md text-center">
|
|
@@ -510,7 +508,7 @@ import { AppHeader } from "./AppHeader";
|
|
|
510
508
|
import type { ReactNode } from "react";
|
|
511
509
|
|
|
512
510
|
export function ClientLayout({ children }: { children: ReactNode }) {
|
|
513
|
-
const router =
|
|
511
|
+
const router = useLocalizedRouter();
|
|
514
512
|
|
|
515
513
|
return (
|
|
516
514
|
<HeroUIProvider navigate={router.push}>
|
|
@@ -686,7 +684,7 @@ import { Header, type MenuItem } from "@lastbrain/ui";
|
|
|
686
684
|
import { menuConfig } from "../config/menu";
|
|
687
685
|
import { supabaseBrowserClient } from "@lastbrain/core";
|
|
688
686
|
import { useRouter } from "next/navigation";
|
|
689
|
-
import { useAuthSession, useNotificationsContext } from "@lastbrain/app";
|
|
687
|
+
import { useAuthSession, useNotificationsContext,LanguageSwitcher } from "@lastbrain/app";
|
|
690
688
|
import { useState, useEffect } from "react";
|
|
691
689
|
|
|
692
690
|
interface MenuIgnored {
|
|
@@ -695,7 +693,7 @@ interface MenuIgnored {
|
|
|
695
693
|
}
|
|
696
694
|
|
|
697
695
|
export function AppHeader() {
|
|
698
|
-
const router =
|
|
696
|
+
const router = useLocalizedRouter();
|
|
699
697
|
const { user, isSuperAdmin } = useAuthSession();
|
|
700
698
|
const { data, loading, markAsRead, markAllAsRead, deleteNotification } =
|
|
701
699
|
useNotificationsContext();
|
|
@@ -757,6 +755,8 @@ export function AppHeader() {
|
|
|
757
755
|
{...(menuIgnored ? { menuIgnored } : {})}
|
|
758
756
|
{...(menuCustom ? { menuCustom } : {})}
|
|
759
757
|
{...{ isLoadingMenus: isLoading }}
|
|
758
|
+
languageSwitcher={<LanguageSwitcher variant="minimal" />}
|
|
759
|
+
|
|
760
760
|
/>
|
|
761
761
|
);
|
|
762
762
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module-build.d.ts","sourceRoot":"","sources":["../../src/scripts/module-build.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"module-build.d.ts","sourceRoot":"","sources":["../../src/scripts/module-build.ts"],"names":[],"mappings":"AAqxDA,wBAAsB,cAAc,kBA8GnC"}
|