@lastbrain/app 0.1.47 → 1.0.1
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/layout.d.ts +1 -1
- package/dist/app-shell/layout.d.ts.map +1 -1
- package/dist/app-shell/layout.js +1 -1
- package/dist/components/NotificationContainer.js +1 -1
- package/dist/index.d.ts +19 -19
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -19
- package/dist/layouts/AdminLayoutWithSidebar.d.ts +3 -2
- package/dist/layouts/AdminLayoutWithSidebar.d.ts.map +1 -1
- package/dist/layouts/AdminLayoutWithSidebar.js +5 -5
- package/dist/layouts/AppProviders.d.ts +1 -1
- package/dist/layouts/AppProviders.d.ts.map +1 -1
- package/dist/layouts/AppProviders.js +3 -3
- package/dist/layouts/AuthLayoutWithSidebar.d.ts +7 -4
- package/dist/layouts/AuthLayoutWithSidebar.d.ts.map +1 -1
- package/dist/layouts/AuthLayoutWithSidebar.js +5 -5
- package/dist/layouts/PublicLayoutWithSidebar.js +2 -2
- package/dist/layouts/RootLayout.js +1 -1
- package/dist/scripts/init-app.d.ts.map +1 -1
- package/dist/scripts/init-app.js +457 -39
- package/dist/scripts/module-add.js +1 -1
- package/dist/scripts/module-build.d.ts.map +1 -1
- package/dist/scripts/module-build.js +36 -15
- package/dist/scripts/module-create.js +8 -8
- package/dist/scripts/module-delete.d.ts.map +1 -1
- package/dist/scripts/module-delete.js +1 -1
- package/dist/templates/DefaultDoc.js +1 -1
- package/dist/templates/DocPage.js +1 -1
- package/dist/templates/DocsPageWithModules.js +1 -1
- package/dist/types/menu.d.ts +23 -0
- package/dist/types/menu.d.ts.map +1 -0
- package/dist/types/menu.js +1 -0
- package/package.json +9 -1
- package/src/app-shell/layout.tsx +1 -1
- package/src/components/NotificationContainer.tsx +1 -1
- package/src/index.ts +24 -19
- package/src/layouts/AdminLayoutWithSidebar.tsx +11 -3
- package/src/layouts/AppProviders.tsx +4 -4
- package/src/layouts/AuthLayoutWithSidebar.tsx +18 -4
- package/src/layouts/PublicLayoutWithSidebar.tsx +2 -2
- package/src/layouts/RootLayout.tsx +1 -1
- package/src/scripts/init-app.ts +479 -49
- package/src/scripts/module-add.ts +1 -1
- package/src/scripts/module-build.ts +46 -22
- package/src/scripts/module-create.ts +8 -8
- package/src/scripts/module-delete.ts +1 -4
- package/src/templates/DefaultDoc.tsx +1 -1
- package/src/templates/DocPage.tsx +1 -1
- package/src/templates/DocsPageWithModules.tsx +1 -1
- package/src/types/menu.ts +18 -0
package/dist/scripts/init-app.js
CHANGED
|
@@ -4,7 +4,7 @@ import { fileURLToPath } from "url";
|
|
|
4
4
|
import chalk from "chalk";
|
|
5
5
|
import inquirer from "inquirer";
|
|
6
6
|
import { execSync } from "child_process";
|
|
7
|
-
import { AVAILABLE_MODULES
|
|
7
|
+
import { AVAILABLE_MODULES } from "@lastbrain/core/config/modules";
|
|
8
8
|
const __filename = fileURLToPath(import.meta.url);
|
|
9
9
|
const __dirname = path.dirname(__filename);
|
|
10
10
|
export async function initApp(options) {
|
|
@@ -131,16 +131,22 @@ export async function initApp(options) {
|
|
|
131
131
|
});
|
|
132
132
|
console.log(chalk.green("\n✓ Migrations synchronisées\n"));
|
|
133
133
|
}
|
|
134
|
-
catch (
|
|
134
|
+
catch (_error) {
|
|
135
135
|
console.log(chalk.yellow("\n⚠️ Erreur de synchronisation des migrations\n"));
|
|
136
136
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
137
|
+
// Ne pas initialiser la BDD en mode monorepo
|
|
138
|
+
if (!isMonorepoProject) {
|
|
139
|
+
console.log(chalk.yellow("🗄️ Initialisation de la base de données...\n"));
|
|
140
|
+
try {
|
|
141
|
+
execSync("pnpm db:init", { cwd: targetDir, stdio: "inherit" });
|
|
142
|
+
console.log(chalk.green("\n✓ Base de données initialisée\n"));
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
console.log(chalk.yellow("\n⚠️ Erreur d'initialisation de la DB (normal si Supabase pas configuré)\n"));
|
|
146
|
+
}
|
|
141
147
|
}
|
|
142
|
-
|
|
143
|
-
console.log(chalk.
|
|
148
|
+
else {
|
|
149
|
+
console.log(chalk.cyan("⏭️ Mode monorepo détecté - BDD centralisée, pas d'initialisation locale requise\n"));
|
|
144
150
|
}
|
|
145
151
|
// Détecter le port (par défaut 3000 pour Next.js)
|
|
146
152
|
const port = 3000;
|
|
@@ -149,10 +155,15 @@ export async function initApp(options) {
|
|
|
149
155
|
console.log(chalk.cyan(`📱 Ouvrez votre navigateur sur : ${url}\n`));
|
|
150
156
|
console.log(chalk.blue("\n📋 Prochaines étapes après le démarrage :"));
|
|
151
157
|
console.log(chalk.white(" 1. Cliquez sur 'Get Started' sur la page d'accueil"));
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
158
|
+
if (isMonorepoProject) {
|
|
159
|
+
console.log(chalk.white(" 2. La BDD est centralisée dans le monorepo\n"));
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
console.log(chalk.white(" 2. Lancez Docker Desktop"));
|
|
163
|
+
console.log(chalk.white(" 3. Installez Supabase CLI si nécessaire : brew install supabase/tap/supabase"));
|
|
164
|
+
console.log(chalk.white(" 4. Exécutez : pnpm db:init"));
|
|
165
|
+
console.log(chalk.white(" 5. Rechargez la page\n"));
|
|
166
|
+
}
|
|
156
167
|
// Ouvrir le navigateur
|
|
157
168
|
const openCommand = process.platform === "darwin"
|
|
158
169
|
? "open"
|
|
@@ -168,7 +179,7 @@ export async function initApp(options) {
|
|
|
168
179
|
}
|
|
169
180
|
}, 2000);
|
|
170
181
|
// Lancer pnpm dev
|
|
171
|
-
execSync("pnpm dev", { cwd: targetDir, stdio: "inherit" });
|
|
182
|
+
execSync("pnpm dev:local", { cwd: targetDir, stdio: "inherit" });
|
|
172
183
|
}
|
|
173
184
|
catch {
|
|
174
185
|
console.error(chalk.red("\n❌ Erreur lors du lancement\n"));
|
|
@@ -177,7 +188,9 @@ export async function initApp(options) {
|
|
|
177
188
|
console.log(chalk.white(" pnpm install"));
|
|
178
189
|
console.log(chalk.white(" pnpm build:modules"));
|
|
179
190
|
console.log(chalk.white(" pnpm db:migrations:sync"));
|
|
180
|
-
|
|
191
|
+
if (!isMonorepoProject) {
|
|
192
|
+
console.log(chalk.white(" pnpm db:init"));
|
|
193
|
+
}
|
|
181
194
|
console.log(chalk.white(" pnpm dev:local (ou pnpm dev:prod)\n"));
|
|
182
195
|
}
|
|
183
196
|
}
|
|
@@ -288,8 +301,8 @@ function getLastBrainVersions(targetDir) {
|
|
|
288
301
|
};
|
|
289
302
|
}
|
|
290
303
|
}
|
|
291
|
-
catch (
|
|
292
|
-
console.warn(chalk.yellow(`⚠️ Impossible de lire les versions locales (${
|
|
304
|
+
catch (_error) {
|
|
305
|
+
console.warn(chalk.yellow(`⚠️ Impossible de lire les versions locales (${_error}), utilisation de 'latest'`));
|
|
293
306
|
}
|
|
294
307
|
// Fallback: utiliser "latest"
|
|
295
308
|
return {
|
|
@@ -722,17 +735,56 @@ async function createAppHeader(targetDir, force) {
|
|
|
722
735
|
if (!fs.existsSync(headerPath) || force) {
|
|
723
736
|
const headerContent = `"use client";
|
|
724
737
|
|
|
725
|
-
import { Header } from "@lastbrain/ui";
|
|
738
|
+
import { Header, type MenuItem } from "@lastbrain/ui";
|
|
726
739
|
import { menuConfig } from "../config/menu";
|
|
727
740
|
import { supabaseBrowserClient } from "@lastbrain/core";
|
|
728
741
|
import { useRouter } from "next/navigation";
|
|
729
742
|
import { useAuthSession, useNotificationsContext } from "@lastbrain/app";
|
|
743
|
+
import { useState, useEffect } from "react";
|
|
744
|
+
|
|
745
|
+
interface MenuIgnored {
|
|
746
|
+
public: { title: string; path: string }[];
|
|
747
|
+
auth: { title: string; path: string }[];
|
|
748
|
+
}
|
|
730
749
|
|
|
731
750
|
export function AppHeader() {
|
|
732
751
|
const router = useRouter();
|
|
733
752
|
const { user, isSuperAdmin } = useAuthSession();
|
|
734
753
|
const { data, loading, markAsRead, markAllAsRead, deleteNotification } =
|
|
735
754
|
useNotificationsContext();
|
|
755
|
+
const [menuIgnored, setMenuIgnored] = useState<MenuIgnored | undefined>();
|
|
756
|
+
const [menuCustom, setMenuCustom] = useState<MenuItem[] | undefined>();
|
|
757
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
758
|
+
|
|
759
|
+
// Charger menuIgnored et menuCustom s'ils existent
|
|
760
|
+
useEffect(() => {
|
|
761
|
+
let loadedIgnored = false;
|
|
762
|
+
let loadedCustom = false;
|
|
763
|
+
|
|
764
|
+
// Charger menu-ignored
|
|
765
|
+
import("../config/menu-ignored")
|
|
766
|
+
.then((mod) => setMenuIgnored(mod.menuIgnored))
|
|
767
|
+
.catch(() => setMenuIgnored(undefined))
|
|
768
|
+
.finally(() => {
|
|
769
|
+
loadedIgnored = true;
|
|
770
|
+
if (loadedIgnored && loadedCustom) setIsLoading(false);
|
|
771
|
+
});
|
|
772
|
+
|
|
773
|
+
// Charger menu-custom
|
|
774
|
+
import("../config/menu-custom")
|
|
775
|
+
.then((mod) => {
|
|
776
|
+
// Combiner les menus custom publics et auth
|
|
777
|
+
const customMenus: MenuItem[] = [];
|
|
778
|
+
if (mod.menuCustom?.public) customMenus.push(...mod.menuCustom.public);
|
|
779
|
+
if (mod.menuCustom?.auth) customMenus.push(...mod.menuCustom.auth);
|
|
780
|
+
setMenuCustom(customMenus.length > 0 ? customMenus : undefined);
|
|
781
|
+
})
|
|
782
|
+
.catch(() => setMenuCustom(undefined))
|
|
783
|
+
.finally(() => {
|
|
784
|
+
loadedCustom = true;
|
|
785
|
+
if (loadedIgnored && loadedCustom) setIsLoading(false);
|
|
786
|
+
});
|
|
787
|
+
}, []);
|
|
736
788
|
|
|
737
789
|
const handleLogout = async () => {
|
|
738
790
|
await supabaseBrowserClient.auth.signOut();
|
|
@@ -755,6 +807,9 @@ export function AppHeader() {
|
|
|
755
807
|
onMarkAsRead={markAsRead}
|
|
756
808
|
onMarkAllAsRead={markAllAsRead}
|
|
757
809
|
onDeleteNotification={deleteNotification}
|
|
810
|
+
{...(menuIgnored ? { menuIgnored } : {})}
|
|
811
|
+
{...(menuCustom ? { menuCustom } : {})}
|
|
812
|
+
{...{ isLoadingMenus: isLoading }}
|
|
758
813
|
/>
|
|
759
814
|
);
|
|
760
815
|
}
|
|
@@ -832,7 +887,58 @@ async function createConfigFiles(targetDir, force, useHeroUI, projectName) {
|
|
|
832
887
|
const middlewarePath = path.join(targetDir, "middleware.ts");
|
|
833
888
|
if (!fs.existsSync(middlewarePath) || force) {
|
|
834
889
|
const middleware = `import { type NextRequest, NextResponse } from "next/server";
|
|
835
|
-
import {
|
|
890
|
+
import { createServerClient, type CookieOptions } from "@supabase/ssr";
|
|
891
|
+
|
|
892
|
+
/**
|
|
893
|
+
* Crée un client Supabase pour le middleware
|
|
894
|
+
*/
|
|
895
|
+
function createMiddlewareClient(request: NextRequest) {
|
|
896
|
+
let response = NextResponse.next({
|
|
897
|
+
request: {
|
|
898
|
+
headers: request.headers,
|
|
899
|
+
},
|
|
900
|
+
});
|
|
901
|
+
|
|
902
|
+
const supabase = createServerClient(
|
|
903
|
+
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
904
|
+
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
|
905
|
+
{
|
|
906
|
+
cookies: {
|
|
907
|
+
get(name: string) {
|
|
908
|
+
return request.cookies.get(name)?.value;
|
|
909
|
+
},
|
|
910
|
+
set(name: string, value: string, options: CookieOptions) {
|
|
911
|
+
request.cookies.set({
|
|
912
|
+
name,
|
|
913
|
+
value,
|
|
914
|
+
...options,
|
|
915
|
+
});
|
|
916
|
+
response = NextResponse.next({
|
|
917
|
+
request: {
|
|
918
|
+
headers: request.headers,
|
|
919
|
+
},
|
|
920
|
+
});
|
|
921
|
+
response.cookies.set({
|
|
922
|
+
name,
|
|
923
|
+
value,
|
|
924
|
+
...options,
|
|
925
|
+
});
|
|
926
|
+
},
|
|
927
|
+
remove(name: string, options: CookieOptions) {
|
|
928
|
+
request.cookies.delete(name);
|
|
929
|
+
response = NextResponse.next({
|
|
930
|
+
request: {
|
|
931
|
+
headers: request.headers,
|
|
932
|
+
},
|
|
933
|
+
});
|
|
934
|
+
response.cookies.delete(name);
|
|
935
|
+
},
|
|
936
|
+
},
|
|
937
|
+
}
|
|
938
|
+
);
|
|
939
|
+
|
|
940
|
+
return { supabase, response };
|
|
941
|
+
}
|
|
836
942
|
|
|
837
943
|
export async function middleware(request: NextRequest) {
|
|
838
944
|
const { pathname } = request.nextUrl;
|
|
@@ -975,9 +1081,9 @@ export const config = {
|
|
|
975
1081
|
const nextConfig = `/** @type {import('next').NextConfig} */
|
|
976
1082
|
const nextConfig = {
|
|
977
1083
|
reactStrictMode: true,
|
|
978
|
-
|
|
1084
|
+
devIndicators: {
|
|
979
1085
|
position: 'bottom-right',
|
|
980
|
-
}
|
|
1086
|
+
}
|
|
981
1087
|
};
|
|
982
1088
|
|
|
983
1089
|
export default nextConfig;
|
|
@@ -990,7 +1096,7 @@ export default nextConfig;
|
|
|
990
1096
|
if (!fs.existsSync(tailwindConfigPath) || force) {
|
|
991
1097
|
let tailwindConfig = "";
|
|
992
1098
|
if (useHeroUI) {
|
|
993
|
-
// Configuration avec HeroUI
|
|
1099
|
+
// Configuration avec HeroUI - complète avec thèmes
|
|
994
1100
|
tailwindConfig = `import { heroui } from "@heroui/theme";
|
|
995
1101
|
|
|
996
1102
|
/** @type {import('tailwindcss').Config} */
|
|
@@ -1002,8 +1108,195 @@ const config = {
|
|
|
1002
1108
|
"./node_modules/@heroui/theme/dist/**/*.{js,mjs}",
|
|
1003
1109
|
],
|
|
1004
1110
|
darkMode: "class",
|
|
1005
|
-
plugins: [
|
|
1006
|
-
|
|
1111
|
+
plugins: [
|
|
1112
|
+
heroui({
|
|
1113
|
+
themes: {
|
|
1114
|
+
light: {
|
|
1115
|
+
colors: {
|
|
1116
|
+
default: {
|
|
1117
|
+
950: "#0d0d0e",
|
|
1118
|
+
900: "#19191c",
|
|
1119
|
+
800: "#26262a",
|
|
1120
|
+
700: "#323238",
|
|
1121
|
+
600: "#3f3f46",
|
|
1122
|
+
500: "#65656b",
|
|
1123
|
+
400: "#8c8c90",
|
|
1124
|
+
300: "#b2b2b5",
|
|
1125
|
+
200: "#d9d9da",
|
|
1126
|
+
100: "#ffffff",
|
|
1127
|
+
foreground: "#000000",
|
|
1128
|
+
DEFAULT: "#d4d4d8",
|
|
1129
|
+
},
|
|
1130
|
+
primary: {
|
|
1131
|
+
50: "#eef2ff",
|
|
1132
|
+
100: "#e0e7ff",
|
|
1133
|
+
200: "#c7d2fe",
|
|
1134
|
+
300: "#a5b4fc",
|
|
1135
|
+
400: "#818cf8",
|
|
1136
|
+
500: "#6366f1",
|
|
1137
|
+
600: "#4f46e5",
|
|
1138
|
+
700: "#4338ca",
|
|
1139
|
+
800: "#3730a3",
|
|
1140
|
+
900: "#312e81",
|
|
1141
|
+
foreground: "#ffffff",
|
|
1142
|
+
DEFAULT: "#6366f1",
|
|
1143
|
+
},
|
|
1144
|
+
secondary: {
|
|
1145
|
+
50: "#f5e8ff",
|
|
1146
|
+
100: "#e8ccff",
|
|
1147
|
+
200: "#d7a6ff",
|
|
1148
|
+
300: "#c57fff",
|
|
1149
|
+
400: "#b359ff",
|
|
1150
|
+
500: "#9b37ff",
|
|
1151
|
+
600: "#7d1fcc",
|
|
1152
|
+
700: "#5f1799",
|
|
1153
|
+
800: "#410f66",
|
|
1154
|
+
900: "#240833",
|
|
1155
|
+
foreground: "#ffffff",
|
|
1156
|
+
DEFAULT: "#9b37ff",
|
|
1157
|
+
},
|
|
1158
|
+
success: {
|
|
1159
|
+
50: "#e7fff7",
|
|
1160
|
+
100: "#c3ffec",
|
|
1161
|
+
200: "#9affdf",
|
|
1162
|
+
300: "#70ffd2",
|
|
1163
|
+
400: "#4bffca",
|
|
1164
|
+
500: "#22e6b0",
|
|
1165
|
+
600: "#18b38a",
|
|
1166
|
+
700: "#108066",
|
|
1167
|
+
800: "#074d40",
|
|
1168
|
+
900: "#012b22",
|
|
1169
|
+
foreground: "#000",
|
|
1170
|
+
DEFAULT: "#22e6b0",
|
|
1171
|
+
},
|
|
1172
|
+
warning: {
|
|
1173
|
+
50: "#fff8e1",
|
|
1174
|
+
100: "#ffecb3",
|
|
1175
|
+
200: "#ffe082",
|
|
1176
|
+
300: "#ffd54f",
|
|
1177
|
+
400: "#ffca28",
|
|
1178
|
+
500: "#ffc107",
|
|
1179
|
+
600: "#ffb300",
|
|
1180
|
+
700: "#ffa000",
|
|
1181
|
+
800: "#ff8f00",
|
|
1182
|
+
900: "#ff6f00",
|
|
1183
|
+
foreground: "#000",
|
|
1184
|
+
DEFAULT: "#ffca28",
|
|
1185
|
+
},
|
|
1186
|
+
danger: {
|
|
1187
|
+
50: "#ffe6e9",
|
|
1188
|
+
100: "#ffbac1",
|
|
1189
|
+
200: "#ff8f99",
|
|
1190
|
+
300: "#ff6471",
|
|
1191
|
+
400: "#ff3949",
|
|
1192
|
+
500: "#ff112a",
|
|
1193
|
+
600: "#d80c22",
|
|
1194
|
+
700: "#b1081b",
|
|
1195
|
+
800: "#890514",
|
|
1196
|
+
900: "#62020d",
|
|
1197
|
+
foreground: "#fff",
|
|
1198
|
+
DEFAULT: "#ff112a",
|
|
1199
|
+
},
|
|
1200
|
+
background: "#f7f8fc",
|
|
1201
|
+
foreground: "#0e0e10",
|
|
1202
|
+
content1: "#ffffff",
|
|
1203
|
+
},
|
|
1204
|
+
},
|
|
1205
|
+
dark: {
|
|
1206
|
+
colors: {
|
|
1207
|
+
default: {
|
|
1208
|
+
50: "#1a1c1f",
|
|
1209
|
+
100: "#232529",
|
|
1210
|
+
200: "#2c2f34",
|
|
1211
|
+
300: "#363940",
|
|
1212
|
+
400: "#40444d",
|
|
1213
|
+
500: "#4b4f59",
|
|
1214
|
+
600: "#6c707b",
|
|
1215
|
+
700: "#8d919b",
|
|
1216
|
+
800: "#afb2bb",
|
|
1217
|
+
900: "#d1d3d9",
|
|
1218
|
+
foreground: "#ffffff",
|
|
1219
|
+
DEFAULT: "#363940",
|
|
1220
|
+
},
|
|
1221
|
+
primary: {
|
|
1222
|
+
50: "#312e81",
|
|
1223
|
+
100: "#3730a3",
|
|
1224
|
+
200: "#4338ca",
|
|
1225
|
+
300: "#4f46e5",
|
|
1226
|
+
400: "#6366f1",
|
|
1227
|
+
500: "#818cf8",
|
|
1228
|
+
600: "#a5b4fc",
|
|
1229
|
+
700: "#c7d2fe",
|
|
1230
|
+
800: "#e0e7ff",
|
|
1231
|
+
900: "#eef2ff",
|
|
1232
|
+
foreground: "#ffffff",
|
|
1233
|
+
DEFAULT: "#6366f1",
|
|
1234
|
+
},
|
|
1235
|
+
secondary: {
|
|
1236
|
+
50: "#240833",
|
|
1237
|
+
100: "#410f66",
|
|
1238
|
+
200: "#5f1799",
|
|
1239
|
+
300: "#7d1fcc",
|
|
1240
|
+
400: "#9b37ff",
|
|
1241
|
+
500: "#b359ff",
|
|
1242
|
+
600: "#c57fff",
|
|
1243
|
+
700: "#d7a6ff",
|
|
1244
|
+
800: "#e8ccff",
|
|
1245
|
+
900: "#f5e8ff",
|
|
1246
|
+
foreground: "#ffffff",
|
|
1247
|
+
DEFAULT: "#9b37ff",
|
|
1248
|
+
},
|
|
1249
|
+
success: {
|
|
1250
|
+
50: "#012b22",
|
|
1251
|
+
100: "#074d40",
|
|
1252
|
+
200: "#108066",
|
|
1253
|
+
300: "#18b38a",
|
|
1254
|
+
400: "#22e6b0",
|
|
1255
|
+
500: "#4bffca",
|
|
1256
|
+
600: "#70ffd2",
|
|
1257
|
+
700: "#9affdf",
|
|
1258
|
+
800: "#c3ffec",
|
|
1259
|
+
900: "#e7fff7",
|
|
1260
|
+
foreground: "#0e0e0e",
|
|
1261
|
+
DEFAULT: "#22e6b0",
|
|
1262
|
+
},
|
|
1263
|
+
warning: {
|
|
1264
|
+
50: "#3a2c00",
|
|
1265
|
+
100: "#5e4700",
|
|
1266
|
+
200: "#836300",
|
|
1267
|
+
300: "#a77e00",
|
|
1268
|
+
400: "#cc9900",
|
|
1269
|
+
500: "#ffc107",
|
|
1270
|
+
600: "#ffd54f",
|
|
1271
|
+
700: "#ffe082",
|
|
1272
|
+
800: "#ffecb3",
|
|
1273
|
+
900: "#fff8e1",
|
|
1274
|
+
foreground: "#000",
|
|
1275
|
+
DEFAULT: "#ffc107",
|
|
1276
|
+
},
|
|
1277
|
+
danger: {
|
|
1278
|
+
50: "#4a000a",
|
|
1279
|
+
100: "#6e000f",
|
|
1280
|
+
200: "#920014",
|
|
1281
|
+
300: "#b60019",
|
|
1282
|
+
400: "#da001f",
|
|
1283
|
+
500: "#ff112a",
|
|
1284
|
+
600: "#ff3949",
|
|
1285
|
+
700: "#ff6471",
|
|
1286
|
+
800: "#ff8f99",
|
|
1287
|
+
900: "#ffbac1",
|
|
1288
|
+
foreground: "#ffffff",
|
|
1289
|
+
DEFAULT: "#ff112a",
|
|
1290
|
+
},
|
|
1291
|
+
background: "#0f1114",
|
|
1292
|
+
foreground: "#f8f8f8",
|
|
1293
|
+
content1: "#15181d",
|
|
1294
|
+
},
|
|
1295
|
+
},
|
|
1296
|
+
},
|
|
1297
|
+
}),
|
|
1298
|
+
],
|
|
1299
|
+
};
|
|
1007
1300
|
|
|
1008
1301
|
export default config;
|
|
1009
1302
|
`;
|
|
@@ -1060,8 +1353,51 @@ export default config;
|
|
|
1060
1353
|
// tsconfig.json
|
|
1061
1354
|
const tsconfigPath = path.join(targetDir, "tsconfig.json");
|
|
1062
1355
|
if (!fs.existsSync(tsconfigPath) || force) {
|
|
1356
|
+
// Détecter si le projet cible est dans un monorepo
|
|
1357
|
+
const targetIsInMonorepo = fs.existsSync(path.join(targetDir, "../../../packages/core/package.json")) ||
|
|
1358
|
+
fs.existsSync(path.join(targetDir, "../../packages/core/package.json"));
|
|
1359
|
+
// Générer les chemins en fonction du contexte
|
|
1360
|
+
const paths = {
|
|
1361
|
+
"@/*": ["./*"],
|
|
1362
|
+
};
|
|
1363
|
+
if (targetIsInMonorepo) {
|
|
1364
|
+
// En monorepo, pointer sur les sources locales
|
|
1365
|
+
paths["@lastbrain/ui"] = ["../../packages/ui/src/index.ts"];
|
|
1366
|
+
paths["@lastbrain/ui/*"] = ["../../packages/ui/src/*"];
|
|
1367
|
+
paths["@lastbrain/core"] = ["../../packages/core/src/index.ts"];
|
|
1368
|
+
paths["@lastbrain/core/*"] = ["../../packages/core/src/*"];
|
|
1369
|
+
paths["@lastbrain/app"] = ["../../packages/app/src/index.ts"];
|
|
1370
|
+
paths["@lastbrain/app/*"] = ["../../packages/app/src/*"];
|
|
1371
|
+
paths["@lastbrain/module-auth"] = [
|
|
1372
|
+
"../../packages/module-auth/src/index.ts",
|
|
1373
|
+
];
|
|
1374
|
+
paths["@lastbrain/module-auth/*"] = ["../../packages/module-auth/src/*"];
|
|
1375
|
+
paths["@lastbrain/module-ai"] = ["../../packages/module-ai/src/index.ts"];
|
|
1376
|
+
paths["@lastbrain/module-ai/*"] = ["../../packages/module-ai/src/*"];
|
|
1377
|
+
paths["@lastbrain/module-legal"] = [
|
|
1378
|
+
"../../packages/module-legal/src/index.ts",
|
|
1379
|
+
];
|
|
1380
|
+
paths["@lastbrain/module-legal/*"] = [
|
|
1381
|
+
"../../packages/module-legal/src/*",
|
|
1382
|
+
];
|
|
1383
|
+
paths["@lastbrain/module-project-board"] = [
|
|
1384
|
+
"../../packages/module-project-board/src/index.ts",
|
|
1385
|
+
];
|
|
1386
|
+
paths["@lastbrain/module-project-board/*"] = [
|
|
1387
|
+
"../../packages/module-project-board/src/*",
|
|
1388
|
+
];
|
|
1389
|
+
paths["@lastbrain/module-tasks"] = [
|
|
1390
|
+
"../../packages/module-tasks/src/index.ts",
|
|
1391
|
+
];
|
|
1392
|
+
paths["@lastbrain/module-tasks/*"] = [
|
|
1393
|
+
"../../packages/module-tasks/src/*",
|
|
1394
|
+
];
|
|
1395
|
+
}
|
|
1396
|
+
else {
|
|
1397
|
+
// Hors monorepo (npm install), ne pas utiliser de paths aliases
|
|
1398
|
+
delete paths["@/*"];
|
|
1399
|
+
}
|
|
1063
1400
|
const tsconfig = {
|
|
1064
|
-
extends: "../../tsconfig.base.json",
|
|
1065
1401
|
compilerOptions: {
|
|
1066
1402
|
target: "ES2020",
|
|
1067
1403
|
lib: ["ES2020", "DOM", "DOM.Iterable"],
|
|
@@ -1078,14 +1414,16 @@ export default config;
|
|
|
1078
1414
|
incremental: true,
|
|
1079
1415
|
isolatedModules: true,
|
|
1080
1416
|
plugins: [{ name: "next" }],
|
|
1081
|
-
paths
|
|
1082
|
-
"@/*": ["./*"],
|
|
1083
|
-
},
|
|
1417
|
+
paths,
|
|
1084
1418
|
types: [],
|
|
1085
1419
|
},
|
|
1086
1420
|
include: ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
|
1087
1421
|
exclude: ["node_modules", "dist", ".next", "out"],
|
|
1088
1422
|
};
|
|
1423
|
+
// Ajouter extends seulement en monorepo
|
|
1424
|
+
if (targetIsInMonorepo) {
|
|
1425
|
+
tsconfig.extends = "../../tsconfig.base.json";
|
|
1426
|
+
}
|
|
1089
1427
|
await fs.writeJson(tsconfigPath, tsconfig, { spaces: 2 });
|
|
1090
1428
|
console.log(chalk.green("✓ tsconfig.json créé"));
|
|
1091
1429
|
}
|
|
@@ -1114,6 +1452,67 @@ export const menuConfig: MenuConfig = {
|
|
|
1114
1452
|
await fs.writeFile(menuConfigPath, menuConfig);
|
|
1115
1453
|
console.log(chalk.green("✓ config/menu.ts créé"));
|
|
1116
1454
|
}
|
|
1455
|
+
// config/menu-ignored.ts - Optional file to hide menus and block routes
|
|
1456
|
+
const menuIgnoredPath = path.join(configDir, "menu-ignored.ts");
|
|
1457
|
+
if (!fs.existsSync(menuIgnoredPath) || force) {
|
|
1458
|
+
const menuIgnored = `import type { MenuIgnored } from "@lastbrain/app";
|
|
1459
|
+
|
|
1460
|
+
/**
|
|
1461
|
+
* Menu items to hide and routes to block
|
|
1462
|
+
* This file is optional - if it doesn't exist, all menus are shown
|
|
1463
|
+
*
|
|
1464
|
+
* Example:
|
|
1465
|
+
* export const menuIgnored: MenuIgnored = {
|
|
1466
|
+
* public: [
|
|
1467
|
+
* { title: "Documentation", path: "/docs" }
|
|
1468
|
+
* ],
|
|
1469
|
+
* auth: [
|
|
1470
|
+
* { title: "Profile", path: "/auth/profile" }
|
|
1471
|
+
* ]
|
|
1472
|
+
* };
|
|
1473
|
+
*/
|
|
1474
|
+
|
|
1475
|
+
export const menuIgnored: MenuIgnored = {
|
|
1476
|
+
public: [],
|
|
1477
|
+
auth: [],
|
|
1478
|
+
};
|
|
1479
|
+
`;
|
|
1480
|
+
await fs.writeFile(menuIgnoredPath, menuIgnored);
|
|
1481
|
+
console.log(chalk.green("✓ config/menu-ignored.ts créé"));
|
|
1482
|
+
}
|
|
1483
|
+
// config/menu-custom.ts - Optional file to add custom menus
|
|
1484
|
+
const menuCustomPath = path.join(configDir, "menu-custom.ts");
|
|
1485
|
+
if (!fs.existsSync(menuCustomPath) || force) {
|
|
1486
|
+
const menuCustom = `import type { MenuCustom } from "@lastbrain/app";
|
|
1487
|
+
|
|
1488
|
+
/**
|
|
1489
|
+
* Custom menu items to add without creating a module
|
|
1490
|
+
* This file is optional - if it doesn't exist, no custom menus are added
|
|
1491
|
+
*
|
|
1492
|
+
* Example:
|
|
1493
|
+
* export const menuCustom: MenuCustom = {
|
|
1494
|
+
* public: [
|
|
1495
|
+
* { label: "Blog", href: "/blog" },
|
|
1496
|
+
* { label: "Pricing", href: "/pricing" }
|
|
1497
|
+
* ],
|
|
1498
|
+
* auth: [
|
|
1499
|
+
* { label: "Invoices", href: "/auth/invoices" }
|
|
1500
|
+
* ],
|
|
1501
|
+
* admin: [
|
|
1502
|
+
* { label: "Reports", href: "/admin/reports" }
|
|
1503
|
+
* ]
|
|
1504
|
+
* };
|
|
1505
|
+
*/
|
|
1506
|
+
|
|
1507
|
+
export const menuCustom: MenuCustom = {
|
|
1508
|
+
public: [],
|
|
1509
|
+
auth: [],
|
|
1510
|
+
admin: [],
|
|
1511
|
+
};
|
|
1512
|
+
`;
|
|
1513
|
+
await fs.writeFile(menuCustomPath, menuCustom);
|
|
1514
|
+
console.log(chalk.green("✓ config/menu-custom.ts créé"));
|
|
1515
|
+
}
|
|
1117
1516
|
// config/footer.ts
|
|
1118
1517
|
const footerConfigPath = path.join(configDir, "footer.ts");
|
|
1119
1518
|
if (!fs.existsSync(footerConfigPath) || force) {
|
|
@@ -1133,6 +1532,28 @@ export const footerConfig: FooterConfig = {
|
|
|
1133
1532
|
await fs.writeFile(footerConfigPath, footerConfig);
|
|
1134
1533
|
console.log(chalk.green("✓ config/footer.ts créé"));
|
|
1135
1534
|
}
|
|
1535
|
+
// config/user-tabs.ts - User detail page tabs configuration
|
|
1536
|
+
const userTabsConfigPath = path.join(configDir, "user-tabs.ts");
|
|
1537
|
+
if (!fs.existsSync(userTabsConfigPath) || force) {
|
|
1538
|
+
const userTabsConfig = `// User tabs configuration
|
|
1539
|
+
// This file is generated and can be regenerated by running: pnpm build:modules
|
|
1540
|
+
"use client";
|
|
1541
|
+
|
|
1542
|
+
import type React from "react";
|
|
1543
|
+
|
|
1544
|
+
export interface ModuleUserTab {
|
|
1545
|
+
id: string;
|
|
1546
|
+
label: string;
|
|
1547
|
+
component: React.ComponentType<{ userId: string }>;
|
|
1548
|
+
}
|
|
1549
|
+
|
|
1550
|
+
// Module user tabs - dynamically imported from active modules
|
|
1551
|
+
// To add tabs from modules, import them here and add to the array below
|
|
1552
|
+
export const moduleUserTabs: ModuleUserTab[] = [];
|
|
1553
|
+
`;
|
|
1554
|
+
await fs.writeFile(userTabsConfigPath, userTabsConfig);
|
|
1555
|
+
console.log(chalk.green("✓ config/user-tabs.ts créé"));
|
|
1556
|
+
}
|
|
1136
1557
|
// Créer les hooks
|
|
1137
1558
|
await createHooksDirectory(targetDir, force);
|
|
1138
1559
|
}
|
|
@@ -1395,8 +1816,8 @@ async function createSupabaseStructure(targetDir, force) {
|
|
|
1395
1816
|
console.log(chalk.green("✓ supabase/migrations/20201010100000_app_base.sql créé (vide)"));
|
|
1396
1817
|
}
|
|
1397
1818
|
}
|
|
1398
|
-
catch (
|
|
1399
|
-
console.error(chalk.red("✗ Erreur lors de la création de la migration:"),
|
|
1819
|
+
catch (_error) {
|
|
1820
|
+
console.error(chalk.red("✗ Erreur lors de la création de la migration:"), _error);
|
|
1400
1821
|
}
|
|
1401
1822
|
}
|
|
1402
1823
|
else {
|
|
@@ -1410,24 +1831,21 @@ async function addScriptsToPackageJson(targetDir) {
|
|
|
1410
1831
|
// Détecter si le projet cible est dans un workspace
|
|
1411
1832
|
const targetIsInMonorepo = fs.existsSync(path.join(targetDir, "../../../packages/core/package.json")) ||
|
|
1412
1833
|
fs.existsSync(path.join(targetDir, "../../packages/core/package.json"));
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
}
|
|
1834
|
+
// Utiliser le CLI depuis le monorepo si présent, sinon depuis node_modules
|
|
1835
|
+
const scriptsPrefix = targetIsInMonorepo
|
|
1836
|
+
? "node ../../packages/app/dist/cli.js"
|
|
1837
|
+
: "node node_modules/@lastbrain/app/dist/cli.js";
|
|
1418
1838
|
const scripts = {
|
|
1419
1839
|
predev: targetIsInMonorepo
|
|
1420
|
-
? "pnpm --filter @lastbrain/core build && pnpm --filter @lastbrain/ui build && pnpm --filter @lastbrain/module-auth build && pnpm --filter @lastbrain/module-ai build"
|
|
1421
|
-
: "echo 'No prebuild needed
|
|
1840
|
+
? "pnpm --filter @lastbrain/core build && pnpm --filter @lastbrain/ui build && pnpm --filter @lastbrain/app build && pnpm --filter @lastbrain/module-auth build && pnpm --filter @lastbrain/module-ai build"
|
|
1841
|
+
: "echo 'No prebuild needed'",
|
|
1422
1842
|
dev: "next dev",
|
|
1423
1843
|
"dev:local": "env-cmd -f .env.local next dev",
|
|
1424
1844
|
"dev:prod": "env-cmd -f .env.prod next dev",
|
|
1425
1845
|
build: "next build",
|
|
1426
1846
|
start: "next start",
|
|
1427
1847
|
lint: "next lint",
|
|
1428
|
-
lastbrain:
|
|
1429
|
-
? "lastbrain"
|
|
1430
|
-
: "node node_modules/@lastbrain/app/dist/cli.js",
|
|
1848
|
+
lastbrain: scriptsPrefix,
|
|
1431
1849
|
"build:modules": `${scriptsPrefix} module:build`,
|
|
1432
1850
|
"db:migrations:sync": `${scriptsPrefix} db:migrations:sync`,
|
|
1433
1851
|
"db:init": `${scriptsPrefix} db:init`,
|
|
@@ -168,7 +168,7 @@ export async function addModule(moduleName, targetDir) {
|
|
|
168
168
|
}
|
|
169
169
|
console.log(chalk.green(`✓ ${migrationFiles.length} migration(s) appliquée(s)`));
|
|
170
170
|
}
|
|
171
|
-
catch (
|
|
171
|
+
catch (_error) {
|
|
172
172
|
console.error(chalk.red("❌ Erreur lors de l'application des migrations"));
|
|
173
173
|
console.log(chalk.gray("\nVous pouvez essayer manuellement:\n supabase db reset\n"));
|
|
174
174
|
}
|
|
@@ -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":"AAi6CA,wBAAsB,cAAc,kBA+FnC"}
|