@lastbrain/app 0.1.44 → 0.1.46

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.
@@ -5,6 +5,7 @@ interface InitAppOptions {
5
5
  useHeroUI: boolean;
6
6
  withAuth?: boolean;
7
7
  interactive?: boolean;
8
+ isMonorepoProject?: boolean;
8
9
  }
9
10
  export declare function initApp(options: InitAppOptions): Promise<void>;
10
11
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"init-app.d.ts","sourceRoot":"","sources":["../../src/scripts/init-app.ts"],"names":[],"mappings":"AAcA,UAAU,cAAc;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,wBAAsB,OAAO,CAAC,OAAO,EAAE,cAAc,iBA0NpD"}
1
+ {"version":3,"file":"init-app.d.ts","sourceRoot":"","sources":["../../src/scripts/init-app.ts"],"names":[],"mappings":"AAcA,UAAU,cAAc;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,wBAAsB,OAAO,CAAC,OAAO,EAAE,cAAc,iBAyQpD"}
@@ -9,7 +9,7 @@ const __filename = fileURLToPath(import.meta.url);
9
9
  const __dirname = path.dirname(__filename);
10
10
  export async function initApp(options) {
11
11
  const { targetDir, force, projectName, useHeroUI, interactive = true, } = options;
12
- let { withAuth = false } = options;
12
+ let { withAuth = false, isMonorepoProject = false } = options;
13
13
  console.log(chalk.blue("\n🚀 LastBrain App Init\n"));
14
14
  console.log(chalk.gray(`📁 Dossier cible: ${targetDir}`));
15
15
  if (useHeroUI) {
@@ -33,15 +33,41 @@ export async function initApp(options) {
33
33
  checked: false,
34
34
  })),
35
35
  },
36
+ {
37
+ type: "rawlist",
38
+ name: "projectType",
39
+ message: "Type de projet ?",
40
+ choices: [
41
+ {
42
+ name: "📦 Indépendant (créer une nouvelle BDD Supabase)",
43
+ value: "independent",
44
+ },
45
+ {
46
+ name: "🏢 Monorepo (utiliser la BDD existante)",
47
+ value: "monorepo",
48
+ },
49
+ ],
50
+ default: "independent",
51
+ },
36
52
  ]);
37
53
  selectedModules.push(...answers.modules);
38
54
  withAuth = selectedModules.includes("auth");
55
+ isMonorepoProject = answers.projectType === "monorepo";
56
+ if (isMonorepoProject) {
57
+ console.log(chalk.cyan("\n💡 Mode monorepo activé:"), chalk.gray("Votre app utilisera la base de données centralisée du monorepo."));
58
+ console.log(chalk.gray(" Aucune configuration Supabase locale ne sera créée.\n"));
59
+ }
60
+ else {
61
+ console.log(chalk.cyan("\n💡 Mode projet indépendant activé:"), chalk.gray("Votre app aura sa propre instance Supabase locale."));
62
+ console.log(chalk.gray(" Configuration complète sera créée.\n"));
63
+ }
39
64
  console.log();
40
65
  }
41
66
  else if (!interactive) {
42
67
  // En mode non-interactif, installer auth et ai par défaut
43
68
  selectedModules.push("auth", "ai");
44
69
  withAuth = true;
70
+ isMonorepoProject = false;
45
71
  console.log(chalk.blue("📦 Modules installés par défaut : Authentication, AI Generation\n"));
46
72
  }
47
73
  // Créer le dossier s'il n'existe pas
