@lastbrain/app 0.1.47 → 1.0.2
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.d.ts.map +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 +264 -0
- package/src/templates/DocPage.tsx +1 -1
- package/src/templates/DocsPageWithModules.tsx +1 -1
- package/src/types/menu.ts +18 -0
package/src/scripts/init-app.ts
CHANGED
|
@@ -4,10 +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 {
|
|
8
|
-
AVAILABLE_MODULES,
|
|
9
|
-
type ModuleMetadata,
|
|
10
|
-
} from "@lastbrain/core/config/modules";
|
|
7
|
+
import { AVAILABLE_MODULES } from "@lastbrain/core/config/modules";
|
|
11
8
|
|
|
12
9
|
const __filename = fileURLToPath(import.meta.url);
|
|
13
10
|
const __dirname = path.dirname(__filename);
|
|
@@ -196,20 +193,31 @@ export async function initApp(options: InitAppOptions) {
|
|
|
196
193
|
stdio: "inherit",
|
|
197
194
|
});
|
|
198
195
|
console.log(chalk.green("\n✓ Migrations synchronisées\n"));
|
|
199
|
-
} catch (
|
|
196
|
+
} catch (_error) {
|
|
200
197
|
console.log(
|
|
201
198
|
chalk.yellow("\n⚠️ Erreur de synchronisation des migrations\n")
|
|
202
199
|
);
|
|
203
200
|
}
|
|
204
201
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
execSync("pnpm db:init", { cwd: targetDir, stdio: "inherit" });
|
|
208
|
-
console.log(chalk.green("\n✓ Base de données initialisée\n"));
|
|
209
|
-
} catch {
|
|
202
|
+
// Ne pas initialiser la BDD en mode monorepo
|
|
203
|
+
if (!isMonorepoProject) {
|
|
210
204
|
console.log(
|
|
211
|
-
chalk.yellow(
|
|
212
|
-
|
|
205
|
+
chalk.yellow("🗄️ Initialisation de la base de données...\n")
|
|
206
|
+
);
|
|
207
|
+
try {
|
|
208
|
+
execSync("pnpm db:init", { cwd: targetDir, stdio: "inherit" });
|
|
209
|
+
console.log(chalk.green("\n✓ Base de données initialisée\n"));
|
|
210
|
+
} catch {
|
|
211
|
+
console.log(
|
|
212
|
+
chalk.yellow(
|
|
213
|
+
"\n⚠️ Erreur d'initialisation de la DB (normal si Supabase pas configuré)\n"
|
|
214
|
+
)
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
} else {
|
|
218
|
+
console.log(
|
|
219
|
+
chalk.cyan(
|
|
220
|
+
"⏭️ Mode monorepo détecté - BDD centralisée, pas d'initialisation locale requise\n"
|
|
213
221
|
)
|
|
214
222
|
);
|
|
215
223
|
}
|
|
@@ -227,14 +235,20 @@ export async function initApp(options: InitAppOptions) {
|
|
|
227
235
|
console.log(
|
|
228
236
|
chalk.white(" 1. Cliquez sur 'Get Started' sur la page d'accueil")
|
|
229
237
|
);
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
+
if (isMonorepoProject) {
|
|
239
|
+
console.log(
|
|
240
|
+
chalk.white(" 2. La BDD est centralisée dans le monorepo\n")
|
|
241
|
+
);
|
|
242
|
+
} else {
|
|
243
|
+
console.log(chalk.white(" 2. Lancez Docker Desktop"));
|
|
244
|
+
console.log(
|
|
245
|
+
chalk.white(
|
|
246
|
+
" 3. Installez Supabase CLI si nécessaire : brew install supabase/tap/supabase"
|
|
247
|
+
)
|
|
248
|
+
);
|
|
249
|
+
console.log(chalk.white(" 4. Exécutez : pnpm db:init"));
|
|
250
|
+
console.log(chalk.white(" 5. Rechargez la page\n"));
|
|
251
|
+
}
|
|
238
252
|
|
|
239
253
|
// Ouvrir le navigateur
|
|
240
254
|
const openCommand =
|
|
@@ -252,7 +266,7 @@ export async function initApp(options: InitAppOptions) {
|
|
|
252
266
|
}, 2000);
|
|
253
267
|
|
|
254
268
|
// Lancer pnpm dev
|
|
255
|
-
execSync("pnpm dev", { cwd: targetDir, stdio: "inherit" });
|
|
269
|
+
execSync("pnpm dev:local", { cwd: targetDir, stdio: "inherit" });
|
|
256
270
|
} catch {
|
|
257
271
|
console.error(chalk.red("\n❌ Erreur lors du lancement\n"));
|
|
258
272
|
console.log(chalk.cyan("\nVous pouvez lancer manuellement avec :"));
|
|
@@ -260,7 +274,9 @@ export async function initApp(options: InitAppOptions) {
|
|
|
260
274
|
console.log(chalk.white(" pnpm install"));
|
|
261
275
|
console.log(chalk.white(" pnpm build:modules"));
|
|
262
276
|
console.log(chalk.white(" pnpm db:migrations:sync"));
|
|
263
|
-
|
|
277
|
+
if (!isMonorepoProject) {
|
|
278
|
+
console.log(chalk.white(" pnpm db:init"));
|
|
279
|
+
}
|
|
264
280
|
console.log(chalk.white(" pnpm dev:local (ou pnpm dev:prod)\n"));
|
|
265
281
|
}
|
|
266
282
|
} else {
|
|
@@ -411,10 +427,10 @@ function getLastBrainVersions(targetDir: string): {
|
|
|
411
427
|
moduleAi: moduleAiVersion,
|
|
412
428
|
};
|
|
413
429
|
}
|
|
414
|
-
} catch (
|
|
430
|
+
} catch (_error) {
|
|
415
431
|
console.warn(
|
|
416
432
|
chalk.yellow(
|
|
417
|
-
`⚠️ Impossible de lire les versions locales (${
|
|
433
|
+
`⚠️ Impossible de lire les versions locales (${_error}), utilisation de 'latest'`
|
|
418
434
|
)
|
|
419
435
|
);
|
|
420
436
|
}
|
|
@@ -917,17 +933,56 @@ async function createAppHeader(targetDir: string, force: boolean) {
|
|
|
917
933
|
if (!fs.existsSync(headerPath) || force) {
|
|
918
934
|
const headerContent = `"use client";
|
|
919
935
|
|
|
920
|
-
import { Header } from "@lastbrain/ui";
|
|
936
|
+
import { Header, type MenuItem } from "@lastbrain/ui";
|
|
921
937
|
import { menuConfig } from "../config/menu";
|
|
922
938
|
import { supabaseBrowserClient } from "@lastbrain/core";
|
|
923
939
|
import { useRouter } from "next/navigation";
|
|
924
940
|
import { useAuthSession, useNotificationsContext } from "@lastbrain/app";
|
|
941
|
+
import { useState, useEffect } from "react";
|
|
942
|
+
|
|
943
|
+
interface MenuIgnored {
|
|
944
|
+
public: { title: string; path: string }[];
|
|
945
|
+
auth: { title: string; path: string }[];
|
|
946
|
+
}
|
|
925
947
|
|
|
926
948
|
export function AppHeader() {
|
|
927
949
|
const router = useRouter();
|
|
928
950
|
const { user, isSuperAdmin } = useAuthSession();
|
|
929
951
|
const { data, loading, markAsRead, markAllAsRead, deleteNotification } =
|
|
930
952
|
useNotificationsContext();
|
|
953
|
+
const [menuIgnored, setMenuIgnored] = useState<MenuIgnored | undefined>();
|
|
954
|
+
const [menuCustom, setMenuCustom] = useState<MenuItem[] | undefined>();
|
|
955
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
956
|
+
|
|
957
|
+
// Charger menuIgnored et menuCustom s'ils existent
|
|
958
|
+
useEffect(() => {
|
|
959
|
+
let loadedIgnored = false;
|
|
960
|
+
let loadedCustom = false;
|
|
961
|
+
|
|
962
|
+
// Charger menu-ignored
|
|
963
|
+
import("../config/menu-ignored")
|
|
964
|
+
.then((mod) => setMenuIgnored(mod.menuIgnored))
|
|
965
|
+
.catch(() => setMenuIgnored(undefined))
|
|
966
|
+
.finally(() => {
|
|
967
|
+
loadedIgnored = true;
|
|
968
|
+
if (loadedIgnored && loadedCustom) setIsLoading(false);
|
|
969
|
+
});
|
|
970
|
+
|
|
971
|
+
// Charger menu-custom
|
|
972
|
+
import("../config/menu-custom")
|
|
973
|
+
.then((mod) => {
|
|
974
|
+
// Combiner les menus custom publics et auth
|
|
975
|
+
const customMenus: MenuItem[] = [];
|
|
976
|
+
if (mod.menuCustom?.public) customMenus.push(...mod.menuCustom.public);
|
|
977
|
+
if (mod.menuCustom?.auth) customMenus.push(...mod.menuCustom.auth);
|
|
978
|
+
setMenuCustom(customMenus.length > 0 ? customMenus : undefined);
|
|
979
|
+
})
|
|
980
|
+
.catch(() => setMenuCustom(undefined))
|
|
981
|
+
.finally(() => {
|
|
982
|
+
loadedCustom = true;
|
|
983
|
+
if (loadedIgnored && loadedCustom) setIsLoading(false);
|
|
984
|
+
});
|
|
985
|
+
}, []);
|
|
931
986
|
|
|
932
987
|
const handleLogout = async () => {
|
|
933
988
|
await supabaseBrowserClient.auth.signOut();
|
|
@@ -950,6 +1005,9 @@ export function AppHeader() {
|
|
|
950
1005
|
onMarkAsRead={markAsRead}
|
|
951
1006
|
onMarkAllAsRead={markAllAsRead}
|
|
952
1007
|
onDeleteNotification={deleteNotification}
|
|
1008
|
+
{...(menuIgnored ? { menuIgnored } : {})}
|
|
1009
|
+
{...(menuCustom ? { menuCustom } : {})}
|
|
1010
|
+
{...{ isLoadingMenus: isLoading }}
|
|
953
1011
|
/>
|
|
954
1012
|
);
|
|
955
1013
|
}
|
|
@@ -1047,7 +1105,58 @@ async function createConfigFiles(
|
|
|
1047
1105
|
const middlewarePath = path.join(targetDir, "middleware.ts");
|
|
1048
1106
|
if (!fs.existsSync(middlewarePath) || force) {
|
|
1049
1107
|
const middleware = `import { type NextRequest, NextResponse } from "next/server";
|
|
1050
|
-
import {
|
|
1108
|
+
import { createServerClient, type CookieOptions } from "@supabase/ssr";
|
|
1109
|
+
|
|
1110
|
+
/**
|
|
1111
|
+
* Crée un client Supabase pour le middleware
|
|
1112
|
+
*/
|
|
1113
|
+
function createMiddlewareClient(request: NextRequest) {
|
|
1114
|
+
let response = NextResponse.next({
|
|
1115
|
+
request: {
|
|
1116
|
+
headers: request.headers,
|
|
1117
|
+
},
|
|
1118
|
+
});
|
|
1119
|
+
|
|
1120
|
+
const supabase = createServerClient(
|
|
1121
|
+
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
1122
|
+
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
|
1123
|
+
{
|
|
1124
|
+
cookies: {
|
|
1125
|
+
get(name: string) {
|
|
1126
|
+
return request.cookies.get(name)?.value;
|
|
1127
|
+
},
|
|
1128
|
+
set(name: string, value: string, options: CookieOptions) {
|
|
1129
|
+
request.cookies.set({
|
|
1130
|
+
name,
|
|
1131
|
+
value,
|
|
1132
|
+
...options,
|
|
1133
|
+
});
|
|
1134
|
+
response = NextResponse.next({
|
|
1135
|
+
request: {
|
|
1136
|
+
headers: request.headers,
|
|
1137
|
+
},
|
|
1138
|
+
});
|
|
1139
|
+
response.cookies.set({
|
|
1140
|
+
name,
|
|
1141
|
+
value,
|
|
1142
|
+
...options,
|
|
1143
|
+
});
|
|
1144
|
+
},
|
|
1145
|
+
remove(name: string, options: CookieOptions) {
|
|
1146
|
+
request.cookies.delete(name);
|
|
1147
|
+
response = NextResponse.next({
|
|
1148
|
+
request: {
|
|
1149
|
+
headers: request.headers,
|
|
1150
|
+
},
|
|
1151
|
+
});
|
|
1152
|
+
response.cookies.delete(name);
|
|
1153
|
+
},
|
|
1154
|
+
},
|
|
1155
|
+
}
|
|
1156
|
+
);
|
|
1157
|
+
|
|
1158
|
+
return { supabase, response };
|
|
1159
|
+
}
|
|
1051
1160
|
|
|
1052
1161
|
export async function middleware(request: NextRequest) {
|
|
1053
1162
|
const { pathname } = request.nextUrl;
|
|
@@ -1195,9 +1304,9 @@ export const config = {
|
|
|
1195
1304
|
const nextConfig = `/** @type {import('next').NextConfig} */
|
|
1196
1305
|
const nextConfig = {
|
|
1197
1306
|
reactStrictMode: true,
|
|
1198
|
-
|
|
1307
|
+
devIndicators: {
|
|
1199
1308
|
position: 'bottom-right',
|
|
1200
|
-
}
|
|
1309
|
+
}
|
|
1201
1310
|
};
|
|
1202
1311
|
|
|
1203
1312
|
export default nextConfig;
|
|
@@ -1212,7 +1321,7 @@ export default nextConfig;
|
|
|
1212
1321
|
let tailwindConfig = "";
|
|
1213
1322
|
|
|
1214
1323
|
if (useHeroUI) {
|
|
1215
|
-
// Configuration avec HeroUI
|
|
1324
|
+
// Configuration avec HeroUI - complète avec thèmes
|
|
1216
1325
|
tailwindConfig = `import { heroui } from "@heroui/theme";
|
|
1217
1326
|
|
|
1218
1327
|
/** @type {import('tailwindcss').Config} */
|
|
@@ -1224,8 +1333,195 @@ const config = {
|
|
|
1224
1333
|
"./node_modules/@heroui/theme/dist/**/*.{js,mjs}",
|
|
1225
1334
|
],
|
|
1226
1335
|
darkMode: "class",
|
|
1227
|
-
plugins: [
|
|
1228
|
-
|
|
1336
|
+
plugins: [
|
|
1337
|
+
heroui({
|
|
1338
|
+
themes: {
|
|
1339
|
+
light: {
|
|
1340
|
+
colors: {
|
|
1341
|
+
default: {
|
|
1342
|
+
950: "#0d0d0e",
|
|
1343
|
+
900: "#19191c",
|
|
1344
|
+
800: "#26262a",
|
|
1345
|
+
700: "#323238",
|
|
1346
|
+
600: "#3f3f46",
|
|
1347
|
+
500: "#65656b",
|
|
1348
|
+
400: "#8c8c90",
|
|
1349
|
+
300: "#b2b2b5",
|
|
1350
|
+
200: "#d9d9da",
|
|
1351
|
+
100: "#ffffff",
|
|
1352
|
+
foreground: "#000000",
|
|
1353
|
+
DEFAULT: "#d4d4d8",
|
|
1354
|
+
},
|
|
1355
|
+
primary: {
|
|
1356
|
+
50: "#eef2ff",
|
|
1357
|
+
100: "#e0e7ff",
|
|
1358
|
+
200: "#c7d2fe",
|
|
1359
|
+
300: "#a5b4fc",
|
|
1360
|
+
400: "#818cf8",
|
|
1361
|
+
500: "#6366f1",
|
|
1362
|
+
600: "#4f46e5",
|
|
1363
|
+
700: "#4338ca",
|
|
1364
|
+
800: "#3730a3",
|
|
1365
|
+
900: "#312e81",
|
|
1366
|
+
foreground: "#ffffff",
|
|
1367
|
+
DEFAULT: "#6366f1",
|
|
1368
|
+
},
|
|
1369
|
+
secondary: {
|
|
1370
|
+
50: "#f5e8ff",
|
|
1371
|
+
100: "#e8ccff",
|
|
1372
|
+
200: "#d7a6ff",
|
|
1373
|
+
300: "#c57fff",
|
|
1374
|
+
400: "#b359ff",
|
|
1375
|
+
500: "#9b37ff",
|
|
1376
|
+
600: "#7d1fcc",
|
|
1377
|
+
700: "#5f1799",
|
|
1378
|
+
800: "#410f66",
|
|
1379
|
+
900: "#240833",
|
|
1380
|
+
foreground: "#ffffff",
|
|
1381
|
+
DEFAULT: "#9b37ff",
|
|
1382
|
+
},
|
|
1383
|
+
success: {
|
|
1384
|
+
50: "#e7fff7",
|
|
1385
|
+
100: "#c3ffec",
|
|
1386
|
+
200: "#9affdf",
|
|
1387
|
+
300: "#70ffd2",
|
|
1388
|
+
400: "#4bffca",
|
|
1389
|
+
500: "#22e6b0",
|
|
1390
|
+
600: "#18b38a",
|
|
1391
|
+
700: "#108066",
|
|
1392
|
+
800: "#074d40",
|
|
1393
|
+
900: "#012b22",
|
|
1394
|
+
foreground: "#000",
|
|
1395
|
+
DEFAULT: "#22e6b0",
|
|
1396
|
+
},
|
|
1397
|
+
warning: {
|
|
1398
|
+
50: "#fff8e1",
|
|
1399
|
+
100: "#ffecb3",
|
|
1400
|
+
200: "#ffe082",
|
|
1401
|
+
300: "#ffd54f",
|
|
1402
|
+
400: "#ffca28",
|
|
1403
|
+
500: "#ffc107",
|
|
1404
|
+
600: "#ffb300",
|
|
1405
|
+
700: "#ffa000",
|
|
1406
|
+
800: "#ff8f00",
|
|
1407
|
+
900: "#ff6f00",
|
|
1408
|
+
foreground: "#000",
|
|
1409
|
+
DEFAULT: "#ffca28",
|
|
1410
|
+
},
|
|
1411
|
+
danger: {
|
|
1412
|
+
50: "#ffe6e9",
|
|
1413
|
+
100: "#ffbac1",
|
|
1414
|
+
200: "#ff8f99",
|
|
1415
|
+
300: "#ff6471",
|
|
1416
|
+
400: "#ff3949",
|
|
1417
|
+
500: "#ff112a",
|
|
1418
|
+
600: "#d80c22",
|
|
1419
|
+
700: "#b1081b",
|
|
1420
|
+
800: "#890514",
|
|
1421
|
+
900: "#62020d",
|
|
1422
|
+
foreground: "#fff",
|
|
1423
|
+
DEFAULT: "#ff112a",
|
|
1424
|
+
},
|
|
1425
|
+
background: "#f7f8fc",
|
|
1426
|
+
foreground: "#0e0e10",
|
|
1427
|
+
content1: "#ffffff",
|
|
1428
|
+
},
|
|
1429
|
+
},
|
|
1430
|
+
dark: {
|
|
1431
|
+
colors: {
|
|
1432
|
+
default: {
|
|
1433
|
+
50: "#1a1c1f",
|
|
1434
|
+
100: "#232529",
|
|
1435
|
+
200: "#2c2f34",
|
|
1436
|
+
300: "#363940",
|
|
1437
|
+
400: "#40444d",
|
|
1438
|
+
500: "#4b4f59",
|
|
1439
|
+
600: "#6c707b",
|
|
1440
|
+
700: "#8d919b",
|
|
1441
|
+
800: "#afb2bb",
|
|
1442
|
+
900: "#d1d3d9",
|
|
1443
|
+
foreground: "#ffffff",
|
|
1444
|
+
DEFAULT: "#363940",
|
|
1445
|
+
},
|
|
1446
|
+
primary: {
|
|
1447
|
+
50: "#312e81",
|
|
1448
|
+
100: "#3730a3",
|
|
1449
|
+
200: "#4338ca",
|
|
1450
|
+
300: "#4f46e5",
|
|
1451
|
+
400: "#6366f1",
|
|
1452
|
+
500: "#818cf8",
|
|
1453
|
+
600: "#a5b4fc",
|
|
1454
|
+
700: "#c7d2fe",
|
|
1455
|
+
800: "#e0e7ff",
|
|
1456
|
+
900: "#eef2ff",
|
|
1457
|
+
foreground: "#ffffff",
|
|
1458
|
+
DEFAULT: "#6366f1",
|
|
1459
|
+
},
|
|
1460
|
+
secondary: {
|
|
1461
|
+
50: "#240833",
|
|
1462
|
+
100: "#410f66",
|
|
1463
|
+
200: "#5f1799",
|
|
1464
|
+
300: "#7d1fcc",
|
|
1465
|
+
400: "#9b37ff",
|
|
1466
|
+
500: "#b359ff",
|
|
1467
|
+
600: "#c57fff",
|
|
1468
|
+
700: "#d7a6ff",
|
|
1469
|
+
800: "#e8ccff",
|
|
1470
|
+
900: "#f5e8ff",
|
|
1471
|
+
foreground: "#ffffff",
|
|
1472
|
+
DEFAULT: "#9b37ff",
|
|
1473
|
+
},
|
|
1474
|
+
success: {
|
|
1475
|
+
50: "#012b22",
|
|
1476
|
+
100: "#074d40",
|
|
1477
|
+
200: "#108066",
|
|
1478
|
+
300: "#18b38a",
|
|
1479
|
+
400: "#22e6b0",
|
|
1480
|
+
500: "#4bffca",
|
|
1481
|
+
600: "#70ffd2",
|
|
1482
|
+
700: "#9affdf",
|
|
1483
|
+
800: "#c3ffec",
|
|
1484
|
+
900: "#e7fff7",
|
|
1485
|
+
foreground: "#0e0e0e",
|
|
1486
|
+
DEFAULT: "#22e6b0",
|
|
1487
|
+
},
|
|
1488
|
+
warning: {
|
|
1489
|
+
50: "#3a2c00",
|
|
1490
|
+
100: "#5e4700",
|
|
1491
|
+
200: "#836300",
|
|
1492
|
+
300: "#a77e00",
|
|
1493
|
+
400: "#cc9900",
|
|
1494
|
+
500: "#ffc107",
|
|
1495
|
+
600: "#ffd54f",
|
|
1496
|
+
700: "#ffe082",
|
|
1497
|
+
800: "#ffecb3",
|
|
1498
|
+
900: "#fff8e1",
|
|
1499
|
+
foreground: "#000",
|
|
1500
|
+
DEFAULT: "#ffc107",
|
|
1501
|
+
},
|
|
1502
|
+
danger: {
|
|
1503
|
+
50: "#4a000a",
|
|
1504
|
+
100: "#6e000f",
|
|
1505
|
+
200: "#920014",
|
|
1506
|
+
300: "#b60019",
|
|
1507
|
+
400: "#da001f",
|
|
1508
|
+
500: "#ff112a",
|
|
1509
|
+
600: "#ff3949",
|
|
1510
|
+
700: "#ff6471",
|
|
1511
|
+
800: "#ff8f99",
|
|
1512
|
+
900: "#ffbac1",
|
|
1513
|
+
foreground: "#ffffff",
|
|
1514
|
+
DEFAULT: "#ff112a",
|
|
1515
|
+
},
|
|
1516
|
+
background: "#0f1114",
|
|
1517
|
+
foreground: "#f8f8f8",
|
|
1518
|
+
content1: "#15181d",
|
|
1519
|
+
},
|
|
1520
|
+
},
|
|
1521
|
+
},
|
|
1522
|
+
}),
|
|
1523
|
+
],
|
|
1524
|
+
};
|
|
1229
1525
|
|
|
1230
1526
|
export default config;
|
|
1231
1527
|
`;
|
|
@@ -1284,8 +1580,56 @@ export default config;
|
|
|
1284
1580
|
// tsconfig.json
|
|
1285
1581
|
const tsconfigPath = path.join(targetDir, "tsconfig.json");
|
|
1286
1582
|
if (!fs.existsSync(tsconfigPath) || force) {
|
|
1287
|
-
|
|
1288
|
-
|
|
1583
|
+
// Détecter si le projet cible est dans un monorepo
|
|
1584
|
+
const targetIsInMonorepo =
|
|
1585
|
+
fs.existsSync(
|
|
1586
|
+
path.join(targetDir, "../../../packages/core/package.json")
|
|
1587
|
+
) ||
|
|
1588
|
+
fs.existsSync(path.join(targetDir, "../../packages/core/package.json"));
|
|
1589
|
+
|
|
1590
|
+
// Générer les chemins en fonction du contexte
|
|
1591
|
+
const paths: Record<string, string[]> = {
|
|
1592
|
+
"@/*": ["./*"],
|
|
1593
|
+
};
|
|
1594
|
+
|
|
1595
|
+
if (targetIsInMonorepo) {
|
|
1596
|
+
// En monorepo, pointer sur les sources locales
|
|
1597
|
+
paths["@lastbrain/ui"] = ["../../packages/ui/src/index.ts"];
|
|
1598
|
+
paths["@lastbrain/ui/*"] = ["../../packages/ui/src/*"];
|
|
1599
|
+
paths["@lastbrain/core"] = ["../../packages/core/src/index.ts"];
|
|
1600
|
+
paths["@lastbrain/core/*"] = ["../../packages/core/src/*"];
|
|
1601
|
+
paths["@lastbrain/app"] = ["../../packages/app/src/index.ts"];
|
|
1602
|
+
paths["@lastbrain/app/*"] = ["../../packages/app/src/*"];
|
|
1603
|
+
paths["@lastbrain/module-auth"] = [
|
|
1604
|
+
"../../packages/module-auth/src/index.ts",
|
|
1605
|
+
];
|
|
1606
|
+
paths["@lastbrain/module-auth/*"] = ["../../packages/module-auth/src/*"];
|
|
1607
|
+
paths["@lastbrain/module-ai"] = ["../../packages/module-ai/src/index.ts"];
|
|
1608
|
+
paths["@lastbrain/module-ai/*"] = ["../../packages/module-ai/src/*"];
|
|
1609
|
+
paths["@lastbrain/module-legal"] = [
|
|
1610
|
+
"../../packages/module-legal/src/index.ts",
|
|
1611
|
+
];
|
|
1612
|
+
paths["@lastbrain/module-legal/*"] = [
|
|
1613
|
+
"../../packages/module-legal/src/*",
|
|
1614
|
+
];
|
|
1615
|
+
paths["@lastbrain/module-project-board"] = [
|
|
1616
|
+
"../../packages/module-project-board/src/index.ts",
|
|
1617
|
+
];
|
|
1618
|
+
paths["@lastbrain/module-project-board/*"] = [
|
|
1619
|
+
"../../packages/module-project-board/src/*",
|
|
1620
|
+
];
|
|
1621
|
+
paths["@lastbrain/module-tasks"] = [
|
|
1622
|
+
"../../packages/module-tasks/src/index.ts",
|
|
1623
|
+
];
|
|
1624
|
+
paths["@lastbrain/module-tasks/*"] = [
|
|
1625
|
+
"../../packages/module-tasks/src/*",
|
|
1626
|
+
];
|
|
1627
|
+
} else {
|
|
1628
|
+
// Hors monorepo (npm install), ne pas utiliser de paths aliases
|
|
1629
|
+
delete paths["@/*"];
|
|
1630
|
+
}
|
|
1631
|
+
|
|
1632
|
+
const tsconfig: any = {
|
|
1289
1633
|
compilerOptions: {
|
|
1290
1634
|
target: "ES2020",
|
|
1291
1635
|
lib: ["ES2020", "DOM", "DOM.Iterable"],
|
|
@@ -1302,14 +1646,18 @@ export default config;
|
|
|
1302
1646
|
incremental: true,
|
|
1303
1647
|
isolatedModules: true,
|
|
1304
1648
|
plugins: [{ name: "next" }],
|
|
1305
|
-
paths
|
|
1306
|
-
"@/*": ["./*"],
|
|
1307
|
-
},
|
|
1649
|
+
paths,
|
|
1308
1650
|
types: [],
|
|
1309
1651
|
},
|
|
1310
1652
|
include: ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
|
1311
1653
|
exclude: ["node_modules", "dist", ".next", "out"],
|
|
1312
1654
|
};
|
|
1655
|
+
|
|
1656
|
+
// Ajouter extends seulement en monorepo
|
|
1657
|
+
if (targetIsInMonorepo) {
|
|
1658
|
+
tsconfig.extends = "../../tsconfig.base.json";
|
|
1659
|
+
}
|
|
1660
|
+
|
|
1313
1661
|
await fs.writeJson(tsconfigPath, tsconfig, { spaces: 2 });
|
|
1314
1662
|
console.log(chalk.green("✓ tsconfig.json créé"));
|
|
1315
1663
|
}
|
|
@@ -1340,6 +1688,69 @@ export const menuConfig: MenuConfig = {
|
|
|
1340
1688
|
console.log(chalk.green("✓ config/menu.ts créé"));
|
|
1341
1689
|
}
|
|
1342
1690
|
|
|
1691
|
+
// config/menu-ignored.ts - Optional file to hide menus and block routes
|
|
1692
|
+
const menuIgnoredPath = path.join(configDir, "menu-ignored.ts");
|
|
1693
|
+
if (!fs.existsSync(menuIgnoredPath) || force) {
|
|
1694
|
+
const menuIgnored = `import type { MenuIgnored } from "@lastbrain/app";
|
|
1695
|
+
|
|
1696
|
+
/**
|
|
1697
|
+
* Menu items to hide and routes to block
|
|
1698
|
+
* This file is optional - if it doesn't exist, all menus are shown
|
|
1699
|
+
*
|
|
1700
|
+
* Example:
|
|
1701
|
+
* export const menuIgnored: MenuIgnored = {
|
|
1702
|
+
* public: [
|
|
1703
|
+
* { title: "Documentation", path: "/docs" }
|
|
1704
|
+
* ],
|
|
1705
|
+
* auth: [
|
|
1706
|
+
* { title: "Profile", path: "/auth/profile" }
|
|
1707
|
+
* ]
|
|
1708
|
+
* };
|
|
1709
|
+
*/
|
|
1710
|
+
|
|
1711
|
+
export const menuIgnored: MenuIgnored = {
|
|
1712
|
+
public: [],
|
|
1713
|
+
auth: [],
|
|
1714
|
+
};
|
|
1715
|
+
`;
|
|
1716
|
+
await fs.writeFile(menuIgnoredPath, menuIgnored);
|
|
1717
|
+
console.log(chalk.green("✓ config/menu-ignored.ts créé"));
|
|
1718
|
+
}
|
|
1719
|
+
|
|
1720
|
+
// config/menu-custom.ts - Optional file to add custom menus
|
|
1721
|
+
const menuCustomPath = path.join(configDir, "menu-custom.ts");
|
|
1722
|
+
if (!fs.existsSync(menuCustomPath) || force) {
|
|
1723
|
+
const menuCustom = `import type { MenuCustom } from "@lastbrain/app";
|
|
1724
|
+
|
|
1725
|
+
/**
|
|
1726
|
+
* Custom menu items to add without creating a module
|
|
1727
|
+
* This file is optional - if it doesn't exist, no custom menus are added
|
|
1728
|
+
*
|
|
1729
|
+
* Example:
|
|
1730
|
+
* export const menuCustom: MenuCustom = {
|
|
1731
|
+
* public: [
|
|
1732
|
+
* { label: "Blog", href: "/blog" },
|
|
1733
|
+
* { label: "Pricing", href: "/pricing" }
|
|
1734
|
+
* ],
|
|
1735
|
+
* auth: [
|
|
1736
|
+
* { label: "Invoices", href: "/auth/invoices" }
|
|
1737
|
+
* ],
|
|
1738
|
+
* admin: [
|
|
1739
|
+
* { label: "Reports", href: "/admin/reports" }
|
|
1740
|
+
* ]
|
|
1741
|
+
* };
|
|
1742
|
+
*/
|
|
1743
|
+
|
|
1744
|
+
export const menuCustom: MenuCustom = {
|
|
1745
|
+
public: [],
|
|
1746
|
+
auth: [],
|
|
1747
|
+
admin: [],
|
|
1748
|
+
};
|
|
1749
|
+
`;
|
|
1750
|
+
await fs.writeFile(menuCustomPath, menuCustom);
|
|
1751
|
+
console.log(chalk.green("✓ config/menu-custom.ts créé"));
|
|
1752
|
+
}
|
|
1753
|
+
|
|
1343
1754
|
// config/footer.ts
|
|
1344
1755
|
const footerConfigPath = path.join(configDir, "footer.ts");
|
|
1345
1756
|
if (!fs.existsSync(footerConfigPath) || force) {
|
|
@@ -1360,6 +1771,29 @@ export const footerConfig: FooterConfig = {
|
|
|
1360
1771
|
console.log(chalk.green("✓ config/footer.ts créé"));
|
|
1361
1772
|
}
|
|
1362
1773
|
|
|
1774
|
+
// config/user-tabs.ts - User detail page tabs configuration
|
|
1775
|
+
const userTabsConfigPath = path.join(configDir, "user-tabs.ts");
|
|
1776
|
+
if (!fs.existsSync(userTabsConfigPath) || force) {
|
|
1777
|
+
const userTabsConfig = `// User tabs configuration
|
|
1778
|
+
// This file is generated and can be regenerated by running: pnpm build:modules
|
|
1779
|
+
"use client";
|
|
1780
|
+
|
|
1781
|
+
import type React from "react";
|
|
1782
|
+
|
|
1783
|
+
export interface ModuleUserTab {
|
|
1784
|
+
id: string;
|
|
1785
|
+
label: string;
|
|
1786
|
+
component: React.ComponentType<{ userId: string }>;
|
|
1787
|
+
}
|
|
1788
|
+
|
|
1789
|
+
// Module user tabs - dynamically imported from active modules
|
|
1790
|
+
// To add tabs from modules, import them here and add to the array below
|
|
1791
|
+
export const moduleUserTabs: ModuleUserTab[] = [];
|
|
1792
|
+
`;
|
|
1793
|
+
await fs.writeFile(userTabsConfigPath, userTabsConfig);
|
|
1794
|
+
console.log(chalk.green("✓ config/user-tabs.ts créé"));
|
|
1795
|
+
}
|
|
1796
|
+
|
|
1363
1797
|
// Créer les hooks
|
|
1364
1798
|
await createHooksDirectory(targetDir, force);
|
|
1365
1799
|
}
|
|
@@ -1666,10 +2100,10 @@ async function createSupabaseStructure(targetDir: string, force: boolean) {
|
|
|
1666
2100
|
)
|
|
1667
2101
|
);
|
|
1668
2102
|
}
|
|
1669
|
-
} catch (
|
|
2103
|
+
} catch (_error) {
|
|
1670
2104
|
console.error(
|
|
1671
2105
|
chalk.red("✗ Erreur lors de la création de la migration:"),
|
|
1672
|
-
|
|
2106
|
+
_error
|
|
1673
2107
|
);
|
|
1674
2108
|
}
|
|
1675
2109
|
} else {
|
|
@@ -1694,26 +2128,22 @@ async function addScriptsToPackageJson(targetDir: string) {
|
|
|
1694
2128
|
) ||
|
|
1695
2129
|
fs.existsSync(path.join(targetDir, "../../packages/core/package.json"));
|
|
1696
2130
|
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
scriptsPrefix = "node node_modules/@lastbrain/app/dist/cli.js";
|
|
1702
|
-
}
|
|
2131
|
+
// Utiliser le CLI depuis le monorepo si présent, sinon depuis node_modules
|
|
2132
|
+
const scriptsPrefix = targetIsInMonorepo
|
|
2133
|
+
? "node ../../packages/app/dist/cli.js"
|
|
2134
|
+
: "node node_modules/@lastbrain/app/dist/cli.js";
|
|
1703
2135
|
|
|
1704
2136
|
const scripts = {
|
|
1705
2137
|
predev: targetIsInMonorepo
|
|
1706
|
-
? "pnpm --filter @lastbrain/core build && pnpm --filter @lastbrain/ui build && pnpm --filter @lastbrain/module-auth build && pnpm --filter @lastbrain/module-ai build"
|
|
1707
|
-
: "echo 'No prebuild needed
|
|
2138
|
+
? "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"
|
|
2139
|
+
: "echo 'No prebuild needed'",
|
|
1708
2140
|
dev: "next dev",
|
|
1709
2141
|
"dev:local": "env-cmd -f .env.local next dev",
|
|
1710
2142
|
"dev:prod": "env-cmd -f .env.prod next dev",
|
|
1711
2143
|
build: "next build",
|
|
1712
2144
|
start: "next start",
|
|
1713
2145
|
lint: "next lint",
|
|
1714
|
-
lastbrain:
|
|
1715
|
-
? "lastbrain"
|
|
1716
|
-
: "node node_modules/@lastbrain/app/dist/cli.js",
|
|
2146
|
+
lastbrain: scriptsPrefix,
|
|
1717
2147
|
"build:modules": `${scriptsPrefix} module:build`,
|
|
1718
2148
|
"db:migrations:sync": `${scriptsPrefix} db:migrations:sync`,
|
|
1719
2149
|
"db:init": `${scriptsPrefix} db:init`,
|
|
@@ -237,7 +237,7 @@ export async function addModule(moduleName: string, targetDir: string) {
|
|
|
237
237
|
`✓ ${migrationFiles.length} migration(s) appliquée(s)`
|
|
238
238
|
)
|
|
239
239
|
);
|
|
240
|
-
} catch (
|
|
240
|
+
} catch (_error) {
|
|
241
241
|
console.error(
|
|
242
242
|
chalk.red("❌ Erreur lors de l'application des migrations")
|
|
243
243
|
);
|