@lastbrain/app 0.1.0
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/README.md +256 -0
- package/dist/app-shell/(admin)/dashboard/page.d.ts +2 -0
- package/dist/app-shell/(admin)/dashboard/page.d.ts.map +1 -0
- package/dist/app-shell/(admin)/dashboard/page.js +5 -0
- package/dist/app-shell/(admin)/layout.d.ts +3 -0
- package/dist/app-shell/(admin)/layout.d.ts.map +1 -0
- package/dist/app-shell/(admin)/layout.js +5 -0
- package/dist/app-shell/(admin)/page.d.ts +2 -0
- package/dist/app-shell/(admin)/page.d.ts.map +1 -0
- package/dist/app-shell/(admin)/page.js +5 -0
- package/dist/app-shell/(auth)/dashboard/page.d.ts +2 -0
- package/dist/app-shell/(auth)/dashboard/page.d.ts.map +1 -0
- package/dist/app-shell/(auth)/dashboard/page.js +5 -0
- package/dist/app-shell/(auth)/layout.d.ts +3 -0
- package/dist/app-shell/(auth)/layout.d.ts.map +1 -0
- package/dist/app-shell/(auth)/layout.js +5 -0
- package/dist/app-shell/(auth)/page.d.ts +2 -0
- package/dist/app-shell/(auth)/page.d.ts.map +1 -0
- package/dist/app-shell/(auth)/page.js +5 -0
- package/dist/app-shell/(public)/page.d.ts +2 -0
- package/dist/app-shell/(public)/page.d.ts.map +1 -0
- package/dist/app-shell/(public)/page.js +5 -0
- package/dist/app-shell/layout.d.ts +3 -0
- package/dist/app-shell/layout.d.ts.map +1 -0
- package/dist/app-shell/layout.js +3 -0
- package/dist/app-shell/not-found.d.ts +2 -0
- package/dist/app-shell/not-found.d.ts.map +1 -0
- package/dist/app-shell/not-found.js +10 -0
- package/dist/auth/authHelpers.d.ts +7 -0
- package/dist/auth/authHelpers.d.ts.map +1 -0
- package/dist/auth/authHelpers.js +19 -0
- package/dist/auth/useAuthSession.d.ts +7 -0
- package/dist/auth/useAuthSession.d.ts.map +1 -0
- package/dist/auth/useAuthSession.js +43 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +88 -0
- package/dist/components/TableStructure.d.ts +8 -0
- package/dist/components/TableStructure.d.ts.map +1 -0
- package/dist/components/TableStructure.js +37 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/layouts/AdminLayout.d.ts +3 -0
- package/dist/layouts/AdminLayout.d.ts.map +1 -0
- package/dist/layouts/AdminLayout.js +5 -0
- package/dist/layouts/AppProviders.d.ts +13 -0
- package/dist/layouts/AppProviders.d.ts.map +1 -0
- package/dist/layouts/AppProviders.js +35 -0
- package/dist/layouts/AuthLayout.d.ts +3 -0
- package/dist/layouts/AuthLayout.d.ts.map +1 -0
- package/dist/layouts/AuthLayout.js +5 -0
- package/dist/layouts/PublicLayout.d.ts +3 -0
- package/dist/layouts/PublicLayout.d.ts.map +1 -0
- package/dist/layouts/PublicLayout.js +5 -0
- package/dist/layouts/RootLayout.d.ts +3 -0
- package/dist/layouts/RootLayout.d.ts.map +1 -0
- package/dist/layouts/RootLayout.js +8 -0
- package/dist/module-build.d.ts +2 -0
- package/dist/module-build.d.ts.map +1 -0
- package/dist/module-build.js +50 -0
- package/dist/modules/index.d.ts +3 -0
- package/dist/modules/index.d.ts.map +1 -0
- package/dist/modules/index.js +2 -0
- package/dist/modules/module-loader.d.ts +5 -0
- package/dist/modules/module-loader.d.ts.map +1 -0
- package/dist/modules/module-loader.js +10 -0
- package/dist/scripts/db-init.d.ts +2 -0
- package/dist/scripts/db-init.d.ts.map +1 -0
- package/dist/scripts/db-init.js +281 -0
- package/dist/scripts/db-migrations-sync.d.ts +2 -0
- package/dist/scripts/db-migrations-sync.d.ts.map +1 -0
- package/dist/scripts/db-migrations-sync.js +55 -0
- package/dist/scripts/dev-sync.d.ts +2 -0
- package/dist/scripts/dev-sync.d.ts.map +1 -0
- package/dist/scripts/dev-sync.js +182 -0
- package/dist/scripts/init-app.d.ts +11 -0
- package/dist/scripts/init-app.d.ts.map +1 -0
- package/dist/scripts/init-app.js +846 -0
- package/dist/scripts/module-add.d.ts +13 -0
- package/dist/scripts/module-add.d.ts.map +1 -0
- package/dist/scripts/module-add.js +178 -0
- package/dist/scripts/module-build.d.ts +2 -0
- package/dist/scripts/module-build.d.ts.map +1 -0
- package/dist/scripts/module-build.js +413 -0
- package/dist/scripts/module-create.d.ts +5 -0
- package/dist/scripts/module-create.d.ts.map +1 -0
- package/dist/scripts/module-create.js +694 -0
- package/dist/scripts/module-list.d.ts +2 -0
- package/dist/scripts/module-list.d.ts.map +1 -0
- package/dist/scripts/module-list.js +31 -0
- package/dist/scripts/module-remove.d.ts +2 -0
- package/dist/scripts/module-remove.d.ts.map +1 -0
- package/dist/scripts/module-remove.js +282 -0
- package/dist/scripts/readme-build.d.ts +2 -0
- package/dist/scripts/readme-build.d.ts.map +1 -0
- package/dist/scripts/readme-build.js +39 -0
- package/dist/templates/AuthGuidePage.d.ts +2 -0
- package/dist/templates/AuthGuidePage.d.ts.map +1 -0
- package/dist/templates/AuthGuidePage.js +9 -0
- package/dist/templates/DefaultDoc.d.ts +2 -0
- package/dist/templates/DefaultDoc.d.ts.map +1 -0
- package/dist/templates/DefaultDoc.js +29 -0
- package/dist/templates/DocPage.d.ts +17 -0
- package/dist/templates/DocPage.d.ts.map +1 -0
- package/dist/templates/DocPage.js +165 -0
- package/dist/templates/DocsPageWithModules.d.ts +2 -0
- package/dist/templates/DocsPageWithModules.d.ts.map +1 -0
- package/dist/templates/DocsPageWithModules.js +8 -0
- package/dist/templates/HomePage.d.ts +6 -0
- package/dist/templates/HomePage.d.ts.map +1 -0
- package/dist/templates/HomePage.js +6 -0
- package/dist/templates/MigrationsGuidePage.d.ts +2 -0
- package/dist/templates/MigrationsGuidePage.d.ts.map +1 -0
- package/dist/templates/MigrationsGuidePage.js +11 -0
- package/dist/templates/ModuleGuidePage.d.ts +2 -0
- package/dist/templates/ModuleGuidePage.d.ts.map +1 -0
- package/dist/templates/ModuleGuidePage.js +14 -0
- package/dist/templates/SimpleDocPage.d.ts +2 -0
- package/dist/templates/SimpleDocPage.d.ts.map +1 -0
- package/dist/templates/SimpleDocPage.js +28 -0
- package/dist/templates/SimpleHomePage.d.ts +6 -0
- package/dist/templates/SimpleHomePage.d.ts.map +1 -0
- package/dist/templates/SimpleHomePage.js +7 -0
- package/dist/templates/env.example/.env.example +6 -0
- package/dist/templates/migrations/20201010100000_app_base.sql +228 -0
- package/dist/templates/migrations/20201010100000_init.sql +123 -0
- package/package.json +75 -0
- package/src/app-shell/(admin)/layout.tsx +13 -0
- package/src/app-shell/(auth)/layout.tsx +13 -0
- package/src/app-shell/(public)/page.tsx +11 -0
- package/src/app-shell/layout.tsx +5 -0
- package/src/app-shell/not-found.tsx +28 -0
- package/src/layouts/AdminLayout.tsx +7 -0
- package/src/layouts/AppProviders.tsx +61 -0
- package/src/layouts/AuthLayout.tsx +7 -0
- package/src/layouts/PublicLayout.tsx +7 -0
- package/src/layouts/RootLayout.tsx +27 -0
- package/src/scripts/README.md +262 -0
- package/src/scripts/db-init.ts +338 -0
- package/src/scripts/db-migrations-sync.ts +86 -0
- package/src/scripts/dev-sync.ts +218 -0
- package/src/scripts/init-app.ts +1011 -0
- package/src/scripts/module-add.ts +242 -0
- package/src/scripts/module-build.ts +502 -0
- package/src/scripts/module-create.ts +809 -0
- package/src/scripts/module-list.ts +37 -0
- package/src/scripts/module-remove.ts +367 -0
- package/src/scripts/readme-build.ts +60 -0
- package/src/templates/AuthGuidePage.tsx +68 -0
- package/src/templates/DefaultDoc.tsx +462 -0
- package/src/templates/DocPage.tsx +381 -0
- package/src/templates/DocsPageWithModules.tsx +22 -0
- package/src/templates/MigrationsGuidePage.tsx +61 -0
- package/src/templates/ModuleGuidePage.tsx +71 -0
- package/src/templates/SimpleDocPage.tsx +587 -0
- package/src/templates/SimpleHomePage.tsx +385 -0
- package/src/templates/env.example/.env.example +6 -0
- package/src/templates/migrations/20201010100000_app_base.sql +228 -0
package/README.md
ADDED
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
# @lastbrain/app
|
|
2
|
+
|
|
3
|
+
Package principal pour créer et gérer des applications Next.js LastBrain.
|
|
4
|
+
|
|
5
|
+
## 🎯 Vue d'ensemble
|
|
6
|
+
|
|
7
|
+
`@lastbrain/app` est le cœur de l'écosystème LastBrain. Il fournit :
|
|
8
|
+
|
|
9
|
+
- 🚀 **CLI `lastbrain`** - Créer une app Next.js complète en une commande
|
|
10
|
+
- 🧱 **Layouts & Providers** - Composants prêts à l'emploi pour structurer votre app
|
|
11
|
+
- 🔧 **Scripts utilitaires** - Gestion modules, migrations DB, génération docs
|
|
12
|
+
- 🎨 **Intégration Tailwind v4** - Configuration optimale out-of-the-box
|
|
13
|
+
|
|
14
|
+
## 📦 Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pnpm add @lastbrain/app @lastbrain/core @lastbrain/ui
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## 🚀 Démarrage rapide
|
|
21
|
+
|
|
22
|
+
### 1. Créer une nouvelle application
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pnpm lastbrain init
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Cette commande génère une application Next.js complète avec :
|
|
29
|
+
|
|
30
|
+
- Structure de routes (`(public)`, `(auth)`, `(admin)`)
|
|
31
|
+
- Layouts et providers configurés
|
|
32
|
+
- Tailwind CSS v4 + next-themes
|
|
33
|
+
- Configuration TypeScript
|
|
34
|
+
- Scripts NPM utilitaires
|
|
35
|
+
|
|
36
|
+
### 2. Installer et démarrer
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
pnpm install
|
|
40
|
+
pnpm db:init # Initialiser Supabase local (optionnel)
|
|
41
|
+
pnpm build:modules # Générer les routes des modules
|
|
42
|
+
pnpm dev # Lancer le serveur
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
🎉 Votre app est prête sur `http://localhost:3000`
|
|
46
|
+
|
|
47
|
+
## 📚 Documentation
|
|
48
|
+
|
|
49
|
+
- **[Guide CLI complet](./CLI.md)** - Toutes les commandes et options
|
|
50
|
+
- **[Architecture](./ARCHITECTURE.md)** - Comment fonctionne @lastbrain/app
|
|
51
|
+
- **[Créer un module](./MODULE_GUIDE.md)** - Développer vos propres modules
|
|
52
|
+
|
|
53
|
+
## 🧩 Composants exportés
|
|
54
|
+
|
|
55
|
+
### Layouts
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
import {
|
|
59
|
+
RootLayout, // Layout racine avec ThemeProvider
|
|
60
|
+
PublicLayout, // Layout pour pages publiques
|
|
61
|
+
AuthLayout, // Layout pour pages d'authentification
|
|
62
|
+
AdminLayout, // Layout pour pages d'administration
|
|
63
|
+
} from "@lastbrain/app";
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Providers
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
import { AppProviders } from "@lastbrain/app";
|
|
70
|
+
|
|
71
|
+
// Inclut :
|
|
72
|
+
// - AuthProvider (Supabase)
|
|
73
|
+
// - ModulesProvider
|
|
74
|
+
// - NotificationsProvider
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Hooks
|
|
78
|
+
|
|
79
|
+
```tsx
|
|
80
|
+
import {
|
|
81
|
+
useAuth, // Accès au contexte d'authentification
|
|
82
|
+
useModules, // Accès aux modules installés
|
|
83
|
+
useNotifications, // Système de notifications
|
|
84
|
+
} from "@lastbrain/app";
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## 🔧 Scripts disponibles
|
|
88
|
+
|
|
89
|
+
Ces scripts sont exécutés via `@lastbrain/app` :
|
|
90
|
+
|
|
91
|
+
### `pnpm build:modules`
|
|
92
|
+
|
|
93
|
+
Analyse tous les modules installés et génère :
|
|
94
|
+
|
|
95
|
+
- Routes API automatiques
|
|
96
|
+
- Pages de navigation
|
|
97
|
+
- Fichiers de types TypeScript
|
|
98
|
+
|
|
99
|
+
### `pnpm db:init`
|
|
100
|
+
|
|
101
|
+
Initialise Supabase local :
|
|
102
|
+
|
|
103
|
+
- Lance `supabase start`
|
|
104
|
+
- Génère `.env.local` avec les clés
|
|
105
|
+
- Affiche le statut
|
|
106
|
+
|
|
107
|
+
### `pnpm db:migrations:sync`
|
|
108
|
+
|
|
109
|
+
Synchronise les migrations de tous les modules vers Supabase local.
|
|
110
|
+
|
|
111
|
+
### `pnpm readme:create`
|
|
112
|
+
|
|
113
|
+
Génère automatiquement la documentation du projet basée sur les modules installés.
|
|
114
|
+
|
|
115
|
+
## 🎨 Structure d'une application générée
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
votre-app/
|
|
119
|
+
├── app/
|
|
120
|
+
│ ├── layout.tsx # RootLayout + ThemeProvider
|
|
121
|
+
│ ├── (public)/
|
|
122
|
+
│ │ ├── layout.tsx # PublicLayout
|
|
123
|
+
│ │ └── page.tsx
|
|
124
|
+
│ ├── (auth)/
|
|
125
|
+
│ │ ├── layout.tsx # AuthLayout
|
|
126
|
+
│ │ └── page.tsx
|
|
127
|
+
│ └── (admin)/
|
|
128
|
+
│ ├── layout.tsx # AdminLayout
|
|
129
|
+
│ └── page.tsx
|
|
130
|
+
├── styles/
|
|
131
|
+
│ └── globals.css
|
|
132
|
+
├── next.config.mjs
|
|
133
|
+
├── tailwind.config.js
|
|
134
|
+
├── postcss.config.mjs
|
|
135
|
+
├── tsconfig.json
|
|
136
|
+
└── package.json
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## 🔌 Intégration avec les modules
|
|
140
|
+
|
|
141
|
+
Les modules LastBrain (comme `@lastbrain/module-auth`) s'intègrent automatiquement :
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
# 1. Installer un module
|
|
145
|
+
pnpm add @lastbrain/module-auth
|
|
146
|
+
|
|
147
|
+
# 2. Générer les routes
|
|
148
|
+
pnpm build:modules
|
|
149
|
+
|
|
150
|
+
# 3. Les pages sont créées automatiquement !
|
|
151
|
+
# → /signin, /signup, etc.
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## 🌐 Configuration Tailwind v4
|
|
155
|
+
|
|
156
|
+
L'app générée utilise Tailwind CSS v4 avec la nouvelle syntaxe :
|
|
157
|
+
|
|
158
|
+
```css
|
|
159
|
+
/* styles/globals.css */
|
|
160
|
+
@import "tailwindcss";
|
|
161
|
+
@config "../tailwind.config.js";
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
```js
|
|
165
|
+
// tailwind.config.js
|
|
166
|
+
module.exports = {
|
|
167
|
+
content: [
|
|
168
|
+
"./app/**/*.{js,ts,jsx,tsx}",
|
|
169
|
+
"./node_modules/@lastbrain/ui/**/*.{js,ts,jsx,tsx}",
|
|
170
|
+
],
|
|
171
|
+
theme: {
|
|
172
|
+
extend: {
|
|
173
|
+
colors: {
|
|
174
|
+
primary: {
|
|
175
|
+
/* ... */
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
};
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## 🎭 Thème sombre
|
|
184
|
+
|
|
185
|
+
Le thème sombre est activé par défaut via `next-themes` :
|
|
186
|
+
|
|
187
|
+
```tsx
|
|
188
|
+
import { ThemeSwitcher } from "@lastbrain/ui";
|
|
189
|
+
|
|
190
|
+
// Ajouter dans votre header
|
|
191
|
+
<ThemeSwitcher />;
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Les classes Tailwind `dark:` fonctionnent automatiquement :
|
|
195
|
+
|
|
196
|
+
```tsx
|
|
197
|
+
<div className="bg-white dark:bg-slate-900">
|
|
198
|
+
<h1 className="text-slate-900 dark:text-white">Hello LastBrain</h1>
|
|
199
|
+
</div>
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## 🔐 Authentification
|
|
203
|
+
|
|
204
|
+
Avec `@lastbrain/module-auth` installé :
|
|
205
|
+
|
|
206
|
+
```tsx
|
|
207
|
+
import { useAuth } from "@lastbrain/app";
|
|
208
|
+
|
|
209
|
+
function MyComponent() {
|
|
210
|
+
const { user, signOut } = useAuth();
|
|
211
|
+
|
|
212
|
+
if (!user) {
|
|
213
|
+
return <div>Non connecté</div>;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return (
|
|
217
|
+
<div>
|
|
218
|
+
<p>Bonjour {user.email}</p>
|
|
219
|
+
<button onClick={signOut}>Déconnexion</button>
|
|
220
|
+
</div>
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## 📦 Publier votre application
|
|
226
|
+
|
|
227
|
+
Une fois votre app prête :
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
# Build de production
|
|
231
|
+
pnpm build
|
|
232
|
+
|
|
233
|
+
# Démarrer en production
|
|
234
|
+
pnpm start
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Pour déployer sur Vercel :
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
vercel
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## 🤝 Contribuer
|
|
244
|
+
|
|
245
|
+
Ce package fait partie du monorepo LastBrain. Voir le [CONTRIBUTING.md](../../CONTRIBUTING.md) principal.
|
|
246
|
+
|
|
247
|
+
## 📄 Licence
|
|
248
|
+
|
|
249
|
+
MIT - Voir [LICENSE](../../LICENSE)
|
|
250
|
+
|
|
251
|
+
## 🔗 Liens utiles
|
|
252
|
+
|
|
253
|
+
- [Documentation Next.js](https://nextjs.org/docs)
|
|
254
|
+
- [Tailwind CSS v4](https://tailwindcss.com/docs)
|
|
255
|
+
- [Supabase](https://supabase.com/docs)
|
|
256
|
+
- [next-themes](https://github.com/pacocoursey/next-themes)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../../src/app-shell/(admin)/dashboard/page.tsx"],"names":[],"mappings":"AAEA,MAAM,CAAC,OAAO,UAAU,kBAAkB,4CAOzC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
export default function AdminDashboardPage() {
|
|
4
|
+
return (_jsxs("div", { className: "mx-auto max-w-4xl space-y-3 px-4 py-16", children: [_jsx("h1", { className: "text-3xl font-bold", children: "Administration" }), _jsx("p", { className: "text-slate-600", children: "Gestion des modules et des utilisateurs." })] }));
|
|
5
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../src/app-shell/(admin)/layout.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAE/C,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EAAE,QAAQ,EAAE,EAAE,iBAAiB,CAAC,EAAE,CAAC,2CAQ3E"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
export default function AdminShellLayout({ children }) {
|
|
4
|
+
return (_jsxs("div", { className: "mx-auto max-w-5xl px-4 py-16", children: [_jsx("h1", { className: "text-3xl font-bold", children: "Section Admin" }), _jsx("p", { className: "text-slate-600", children: "Gestion avanc\u00E9e des modules." }), children] }));
|
|
5
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../src/app-shell/(admin)/page.tsx"],"names":[],"mappings":"AAEA,MAAM,CAAC,OAAO,UAAU,kBAAkB,4CAOzC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
export default function AdminDashboardPage() {
|
|
4
|
+
return (_jsxs("div", { className: "mx-auto max-w-4xl space-y-3 px-4 py-16", children: [_jsx("h1", { className: "text-3xl font-bold", children: "Administration" }), _jsx("p", { className: "text-slate-600", children: "Gestion des modules et des utilisateurs." })] }));
|
|
5
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../../src/app-shell/(auth)/dashboard/page.tsx"],"names":[],"mappings":"AAEA,MAAM,CAAC,OAAO,UAAU,iBAAiB,4CAOxC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
export default function AuthDashboardPage() {
|
|
4
|
+
return (_jsxs("div", { className: "mx-auto max-w-4xl space-y-3 px-4 py-16", children: [_jsx("h1", { className: "text-3xl font-bold", children: "Tableau de bord" }), _jsx("p", { className: "text-slate-600", children: "Bienvenue utilisateur \u2014 votre session est active." })] }));
|
|
5
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../src/app-shell/(auth)/layout.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAE/C,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,EAAE,QAAQ,EAAE,EAAE,iBAAiB,CAAC,EAAE,CAAC,2CAQrE"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
export default function AuthLayout({ children }) {
|
|
4
|
+
return (_jsxs("div", { className: "mx-auto max-w-5xl px-4 py-16", children: [_jsx("h1", { className: "text-3xl font-bold", children: "Section Auth" }), _jsx("p", { className: "text-slate-600", children: "Les pages authentifi\u00E9es regroup\u00E9es ici." }), children] }));
|
|
5
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../src/app-shell/(auth)/page.tsx"],"names":[],"mappings":"AAEA,MAAM,CAAC,OAAO,UAAU,iBAAiB,4CAOxC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
export default function AuthDashboardPage() {
|
|
4
|
+
return (_jsxs("div", { className: "mx-auto max-w-4xl space-y-3 px-4 py-16", children: [_jsx("h1", { className: "text-3xl font-bold", children: "Tableau de bord" }), _jsx("p", { className: "text-slate-600", children: "Bienvenue utilisateur \u2014 votre session est active." })] }));
|
|
5
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../src/app-shell/(public)/page.tsx"],"names":[],"mappings":"AAEA,MAAM,CAAC,OAAO,UAAU,UAAU,4CAQjC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
export default function PublicPage() {
|
|
4
|
+
return (_jsxs("div", { className: "mx-auto max-w-3xl space-y-4 px-4 py-16 text-center", children: [_jsx("h1", { className: "text-3xl font-bold", children: "Bienvenue sur LastBrain" }), _jsx("p", { className: "text-slate-600", children: "Cette coquille publique pr\u00E9sente la structure par d\u00E9faut." }), _jsx("button", { className: "rounded-full bg-slate-900 px-5 py-2 text-white", children: "Connexion" })] }));
|
|
5
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../src/app-shell/layout.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEtD,eAAe,UAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"not-found.d.ts","sourceRoot":"","sources":["../../src/app-shell/not-found.tsx"],"names":[],"mappings":"AAIA,MAAM,CAAC,OAAO,UAAU,QAAQ,4CAuB/B"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Button } from "@lastbrain/ui";
|
|
4
|
+
import { useRouter } from "next/navigation";
|
|
5
|
+
export default function NotFound() {
|
|
6
|
+
const router = useRouter();
|
|
7
|
+
return (_jsx("div", { className: "flex min-h-screen items-center justify-center bg-background", children: _jsxs("div", { className: "mx-auto max-w-md text-center", children: [_jsx("h1", { className: "mb-4 text-6xl font-bold text-foreground", children: "404" }), _jsx("h2", { className: "mb-4 text-2xl font-semibold text-foreground", children: "Page non trouv\u00E9e" }), _jsx("p", { className: "mb-8 text-muted-foreground", children: "La page que vous recherchez n'existe pas ou a \u00E9t\u00E9 d\u00E9plac\u00E9e." }), _jsx(Button, { onPress: () => {
|
|
8
|
+
router.back();
|
|
9
|
+
}, className: "inline-flex items-center justify-center rounded-md bg-primary px-6 py-3 text-sm font-medium text-primary-foreground transition-colors hover:bg-primary/90", children: "Retour \u00E0 l'accueil" })] }) }));
|
|
10
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare function signOut(): Promise<void>;
|
|
2
|
+
export declare function signIn(email: string, password: string): Promise<{
|
|
3
|
+
user: import("@supabase/supabase-js").AuthUser;
|
|
4
|
+
session: import("@supabase/supabase-js").AuthSession;
|
|
5
|
+
weakPassword?: import("@supabase/supabase-js").WeakPassword;
|
|
6
|
+
}>;
|
|
7
|
+
//# sourceMappingURL=authHelpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authHelpers.d.ts","sourceRoot":"","sources":["../../src/auth/authHelpers.ts"],"names":[],"mappings":"AAIA,wBAAsB,OAAO,kBAM5B;AAED,wBAAsB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;;;;GAW3D"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { supabaseBrowserClient } from "@lastbrain/core";
|
|
3
|
+
export async function signOut() {
|
|
4
|
+
const { error } = await supabaseBrowserClient.auth.signOut();
|
|
5
|
+
if (error) {
|
|
6
|
+
console.error("Error signing out:", error);
|
|
7
|
+
throw error;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export async function signIn(email, password) {
|
|
11
|
+
const { data, error } = await supabaseBrowserClient.auth.signInWithPassword({
|
|
12
|
+
email,
|
|
13
|
+
password,
|
|
14
|
+
});
|
|
15
|
+
if (error) {
|
|
16
|
+
throw error;
|
|
17
|
+
}
|
|
18
|
+
return data;
|
|
19
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAuthSession.d.ts","sourceRoot":"","sources":["../../src/auth/useAuthSession.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAElD,wBAAgB,cAAc;;;;EA+C7B"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
import { supabaseBrowserClient } from "@lastbrain/core";
|
|
4
|
+
export function useAuthSession() {
|
|
5
|
+
const [user, setUser] = useState(null);
|
|
6
|
+
const [loading, setLoading] = useState(true);
|
|
7
|
+
const [isSuperAdmin, setIsSuperAdmin] = useState(false);
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
const checkSuperAdmin = async (userId) => {
|
|
10
|
+
try {
|
|
11
|
+
const { data, error } = await supabaseBrowserClient.rpc("is_superadmin", { user_id: userId });
|
|
12
|
+
if (!error && data) {
|
|
13
|
+
setIsSuperAdmin(data);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
console.error("Error checking superadmin status:", error);
|
|
18
|
+
setIsSuperAdmin(false);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
// Récupérer la session initiale
|
|
22
|
+
supabaseBrowserClient.auth.getSession().then(({ data: { session } }) => {
|
|
23
|
+
setUser(session?.user ?? null);
|
|
24
|
+
if (session?.user) {
|
|
25
|
+
checkSuperAdmin(session.user.id);
|
|
26
|
+
}
|
|
27
|
+
setLoading(false);
|
|
28
|
+
});
|
|
29
|
+
// Écouter les changements d'auth
|
|
30
|
+
const { data: { subscription }, } = supabaseBrowserClient.auth.onAuthStateChange((_event, session) => {
|
|
31
|
+
setUser(session?.user ?? null);
|
|
32
|
+
if (session?.user) {
|
|
33
|
+
checkSuperAdmin(session.user.id);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
setIsSuperAdmin(false);
|
|
37
|
+
}
|
|
38
|
+
setLoading(false);
|
|
39
|
+
});
|
|
40
|
+
return () => subscription.unsubscribe();
|
|
41
|
+
}, []);
|
|
42
|
+
return { user, loading, isSuperAdmin };
|
|
43
|
+
}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { initApp } from "./scripts/init-app.js";
|
|
5
|
+
import { addModule } from "./scripts/module-add.js";
|
|
6
|
+
import { removeModule } from "./scripts/module-remove.js";
|
|
7
|
+
import { listModules } from "./scripts/module-list.js";
|
|
8
|
+
import { createModule } from "./scripts/module-create.js";
|
|
9
|
+
const program = new Command();
|
|
10
|
+
program
|
|
11
|
+
.name("lastbrain")
|
|
12
|
+
.description("CLI pour créer et gérer des applications LastBrain")
|
|
13
|
+
.version("0.1.0");
|
|
14
|
+
program
|
|
15
|
+
.command("init [directory]")
|
|
16
|
+
.description("Initialise une nouvelle application Next.js LastBrain")
|
|
17
|
+
.option("-f, --force", "Écrase les fichiers existants")
|
|
18
|
+
.option("--heroui", "Utiliser HeroUI comme bibliothèque de composants")
|
|
19
|
+
.option("--with-auth", "Inclure le module d'authentification")
|
|
20
|
+
.option("--no-interactive", "Mode non-interactif (skip la sélection des modules)")
|
|
21
|
+
.action(async (directory, options) => {
|
|
22
|
+
try {
|
|
23
|
+
const targetDir = directory
|
|
24
|
+
? path.resolve(process.cwd(), directory)
|
|
25
|
+
: process.cwd();
|
|
26
|
+
await initApp({
|
|
27
|
+
force: options.force || false,
|
|
28
|
+
targetDir,
|
|
29
|
+
projectName: directory || path.basename(process.cwd()),
|
|
30
|
+
useHeroUI: options.heroui || false,
|
|
31
|
+
withAuth: options.withAuth || false,
|
|
32
|
+
interactive: options.interactive !== false,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
console.error("❌ Erreur lors de l'initialisation:", error);
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
program
|
|
41
|
+
.command("add-module <module>")
|
|
42
|
+
.description("Ajoute un module à l'application")
|
|
43
|
+
.action(async (moduleName) => {
|
|
44
|
+
try {
|
|
45
|
+
await addModule(moduleName, process.cwd());
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
console.error("❌ Erreur lors de l'ajout du module:", error);
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
program
|
|
53
|
+
.command("remove-module <module>")
|
|
54
|
+
.description("Supprime un module de l'application")
|
|
55
|
+
.action(async (moduleName) => {
|
|
56
|
+
try {
|
|
57
|
+
await removeModule(moduleName, process.cwd());
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
console.error("❌ Erreur lors de la suppression du module:", error);
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
program
|
|
65
|
+
.command("list-modules")
|
|
66
|
+
.description("Liste les modules disponibles et installés")
|
|
67
|
+
.action(async () => {
|
|
68
|
+
try {
|
|
69
|
+
await listModules(process.cwd());
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
console.error("❌ Erreur lors de la liste des modules:", error);
|
|
73
|
+
process.exit(1);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
program
|
|
77
|
+
.command("create-module")
|
|
78
|
+
.description("Crée un nouveau module dans packages/")
|
|
79
|
+
.action(async () => {
|
|
80
|
+
try {
|
|
81
|
+
await createModule();
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
console.error("❌ Erreur lors de la création du module:", error);
|
|
85
|
+
process.exit(1);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
program.parse();
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
interface TableStructureProps {
|
|
2
|
+
tableName: string;
|
|
3
|
+
title?: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function TableStructure({ tableName, title, description, }: TableStructureProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=TableStructure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TableStructure.d.ts","sourceRoot":"","sources":["../../src/components/TableStructure.tsx"],"names":[],"mappings":"AA6BA,UAAU,mBAAmB;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,cAAc,CAAC,EAC7B,SAAS,EACT,KAAK,EACL,WAAW,GACZ,EAAE,mBAAmB,2CAgIrB"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import { Card, CardBody, CardHeader, Table, TableHeader, TableColumn, TableBody, TableRow, TableCell, Chip, Spinner, } from "@lastbrain/ui";
|
|
5
|
+
import { createBrowserClient } from "@supabase/ssr";
|
|
6
|
+
export function TableStructure({ tableName, title, description, }) {
|
|
7
|
+
const [columns, setColumns] = useState([]);
|
|
8
|
+
const [loading, setLoading] = useState(true);
|
|
9
|
+
const [error, setError] = useState(null);
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
const fetchStructure = async () => {
|
|
12
|
+
try {
|
|
13
|
+
const supabase = createBrowserClient(process.env.NEXT_PUBLIC_SUPABASE_URL, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY);
|
|
14
|
+
const { data, error } = await supabase.rpc("get_table_structure", {
|
|
15
|
+
table_name: tableName,
|
|
16
|
+
});
|
|
17
|
+
if (error)
|
|
18
|
+
throw error;
|
|
19
|
+
setColumns(data || []);
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
setError(err instanceof Error ? err.message : "Erreur lors du chargement");
|
|
23
|
+
}
|
|
24
|
+
finally {
|
|
25
|
+
setLoading(false);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
fetchStructure();
|
|
29
|
+
}, [tableName]);
|
|
30
|
+
if (loading) {
|
|
31
|
+
return (_jsx(Card, { children: _jsx(CardBody, { className: "flex justify-center items-center py-8", children: _jsx(Spinner, { size: "lg" }) }) }));
|
|
32
|
+
}
|
|
33
|
+
if (error) {
|
|
34
|
+
return (_jsx(Card, { children: _jsx(CardBody, { children: _jsxs("p", { className: "text-red-500", children: ["Erreur: ", error] }) }) }));
|
|
35
|
+
}
|
|
36
|
+
return (_jsxs(Card, { children: [_jsx(CardHeader, { children: _jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("h3", { className: "text-lg font-semibold", children: title || `Table: ${tableName}` }), description && (_jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400", children: description }))] }) }), _jsx(CardBody, { children: _jsxs(Table, { "aria-label": `Structure de la table ${tableName}`, children: [_jsxs(TableHeader, { children: [_jsx(TableColumn, { children: "COLONNE" }), _jsx(TableColumn, { children: "TYPE" }), _jsx(TableColumn, { children: "NULLABLE" }), _jsx(TableColumn, { children: "CONTRAINTES" }), _jsx(TableColumn, { children: "RELATION" })] }), _jsx(TableBody, { children: columns.map((col) => (_jsxs(TableRow, { children: [_jsx(TableCell, { children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("code", { className: "font-mono text-sm", children: col.column_name }), col.is_primary_key && (_jsx(Chip, { size: "sm", color: "primary", variant: "flat", children: "PK" }))] }) }), _jsx(TableCell, { children: _jsx("code", { className: "font-mono text-sm text-purple-600 dark:text-purple-400", children: col.data_type }) }), _jsx(TableCell, { children: _jsx(Chip, { size: "sm", color: col.is_nullable === "YES" ? "warning" : "success", variant: "flat", children: col.is_nullable === "YES" ? "NULL" : "NOT NULL" }) }), _jsx(TableCell, { children: col.column_default && (_jsxs(Chip, { size: "sm", variant: "flat", children: ["default: ", col.column_default.substring(0, 30), col.column_default.length > 30 ? "..." : ""] })) }), _jsx(TableCell, { children: col.is_foreign_key && col.foreign_table && (_jsxs("div", { className: "flex items-center gap-1", children: [_jsx(Chip, { size: "sm", color: "secondary", variant: "flat", children: "FK" }), _jsxs("code", { className: "font-mono text-xs", children: ["\u2192 ", col.foreign_table, ".", col.foreign_column] })] })) })] }, col.column_name))) })] }) })] }));
|
|
37
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export { AppProviders, useAuth, useModules, useNotifications, } from "./layouts/AppProviders.js";
|
|
2
|
+
export { useAuthSession } from "./auth/useAuthSession.js";
|
|
3
|
+
export { signOut, signIn } from "./auth/authHelpers.js";
|
|
4
|
+
export { RootLayout } from "./layouts/RootLayout.js";
|
|
5
|
+
export { PublicLayout } from "./layouts/PublicLayout.js";
|
|
6
|
+
export { AuthLayout } from "./layouts/AuthLayout.js";
|
|
7
|
+
export { AdminLayout } from "./layouts/AdminLayout.js";
|
|
8
|
+
export { getModuleConfigs } from "./modules/module-loader.js";
|
|
9
|
+
export { SimpleHomePage } from "./templates/SimpleHomePage.js";
|
|
10
|
+
export { DocPage } from "./templates/DocPage.js";
|
|
11
|
+
export { SimpleDocPage } from "./templates/SimpleDocPage.js";
|
|
12
|
+
export { ModuleGuidePage } from "./templates/ModuleGuidePage.js";
|
|
13
|
+
export { AuthGuidePage } from "./templates/AuthGuidePage.js";
|
|
14
|
+
export { MigrationsGuidePage } from "./templates/MigrationsGuidePage.js";
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|