@@ -59,9 +85,15 @@ export async function initApp(options) {
59
85
  // 6. Créer .gitignore et .env.local.example
60
86
  await createGitIgnore(targetDir, force);
61
87
  await createEnvExample(targetDir, force);
62
- await createEnvLocal(targetDir, force);
63
- // 7. Créer la structure Supabase avec migrations
64
- await createSupabaseStructure(targetDir, force);
88
+ await createEnvLocal(targetDir, force, isMonorepoProject);
89
+ // 7. Créer la structure Supabase avec migrations (seulement pour projets indépendants)
90
+ if (!isMonorepoProject) {
91
+ console.log(chalk.blue("🗄️ Création de la structure Supabase locale...\n"));
92
+ await createSupabaseStructure(targetDir, force);
93
+ }
94
+ else {
95
+ console.log(chalk.yellow("⏭️ Projet monorepo détecté - pas de configuration Supabase locale requise\n"));
96
+ }
65
97
  // 8. Ajouter les scripts NPM
66
98
  await addScriptsToPackageJson(targetDir);
67
99
  // 9. Enregistrer les modules sélectionnés
@@ -613,9 +645,8 @@ export default function AuthLayout({
613
645
  else {
614
646
  // Layout standard pour les autres routes (ex: docs = public)
615
647
  const layoutComponent = layoutType.charAt(0).toUpperCase() + layoutType.slice(1) + "Layout";
616
- if (routeName === "docs") {
617
- // Layout docs avec footer
618
- layoutContent = `import { ${layoutComponent} } from "@lastbrain/app";
648
+ // Layout docs avec footer
649
+ layoutContent = `import { ${layoutComponent} } from "@lastbrain/app";
619
650
  import { footerConfig } from "../../config/footer";
620
651
 
621
652
  export default function DocsLayout({
@@ -625,12 +656,6 @@ export default function DocsLayout({
625
656
  }) {
626
657
  return <${layoutComponent} footerConfig={footerConfig}>{children}</${layoutComponent}>;
627
658
  }`;
628
- }
629
- else {
630
- layoutContent = `import { ${layoutComponent} } from "@lastbrain/app";
631
-
632
- export default ${layoutComponent};`;
633
- }
634
659
  }
635
660
  await fs.writeFile(layoutPath, layoutContent);
636
661
  console.log(chalk.green(`✓ app/${routeName}/layout.tsx créé`));
@@ -714,6 +739,7 @@ export function AppHeader() {
714
739
  user={user}
715
740
  onLogout={handleLogout}
716
741
  menuConfig={menuConfig}
742
+ accountMenu={menuConfig.account}
717
743
  brandName="LastBrain App"
718
744
  brandHref="/"
719
745
  isSuperAdmin={isSuperAdmin}
@@ -815,6 +841,11 @@ export async function middleware(request: NextRequest) {
815
841
  "/callback",
816
842
  ];
817
843
 
844
+ if(process.env.MAINTENANCE_MODE === "true" && !pathname.startsWith("/maintenance")) {
845
+ const redirectUrl = new URL("/maintenance", request.url);
846
+ return NextResponse.redirect(redirectUrl);
847
+ }
848
+
818
849
  const isPublicAuthPage = publicAuthPages.some((page) =>
819
850
  pathname.startsWith(page)
820
851
  );
@@ -1292,11 +1323,25 @@ SUPABASE_SERVICE_ROLE_KEY=YOUR_LOCAL_SERVICE_ROLE_KEY
1292
1323
  console.log(chalk.green("✓ .env.local.example créé"));
1293
1324
  }
1294
1325
  }
1295
- async function createEnvLocal(targetDir, force) {
1326
+ async function createEnvLocal(targetDir, force, isMonorepoProject = false) {
1296
1327
  const envLocalPath = path.join(targetDir, ".env.local");
1297
1328
  if (!fs.existsSync(envLocalPath) || force) {
1298
1329
  console.log(chalk.yellow("\n🔐 Création de .env.local..."));
1299
- const envContent = `# Supabase Configuration
1330
+ let envContent;
1331
+ if (isMonorepoProject) {
1332
+ // Pour les projets monorepo, utiliser les variables du monorepo
1333
+ envContent = `# Supabase Configuration (Monorepo - Centralisé)
1334
+ # Les variables Supabase sont gérées au niveau du monorepo
1335
+
1336
+ # OpenAI Configuration (clé factice pour éviter les erreurs de build)
1337
+ OPENAI_API_KEY=sk-fake-openai-key-for-development-replace-with-real-key
1338
+
1339
+ # Note: Les variables Supabase sont fournies par le monorepo parent
1340
+ `;
1341
+ }
1342
+ else {
1343
+ // Pour les projets indépendants
1344
+ envContent = `# Supabase Configuration
1300
1345
  # Valeurs par défaut pour le développement local
1301
1346
 
1302
1347
  # Supabase Local (par défaut)
@@ -1307,6 +1352,7 @@ SUPABASE_SERVICE_ROLE_KEY=eyJhbGc...
1307
1352
  # OpenAI Configuration (clé factice pour éviter les erreurs de build)
1308
1353
  OPENAI_API_KEY=sk-fake-openai-key-for-development-replace-with-real-key
1309
1354
  `;
1355
+ }
1310
1356
  await fs.writeFile(envLocalPath, envContent);
1311
1357
  console.log(chalk.green("✓ .env.local créé"));
1312
1358
  }
@@ -122,10 +122,12 @@ function toPascalCase(value) {
122
122
  .join("");
123
123
  }
124
124
  function buildPage(moduleConfig, page) {
125
- // Extraire le préfixe du module (ex: @lastbrain/module-auth -> auth, @lastbrain-labs/module-recipes-pro -> recipes-pro)
125
+ // Extraire le préfixe du module (ex: @lastbrain/module-auth -> auth, @lastbrain-labs/module-recipes-pro -> recipes)
126
+ // Enlever -pro pour les routes auth et admin afin d'avoir des chemins propres
126
127
  const modulePrefix = moduleConfig.moduleName
127
128
  .replace(/^@lastbrain\/module-/, "")
128
129
  .replace(/^@lastbrain-labs\/module-/, "")
130
+ .replace(/-pro$/, "") // Enlever le suffixe -pro
129
131
  .toLowerCase();
130
132
  if (isDebugMode) {
131
133
  console.log(`🔄 Building page for module ${modulePrefix}: ${page.path}`);
@@ -1 +1 @@
1
- {"version":3,"file":"module-create.d.ts","sourceRoot":"","sources":["../../src/scripts/module-create.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,CAAC,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC;CAC3C;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AAwwCD;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAiB1C;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,MAAM,iBAoLhB;AAED;;GAEG;AACH,wBAAsB,YAAY,kBAsLjC"}
1
+ {"version":3,"file":"module-create.d.ts","sourceRoot":"","sources":["../../src/scripts/module-create.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,CAAC,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC;CAC3C;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AAswCD;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAiB1C;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,MAAM,iBAoLhB;AAED;;GAEG;AACH,wBAAsB,YAAY,kBAsLjC"}
@@ -1 +1 @@
1
- {"version":3,"file":"DefaultDoc.d.ts","sourceRoot":"","sources":["../../src/templates/DefaultDoc.tsx"],"names":[],"mappings":"AAoBA,wBAAgB,oBAAoB,4CAsoDnC"}
1
+ {"version":3,"file":"DefaultDoc.d.ts","sourceRoot":"","sources":["../../src/templates/DefaultDoc.tsx"],"names":[],"mappings":"AAoBA,wBAAgB,oBAAoB,4CAkqDnC"}
@@ -236,5 +236,5 @@ export function DocUsageCustom() {
236
236
  <p>Description...</p>
237
237
  </div>
238
238
  );
239
- }` }) }), _jsx("h3", { className: "text-lg font-semibold mb-2", children: "Exporter la documentation" }), _jsxs("p", { className: "text-sm text-slate-600 dark:text-slate-400 mb-2", children: ["Dans", " ", _jsx("code", { className: "text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded", children: "src/index.ts" }), " ", ":"] }), _jsx(Alert, { hideIcon: true, color: "primary", className: "p-4 mb-4", children: _jsx("pre", { className: "whitespace-pre-wrap", children: `export { MonModuleDoc } from "./components/Doc.js";` }) })] })] }), _jsxs(Card, { id: "section-links", className: "scroll-mt-32", children: [_jsx(CardHeader, { children: _jsxs("h2", { className: "text-2xl font-semibold flex items-center gap-2", children: [_jsx(Link, { size: 24 }), "Liens utiles & remerciements \uD83D\uDE4F"] }) }), _jsx(CardBody, { children: _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4", children: [_jsx(Card, { className: "hover:shadow-lg transition-shadow", isPressable: true, as: "a", href: "https://nextjs.org/docs", target: "_blank", rel: "noopener noreferrer", children: _jsxs(CardBody, { children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: "Next.js" }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400 mb-3", children: "Documentation officielle" }), _jsx("p", { className: "text-xs text-blue-600 dark:text-blue-400 truncate", children: "https://nextjs.org/docs" })] }) }), _jsx(Card, { className: "hover:shadow-lg transition-shadow", isPressable: true, as: "a", href: "https://supabase.com/docs", target: "_blank", rel: "noopener noreferrer", children: _jsxs(CardBody, { children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: "Supabase" }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400 mb-3", children: "Documentation officielle" }), _jsx("p", { className: "text-xs text-blue-600 dark:text-blue-400 truncate", children: "https://supabase.com/docs" })] }) }), _jsx(Card, { className: "hover:shadow-lg transition-shadow", isPressable: true, as: "a", href: "https://www.heroui.com/docs", target: "_blank", rel: "noopener noreferrer", children: _jsxs(CardBody, { children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: "Heroui" }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400 mb-3", children: "Composants UI" }), _jsx("p", { className: "text-xs text-blue-600 dark:text-blue-400 truncate", children: "https://www.heroui.com/docs" })] }) }), _jsx(Card, { className: "hover:shadow-lg transition-shadow", isPressable: true, as: "a", href: "https://tailwindcss.com/docs", target: "_blank", rel: "noopener noreferrer", children: _jsxs(CardBody, { children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: "Tailwind CSS" }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400 mb-3", children: "Framework CSS" }), _jsx("p", { className: "text-xs text-blue-600 dark:text-blue-400 truncate", children: "https://tailwindcss.com/docs" })] }) }), _jsx(Card, { className: "hover:shadow-lg transition-shadow", isPressable: true, as: "a", href: "https://lucide.dev/", target: "_blank", rel: "noopener noreferrer", children: _jsxs(CardBody, { children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: "Lucide Icons" }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400 mb-3", children: "Icones SVG" }), _jsx("p", { className: "text-xs text-blue-600 dark:text-blue-400 truncate", children: "https://lucide.dev/" })] }) }), _jsx(Card, { className: "hover:shadow-lg transition-shadow", isPressable: true, as: "a", href: "https://stripe.com/docs", target: "_blank", rel: "noopener noreferrer", children: _jsxs(CardBody, { children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: "Stripe" }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400 mb-3", children: "Syst\u00E8me de paiement" }), _jsx("p", { className: "text-xs text-blue-600 dark:text-blue-400 truncate", children: "https://stripe.com/docs" })] }) })] }) })] }), _jsxs(Card, { id: "section-modules", className: "scroll-mt-32", children: [_jsx(CardHeader, { children: _jsxs("h2", { className: "text-2xl font-semibold flex items-center gap-2", children: [_jsx(Package, { size: 24 }), "Modules"] }) }), _jsxs(CardBody, { className: "space-y-6", children: [_jsx("p", { className: "text-slate-600 dark:text-slate-400", children: "Les modules LastBrain permettent d'ajouter des fonctionnalit\u00E9s compl\u00E8tes \u00E0 votre application de mani\u00E8re modulaire." }), _jsxs("div", { children: [_jsx("h3", { className: "text-xl font-semibold mb-4", children: "Modules Disponibles" }), _jsxs("div", { className: "grid grid-cols-1 gap-4", children: [_jsx(Card, { className: "hover:shadow-lg transition-shadow border-l-4 border-l-blue-500", children: _jsxs(CardBody, { className: "space-y-3", children: [_jsxs("div", { className: "flex items-start justify-between", children: [_jsx("h3", { className: "text-lg font-semibold", children: "Ai" }), _jsx("span", { className: "text-xs bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200 px-2 py-1 rounded", children: "FREE" })] }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400", children: "Module LastBrain" }), _jsxs("p", { className: "text-xs text-slate-500 dark:text-slate-500", children: [_jsx("strong", { children: "Pages:" }), " 1 auth, 1 admin"] }), _jsx(Snippet, { symbol: "\uD83D\uDCBB", hideSymbol: true, className: "text-sm", children: `pnpm lastbrain add-module ai` }), _jsx("a", { href: "https://github.com/Lastbrain-labs/lb-starter/tree/main/packages/module-ai", className: "text-sm text-blue-600 dark:text-blue-400 hover:underline inline-flex items-center gap-1", target: "_blank", rel: "noopener noreferrer", children: "\uD83D\uDCD6 Documentation \u2192" })] }) }), _jsx(Card, { className: "hover:shadow-lg transition-shadow border-l-4 border-l-blue-500", children: _jsxs(CardBody, { className: "space-y-3", children: [_jsxs("div", { className: "flex items-start justify-between", children: [_jsx("h3", { className: "text-lg font-semibold", children: "Auth" }), _jsx("span", { className: "text-xs bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200 px-2 py-1 rounded", children: "FREE" })] }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400", children: "Module LastBrain" }), _jsxs("p", { className: "text-xs text-slate-500 dark:text-slate-500", children: [_jsx("strong", { children: "Pages:" }), " 3 publique(s), 4 auth, 2 admin"] }), _jsx(Snippet, { symbol: "\uD83D\uDCBB", hideSymbol: true, className: "text-sm", children: `pnpm lastbrain add-module auth` }), _jsx("a", { href: "https://github.com/Lastbrain-labs/lb-starter/tree/main/packages/module-auth", className: "text-sm text-blue-600 dark:text-blue-400 hover:underline inline-flex items-center gap-1", target: "_blank", rel: "noopener noreferrer", children: "\uD83D\uDCD6 Documentation \u2192" })] }) }), _jsx(Card, { className: "hover:shadow-lg transition-shadow border-l-4 border-l-purple-500", children: _jsxs(CardBody, { className: "space-y-3", children: [_jsxs("div", { className: "flex items-start justify-between", children: [_jsx("h3", { className: "text-lg font-semibold", children: "Billing Pro" }), _jsx("span", { className: "text-xs bg-purple-100 dark:bg-purple-900 text-purple-800 dark:text-purple-200 px-2 py-1 rounded", children: "PRO" })] }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400", children: "Module LastBrain" }), _jsxs("p", { className: "text-xs text-slate-500 dark:text-slate-500", children: [_jsx("strong", { children: "Pages:" }), " 3 auth, 2 admin"] }), _jsx(Snippet, { symbol: "\uD83D\uDCBB", hideSymbol: true, className: "text-sm", children: `pnpm lastbrain add-module billing-pro` }), _jsx("span", { className: "text-xs text-slate-500 dark:text-slate-400 inline-flex items-center gap-1", children: "\uD83D\uDD12 Documentation priv\u00E9e" })] }) }), _jsx(Card, { className: "hover:shadow-lg transition-shadow border-l-4 border-l-purple-500", children: _jsxs(CardBody, { className: "space-y-3", children: [_jsxs("div", { className: "flex items-start justify-between", children: [_jsx("h3", { className: "text-lg font-semibold", children: "Core Cart Pro" }), _jsx("span", { className: "text-xs bg-purple-100 dark:bg-purple-900 text-purple-800 dark:text-purple-200 px-2 py-1 rounded", children: "PRO" })] }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400", children: "Module LastBrain" }), _jsxs("p", { className: "text-xs text-slate-500 dark:text-slate-500", children: [_jsx("strong", { children: "Pages:" }), " 2 auth, 1 admin"] }), _jsx(Snippet, { symbol: "\uD83D\uDCBB", hideSymbol: true, className: "text-sm", children: `pnpm lastbrain add-module core-cart-pro` }), _jsx("span", { className: "text-xs text-slate-500 dark:text-slate-400 inline-flex items-center gap-1", children: "\uD83D\uDD12 Documentation priv\u00E9e" })] }) }), _jsx(Card, { className: "hover:shadow-lg transition-shadow border-l-4 border-l-purple-500", children: _jsxs(CardBody, { className: "space-y-3", children: [_jsxs("div", { className: "flex items-start justify-between", children: [_jsx("h3", { className: "text-lg font-semibold", children: "Core Commerce Pro" }), _jsx("span", { className: "text-xs bg-purple-100 dark:bg-purple-900 text-purple-800 dark:text-purple-200 px-2 py-1 rounded", children: "PRO" })] }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400", children: "Module LastBrain" }), _jsx(Snippet, { symbol: "\uD83D\uDCBB", hideSymbol: true, className: "text-sm", children: `pnpm lastbrain add-module core-commerce-pro` }), _jsx("span", { className: "text-xs text-slate-500 dark:text-slate-400 inline-flex items-center gap-1", children: "\uD83D\uDD12 Documentation priv\u00E9e" })] }) }), _jsx(Card, { className: "hover:shadow-lg transition-shadow border-l-4 border-l-purple-500", children: _jsxs(CardBody, { className: "space-y-3", children: [_jsxs("div", { className: "flex items-start justify-between", children: [_jsx("h3", { className: "text-lg font-semibold", children: "Core Order Pro" }), _jsx("span", { className: "text-xs bg-purple-100 dark:bg-purple-900 text-purple-800 dark:text-purple-200 px-2 py-1 rounded", children: "PRO" })] }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400", children: "Module LastBrain" }), _jsxs("p", { className: "text-xs text-slate-500 dark:text-slate-500", children: [_jsx("strong", { children: "Pages:" }), " 2 auth"] }), _jsx(Snippet, { symbol: "\uD83D\uDCBB", hideSymbol: true, className: "text-sm", children: `pnpm lastbrain add-module core-order-pro` }), _jsx("span", { className: "text-xs text-slate-500 dark:text-slate-400 inline-flex items-center gap-1", children: "\uD83D\uDD12 Documentation priv\u00E9e" })] }) }), _jsx(Card, { className: "hover:shadow-lg transition-shadow border-l-4 border-l-purple-500", children: _jsxs(CardBody, { className: "space-y-3", children: [_jsxs("div", { className: "flex items-start justify-between", children: [_jsx("h3", { className: "text-lg font-semibold", children: "Core Payment Pro" }), _jsx("span", { className: "text-xs bg-purple-100 dark:bg-purple-900 text-purple-800 dark:text-purple-200 px-2 py-1 rounded", children: "PRO" })] }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400", children: "Module LastBrain" }), _jsxs("p", { className: "text-xs text-slate-500 dark:text-slate-500", children: [_jsx("strong", { children: "Pages:" }), " 1 admin"] }), _jsx(Snippet, { symbol: "\uD83D\uDCBB", hideSymbol: true, className: "text-sm", children: `pnpm lastbrain add-module core-payment-pro` }), _jsx("span", { className: "text-xs text-slate-500 dark:text-slate-400 inline-flex items-center gap-1", children: "\uD83D\uDD12 Documentation priv\u00E9e" })] }) }), _jsx(Card, { className: "hover:shadow-lg transition-shadow border-l-4 border-l-purple-500", children: _jsxs(CardBody, { className: "space-y-3", children: [_jsxs("div", { className: "flex items-start justify-between", children: [_jsx("h3", { className: "text-lg font-semibold", children: "Core Product Pro" }), _jsx("span", { className: "text-xs bg-purple-100 dark:bg-purple-900 text-purple-800 dark:text-purple-200 px-2 py-1 rounded", children: "PRO" })] }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400", children: "Module LastBrain" }), _jsxs("p", { className: "text-xs text-slate-500 dark:text-slate-500", children: [_jsx("strong", { children: "Pages:" }), " 2 publique(s)"] }), _jsx(Snippet, { symbol: "\uD83D\uDCBB", hideSymbol: true, className: "text-sm", children: `pnpm lastbrain add-module core-product-pro` }), _jsx("span", { className: "text-xs text-slate-500 dark:text-slate-400 inline-flex items-center gap-1", children: "\uD83D\uDD12 Documentation priv\u00E9e" })] }) }), _jsx(Card, { className: "hover:shadow-lg transition-shadow border-l-4 border-l-blue-500", children: _jsxs(CardBody, { className: "space-y-3", children: [_jsxs("div", { className: "flex items-start justify-between", children: [_jsx("h3", { className: "text-lg font-semibold", children: "Legal" }), _jsx("span", { className: "text-xs bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200 px-2 py-1 rounded", children: "FREE" })] }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400", children: "Module LastBrain" }), _jsxs("p", { className: "text-xs text-slate-500 dark:text-slate-500", children: [_jsx("strong", { children: "Pages:" }), " 4 publique(s), 2 admin"] }), _jsx(Snippet, { symbol: "\uD83D\uDCBB", hideSymbol: true, className: "text-sm", children: `pnpm lastbrain add-module legal` }), _jsx("a", { href: "https://github.com/Lastbrain-labs/lb-starter/tree/main/packages/module-legal", className: "text-sm text-blue-600 dark:text-blue-400 hover:underline inline-flex items-center gap-1", target: "_blank", rel: "noopener noreferrer", children: "\uD83D\uDCD6 Documentation \u2192" })] }) }), _jsx(Card, { className: "hover:shadow-lg transition-shadow border-l-4 border-l-purple-500", children: _jsxs(CardBody, { className: "space-y-3", children: [_jsxs("div", { className: "flex items-start justify-between", children: [_jsx("h3", { className: "text-lg font-semibold", children: "Recipes Pro" }), _jsx("span", { className: "text-xs bg-purple-100 dark:bg-purple-900 text-purple-800 dark:text-purple-200 px-2 py-1 rounded", children: "PRO" })] }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400", children: "Module LastBrain" }), _jsxs("p", { className: "text-xs text-slate-500 dark:text-slate-500", children: [_jsx("strong", { children: "Pages:" }), " 4 auth"] }), _jsx(Snippet, { symbol: "\uD83D\uDCBB", hideSymbol: true, className: "text-sm", children: `pnpm lastbrain add-module recipes-pro` }), _jsx("span", { className: "text-xs text-slate-500 dark:text-slate-400 inline-flex items-center gap-1", children: "\uD83D\uDD12 Documentation priv\u00E9e" })] }) }), _jsx(Card, { className: "hover:shadow-lg transition-shadow border-l-4 border-l-blue-500", children: _jsxs(CardBody, { className: "space-y-3", children: [_jsxs("div", { className: "flex items-start justify-between", children: [_jsx("h3", { className: "text-lg font-semibold", children: "Tasks" }), _jsx("span", { className: "text-xs bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200 px-2 py-1 rounded", children: "FREE" })] }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400", children: "Module LastBrain" }), _jsxs("p", { className: "text-xs text-slate-500 dark:text-slate-500", children: [_jsx("strong", { children: "Pages:" }), " 2 auth, 1 admin"] }), _jsx(Snippet, { symbol: "\uD83D\uDCBB", hideSymbol: true, className: "text-sm", children: `pnpm lastbrain add-module nom-du-module` }), _jsx("a", { href: "https://github.com/Lastbrain-labs/lb-starter/tree/main/packages/module-tasks", className: "text-sm text-blue-600 dark:text-blue-400 hover:underline inline-flex items-center gap-1", target: "_blank", rel: "noopener noreferrer", children: "\uD83D\uDCD6 Documentation \u2192" })] }) })] })] }), _jsx("h3", { className: "text-lg font-semibold mb-2", children: "Commandes" }), _jsx("h4", { className: "font-medium mb-2", children: "Installer un module" }), _jsx(Snippet, { symbol: "", hideSymbol: true, className: "text-sm mb-2", children: `pnpm lastbrain add-module nom-du-module` }), _jsx(Snippet, { symbol: "", hideSymbol: true, className: "text-sm mb-2", children: `pnpm build:modules` }), _jsx("h4", { className: "font-medium mb-2", children: "Cr\u00E9er un nouveau module" }), _jsx(Snippet, { symbol: "", hideSymbol: true, className: "text-sm mb-2", children: `pnpm lastbrain create-module nom-du-module` }), _jsx("h4", { className: "font-medium mb-2", children: "G\u00E9n\u00E9rer la documentation des modules" }), _jsx(Snippet, { symbol: "", hideSymbol: true, className: "text-sm mb-2", children: `pnpm generate:module-docs` }), _jsx("h4", { className: "font-medium mb-2", children: "Supprimer un module" }), _jsx(Snippet, { symbol: "", hideSymbol: true, className: "text-sm mb-2", children: `pnpm lastbrain remove-module nom-du-module` }), _jsx(Snippet, { symbol: "", hideSymbol: true, className: "text-sm mb-2", children: `pnpm build:modules` }), _jsx("h3", { className: "text-lg font-semibold mb-2", children: "D\u00E9veloppement de modules" }), _jsxs("p", { className: "text-sm text-slate-600 dark:text-slate-400 mb-2", children: ["Pour cr\u00E9er un nouveau module, consultez la", " ", _jsx("a", { href: "./004_CREATE_MODULE.md", className: "text-blue-600 hover:underline", target: "_blank", rel: "noopener noreferrer", children: "documentation de cr\u00E9ation de modules" }), "."] }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400 mb-2", children: "La documentation de chaque module est g\u00E9n\u00E9r\u00E9e automatiquement depuis :" }), _jsxs("div", { className: "space-y-2", children: [_jsxs("div", { className: "flex items-start gap-2", children: [_jsx("span", { className: "text-green-600", children: "\u2705" }), _jsxs("span", { children: ["Le fichier", " ", _jsx("code", { className: "text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded", children: "module-name.build.config.ts" }), " ", "pour les pages et APIs"] })] }), _jsxs("div", { className: "flex items-start gap-2", children: [_jsx("span", { className: "text-green-600", children: "\u2705" }), _jsx("span", { children: "Les fichiers de migration SQL pour les tables" })] }), _jsxs("div", { className: "flex items-start gap-2", children: [_jsx("span", { className: "text-green-600", children: "\u2705" }), _jsxs("span", { children: ["Le README.md est auto-g\u00E9n\u00E9r\u00E9 avec", " ", _jsx("code", { className: "text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded", children: "pnpm generate:module-docs" })] })] })] })] })] })] }));
239
+ }` }) }), _jsx("h3", { className: "text-lg font-semibold mb-2", children: "Exporter la documentation" }), _jsxs("p", { className: "text-sm text-slate-600 dark:text-slate-400 mb-2", children: ["Dans", " ", _jsx("code", { className: "text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded", children: "src/index.ts" }), " ", ":"] }), _jsx(Alert, { hideIcon: true, color: "primary", className: "p-4 mb-4", children: _jsx("pre", { className: "whitespace-pre-wrap", children: `export { MonModuleDoc } from "./components/Doc.js";` }) })] })] }), _jsxs(Card, { id: "section-links", className: "scroll-mt-32", children: [_jsx(CardHeader, { children: _jsxs("h2", { className: "text-2xl font-semibold flex items-center gap-2", children: [_jsx(Link, { size: 24 }), "Liens utiles & remerciements \uD83D\uDE4F"] }) }), _jsx(CardBody, { children: _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4", children: [_jsx(Card, { className: "hover:shadow-lg transition-shadow", isPressable: true, as: "a", href: "https://nextjs.org/docs", target: "_blank", rel: "noopener noreferrer", children: _jsxs(CardBody, { children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: "Next.js" }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400 mb-3", children: "Documentation officielle" }), _jsx("p", { className: "text-xs text-blue-600 dark:text-blue-400 truncate", children: "https://nextjs.org/docs" })] }) }), _jsx(Card, { className: "hover:shadow-lg transition-shadow", isPressable: true, as: "a", href: "https://supabase.com/docs", target: "_blank", rel: "noopener noreferrer", children: _jsxs(CardBody, { children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: "Supabase" }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400 mb-3", children: "Documentation officielle" }), _jsx("p", { className: "text-xs text-blue-600 dark:text-blue-400 truncate", children: "https://supabase.com/docs" })] }) }), _jsx(Card, { className: "hover:shadow-lg transition-shadow", isPressable: true, as: "a", href: "https://www.heroui.com/docs", target: "_blank", rel: "noopener noreferrer", children: _jsxs(CardBody, { children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: "Heroui" }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400 mb-3", children: "Composants UI" }), _jsx("p", { className: "text-xs text-blue-600 dark:text-blue-400 truncate", children: "https://www.heroui.com/docs" })] }) }), _jsx(Card, { className: "hover:shadow-lg transition-shadow", isPressable: true, as: "a", href: "https://tailwindcss.com/docs", target: "_blank", rel: "noopener noreferrer", children: _jsxs(CardBody, { children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: "Tailwind CSS" }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400 mb-3", children: "Framework CSS" }), _jsx("p", { className: "text-xs text-blue-600 dark:text-blue-400 truncate", children: "https://tailwindcss.com/docs" })] }) }), _jsx(Card, { className: "hover:shadow-lg transition-shadow", isPressable: true, as: "a", href: "https://lucide.dev/", target: "_blank", rel: "noopener noreferrer", children: _jsxs(CardBody, { children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: "Lucide Icons" }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400 mb-3", children: "Icones SVG" }), _jsx("p", { className: "text-xs text-blue-600 dark:text-blue-400 truncate", children: "https://lucide.dev/" })] }) }), _jsx(Card, { className: "hover:shadow-lg transition-shadow", isPressable: true, as: "a", href: "https://stripe.com/docs", target: "_blank", rel: "noopener noreferrer", children: _jsxs(CardBody, { children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: "Stripe" }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400 mb-3", children: "Syst\u00E8me de paiement" }), _jsx("p", { className: "text-xs text-blue-600 dark:text-blue-400 truncate", children: "https://stripe.com/docs" })] }) })] }) })] }), _jsxs(Card, { id: "section-modules", className: "scroll-mt-32", children: [_jsx(CardHeader, { children: _jsxs("h2", { className: "text-2xl font-semibold flex items-center gap-2", children: [_jsx(Package, { size: 24 }), "Modules"] }) }), _jsxs(CardBody, { className: "space-y-6", children: [_jsx("p", { className: "text-slate-600 dark:text-slate-400", children: "Les modules LastBrain permettent d'ajouter des fonctionnalit\u00E9s compl\u00E8tes \u00E0 votre application de mani\u00E8re modulaire." }), _jsxs("div", { children: [_jsx("h3", { className: "text-xl font-semibold mb-4", children: "Modules Disponibles" }), _jsxs("div", { className: "grid grid-cols-1 gap-4", children: [_jsx(Card, { className: "hover:shadow-lg transition-shadow border-l-4 border-l-blue-500", children: _jsxs(CardBody, { className: "space-y-3", children: [_jsxs("div", { className: "flex items-start justify-between", children: [_jsx("h3", { className: "text-lg font-semibold", children: "Ai" }), _jsx("span", { className: "text-xs bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200 px-2 py-1 rounded", children: "FREE" })] }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400", children: "Module LastBrain" }), _jsxs("p", { className: "text-xs text-slate-500 dark:text-slate-500", children: [_jsx("strong", { children: "Pages:" }), " 1 auth, 1 admin"] }), _jsx(Snippet, { symbol: "\uD83D\uDCBB", hideSymbol: true, className: "text-sm", children: `pnpm lastbrain add-module ai` }), _jsx("a", { href: "https://github.com/Lastbrain-labs/lb-starter/tree/main/packages/module-ai", className: "text-sm text-blue-600 dark:text-blue-400 hover:underline inline-flex items-center gap-1", target: "_blank", rel: "noopener noreferrer", children: "\uD83D\uDCD6 Documentation \u2192" })] }) }), _jsx(Card, { className: "hover:shadow-lg transition-shadow border-l-4 border-l-blue-500", children: _jsxs(CardBody, { className: "space-y-3", children: [_jsxs("div", { className: "flex items-start justify-between", children: [_jsx("h3", { className: "text-lg font-semibold", children: "Auth" }), _jsx("span", { className: "text-xs bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200 px-2 py-1 rounded", children: "FREE" })] }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400", children: "Module LastBrain" }), _jsxs("p", { className: "text-xs text-slate-500 dark:text-slate-500", children: [_jsx("strong", { children: "Pages:" }), " 3 publique(s), 4 auth, 2 admin"] }), _jsx(Snippet, { symbol: "\uD83D\uDCBB", hideSymbol: true, className: "text-sm", children: `pnpm lastbrain add-module auth` }), _jsx("a", { href: "https://github.com/Lastbrain-labs/lb-starter/tree/main/packages/module-auth", className: "text-sm text-blue-600 dark:text-blue-400 hover:underline inline-flex items-center gap-1", target: "_blank", rel: "noopener noreferrer", children: "\uD83D\uDCD6 Documentation \u2192" })] }) }), _jsx(Card, { className: "hover:shadow-lg transition-shadow border-l-4 border-l-purple-500", children: _jsxs(CardBody, { className: "space-y-3", children: [_jsxs("div", { className: "flex items-start justify-between", children: [_jsx("h3", { className: "text-lg font-semibold", children: "Billing Pro" }), _jsx("span", { className: "text-xs bg-purple-100 dark:bg-purple-900 text-purple-800 dark:text-purple-200 px-2 py-1 rounded", children: "PRO" })] }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400", children: "Module LastBrain" }), _jsxs("p", { className: "text-xs text-slate-500 dark:text-slate-500", children: [_jsx("strong", { children: "Pages:" }), " 3 auth, 2 admin"] }), _jsx(Snippet, { symbol: "\uD83D\uDCBB", hideSymbol: true, className: "text-sm", children: `pnpm lastbrain add-module billing-pro` }), _jsx("span", { className: "text-xs text-slate-500 dark:text-slate-400 inline-flex items-center gap-1", children: "\uD83D\uDD12 Documentation priv\u00E9e" })] }) }), _jsx(Card, { className: "hover:shadow-lg transition-shadow border-l-4 border-l-purple-500", children: _jsxs(CardBody, { className: "space-y-3", children: [_jsxs("div", { className: "flex items-start justify-between", children: [_jsx("h3", { className: "text-lg font-semibold", children: "Core Cart Pro" }), _jsx("span", { className: "text-xs bg-purple-100 dark:bg-purple-900 text-purple-800 dark:text-purple-200 px-2 py-1 rounded", children: "PRO" })] }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400", children: "Module LastBrain" }), _jsxs("p", { className: "text-xs text-slate-500 dark:text-slate-500", children: [_jsx("strong", { children: "Pages:" }), " 2 auth, 1 admin"] }), _jsx(Snippet, { symbol: "\uD83D\uDCBB", hideSymbol: true, className: "text-sm", children: `pnpm lastbrain add-module core-cart-pro` }), _jsx("span", { className: "text-xs text-slate-500 dark:text-slate-400 inline-flex items-center gap-1", children: "\uD83D\uDD12 Documentation priv\u00E9e" })] }) }), _jsx(Card, { className: "hover:shadow-lg transition-shadow border-l-4 border-l-purple-500", children: _jsxs(CardBody, { className: "space-y-3", children: [_jsxs("div", { className: "flex items-start justify-between", children: [_jsx("h3", { className: "text-lg font-semibold", children: "Core Commerce Pro" }), _jsx("span", { className: "text-xs bg-purple-100 dark:bg-purple-900 text-purple-800 dark:text-purple-200 px-2 py-1 rounded", children: "PRO" })] }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400", children: "Module LastBrain" }), _jsx(Snippet, { symbol: "\uD83D\uDCBB", hideSymbol: true, className: "text-sm", children: `pnpm lastbrain add-module core-commerce-pro` }), _jsx("span", { className: "text-xs text-slate-500 dark:text-slate-400 inline-flex items-center gap-1", children: "\uD83D\uDD12 Documentation priv\u00E9e" })] }) }), _jsx(Card, { className: "hover:shadow-lg transition-shadow border-l-4 border-l-purple-500", children: _jsxs(CardBody, { className: "space-y-3", children: [_jsxs("div", { className: "flex items-start justify-between", children: [_jsx("h3", { className: "text-lg font-semibold", children: "Core Order Pro" }), _jsx("span", { className: "text-xs bg-purple-100 dark:bg-purple-900 text-purple-800 dark:text-purple-200 px-2 py-1 rounded", children: "PRO" })] }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400", children: "Module LastBrain" }), _jsxs("p", { className: "text-xs text-slate-500 dark:text-slate-500", children: [_jsx("strong", { children: "Pages:" }), " 2 auth"] }), _jsx(Snippet, { symbol: "\uD83D\uDCBB", hideSymbol: true, className: "text-sm", children: `pnpm lastbrain add-module core-order-pro` }), _jsx("span", { className: "text-xs text-slate-500 dark:text-slate-400 inline-flex items-center gap-1", children: "\uD83D\uDD12 Documentation priv\u00E9e" })] }) }), _jsx(Card, { className: "hover:shadow-lg transition-shadow border-l-4 border-l-purple-500", children: _jsxs(CardBody, { className: "space-y-3", children: [_jsxs("div", { className: "flex items-start justify-between", children: [_jsx("h3", { className: "text-lg font-semibold", children: "Core Payment Pro" }), _jsx("span", { className: "text-xs bg-purple-100 dark:bg-purple-900 text-purple-800 dark:text-purple-200 px-2 py-1 rounded", children: "PRO" })] }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400", children: "Module LastBrain" }), _jsxs("p", { className: "text-xs text-slate-500 dark:text-slate-500", children: [_jsx("strong", { children: "Pages:" }), " 1 admin"] }), _jsx(Snippet, { symbol: "\uD83D\uDCBB", hideSymbol: true, className: "text-sm", children: `pnpm lastbrain add-module core-payment-pro` }), _jsx("span", { className: "text-xs text-slate-500 dark:text-slate-400 inline-flex items-center gap-1", children: "\uD83D\uDD12 Documentation priv\u00E9e" })] }) }), _jsx(Card, { className: "hover:shadow-lg transition-shadow border-l-4 border-l-purple-500", children: _jsxs(CardBody, { className: "space-y-3", children: [_jsxs("div", { className: "flex items-start justify-between", children: [_jsx("h3", { className: "text-lg font-semibold", children: "Core Product Pro" }), _jsx("span", { className: "text-xs bg-purple-100 dark:bg-purple-900 text-purple-800 dark:text-purple-200 px-2 py-1 rounded", children: "PRO" })] }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400", children: "Module LastBrain" }), _jsxs("p", { className: "text-xs text-slate-500 dark:text-slate-500", children: [_jsx("strong", { children: "Pages:" }), " 2 publique(s)"] }), _jsx(Snippet, { symbol: "\uD83D\uDCBB", hideSymbol: true, className: "text-sm", children: `pnpm lastbrain add-module core-product-pro` }), _jsx("span", { className: "text-xs text-slate-500 dark:text-slate-400 inline-flex items-center gap-1", children: "\uD83D\uDD12 Documentation priv\u00E9e" })] }) }), _jsx(Card, { className: "hover:shadow-lg transition-shadow border-l-4 border-l-blue-500", children: _jsxs(CardBody, { className: "space-y-3", children: [_jsxs("div", { className: "flex items-start justify-between", children: [_jsx("h3", { className: "text-lg font-semibold", children: "Legal" }), _jsx("span", { className: "text-xs bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200 px-2 py-1 rounded", children: "FREE" })] }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400", children: "Module LastBrain" }), _jsxs("p", { className: "text-xs text-slate-500 dark:text-slate-500", children: [_jsx("strong", { children: "Pages:" }), " 4 publique(s), 2 admin"] }), _jsx(Snippet, { symbol: "\uD83D\uDCBB", hideSymbol: true, className: "text-sm", children: `pnpm lastbrain add-module legal` }), _jsx("a", { href: "https://github.com/Lastbrain-labs/lb-starter/tree/main/packages/module-legal", className: "text-sm text-blue-600 dark:text-blue-400 hover:underline inline-flex items-center gap-1", target: "_blank", rel: "noopener noreferrer", children: "\uD83D\uDCD6 Documentation \u2192" })] }) }), _jsx(Card, { className: "hover:shadow-lg transition-shadow border-l-4 border-l-blue-500", children: _jsxs(CardBody, { className: "space-y-3", children: [_jsxs("div", { className: "flex items-start justify-between", children: [_jsx("h3", { className: "text-lg font-semibold", children: "Project Board" }), _jsx("span", { className: "text-xs bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200 px-2 py-1 rounded", children: "FREE" })] }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400", children: "Module LastBrain" }), _jsxs("p", { className: "text-xs text-slate-500 dark:text-slate-500", children: [_jsx("strong", { children: "Pages:" }), " 2 auth"] }), _jsx(Snippet, { symbol: "\uD83D\uDCBB", hideSymbol: true, className: "text-sm", children: `pnpm lastbrain add-module project-board` }), _jsx("a", { href: "https://github.com/Lastbrain-labs/lb-starter/tree/main/packages/module-project-board", className: "text-sm text-blue-600 dark:text-blue-400 hover:underline inline-flex items-center gap-1", target: "_blank", rel: "noopener noreferrer", children: "\uD83D\uDCD6 Documentation \u2192" })] }) }), _jsx(Card, { className: "hover:shadow-lg transition-shadow border-l-4 border-l-purple-500", children: _jsxs(CardBody, { className: "space-y-3", children: [_jsxs("div", { className: "flex items-start justify-between", children: [_jsx("h3", { className: "text-lg font-semibold", children: "Recipes Pro" }), _jsx("span", { className: "text-xs bg-purple-100 dark:bg-purple-900 text-purple-800 dark:text-purple-200 px-2 py-1 rounded", children: "PRO" })] }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400", children: "Module LastBrain" }), _jsxs("p", { className: "text-xs text-slate-500 dark:text-slate-500", children: [_jsx("strong", { children: "Pages:" }), " 4 auth"] }), _jsx(Snippet, { symbol: "\uD83D\uDCBB", hideSymbol: true, className: "text-sm", children: `pnpm lastbrain add-module recipes-pro` }), _jsx("span", { className: "text-xs text-slate-500 dark:text-slate-400 inline-flex items-center gap-1", children: "\uD83D\uDD12 Documentation priv\u00E9e" })] }) }), _jsx(Card, { className: "hover:shadow-lg transition-shadow border-l-4 border-l-blue-500", children: _jsxs(CardBody, { className: "space-y-3", children: [_jsxs("div", { className: "flex items-start justify-between", children: [_jsx("h3", { className: "text-lg font-semibold", children: "Tasks" }), _jsx("span", { className: "text-xs bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200 px-2 py-1 rounded", children: "FREE" })] }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400", children: "Module LastBrain" }), _jsxs("p", { className: "text-xs text-slate-500 dark:text-slate-500", children: [_jsx("strong", { children: "Pages:" }), " 2 auth, 1 admin"] }), _jsx(Snippet, { symbol: "\uD83D\uDCBB", hideSymbol: true, className: "text-sm", children: `pnpm lastbrain add-module nom-du-module` }), _jsx("a", { href: "https://github.com/Lastbrain-labs/lb-starter/tree/main/packages/module-tasks", className: "text-sm text-blue-600 dark:text-blue-400 hover:underline inline-flex items-center gap-1", target: "_blank", rel: "noopener noreferrer", children: "\uD83D\uDCD6 Documentation \u2192" })] }) })] })] }), _jsx("h3", { className: "text-lg font-semibold mb-2", children: "Commandes" }), _jsx("h4", { className: "font-medium mb-2", children: "Installer un module" }), _jsx(Snippet, { symbol: "", hideSymbol: true, className: "text-sm mb-2", children: `pnpm lastbrain add-module nom-du-module` }), _jsx(Snippet, { symbol: "", hideSymbol: true, className: "text-sm mb-2", children: `pnpm build:modules` }), _jsx("h4", { className: "font-medium mb-2", children: "Cr\u00E9er un nouveau module" }), _jsx(Snippet, { symbol: "", hideSymbol: true, className: "text-sm mb-2", children: `pnpm lastbrain create-module nom-du-module` }), _jsx("h4", { className: "font-medium mb-2", children: "G\u00E9n\u00E9rer la documentation des modules" }), _jsx(Snippet, { symbol: "", hideSymbol: true, className: "text-sm mb-2", children: `pnpm generate:module-docs` }), _jsx("h4", { className: "font-medium mb-2", children: "Supprimer un module" }), _jsx(Snippet, { symbol: "", hideSymbol: true, className: "text-sm mb-2", children: `pnpm lastbrain remove-module nom-du-module` }), _jsx(Snippet, { symbol: "", hideSymbol: true, className: "text-sm mb-2", children: `pnpm build:modules` }), _jsx("h3", { className: "text-lg font-semibold mb-2", children: "D\u00E9veloppement de modules" }), _jsxs("p", { className: "text-sm text-slate-600 dark:text-slate-400 mb-2", children: ["Pour cr\u00E9er un nouveau module, consultez la", " ", _jsx("a", { href: "./004_CREATE_MODULE.md", className: "text-blue-600 hover:underline", target: "_blank", rel: "noopener noreferrer", children: "documentation de cr\u00E9ation de modules" }), "."] }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400 mb-2", children: "La documentation de chaque module est g\u00E9n\u00E9r\u00E9e automatiquement depuis :" }), _jsxs("div", { className: "space-y-2", children: [_jsxs("div", { className: "flex items-start gap-2", children: [_jsx("span", { className: "text-green-600", children: "\u2705" }), _jsxs("span", { children: ["Le fichier", " ", _jsx("code", { className: "text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded", children: "module-name.build.config.ts" }), " ", "pour les pages et APIs"] })] }), _jsxs("div", { className: "flex items-start gap-2", children: [_jsx("span", { className: "text-green-600", children: "\u2705" }), _jsx("span", { children: "Les fichiers de migration SQL pour les tables" })] }), _jsxs("div", { className: "flex items-start gap-2", children: [_jsx("span", { className: "text-green-600", children: "\u2705" }), _jsxs("span", { children: ["Le README.md est auto-g\u00E9n\u00E9r\u00E9 avec", " ", _jsx("code", { className: "text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded", children: "pnpm generate:module-docs" })] })] })] })] })] })] }));
240
240
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lastbrain/app",
3
- "version": "0.1.44",
3
+ "version": "0.1.46",
4
4
  "description": "Framework modulaire Next.js avec CLI et système de modules",
5
5
  "private": false,
6
6
  "type": "module",
@@ -14,7 +14,7 @@ export function useAuthSession() {
14
14
  try {
15
15
  const { data, error } = await supabaseBrowserClient.rpc(
16
16
  "is_superadmin",
17
- { user_id: userId },
17
+ { user_id: userId }
18
18
  );
19
19
  if (!error && data) {
20
20
  setIsSuperAdmin(data);
package/src/cli.ts CHANGED
@@ -23,7 +23,7 @@ program
23
23
  .option("--with-auth", "Inclure le module d'authentification")
24
24
  .option(
25
25
  "--no-interactive",
26
- "Mode non-interactif (skip la sélection des modules)",
26
+ "Mode non-interactif (skip la sélection des modules)"
27
27
  )
28
28
  .action(async (directory: string | undefined, options) => {
29
29
  try {
@@ -66,7 +66,7 @@ export function useNotifications(user?: User | null) {
66
66
  setError(
67
67
  err instanceof Error
68
68
  ? err.message
69
- : "Erreur lors du chargement des notifications",
69
+ : "Erreur lors du chargement des notifications"
70
70
  );
71
71
  console.error("[useNotifications] Erreur:", err);
72
72
  } finally {
@@ -88,7 +88,7 @@ export function useNotifications(user?: User | null) {
88
88
  fetchNotifications();
89
89
  }
90
90
  },
91
- },
91
+ }
92
92
  );
93
93
 
94
94
  // Marquer une notification comme lue
@@ -114,7 +114,7 @@ export function useNotifications(user?: User | null) {
114
114
  setData((prev) => ({
115
115
  ...prev,
116
116
  notifications: prev.notifications.map((n) =>
117
- n.id === notificationId ? { ...n, read: true } : n,
117
+ n.id === notificationId ? { ...n, read: true } : n
118
118
  ),
119
119
  unreadCount: Math.max(0, prev.unreadCount - 1),
120
120
  }));
@@ -123,7 +123,7 @@ export function useNotifications(user?: User | null) {
123
123
  throw err;
124
124
  }
125
125
  },
126
- [user?.id],
126
+ [user?.id]
127
127
  );
128
128
 
129
129
  // Marquer toutes les notifications comme lues
@@ -175,11 +175,11 @@ export function useNotifications(user?: User | null) {
175
175
  // Mettre à jour localement
176
176
  setData((prev) => {
177
177
  const notification = prev.notifications.find(
178
- (n) => n.id === notificationId,
178
+ (n) => n.id === notificationId
179
179
  );
180
180
  return {
181
181
  notifications: prev.notifications.filter(
182
- (n) => n.id !== notificationId,
182
+ (n) => n.id !== notificationId
183
183
  ),
184
184
  unreadCount:
185
185
  notification && !notification.read
@@ -192,7 +192,7 @@ export function useNotifications(user?: User | null) {
192
192
  throw err;
193
193
  }
194
194
  },
195
- [user?.id],
195
+ [user?.id]
196
196
  );
197
197
 
198
198
  // Charger les notifications initiales
@@ -51,17 +51,17 @@ export function AdminLayoutWithSidebar({
51
51
  // Écouter l'événement custom pour les changements du même onglet
52
52
  window.addEventListener(
53
53
  "localStorage-changed",
54
- handleStorageChange as EventListener,
54
+ handleStorageChange as EventListener
55
55
  );
56
56
 
57
57
  return () => {
58
58
  window.removeEventListener(
59
59
  "storage",
60
- handleStorageChange as EventListener,
60
+ handleStorageChange as EventListener
61
61
  );
62
62
  window.removeEventListener(
63
63
  "localStorage-changed",
64
- handleStorageChange as EventListener,
64
+ handleStorageChange as EventListener
65
65
  );
66
66
  };
67
67
  }
@@ -74,7 +74,7 @@ export function AppProviders({
74
74
 
75
75
  const authValue = useMemo(
76
76
  () => ({ user, loading: authLoading, isSuperAdmin }),
77
- [user, authLoading, isSuperAdmin],
77
+ [user, authLoading, isSuperAdmin]
78
78
  ); // const handleLogout = async () => {
79
79
  // const { signOut } = await import("../auth/authHelpers.js");
80
80
  // await signOut();
@@ -49,17 +49,17 @@ export function AuthLayoutWithSidebar({
49
49
  // Écouter l'événement custom pour les changements du même onglet
50
50
  window.addEventListener(
51
51
  "localStorage-changed",
52
- handleStorageChange as EventListener,
52
+ handleStorageChange as EventListener
53
53
  );
54
54
 
55
55
  return () => {
56
56
  window.removeEventListener(
57
57
  "storage",
58
- handleStorageChange as EventListener,
58
+ handleStorageChange as EventListener
59
59
  );
60
60
  window.removeEventListener(
61
61
  "localStorage-changed",
62
- handleStorageChange as EventListener,
62
+ handleStorageChange as EventListener
63
63
  );
64
64
  };
65
65
  }
@@ -49,17 +49,17 @@ export function PublicLayoutWithSidebar({
49
49
  // Écouter l'événement custom pour les changements du même onglet
50
50
  window.addEventListener(
51
51
  "localStorage-changed",
52
- handleStorageChange as EventListener,
52
+ handleStorageChange as EventListener
53
53
  );
54
54
 
55
55
  return () => {
56
56
  window.removeEventListener(
57
57
  "storage",
58
- handleStorageChange as EventListener,
58
+ handleStorageChange as EventListener
59
59
  );
60
60
  window.removeEventListener(
61
61
  "localStorage-changed",
62
- handleStorageChange as EventListener,
62
+ handleStorageChange as EventListener
63
63
  );
64
64
  };
65
65
  }
@@ -20,7 +20,7 @@ const packageAppDir = path
20
20
  .replace(/dist\/scripts$/, "src");
21
21
  const envExampleTemplate = path.join(
22
22
  packageAppDir,
23
- "templates/env.example/.env.example",
23
+ "templates/env.example/.env.example"
24
24
  );
25
25
 
26
26
  function ensureDirectory(dir: string) {
@@ -78,7 +78,7 @@ function runSupabase(...args: any[]): Buffer | null {
78
78
  // Si le processus s'est terminé avec un code de sortie non nul, propager l'erreur
79
79
  if (result.status !== 0) {
80
80
  const error: any = new Error(
81
- `Command failed with exit code ${result.status}`,
81
+ `Command failed with exit code ${result.status}`
82
82
  );
83
83
  error.status = result.status;
84
84
  throw error;
@@ -89,7 +89,7 @@ function runSupabase(...args: any[]): Buffer | null {
89
89
  }
90
90
 
91
91
  throw new Error(
92
- "Unable to locate Supabase CLI (install it globally or via pnpm).",
92
+ "Unable to locate Supabase CLI (install it globally or via pnpm)."
93
93
  );
94
94
  }
95
95
 
@@ -110,7 +110,7 @@ function parseEnvFile(filePath: string) {
110
110
  .map((line) => {
111
111
  const [key, ...value] = line.split("=");
112
112
  return [key, value.join("=")];
113
- }),
113
+ })
114
114
  ) as Record<string, string>;
115
115
  }
116
116
 
@@ -129,7 +129,7 @@ function ensureEnvFile(values: Record<string, string>) {
129
129
  .map((line) => {
130
130
  const [key, ...value] = line.split("=");
131
131
  return [key, value.join("=")];
132
- }),
132
+ })
133
133
  );
134
134
  } catch (error) {
135
135
  console.warn(`⚠️ Erreur lors de la lecture de ${target}:`, error);
@@ -300,7 +300,7 @@ async function main() {
300
300
  stdio: "inherit",
301
301
  env: { ...process.env, PATH: enhancedPath },
302
302
  shell: true,
303
- },
303
+ }
304
304
  );
305
305
 
306
306
  if (migrationResult.error || migrationResult.status !== 0) {
@@ -338,7 +338,7 @@ async function main() {
338
338
  console.log("ℹ️ Copied .env.example into .env.local as fallback.");
339
339
  }
340
340
  console.warn(
341
- "⚠️ Impossible de récupérer automatiquement les accès Supabase.",
341
+ "⚠️ Impossible de récupérer automatiquement les accès Supabase."
342
342
  );
343
343
  }
344
344
 
@@ -67,7 +67,7 @@ function syncModuleMigrations() {
67
67
  const activeModules = modules.filter((m: any) => m.active !== false);
68
68
 
69
69
  console.log(
70
- `🔄 Syncing migrations from ${activeModules.length} active module(s)...\n`,
70
+ `🔄 Syncing migrations from ${activeModules.length} active module(s)...\n`
71
71
  );
72
72
 
73
73
  let totalCopied = 0;
@@ -87,7 +87,7 @@ function syncModuleMigrations() {
87
87
  "..",
88
88
  "..",
89
89
  "packages",
90
- moduleName.replace("@lastbrain/", "").replace("@lastbrain-labs/", ""),
90
+ moduleName.replace("@lastbrain/", "").replace("@lastbrain-labs/", "")
91
91
  ),
92
92
  ];
93
93
 
@@ -29,12 +29,12 @@ const dependenciesToEnsure = {
29
29
 
30
30
  const gitignoreTemplate = path.join(
31
31
  projectRoot,
32
- "packages/app/src/templates/gitignore/.gitignore",
32
+ "packages/app/src/templates/gitignore/.gitignore"
33
33
  );
34
34
  const consumerGitignore = path.join(projectRoot, "apps/web/.gitignore");
35
35
  const envTemplate = path.join(
36
36
  projectRoot,
37
- "packages/app/src/templates/env.example/.env.example",
37
+ "packages/app/src/templates/env.example/.env.example"
38
38
  );
39
39
  const consumerEnvExample = path.join(projectRoot, "apps/web/.env.example");
40
40
  const consumerEnvLocal = path.join(projectRoot, "apps/web/.env.local");
@@ -75,7 +75,7 @@ function _copyDirectory(srcDir: string, destDir: string) {
75
75
  for (const entry of entries) {
76
76
  _copyDirectory(
77
77
  path.join(srcDir, entry.name),
78
- path.join(destDir, entry.name),
78
+ path.join(destDir, entry.name)
79
79
  );
80
80
  }
81
81
  } else if (stats.isFile()) {
@@ -133,7 +133,7 @@ function cleanupStaleGroupFiles() {
133
133
 
134
134
  function mergeScripts(
135
135
  base: Record<string, string>,
136
- additions: Record<string, string>,
136
+ additions: Record<string, string>
137
137
  ) {
138
138
  return { ...base, ...additions };
139
139
  }
@@ -224,7 +224,7 @@ function main() {
224
224
  console.log("✅ apps/web synced with @lastbrain/app");
225
225
  console.log(`Copied or updated files (${copiedFiles.length}):`);
226
226
  copiedFiles.forEach((file) =>
227
- console.log(` • ${path.relative(projectRoot, file)}`),
227
+ console.log(` • ${path.relative(projectRoot, file)}`)
228
228
  );
229
229
  console.log("Scripts ensured in apps/web/package.json:");
230
230
  changes.scripts.forEach((script) => console.log(` • ${script}`));
@@ -232,17 +232,17 @@ function main() {
232
232
  changes.dependencies.forEach((dep) => console.log(` • ${dep}`));
233
233
  if (gitignoreSynced) {
234
234
  console.log(
235
- `.gitignore ensured at ${path.relative(projectRoot, gitignoreSynced)}`,
235
+ `.gitignore ensured at ${path.relative(projectRoot, gitignoreSynced)}`
236
236
  );
237
237
  }
238
238
  if (envExampleSynced) {
239
239
  console.log(
240
- `.env.example ensured at ${path.relative(projectRoot, envExampleSynced)}`,
240
+ `.env.example ensured at ${path.relative(projectRoot, envExampleSynced)}`
241
241
  );
242
242
  }
243
243
  if (envLocalCreated) {
244
244
  console.log(
245
- `.env.local ensured at ${path.relative(projectRoot, envLocalCreated)}`,
245
+ `.env.local ensured at ${path.relative(projectRoot, envLocalCreated)}`
246
246
  );
247
247
  }
248
248
  }