@lastbrain/app 0.1.34 → 0.1.37
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 +23 -5
- package/dist/__tests__/module-registry.test.js +5 -16
- package/dist/scripts/init-app.d.ts.map +1 -1
- package/dist/scripts/init-app.js +2 -2
- package/dist/scripts/module-add.d.ts +0 -11
- package/dist/scripts/module-add.d.ts.map +1 -1
- package/dist/scripts/module-add.js +45 -22
- package/dist/scripts/module-build.d.ts.map +1 -1
- package/dist/scripts/module-build.js +90 -1
- package/dist/scripts/module-create.d.ts +23 -0
- package/dist/scripts/module-create.d.ts.map +1 -1
- package/dist/scripts/module-create.js +737 -52
- package/dist/scripts/module-delete.d.ts +6 -0
- package/dist/scripts/module-delete.d.ts.map +1 -0
- package/dist/scripts/module-delete.js +143 -0
- package/dist/scripts/module-list.d.ts.map +1 -1
- package/dist/scripts/module-list.js +2 -2
- package/dist/scripts/module-remove.d.ts.map +1 -1
- package/dist/scripts/module-remove.js +20 -4
- package/dist/styles.css +1 -1
- package/dist/templates/DefaultDoc.d.ts.map +1 -1
- package/dist/templates/DefaultDoc.js +170 -30
- package/dist/templates/DocPage.d.ts.map +1 -1
- package/dist/templates/DocPage.js +25 -8
- package/dist/templates/migrations/20201010100000_app_base.sql +23 -24
- package/package.json +4 -4
- package/src/__tests__/module-registry.test.ts +5 -17
- package/src/scripts/db-init.ts +2 -2
- package/src/scripts/init-app.ts +5 -2
- package/src/scripts/module-add.ts +55 -23
- package/src/scripts/module-build.ts +109 -1
- package/src/scripts/module-create.ts +885 -63
- package/src/scripts/module-delete.ts +202 -0
- package/src/scripts/module-list.ts +9 -2
- package/src/scripts/module-remove.ts +36 -4
- package/src/templates/DefaultDoc.tsx +1163 -753
- package/src/templates/DocPage.tsx +28 -11
- package/src/templates/migrations/20201010100000_app_base.sql +23 -24
|
@@ -1,14 +1,20 @@
|
|
|
1
|
+
// GENERATED FILE - DO NOT EDIT MANUALLY
|
|
2
|
+
// This file is auto-generated from markdown files in docs/
|
|
3
|
+
// Run 'pnpm sync:docs' to regenerate
|
|
1
4
|
import React from "react";
|
|
2
|
-
import { Card, CardBody, CardHeader,
|
|
5
|
+
import { Card, CardBody, CardHeader, Snippet, Alert } from "@lastbrain/ui";
|
|
3
6
|
import {
|
|
7
|
+
FileText,
|
|
4
8
|
Rocket,
|
|
5
9
|
Building2,
|
|
6
10
|
BookOpen,
|
|
7
11
|
Database,
|
|
8
|
-
|
|
9
|
-
Link as LinkIcon,
|
|
12
|
+
User,
|
|
10
13
|
Shield,
|
|
11
14
|
Zap,
|
|
15
|
+
Palette,
|
|
16
|
+
HardDrive,
|
|
17
|
+
Link,
|
|
12
18
|
} from "lucide-react";
|
|
13
19
|
|
|
14
20
|
export function DefaultDocumentation() {
|
|
@@ -16,20 +22,23 @@ export function DefaultDocumentation() {
|
|
|
16
22
|
<div className="space-y-6">
|
|
17
23
|
<Card id="section-welcome" className="scroll-mt-32">
|
|
18
24
|
<CardHeader>
|
|
19
|
-
<
|
|
20
|
-
<
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
</Chip>
|
|
24
|
-
</div>
|
|
25
|
+
<h2 className="text-2xl font-semibold flex items-center gap-2">
|
|
26
|
+
<FileText size={24} />
|
|
27
|
+
Documentation LastBrain
|
|
28
|
+
</h2>
|
|
25
29
|
</CardHeader>
|
|
26
|
-
<CardBody className="space-y-
|
|
27
|
-
<
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
<CardBody className="space-y-4">
|
|
31
|
+
<p className="text-slate-600 dark:text-slate-400">
|
|
32
|
+
Framework modulaire pour créer rapidement des applications Next.js
|
|
33
|
+
avec système de modules, authentification et base de données.
|
|
34
|
+
</p>
|
|
35
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
36
|
+
LastBrain est un framework modulaire pour créer des applications
|
|
37
|
+
Next.js avec une architecture basée sur des modules réutilisables.
|
|
38
|
+
</p>
|
|
39
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
40
|
+
<strong>Version:</strong> v1.0.0
|
|
41
|
+
</p>
|
|
33
42
|
</CardBody>
|
|
34
43
|
</Card>
|
|
35
44
|
|
|
@@ -41,65 +50,173 @@ export function DefaultDocumentation() {
|
|
|
41
50
|
</h2>
|
|
42
51
|
</CardHeader>
|
|
43
52
|
<CardBody className="space-y-4">
|
|
44
|
-
<
|
|
45
|
-
<
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
<
|
|
53
|
-
|
|
54
|
-
</
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
<
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
53
|
+
<p className="text-slate-600 dark:text-slate-400">
|
|
54
|
+
<strong>Note importante :</strong> LastBrain est un écosystème de
|
|
55
|
+
packages interconnectés. L'application générée utilise
|
|
56
|
+
automatiquement{" "}
|
|
57
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
58
|
+
@lastbrain/core
|
|
59
|
+
</code>
|
|
60
|
+
,{" "}
|
|
61
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
62
|
+
@lastbrain/ui
|
|
63
|
+
</code>
|
|
64
|
+
, et les modules comme{" "}
|
|
65
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
66
|
+
@lastbrain/module-auth
|
|
67
|
+
</code>{" "}
|
|
68
|
+
et{" "}
|
|
69
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
70
|
+
@lastbrain/module-ai
|
|
71
|
+
</code>
|
|
72
|
+
. Tous ces packages sont nécessaires pour le bon fonctionnement.
|
|
73
|
+
</p>
|
|
74
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
75
|
+
{`# 1. Créer une nouvelle application (utilise @latest pour la version la plus récente)`}
|
|
76
|
+
</Snippet>
|
|
77
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
78
|
+
{`pnpx @lastbrain/app@latest init mon-app`}
|
|
79
|
+
</Snippet>
|
|
80
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
81
|
+
{`# 2. Accéder au dossier`}
|
|
82
|
+
</Snippet>
|
|
83
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
84
|
+
{`cd mon-app`}
|
|
85
|
+
</Snippet>
|
|
86
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
87
|
+
{`# 3. Initialiser Supabase`}
|
|
88
|
+
</Snippet>
|
|
89
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
90
|
+
{`pnpm db:init`}
|
|
91
|
+
</Snippet>
|
|
92
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
93
|
+
{`# 4. Démarrer l'application`}
|
|
94
|
+
</Snippet>
|
|
95
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
96
|
+
{`pnpm dev`}
|
|
97
|
+
</Snippet>
|
|
98
|
+
<h3 className="text-lg font-semibold mb-2">
|
|
99
|
+
Explication de la commande
|
|
100
|
+
</h3>
|
|
101
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
102
|
+
{`pnpx @lastbrain/app@latest init mon-app`}
|
|
103
|
+
</Snippet>
|
|
104
|
+
<div className="space-y-2">
|
|
105
|
+
<div className="flex items-start gap-2">
|
|
106
|
+
<span className="text-green-600">✅</span>
|
|
107
|
+
<span>
|
|
108
|
+
<strong>
|
|
109
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
110
|
+
pnpx
|
|
111
|
+
</code>
|
|
112
|
+
</strong>{" "}
|
|
113
|
+
: Exécute un package npm sans l'installer globalement
|
|
114
|
+
</span>
|
|
115
|
+
</div>
|
|
116
|
+
<div className="flex items-start gap-2">
|
|
117
|
+
<span className="text-green-600">✅</span>
|
|
118
|
+
<span>
|
|
119
|
+
<strong>
|
|
120
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
121
|
+
@lastbrain/app@latest
|
|
122
|
+
</code>
|
|
123
|
+
</strong>{" "}
|
|
124
|
+
: Package CLI de LastBrain en version la plus récente
|
|
125
|
+
</span>
|
|
126
|
+
</div>
|
|
127
|
+
<div className="flex items-start gap-2">
|
|
128
|
+
<span className="text-green-600">✅</span>
|
|
129
|
+
<span>
|
|
130
|
+
<strong>
|
|
131
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
132
|
+
init
|
|
133
|
+
</code>
|
|
134
|
+
</strong>{" "}
|
|
135
|
+
: Commande pour initialiser une nouvelle application
|
|
136
|
+
</span>
|
|
137
|
+
</div>
|
|
138
|
+
<div className="flex items-start gap-2">
|
|
139
|
+
<span className="text-green-600">✅</span>
|
|
140
|
+
<span>
|
|
141
|
+
<strong>
|
|
142
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
143
|
+
mon-app
|
|
144
|
+
</code>
|
|
145
|
+
</strong>{" "}
|
|
146
|
+
: Nom du dossier de votre application
|
|
147
|
+
</span>
|
|
148
|
+
</div>
|
|
87
149
|
</div>
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
</
|
|
96
|
-
<
|
|
97
|
-
|
|
98
|
-
<
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
150
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
151
|
+
Cette commande va :
|
|
152
|
+
</p>
|
|
153
|
+
<div className="space-y-2">
|
|
154
|
+
<div className="flex items-start gap-2">
|
|
155
|
+
<span className="text-green-600">✅</span>
|
|
156
|
+
<span>Créer la structure Next.js complète</span>
|
|
157
|
+
</div>
|
|
158
|
+
<div className="flex items-start gap-2">
|
|
159
|
+
<span className="text-green-600">✅</span>
|
|
160
|
+
<span>
|
|
161
|
+
Installer automatiquement tous les packages nécessaires (
|
|
162
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
163
|
+
@lastbrain/core
|
|
164
|
+
</code>
|
|
165
|
+
,{" "}
|
|
166
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
167
|
+
@lastbrain/ui
|
|
168
|
+
</code>
|
|
169
|
+
, modules...)
|
|
170
|
+
</span>
|
|
171
|
+
</div>
|
|
172
|
+
<div className="flex items-start gap-2">
|
|
173
|
+
<span className="text-green-600">✅</span>
|
|
174
|
+
<span>Configurer Supabase et les migrations</span>
|
|
175
|
+
</div>
|
|
176
|
+
<div className="flex items-start gap-2">
|
|
177
|
+
<span className="text-green-600">✅</span>
|
|
178
|
+
<span>Générer les routes des modules sélectionnés</span>
|
|
179
|
+
</div>
|
|
102
180
|
</div>
|
|
181
|
+
<h3 className="text-lg font-semibold mb-2">
|
|
182
|
+
Création du Compte Admin
|
|
183
|
+
</h3>
|
|
184
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
185
|
+
{`# Promouvoir votre compte en admin via Supabase`}
|
|
186
|
+
</Snippet>
|
|
187
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
188
|
+
{`update auth.users`}
|
|
189
|
+
</Snippet>
|
|
190
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
191
|
+
{`set raw_app_meta_data = jsonb_set(`}
|
|
192
|
+
</Snippet>
|
|
193
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
194
|
+
{` coalesce(raw_app_meta_data, '{}'::jsonb),`}
|
|
195
|
+
</Snippet>
|
|
196
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
197
|
+
{` '{roles}',`}
|
|
198
|
+
</Snippet>
|
|
199
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
200
|
+
{` '["admin"]'::jsonb`}
|
|
201
|
+
</Snippet>
|
|
202
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
203
|
+
{`)`}
|
|
204
|
+
</Snippet>
|
|
205
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
206
|
+
{`where email = 'votre@email.com';`}
|
|
207
|
+
</Snippet>
|
|
208
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
209
|
+
Votre application est maintenant disponible sur{" "}
|
|
210
|
+
<a
|
|
211
|
+
href="http://localhost:3000"
|
|
212
|
+
className="text-blue-600 hover:underline"
|
|
213
|
+
target="_blank"
|
|
214
|
+
rel="noopener noreferrer"
|
|
215
|
+
>
|
|
216
|
+
http://localhost:3000
|
|
217
|
+
</a>{" "}
|
|
218
|
+
! 🎉
|
|
219
|
+
</p>
|
|
103
220
|
</CardBody>
|
|
104
221
|
</Card>
|
|
105
222
|
|
|
@@ -111,59 +228,29 @@ export function DefaultDocumentation() {
|
|
|
111
228
|
</h2>
|
|
112
229
|
</CardHeader>
|
|
113
230
|
<CardBody className="space-y-4">
|
|
114
|
-
<p className="text-slate-600 dark:text-slate-400">
|
|
231
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
115
232
|
Le projet est organisé en monorepo avec pnpm workspaces :
|
|
116
233
|
</p>
|
|
117
|
-
|
|
118
|
-
<
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
<p className="text-sm text-slate-600 dark:text-slate-400">
|
|
138
|
-
Utilitaires et types partagés. Contient les helpers Supabase,
|
|
139
|
-
fonctions serveur et types TypeScript communs.
|
|
140
|
-
</p>
|
|
141
|
-
</div>
|
|
142
|
-
|
|
143
|
-
<div className="border-l-4 border-purple-500 pl-4">
|
|
144
|
-
<h3 className="font-semibold text-lg mb-1">
|
|
145
|
-
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
146
|
-
@lastbrain/ui
|
|
147
|
-
</code>
|
|
148
|
-
</h3>
|
|
149
|
-
<p className="text-sm text-slate-600 dark:text-slate-400">
|
|
150
|
-
Composants UI réutilisables basés sur NextUI et Tailwind CSS.
|
|
151
|
-
Fournit les composants Card, Button, Input, etc.
|
|
152
|
-
</p>
|
|
153
|
-
</div>
|
|
154
|
-
|
|
155
|
-
<div className="border-l-4 border-orange-500 pl-4">
|
|
156
|
-
<h3 className="font-semibold text-lg mb-1">
|
|
157
|
-
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
158
|
-
@lastbrain/module-*
|
|
159
|
-
</code>
|
|
160
|
-
</h3>
|
|
161
|
-
<p className="text-sm text-slate-600 dark:text-slate-400">
|
|
162
|
-
Modules fonctionnels (auth, ai, etc.). Chaque module contient
|
|
163
|
-
ses pages, APIs, composants, migrations et documentation.
|
|
164
|
-
</p>
|
|
165
|
-
</div>
|
|
166
|
-
</div>
|
|
234
|
+
<h3 className="text-lg font-semibold mb-2">@lastbrain/app</h3>
|
|
235
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
236
|
+
Framework principal et CLI. Contient les layouts, scripts de build,
|
|
237
|
+
templates et la logique de génération des pages.
|
|
238
|
+
</p>
|
|
239
|
+
<h3 className="text-lg font-semibold mb-2">@lastbrain/core</h3>
|
|
240
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
241
|
+
Utilitaires et types partagés. Contient les helpers Supabase,
|
|
242
|
+
fonctions serveur et types TypeScript communs.
|
|
243
|
+
</p>
|
|
244
|
+
<h3 className="text-lg font-semibold mb-2">@lastbrain/ui</h3>
|
|
245
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
246
|
+
Composants UI réutilisables basés sur NextUI et Tailwind CSS.
|
|
247
|
+
Fournit les composants Card, Button, Input, etc.
|
|
248
|
+
</p>
|
|
249
|
+
<h3 className="text-lg font-semibold mb-2">@lastbrain/module-\*</h3>
|
|
250
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
251
|
+
Modules fonctionnels (auth, ai, etc.). Chaque module contient ses
|
|
252
|
+
pages, APIs, composants, migrations et documentation.
|
|
253
|
+
</p>
|
|
167
254
|
</CardBody>
|
|
168
255
|
</Card>
|
|
169
256
|
|
|
@@ -175,71 +262,61 @@ export function DefaultDocumentation() {
|
|
|
175
262
|
</h2>
|
|
176
263
|
</CardHeader>
|
|
177
264
|
<CardBody className="space-y-4">
|
|
178
|
-
<
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
217
|
-
Le fichier{" "}
|
|
218
|
-
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
219
|
-
{"{slug}"}.build.config.ts
|
|
220
|
-
</code>{" "}
|
|
221
|
-
définit les pages et APIs :
|
|
222
|
-
</p>
|
|
223
|
-
<div className="bg-slate-50 dark:bg-slate-900 p-4 rounded-lg text-sm font-mono overflow-x-auto">
|
|
224
|
-
<pre>{`export default {
|
|
265
|
+
<h3 className="text-lg font-semibold mb-2">Commande CLI</h3>
|
|
266
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
267
|
+
{`pnpm lastbrain create-module mon-module`}
|
|
268
|
+
</Snippet>
|
|
269
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
270
|
+
Crée un nouveau module dans{" "}
|
|
271
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
272
|
+
packages/module-mon-module
|
|
273
|
+
</code>
|
|
274
|
+
</p>
|
|
275
|
+
<h3 className="text-lg font-semibold mb-2">Structure d'un module</h3>
|
|
276
|
+
<Alert
|
|
277
|
+
hideIcon
|
|
278
|
+
color="primary"
|
|
279
|
+
className="p-4 mb-4 whitespace-pre-wrap"
|
|
280
|
+
>{`📁 module-mon-module/
|
|
281
|
+
├── 📄 package.json
|
|
282
|
+
├── 📄 mon-module.build.config.ts
|
|
283
|
+
└── 📁 src/
|
|
284
|
+
├── 📄 index.ts
|
|
285
|
+
├── 📄 server.ts
|
|
286
|
+
├── 📁 web/
|
|
287
|
+
├── 📁 api/
|
|
288
|
+
├── 📁 components/
|
|
289
|
+
└── 📁 supabase/
|
|
290
|
+
└── 📁 migrations/`}</Alert>
|
|
291
|
+
<h3 className="text-lg font-semibold mb-2">
|
|
292
|
+
Configuration du module
|
|
293
|
+
</h3>
|
|
294
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
295
|
+
Le fichier{" "}
|
|
296
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
297
|
+
module-name.build.config.ts
|
|
298
|
+
</code>{" "}
|
|
299
|
+
définit les pages et APIs :
|
|
300
|
+
</p>
|
|
301
|
+
<Alert hideIcon color="primary" className="p-4 mb-4">
|
|
302
|
+
<pre className="whitespace-pre-wrap">{`export default {
|
|
225
303
|
name: "Mon Module",
|
|
226
304
|
description: "Description du module",
|
|
227
305
|
pages: [
|
|
228
306
|
{
|
|
229
307
|
path: "/ma-page",
|
|
230
308
|
component: "./web/MaPage",
|
|
231
|
-
layout: "auth"
|
|
232
|
-
}
|
|
309
|
+
layout: "auth",
|
|
310
|
+
},
|
|
233
311
|
],
|
|
234
312
|
apis: [
|
|
235
313
|
{
|
|
236
314
|
path: "/api/mon-api",
|
|
237
|
-
handler: "./api/mon-api"
|
|
238
|
-
}
|
|
239
|
-
]
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
</div>
|
|
315
|
+
handler: "./api/mon-api",
|
|
316
|
+
},
|
|
317
|
+
],
|
|
318
|
+
};`}</pre>
|
|
319
|
+
</Alert>
|
|
243
320
|
</CardBody>
|
|
244
321
|
</Card>
|
|
245
322
|
|
|
@@ -251,105 +328,85 @@ export function DefaultDocumentation() {
|
|
|
251
328
|
</h2>
|
|
252
329
|
</CardHeader>
|
|
253
330
|
<CardBody className="space-y-4">
|
|
254
|
-
<
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
<p className="text-sm font-medium mb-1">
|
|
280
|
-
Créer une migration :
|
|
281
|
-
</p>
|
|
282
|
-
<Snippet symbol="" hideSymbol className="text-sm">
|
|
283
|
-
supabase migration new ma_migration
|
|
284
|
-
</Snippet>
|
|
285
|
-
</div>
|
|
286
|
-
</div>
|
|
287
|
-
</div>
|
|
288
|
-
|
|
289
|
-
<div>
|
|
290
|
-
<h3 className="text-lg font-semibold mb-2">
|
|
291
|
-
Migrations des modules
|
|
292
|
-
</h3>
|
|
293
|
-
<p className="text-sm text-slate-600 dark:text-slate-400">
|
|
294
|
-
Les modules peuvent avoir leurs propres migrations dans{" "}
|
|
295
|
-
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
296
|
-
supabase/migrations/
|
|
297
|
-
</code>
|
|
298
|
-
. Elles sont automatiquement synchronisées lors du build.
|
|
299
|
-
</p>
|
|
300
|
-
</div>
|
|
331
|
+
<h3 className="text-lg font-semibold mb-2">Supabase local</h3>
|
|
332
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
333
|
+
LastBrain utilise Supabase pour la base de données et
|
|
334
|
+
l'authentification.
|
|
335
|
+
</p>
|
|
336
|
+
<h4 className="font-medium mb-2">Démarrer Supabase</h4>
|
|
337
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
338
|
+
{`pnpm db:init`}
|
|
339
|
+
</Snippet>
|
|
340
|
+
<h4 className="font-medium mb-2">Synchroniser les migrations</h4>
|
|
341
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
342
|
+
{`pnpm db:migrations:sync`}
|
|
343
|
+
</Snippet>
|
|
344
|
+
<h4 className="font-medium mb-2">Créer une migration</h4>
|
|
345
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
346
|
+
{`supabase migration new ma_migration`}
|
|
347
|
+
</Snippet>
|
|
348
|
+
<h3 className="text-lg font-semibold mb-2">Migrations des modules</h3>
|
|
349
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
350
|
+
Les modules peuvent avoir leurs propres migrations dans{" "}
|
|
351
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
352
|
+
supabase/migrations/
|
|
353
|
+
</code>
|
|
354
|
+
. Elles sont automatiquement synchronisées lors du build.
|
|
355
|
+
</p>
|
|
301
356
|
</CardBody>
|
|
302
357
|
</Card>
|
|
303
358
|
|
|
304
359
|
<Card id="section-admin" className="scroll-mt-32">
|
|
305
360
|
<CardHeader>
|
|
306
|
-
<h2 className="text-2xl font-semibold">
|
|
307
|
-
|
|
361
|
+
<h2 className="text-2xl font-semibold flex items-center gap-2">
|
|
362
|
+
<User size={24} />
|
|
363
|
+
Créer un Compte Administrateur
|
|
308
364
|
</h2>
|
|
309
365
|
</CardHeader>
|
|
310
366
|
<CardBody className="space-y-4">
|
|
311
|
-
<
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
367
|
+
<h3 className="text-lg font-semibold mb-2">1. Créer un compte</h3>
|
|
368
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
369
|
+
Allez sur{" "}
|
|
370
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
371
|
+
/signup
|
|
372
|
+
</code>{" "}
|
|
373
|
+
et créez votre compte
|
|
374
|
+
</p>
|
|
375
|
+
<h3 className="text-lg font-semibold mb-2">
|
|
376
|
+
2. Promouvoir en administrateur
|
|
377
|
+
</h3>
|
|
378
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
379
|
+
Exécutez cette requête SQL dans le Studio Supabase (
|
|
380
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
381
|
+
http://localhost:54323
|
|
382
|
+
</code>
|
|
383
|
+
) ou via psql :
|
|
384
|
+
</p>
|
|
385
|
+
<Snippet hideSymbol color="primary" className="text-sm mb-2">
|
|
386
|
+
<span>{`update auth.users
|
|
387
|
+
`}</span>
|
|
388
|
+
<span>{`set raw_app_meta_data = jsonb_set(
|
|
389
|
+
`}</span>
|
|
390
|
+
<span>{` coalesce(raw_app_meta_data, '{}'::jsonb),
|
|
391
|
+
`}</span>
|
|
392
|
+
<span>{` '{roles}',
|
|
393
|
+
`}</span>
|
|
394
|
+
<span>{` '["admin"]'::jsonb
|
|
395
|
+
`}</span>
|
|
396
|
+
<span>{`)
|
|
397
|
+
`}</span>
|
|
398
|
+
<span>{`where email = 'votre@email.com';
|
|
399
|
+
`}</span>
|
|
400
|
+
</Snippet>
|
|
401
|
+
<h3 className="text-lg font-semibold mb-2">
|
|
402
|
+
3. Accéder à l'interface admin
|
|
403
|
+
</h3>
|
|
404
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
405
|
+
Vous pouvez maintenant accéder à{" "}
|
|
406
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
407
|
+
/admin
|
|
408
|
+
</code>
|
|
409
|
+
</p>
|
|
353
410
|
</CardBody>
|
|
354
411
|
</Card>
|
|
355
412
|
|
|
@@ -361,40 +418,32 @@ export function DefaultDocumentation() {
|
|
|
361
418
|
</h2>
|
|
362
419
|
</CardHeader>
|
|
363
420
|
<CardBody className="space-y-4">
|
|
364
|
-
<
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
</
|
|
383
|
-
<
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
<h3 className="text-lg font-semibold mb-2">Développer un module</h3>
|
|
391
|
-
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
392
|
-
cd packages/module-auth
|
|
393
|
-
</Snippet>
|
|
394
|
-
<Snippet symbol="" hideSymbol className="text-sm">
|
|
395
|
-
pnpm dev
|
|
396
|
-
</Snippet>
|
|
397
|
-
</div>
|
|
421
|
+
<h3 className="text-lg font-semibold mb-2">
|
|
422
|
+
Lancer le serveur de développement
|
|
423
|
+
</h3>
|
|
424
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
425
|
+
{`pnpm dev`}
|
|
426
|
+
</Snippet>
|
|
427
|
+
<h3 className="text-lg font-semibold mb-2">
|
|
428
|
+
Générer les routes des modules
|
|
429
|
+
</h3>
|
|
430
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
431
|
+
À exécuter après avoir ajouté ou modifié des modules
|
|
432
|
+
</p>
|
|
433
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
434
|
+
{`pnpm build:modules`}
|
|
435
|
+
</Snippet>
|
|
436
|
+
<h3 className="text-lg font-semibold mb-2">Build de production</h3>
|
|
437
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
438
|
+
{`pnpm build`}
|
|
439
|
+
</Snippet>
|
|
440
|
+
<h3 className="text-lg font-semibold mb-2">Développer un module</h3>
|
|
441
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
442
|
+
{`cd packages/module-auth`}
|
|
443
|
+
</Snippet>
|
|
444
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
445
|
+
{`pnpm dev`}
|
|
446
|
+
</Snippet>
|
|
398
447
|
</CardBody>
|
|
399
448
|
</Card>
|
|
400
449
|
|
|
@@ -406,30 +455,42 @@ export function DefaultDocumentation() {
|
|
|
406
455
|
</h2>
|
|
407
456
|
</CardHeader>
|
|
408
457
|
<CardBody className="space-y-4">
|
|
409
|
-
<p className="text-slate-600 dark:text-slate-400 mb-
|
|
458
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
410
459
|
Le middleware protège automatiquement vos routes selon ces règles :
|
|
411
460
|
</p>
|
|
461
|
+
<h3 className="text-lg font-semibold mb-2">Routes</h3>
|
|
412
462
|
<div className="space-y-2">
|
|
413
|
-
<div className="
|
|
414
|
-
<
|
|
415
|
-
<span
|
|
463
|
+
<div className="flex items-start gap-2">
|
|
464
|
+
<span className="text-green-600">✅</span>
|
|
465
|
+
<span>
|
|
466
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
467
|
+
/auth/*
|
|
468
|
+
</code>{" "}
|
|
469
|
+
→ Authentification requise
|
|
470
|
+
</span>
|
|
416
471
|
</div>
|
|
417
|
-
<div className="
|
|
418
|
-
<
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
472
|
+
<div className="flex items-start gap-2">
|
|
473
|
+
<span className="text-green-600">✅</span>
|
|
474
|
+
<span>
|
|
475
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
476
|
+
/admin/*
|
|
477
|
+
</code>{" "}
|
|
478
|
+
→ Superadmin uniquement
|
|
479
|
+
</span>
|
|
422
480
|
</div>
|
|
423
|
-
<div className="
|
|
424
|
-
<
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
481
|
+
<div className="flex items-start gap-2">
|
|
482
|
+
<span className="text-green-600">✅</span>
|
|
483
|
+
<span>
|
|
484
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
485
|
+
/docs/*
|
|
486
|
+
</code>{" "}
|
|
487
|
+
→ Accès public
|
|
488
|
+
</span>
|
|
428
489
|
</div>
|
|
429
490
|
</div>
|
|
430
|
-
<p className="text-sm text-slate-600 dark:text-slate-400
|
|
491
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
431
492
|
Le middleware se trouve dans{" "}
|
|
432
|
-
<code className="
|
|
493
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
433
494
|
middleware.ts
|
|
434
495
|
</code>
|
|
435
496
|
</p>
|
|
@@ -444,53 +505,37 @@ export function DefaultDocumentation() {
|
|
|
444
505
|
</h2>
|
|
445
506
|
</CardHeader>
|
|
446
507
|
<CardBody className="space-y-4">
|
|
447
|
-
<
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
</
|
|
458
|
-
<
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
</Snippet>
|
|
479
|
-
</div>
|
|
480
|
-
<div>
|
|
481
|
-
<h3 className="text-lg font-semibold mb-2">
|
|
482
|
-
4. Appliquer les migrations
|
|
483
|
-
</h3>
|
|
484
|
-
<Snippet symbol="" hideSymbol className="text-sm">
|
|
485
|
-
supabase migration up
|
|
486
|
-
</Snippet>
|
|
487
|
-
</div>
|
|
488
|
-
<div>
|
|
489
|
-
<h3 className="text-lg font-semibold mb-2">5. Tester</h3>
|
|
490
|
-
<Snippet symbol="" hideSymbol className="text-sm">
|
|
491
|
-
pnpm dev
|
|
492
|
-
</Snippet>
|
|
493
|
-
</div>
|
|
508
|
+
<h3 className="text-lg font-semibold mb-2">1. Modifier un module</h3>
|
|
509
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
510
|
+
Éditez les fichiers dans{" "}
|
|
511
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
512
|
+
packages/module-*/src
|
|
513
|
+
</code>
|
|
514
|
+
</p>
|
|
515
|
+
<h3 className="text-lg font-semibold mb-2">2. Compiler le module</h3>
|
|
516
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
517
|
+
{`cd packages/module-auth`}
|
|
518
|
+
</Snippet>
|
|
519
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
520
|
+
{`pnpm build`}
|
|
521
|
+
</Snippet>
|
|
522
|
+
<h3 className="text-lg font-semibold mb-2">3. Régénérer les pages</h3>
|
|
523
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
524
|
+
{`cd apps/my-app`}
|
|
525
|
+
</Snippet>
|
|
526
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
527
|
+
{`pnpm build:modules`}
|
|
528
|
+
</Snippet>
|
|
529
|
+
<h3 className="text-lg font-semibold mb-2">
|
|
530
|
+
4. Appliquer les migrations
|
|
531
|
+
</h3>
|
|
532
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
533
|
+
{`supabase migration up`}
|
|
534
|
+
</Snippet>
|
|
535
|
+
<h3 className="text-lg font-semibold mb-2">5. Tester</h3>
|
|
536
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
537
|
+
{`pnpm dev`}
|
|
538
|
+
</Snippet>
|
|
494
539
|
</CardBody>
|
|
495
540
|
</Card>
|
|
496
541
|
|
|
@@ -502,127 +547,93 @@ export function DefaultDocumentation() {
|
|
|
502
547
|
</h2>
|
|
503
548
|
</CardHeader>
|
|
504
549
|
<CardBody className="space-y-4">
|
|
505
|
-
<
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
Le projet utilise Tailwind CSS v4 avec un preset personnalisé
|
|
532
|
-
partagé via{" "}
|
|
533
|
-
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
534
|
-
@lastbrain/ui/tailwind.preset
|
|
535
|
-
</code>
|
|
536
|
-
.
|
|
537
|
-
</p>
|
|
538
|
-
</div>
|
|
550
|
+
<h3 className="text-lg font-semibold mb-2">Composants NextUI</h3>
|
|
551
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
552
|
+
Le package{" "}
|
|
553
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
554
|
+
@lastbrain/ui
|
|
555
|
+
</code>{" "}
|
|
556
|
+
réexporte les composants NextUI avec une configuration Tailwind
|
|
557
|
+
personnalisée.
|
|
558
|
+
</p>
|
|
559
|
+
<h3 className="text-lg font-semibold mb-2">Thèmes</h3>
|
|
560
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
561
|
+
Le mode sombre/clair est géré par{" "}
|
|
562
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
563
|
+
next-themes
|
|
564
|
+
</code>
|
|
565
|
+
. Le switch est disponible dans le header de l'application.
|
|
566
|
+
</p>
|
|
567
|
+
<h3 className="text-lg font-semibold mb-2">Tailwind CSS v4</h3>
|
|
568
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
569
|
+
Le projet utilise Tailwind CSS v4 avec un preset personnalisé
|
|
570
|
+
partagé via{" "}
|
|
571
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
572
|
+
@lastbrain/ui/tailwind.preset
|
|
573
|
+
</code>
|
|
574
|
+
.
|
|
575
|
+
</p>
|
|
539
576
|
</CardBody>
|
|
540
577
|
</Card>
|
|
541
578
|
|
|
542
579
|
<Card id="section-storage" className="scroll-mt-32">
|
|
543
580
|
<CardHeader>
|
|
544
581
|
<h2 className="text-2xl font-semibold flex items-center gap-2">
|
|
545
|
-
<
|
|
582
|
+
<HardDrive size={24} />
|
|
546
583
|
Système de Proxy Storage
|
|
547
584
|
</h2>
|
|
548
585
|
</CardHeader>
|
|
549
586
|
<CardBody className="space-y-4">
|
|
550
|
-
<p className="text-slate-600 dark:text-slate-400">
|
|
587
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
551
588
|
LastBrain intègre un système de proxy pour les fichiers Supabase
|
|
552
589
|
Storage qui permet d'utiliser des URLs propres avec contrôle d'accès
|
|
553
590
|
granulaire.
|
|
554
591
|
</p>
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
</
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
<
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
<code className="text-xs bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
594
|
-
/api/storage/avatar/user_128_123456.webp
|
|
595
|
-
</code>
|
|
596
|
-
</div>
|
|
597
|
-
|
|
598
|
-
<div className="border-l-4 border-blue-500 pl-4">
|
|
599
|
-
<h4 className="font-semibold text-blue-600 dark:text-blue-400">
|
|
600
|
-
🔒 app (Privé)
|
|
601
|
-
</h4>
|
|
602
|
-
<p className="text-sm text-slate-600 dark:text-slate-400">
|
|
603
|
-
Fichiers privés des utilisateurs • 100MB max •
|
|
604
|
-
Authentification requise
|
|
605
|
-
</p>
|
|
606
|
-
<code className="text-xs bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
607
|
-
/api/storage/app/user-id/documents/file.pdf
|
|
608
|
-
</code>
|
|
609
|
-
</div>
|
|
610
|
-
</div>
|
|
611
|
-
</div>
|
|
612
|
-
|
|
613
|
-
<div>
|
|
614
|
-
<h3 className="text-lg font-semibold mb-2">
|
|
615
|
-
Utilisation dans le code
|
|
616
|
-
</h3>
|
|
617
|
-
<div className="bg-slate-50 dark:bg-slate-900 p-4 rounded-lg text-sm font-mono overflow-x-auto">
|
|
618
|
-
<pre>{`// Upload d'un fichier
|
|
592
|
+
<h3 className="text-lg font-semibold mb-2">
|
|
593
|
+
URLs Proxy vs URLs Supabase
|
|
594
|
+
</h3>
|
|
595
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
596
|
+
<strong>❌ URL Supabase classique (longue)</strong>
|
|
597
|
+
</p>
|
|
598
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
599
|
+
{`https://xxx.supabase.co/storage/v1/object/public/avatar/user_128_123456.webp`}
|
|
600
|
+
</Snippet>
|
|
601
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
602
|
+
<strong>✅ URL Proxy (propre)</strong>
|
|
603
|
+
</p>
|
|
604
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
605
|
+
{`/api/storage/avatar/user_128_123456.webp`}
|
|
606
|
+
</Snippet>
|
|
607
|
+
<h3 className="text-lg font-semibold mb-2">
|
|
608
|
+
Configuration des Buckets
|
|
609
|
+
</h3>
|
|
610
|
+
<h4 className="font-medium mb-2">📂 avatar (Public)</h4>
|
|
611
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
612
|
+
Photos de profil et avatars • 10MB max • Types: JPEG, PNG, WebP, GIF
|
|
613
|
+
</p>
|
|
614
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
615
|
+
{`/api/storage/avatar/user_128_123456.webp`}
|
|
616
|
+
</Snippet>
|
|
617
|
+
<h4 className="font-medium mb-2">🔒 app (Privé)</h4>
|
|
618
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
619
|
+
Fichiers privés des utilisateurs • 100MB max • Authentification
|
|
620
|
+
requise
|
|
621
|
+
</p>
|
|
622
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
623
|
+
{`/api/storage/app/user-id/documents/file.pdf`}
|
|
624
|
+
</Snippet>
|
|
625
|
+
<h3 className="text-lg font-semibold mb-2">
|
|
626
|
+
Utilisation dans le code
|
|
627
|
+
</h3>
|
|
628
|
+
<Alert hideIcon color="primary" className="p-4 mb-4">
|
|
629
|
+
<pre className="whitespace-pre-wrap">{`// Upload d'un fichier
|
|
619
630
|
import { uploadFile } from "@/api/storage";
|
|
620
631
|
|
|
621
632
|
const proxyUrl = await uploadFile(
|
|
622
|
-
"avatar",
|
|
623
|
-
"user_128_123456.webp",
|
|
624
|
-
file,
|
|
625
|
-
"image/webp"
|
|
633
|
+
"avatar",
|
|
634
|
+
"user_128_123456.webp",
|
|
635
|
+
file,
|
|
636
|
+
"image/webp",
|
|
626
637
|
);
|
|
627
638
|
// Retourne: "/api/storage/avatar/user_128_123456.webp"
|
|
628
639
|
|
|
@@ -631,36 +642,26 @@ import { storagePathToProxyUrl } from "@/lib/storage";
|
|
|
631
642
|
|
|
632
643
|
const proxyUrl = storagePathToProxyUrl("avatar/user_128_123456.webp");
|
|
633
644
|
// Retourne: "/api/storage/avatar/user_128_123456.webp"`}</pre>
|
|
645
|
+
</Alert>
|
|
646
|
+
<h3 className="text-lg font-semibold mb-2">Avantages du système</h3>
|
|
647
|
+
<div className="space-y-2">
|
|
648
|
+
<div className="flex items-start gap-2">
|
|
649
|
+
<span>✅ URLs plus courtes et lisibles</span>
|
|
634
650
|
</div>
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
<
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
<
|
|
649
|
-
<span className="text-green-600">✅</span>
|
|
650
|
-
<span>Cache optimisé (1 an)</span>
|
|
651
|
-
</div>
|
|
652
|
-
<div className="flex items-start gap-2">
|
|
653
|
-
<span className="text-green-600">✅</span>
|
|
654
|
-
<span>Sécurité améliorée</span>
|
|
655
|
-
</div>
|
|
656
|
-
<div className="flex items-start gap-2">
|
|
657
|
-
<span className="text-green-600">✅</span>
|
|
658
|
-
<span>Détection auto des types MIME</span>
|
|
659
|
-
</div>
|
|
660
|
-
<div className="flex items-start gap-2">
|
|
661
|
-
<span className="text-green-600">✅</span>
|
|
662
|
-
<span>Extensible facilement</span>
|
|
663
|
-
</div>
|
|
651
|
+
<div className="flex items-start gap-2">
|
|
652
|
+
<span>✅ Contrôle d'accès granulaire</span>
|
|
653
|
+
</div>
|
|
654
|
+
<div className="flex items-start gap-2">
|
|
655
|
+
<span>✅ Cache optimisé (1 an)</span>
|
|
656
|
+
</div>
|
|
657
|
+
<div className="flex items-start gap-2">
|
|
658
|
+
<span>✅ Sécurité améliorée</span>
|
|
659
|
+
</div>
|
|
660
|
+
<div className="flex items-start gap-2">
|
|
661
|
+
<span>✅ Détection auto des types MIME</span>
|
|
662
|
+
</div>
|
|
663
|
+
<div className="flex items-start gap-2">
|
|
664
|
+
<span>✅ Extensible facilement</span>
|
|
664
665
|
</div>
|
|
665
666
|
</div>
|
|
666
667
|
</CardBody>
|
|
@@ -674,28 +675,26 @@ const proxyUrl = storagePathToProxyUrl("avatar/user_128_123456.webp");
|
|
|
674
675
|
</h2>
|
|
675
676
|
</CardHeader>
|
|
676
677
|
<CardBody className="space-y-4">
|
|
677
|
-
<p className="text-slate-600 dark:text-slate-400">
|
|
678
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
678
679
|
LastBrain intègre un système de notifications et de synchronisation
|
|
679
680
|
en temps réel basé sur Supabase Realtime. Le système est entièrement
|
|
680
681
|
automatisé et scalable.
|
|
681
682
|
</p>
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
<
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
<div className="bg-slate-50 dark:bg-slate-900 p-4 rounded-lg text-sm font-mono overflow-x-auto">
|
|
695
|
-
<pre>{`export default {
|
|
683
|
+
<h3 className="text-lg font-semibold mb-2">
|
|
684
|
+
Configuration dans les modules
|
|
685
|
+
</h3>
|
|
686
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
687
|
+
Ajoutez la configuration realtime dans votre{" "}
|
|
688
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
689
|
+
build.config.ts
|
|
690
|
+
</code>{" "}
|
|
691
|
+
pour activer la synchronisation en temps réel :
|
|
692
|
+
</p>
|
|
693
|
+
<Alert hideIcon color="primary" className="p-4 mb-4">
|
|
694
|
+
<pre className="whitespace-pre-wrap">{`export default {
|
|
696
695
|
name: "Module Auth",
|
|
697
696
|
description: "Gestion de l'authentification",
|
|
698
|
-
|
|
697
|
+
|
|
699
698
|
// Configuration realtime
|
|
700
699
|
realtime: {
|
|
701
700
|
moduleId: "module-auth",
|
|
@@ -705,63 +704,53 @@ const proxyUrl = storagePathToProxyUrl("avatar/user_128_123456.webp");
|
|
|
705
704
|
table: "user_notifications",
|
|
706
705
|
event: "*", // INSERT, UPDATE, DELETE ou *
|
|
707
706
|
filter: "owner_id=eq.\${USER_ID}",
|
|
708
|
-
broadcast: "user_notifications_updated"
|
|
707
|
+
broadcast: "user_notifications_updated",
|
|
709
708
|
},
|
|
710
709
|
{
|
|
711
|
-
schema: "public",
|
|
710
|
+
schema: "public",
|
|
712
711
|
table: "user_profiles",
|
|
713
712
|
event: "*",
|
|
714
713
|
filter: "owner_id=eq.\${USER_ID}",
|
|
715
|
-
broadcast: "user_profile_updated"
|
|
716
|
-
}
|
|
717
|
-
]
|
|
714
|
+
broadcast: "user_profile_updated",
|
|
715
|
+
},
|
|
716
|
+
],
|
|
718
717
|
},
|
|
719
|
-
|
|
718
|
+
|
|
720
719
|
pages: [
|
|
721
720
|
// vos pages...
|
|
722
|
-
]
|
|
723
|
-
}
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
<p className="text-sm text-slate-600 dark:text-slate-400 mb-3">
|
|
752
|
-
Utilisez les hooks pré-construits pour écouter les changements :
|
|
753
|
-
</p>
|
|
754
|
-
<div className="space-y-4">
|
|
755
|
-
<div>
|
|
756
|
-
<h4 className="font-medium mb-2">
|
|
757
|
-
1. Hook générique pour une table
|
|
758
|
-
</h4>
|
|
759
|
-
<div className="bg-slate-50 dark:bg-slate-900 p-4 rounded-lg text-sm font-mono overflow-x-auto">
|
|
760
|
-
<pre>{`import { useTableRealtime } from "@lastbrain/core";
|
|
721
|
+
],
|
|
722
|
+
};`}</pre>
|
|
723
|
+
</Alert>
|
|
724
|
+
<h3 className="text-lg font-semibold mb-2">
|
|
725
|
+
Génération automatique de la configuration
|
|
726
|
+
</h3>
|
|
727
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
728
|
+
Lors du build des modules, la configuration realtime est
|
|
729
|
+
automatiquement générée :
|
|
730
|
+
</p>
|
|
731
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
732
|
+
{`pnpm build:modules`}
|
|
733
|
+
</Snippet>
|
|
734
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
735
|
+
Cela génère automatiquement{" "}
|
|
736
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
737
|
+
config/realtime.ts
|
|
738
|
+
</code>{" "}
|
|
739
|
+
avec toutes les configurations des modules.
|
|
740
|
+
</p>
|
|
741
|
+
<h3 className="text-lg font-semibold mb-2">
|
|
742
|
+
Utilisation dans les composants
|
|
743
|
+
</h3>
|
|
744
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
745
|
+
Utilisez les hooks pré-construits pour écouter les changements :
|
|
746
|
+
</p>
|
|
747
|
+
<h4 className="font-medium mb-2">1. Hook générique pour une table</h4>
|
|
748
|
+
<Alert hideIcon color="primary" className="p-4 mb-4">
|
|
749
|
+
<pre className="whitespace-pre-wrap">{`import { useTableRealtime } from "@lastbrain/core";
|
|
761
750
|
|
|
762
751
|
function MonComposant() {
|
|
763
752
|
const signal = useTableRealtime("user_notifications");
|
|
764
|
-
|
|
753
|
+
|
|
765
754
|
useEffect(() => {
|
|
766
755
|
if (signal.hasUpdates) {
|
|
767
756
|
console.log("Nouvelle notification!");
|
|
@@ -770,19 +759,16 @@ function MonComposant() {
|
|
|
770
759
|
}
|
|
771
760
|
}, [signal.tick]);
|
|
772
761
|
}`}</pre>
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
</h4>
|
|
780
|
-
<div className="bg-slate-50 dark:bg-slate-900 p-4 rounded-lg text-sm font-mono overflow-x-auto">
|
|
781
|
-
<pre>{`import { useNotifications } from "../hooks/useNotifications";
|
|
762
|
+
</Alert>
|
|
763
|
+
<h4 className="font-medium mb-2">
|
|
764
|
+
2. Hook spécialisé pour les notifications
|
|
765
|
+
</h4>
|
|
766
|
+
<Alert hideIcon color="primary" className="p-4 mb-4">
|
|
767
|
+
<pre className="whitespace-pre-wrap">{`import { useNotifications } from "../hooks/useNotifications";
|
|
782
768
|
|
|
783
769
|
function NotificationBell() {
|
|
784
770
|
const { notifications, loading, hasUpdates } = useNotifications();
|
|
785
|
-
|
|
771
|
+
|
|
786
772
|
return (
|
|
787
773
|
<div>
|
|
788
774
|
🔔 {notifications.length}
|
|
@@ -790,19 +776,14 @@ function NotificationBell() {
|
|
|
790
776
|
</div>
|
|
791
777
|
);
|
|
792
778
|
}`}</pre>
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
<h4 className="font-medium mb-2">
|
|
798
|
-
3. Hook bas niveau avec EventBus
|
|
799
|
-
</h4>
|
|
800
|
-
<div className="bg-slate-50 dark:bg-slate-900 p-4 rounded-lg text-sm font-mono overflow-x-auto">
|
|
801
|
-
<pre>{`import { useRealtimeSignal } from "@lastbrain/core";
|
|
779
|
+
</Alert>
|
|
780
|
+
<h4 className="font-medium mb-2">3. Hook bas niveau avec EventBus</h4>
|
|
781
|
+
<Alert hideIcon color="primary" className="p-4 mb-4">
|
|
782
|
+
<pre className="whitespace-pre-wrap">{`import { useRealtimeSignal } from "@lastbrain/core";
|
|
802
783
|
|
|
803
784
|
function MonComposant() {
|
|
804
785
|
const signal = useRealtimeSignal("user_notifications_updated");
|
|
805
|
-
|
|
786
|
+
|
|
806
787
|
useEffect(() => {
|
|
807
788
|
if (signal.hasUpdates) {
|
|
808
789
|
// Événement spécifique reçu
|
|
@@ -811,121 +792,73 @@ function MonComposant() {
|
|
|
811
792
|
}
|
|
812
793
|
}, [signal.tick]);
|
|
813
794
|
}`}</pre>
|
|
814
|
-
|
|
815
|
-
|
|
795
|
+
</Alert>
|
|
796
|
+
<h3 className="text-lg font-semibold mb-2">
|
|
797
|
+
Architecture du système
|
|
798
|
+
</h3>
|
|
799
|
+
<h4 className="font-medium mb-2">🎯 EventBus Global</h4>
|
|
800
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
801
|
+
Système central de coordination des événements realtime à travers
|
|
802
|
+
toute l'application.
|
|
803
|
+
</p>
|
|
804
|
+
<h4 className="font-medium mb-2">🔌 RealtimeProvider</h4>
|
|
805
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
806
|
+
Provider React qui établit les connexions Supabase Realtime basées
|
|
807
|
+
sur la configuration des modules.
|
|
808
|
+
</p>
|
|
809
|
+
<h4 className="font-medium mb-2">⚡ Hooks Scalables</h4>
|
|
810
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
811
|
+
Collection de hooks React pour écouter des tables ou événements
|
|
812
|
+
spécifiques avec auto-refresh.
|
|
813
|
+
</p>
|
|
814
|
+
<h4 className="font-medium mb-2">🛠️ Build intégré</h4>
|
|
815
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
816
|
+
Génération automatique de la configuration TypeScript lors du build
|
|
817
|
+
des modules.
|
|
818
|
+
</p>
|
|
819
|
+
<h3 className="text-lg font-semibold mb-2">Avantages du système</h3>
|
|
820
|
+
<div className="space-y-2">
|
|
821
|
+
<div className="flex items-start gap-2">
|
|
822
|
+
<span>✅ Configuration déclarative dans les modules</span>
|
|
816
823
|
</div>
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
<div>
|
|
820
|
-
<h3 className="text-lg font-semibold mb-2">
|
|
821
|
-
Architecture du système
|
|
822
|
-
</h3>
|
|
823
|
-
<div className="space-y-3">
|
|
824
|
-
<div className="border-l-4 border-blue-500 pl-4">
|
|
825
|
-
<h4 className="font-semibold text-blue-600 dark:text-blue-400">
|
|
826
|
-
🎯 EventBus Global
|
|
827
|
-
</h4>
|
|
828
|
-
<p className="text-sm text-slate-600 dark:text-slate-400">
|
|
829
|
-
Système central de coordination des événements realtime à
|
|
830
|
-
travers toute l'application.
|
|
831
|
-
</p>
|
|
832
|
-
</div>
|
|
833
|
-
|
|
834
|
-
<div className="border-l-4 border-green-500 pl-4">
|
|
835
|
-
<h4 className="font-semibold text-green-600 dark:text-green-400">
|
|
836
|
-
🔌 RealtimeProvider
|
|
837
|
-
</h4>
|
|
838
|
-
<p className="text-sm text-slate-600 dark:text-slate-400">
|
|
839
|
-
Provider React qui établit les connexions Supabase Realtime
|
|
840
|
-
basées sur la configuration des modules.
|
|
841
|
-
</p>
|
|
842
|
-
</div>
|
|
843
|
-
|
|
844
|
-
<div className="border-l-4 border-purple-500 pl-4">
|
|
845
|
-
<h4 className="font-semibold text-purple-600 dark:text-purple-400">
|
|
846
|
-
⚡ Hooks Scalables
|
|
847
|
-
</h4>
|
|
848
|
-
<p className="text-sm text-slate-600 dark:text-slate-400">
|
|
849
|
-
Collection de hooks React pour écouter des tables ou
|
|
850
|
-
événements spécifiques avec auto-refresh.
|
|
851
|
-
</p>
|
|
852
|
-
</div>
|
|
853
|
-
|
|
854
|
-
<div className="border-l-4 border-orange-500 pl-4">
|
|
855
|
-
<h4 className="font-semibold text-orange-600 dark:text-orange-400">
|
|
856
|
-
🛠️ Build intégré
|
|
857
|
-
</h4>
|
|
858
|
-
<p className="text-sm text-slate-600 dark:text-slate-400">
|
|
859
|
-
Génération automatique de la configuration TypeScript lors du
|
|
860
|
-
build des modules.
|
|
861
|
-
</p>
|
|
862
|
-
</div>
|
|
824
|
+
<div className="flex items-start gap-2">
|
|
825
|
+
<span>✅ Génération automatique de config</span>
|
|
863
826
|
</div>
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
<
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
<span>Génération automatique de config</span>
|
|
876
|
-
</div>
|
|
877
|
-
<div className="flex items-start gap-2">
|
|
878
|
-
<span className="text-green-600">✅</span>
|
|
879
|
-
<span>Hooks React prêts à l'emploi</span>
|
|
880
|
-
</div>
|
|
881
|
-
<div className="flex items-start gap-2">
|
|
882
|
-
<span className="text-green-600">✅</span>
|
|
883
|
-
<span>Sécurité RLS de Supabase</span>
|
|
884
|
-
</div>
|
|
885
|
-
<div className="flex items-start gap-2">
|
|
886
|
-
<span className="text-green-600">✅</span>
|
|
887
|
-
<span>Scalable pour n'importe quelle table</span>
|
|
888
|
-
</div>
|
|
889
|
-
<div className="flex items-start gap-2">
|
|
890
|
-
<span className="text-green-600">✅</span>
|
|
891
|
-
<span>TypeScript avec types générés</span>
|
|
892
|
-
</div>
|
|
827
|
+
<div className="flex items-start gap-2">
|
|
828
|
+
<span>✅ Hooks React prêts à l'emploi</span>
|
|
829
|
+
</div>
|
|
830
|
+
<div className="flex items-start gap-2">
|
|
831
|
+
<span>✅ Sécurité RLS de Supabase</span>
|
|
832
|
+
</div>
|
|
833
|
+
<div className="flex items-start gap-2">
|
|
834
|
+
<span>✅ Scalable pour n'importe quelle table</span>
|
|
835
|
+
</div>
|
|
836
|
+
<div className="flex items-start gap-2">
|
|
837
|
+
<span>✅ TypeScript avec types générés</span>
|
|
893
838
|
</div>
|
|
894
839
|
</div>
|
|
895
|
-
|
|
896
|
-
<div>
|
|
897
|
-
<
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
</
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
</
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
</p>
|
|
918
|
-
</div>
|
|
919
|
-
|
|
920
|
-
<div className="p-3 bg-green-50 dark:bg-green-950 rounded-lg">
|
|
921
|
-
<h4 className="font-medium text-green-700 dark:text-green-300 mb-1">
|
|
922
|
-
📊 Données collaboratives
|
|
923
|
-
</h4>
|
|
924
|
-
<p className="text-sm text-green-600 dark:text-green-400">
|
|
925
|
-
Synchronisation automatique des modifications de données entre
|
|
926
|
-
utilisateurs
|
|
927
|
-
</p>
|
|
928
|
-
</div>
|
|
840
|
+
<h3 className="text-lg font-semibold mb-2">Exemples d'utilisation</h3>
|
|
841
|
+
<div className="space-y-2">
|
|
842
|
+
<div className="flex items-start gap-2">
|
|
843
|
+
<span className="text-green-600">✅</span>
|
|
844
|
+
<span>
|
|
845
|
+
<strong>🔔 Notifications</strong>: Affichage en temps réel des
|
|
846
|
+
nouvelles notifications avec badge et auto-refresh
|
|
847
|
+
</span>
|
|
848
|
+
</div>
|
|
849
|
+
<div className="flex items-start gap-2">
|
|
850
|
+
<span className="text-green-600">✅</span>
|
|
851
|
+
<span>
|
|
852
|
+
<strong>👥 Utilisateurs en ligne</strong>: Suivi des
|
|
853
|
+
connexions/déconnexions des utilisateurs en direct
|
|
854
|
+
</span>
|
|
855
|
+
</div>
|
|
856
|
+
<div className="flex items-start gap-2">
|
|
857
|
+
<span className="text-green-600">✅</span>
|
|
858
|
+
<span>
|
|
859
|
+
<strong>📊 Données collaboratives</strong>: Synchronisation
|
|
860
|
+
automatique des modifications de données entre utilisateurs
|
|
861
|
+
</span>
|
|
929
862
|
</div>
|
|
930
863
|
</div>
|
|
931
864
|
</CardBody>
|
|
@@ -939,24 +872,277 @@ function MonComposant() {
|
|
|
939
872
|
</h2>
|
|
940
873
|
</CardHeader>
|
|
941
874
|
<CardBody className="space-y-4">
|
|
942
|
-
<p className="text-slate-600 dark:text-slate-400">
|
|
875
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
943
876
|
Chaque module peut exporter un composant de documentation qui sera
|
|
944
877
|
automatiquement intégré dans cette page.
|
|
945
878
|
</p>
|
|
879
|
+
<h3 className="text-lg font-semibold mb-2">
|
|
880
|
+
Documentation auto-générée
|
|
881
|
+
</h3>
|
|
882
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
883
|
+
Lorsque vous créez un module, la documentation de base (
|
|
884
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
885
|
+
Doc.tsx
|
|
886
|
+
</code>
|
|
887
|
+
) est automatiquement générée à partir du fichier{" "}
|
|
888
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
889
|
+
build.config.ts
|
|
890
|
+
</code>
|
|
891
|
+
. Cette documentation inclut :
|
|
892
|
+
</p>
|
|
893
|
+
<div className="space-y-2">
|
|
894
|
+
<div className="flex items-start gap-2">
|
|
895
|
+
<span className="text-green-600">✅</span>
|
|
896
|
+
<span>Les pages disponibles</span>
|
|
897
|
+
</div>
|
|
898
|
+
<div className="flex items-start gap-2">
|
|
899
|
+
<span className="text-green-600">✅</span>
|
|
900
|
+
<span>Les routes API</span>
|
|
901
|
+
</div>
|
|
902
|
+
<div className="flex items-start gap-2">
|
|
903
|
+
<span className="text-green-600">✅</span>
|
|
904
|
+
<span>Les tables de base de données</span>
|
|
905
|
+
</div>
|
|
906
|
+
<div className="flex items-start gap-2">
|
|
907
|
+
<span className="text-green-600">✅</span>
|
|
908
|
+
<span>Les instructions d'installation</span>
|
|
909
|
+
</div>
|
|
910
|
+
</div>
|
|
911
|
+
<h4 className="font-medium mb-2">Régénérer la documentation</h4>
|
|
912
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
913
|
+
{`pnpm update:module-docs`}
|
|
914
|
+
</Snippet>
|
|
915
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
916
|
+
{`# ou pour un module spécifique`}
|
|
917
|
+
</Snippet>
|
|
918
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
919
|
+
{`pnpm update:module-docs auth`}
|
|
920
|
+
</Snippet>
|
|
921
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
922
|
+
⚠️ <strong>Important</strong> : Le fichier{" "}
|
|
923
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
924
|
+
Doc.tsx
|
|
925
|
+
</code>{" "}
|
|
926
|
+
est <strong>écrasé</strong> à chaque génération. Ne le modifiez pas
|
|
927
|
+
directement !
|
|
928
|
+
</p>
|
|
929
|
+
<h3 className="text-lg font-semibold mb-2">
|
|
930
|
+
Personnaliser la section "Utilisation"
|
|
931
|
+
</h3>
|
|
932
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
933
|
+
Pour ajouter du contenu personnalisé qui ne sera{" "}
|
|
934
|
+
<strong>jamais écrasé</strong>, créez un fichier{" "}
|
|
935
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
936
|
+
DocUsageCustom.tsx
|
|
937
|
+
</code>{" "}
|
|
938
|
+
:
|
|
939
|
+
</p>
|
|
940
|
+
<h4 className="font-medium mb-2">
|
|
941
|
+
Étape 1 : Créer le composant personnalisé
|
|
942
|
+
</h4>
|
|
943
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
944
|
+
Dans{" "}
|
|
945
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
946
|
+
packages/votre-module/src/components/DocUsageCustom.tsx
|
|
947
|
+
</code>{" "}
|
|
948
|
+
:
|
|
949
|
+
</p>
|
|
950
|
+
<Alert hideIcon color="primary" className="p-4 mb-4">
|
|
951
|
+
<pre className="whitespace-pre-wrap">{`"use client";
|
|
946
952
|
|
|
953
|
+
import { Card, CardBody, CardHeader, Alert, Tabs, Tab } from "@lastbrain/ui";
|
|
954
|
+
import { Lightbulb } from "lucide-react";
|
|
955
|
+
// Importez vos composants à documenter
|
|
956
|
+
import { MonComposant } from "../web/components/MonComposant";
|
|
957
|
+
|
|
958
|
+
export function DocUsageCustom() {
|
|
959
|
+
return (
|
|
960
|
+
<div className="space-y-6">
|
|
961
|
+
<Alert color="primary" className="mb-6">
|
|
962
|
+
<div className="flex items-start gap-2">
|
|
963
|
+
<Lightbulb size={20} className="mt-0.5 flex-shrink-0" />
|
|
947
964
|
<div>
|
|
948
|
-
<
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
952
|
-
Dans votre module, créez{" "}
|
|
953
|
-
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
954
|
-
src/components/Doc.tsx
|
|
955
|
-
</code>{" "}
|
|
956
|
-
:
|
|
965
|
+
<p className="font-semibold">Introduction</p>
|
|
966
|
+
<p className="text-sm mt-1">
|
|
967
|
+
Description de votre module et de ses fonctionnalités principales.
|
|
957
968
|
</p>
|
|
958
|
-
|
|
959
|
-
|
|
969
|
+
</div>
|
|
970
|
+
</div>
|
|
971
|
+
</Alert>
|
|
972
|
+
|
|
973
|
+
<Tabs aria-label="Exemples d'utilisation">
|
|
974
|
+
<Tab key="exemple1" title="Exemple 1">
|
|
975
|
+
<Card className="mt-4">
|
|
976
|
+
<CardHeader>
|
|
977
|
+
<h3 className="text-xl font-semibold">MonComposant</h3>
|
|
978
|
+
</CardHeader>
|
|
979
|
+
<CardBody className="space-y-6">
|
|
980
|
+
<div>
|
|
981
|
+
<h4 className="text-lg font-semibold mb-2">Description</h4>
|
|
982
|
+
<p className="text-slate-600 dark:text-slate-400">
|
|
983
|
+
Décrivez votre composant et son utilisation.
|
|
984
|
+
</p>
|
|
985
|
+
</div>
|
|
986
|
+
|
|
987
|
+
<div>
|
|
988
|
+
<h4 className="text-lg font-semibold mb-3">Exemple interactif</h4>
|
|
989
|
+
<MonComposant />
|
|
990
|
+
</div>
|
|
991
|
+
|
|
992
|
+
<div>
|
|
993
|
+
<h4 className="text-lg font-semibold mb-2">Code d'utilisation</h4>
|
|
994
|
+
<Alert color="default" className="p-4">
|
|
995
|
+
<pre className="whitespace-pre-wrap text-sm">{\`import { MonComposant } from "@lastbrain/votre-module";
|
|
996
|
+
|
|
997
|
+
export function MyApp() {
|
|
998
|
+
return <MonComposant />;
|
|
999
|
+
}\`}</pre>
|
|
1000
|
+
</Alert>
|
|
1001
|
+
</div>
|
|
1002
|
+
|
|
1003
|
+
<div>
|
|
1004
|
+
<h4 className="text-lg font-semibold mb-2">Props disponibles</h4>
|
|
1005
|
+
<div className="overflow-x-auto">
|
|
1006
|
+
<table className="w-full text-sm">
|
|
1007
|
+
<thead className="border-b">
|
|
1008
|
+
<tr>
|
|
1009
|
+
<th className="text-left py-2 px-2">Prop</th>
|
|
1010
|
+
<th className="text-left py-2 px-2">Type</th>
|
|
1011
|
+
<th className="text-left py-2 px-2">Description</th>
|
|
1012
|
+
</tr>
|
|
1013
|
+
</thead>
|
|
1014
|
+
<tbody className="divide-y">
|
|
1015
|
+
<tr>
|
|
1016
|
+
<td className="py-2 px-2 font-mono">prop1</td>
|
|
1017
|
+
<td className="py-2 px-2">string</td>
|
|
1018
|
+
<td className="py-2 px-2">Description de la prop</td>
|
|
1019
|
+
</tr>
|
|
1020
|
+
</tbody>
|
|
1021
|
+
</table>
|
|
1022
|
+
</div>
|
|
1023
|
+
</div>
|
|
1024
|
+
</CardBody>
|
|
1025
|
+
</Card>
|
|
1026
|
+
</Tab>
|
|
1027
|
+
|
|
1028
|
+
<Tab key="exemple2" title="Exemple 2">
|
|
1029
|
+
{/* Autres exemples */}
|
|
1030
|
+
</Tab>
|
|
1031
|
+
</Tabs>
|
|
1032
|
+
</div>
|
|
1033
|
+
);
|
|
1034
|
+
}`}</pre>
|
|
1035
|
+
</Alert>
|
|
1036
|
+
<h4 className="font-medium mb-2">
|
|
1037
|
+
Étape 2 : Le générateur l'intègre automatiquement
|
|
1038
|
+
</h4>
|
|
1039
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
1040
|
+
Une fois{" "}
|
|
1041
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
1042
|
+
DocUsageCustom.tsx
|
|
1043
|
+
</code>{" "}
|
|
1044
|
+
créé, lancez la régénération :
|
|
1045
|
+
</p>
|
|
1046
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
1047
|
+
{`pnpm update:module-docs`}
|
|
1048
|
+
</Snippet>
|
|
1049
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
1050
|
+
Le script détecte automatiquement l'existence de{" "}
|
|
1051
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
1052
|
+
DocUsageCustom.tsx
|
|
1053
|
+
</code>{" "}
|
|
1054
|
+
et l'importe dans{" "}
|
|
1055
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
1056
|
+
Doc.tsx
|
|
1057
|
+
</code>{" "}
|
|
1058
|
+
:
|
|
1059
|
+
</p>
|
|
1060
|
+
<Alert hideIcon color="primary" className="p-4 mb-4">
|
|
1061
|
+
<pre className="whitespace-pre-wrap">{`// Doc.tsx (généré automatiquement)
|
|
1062
|
+
import { DocUsageCustom } from "./DocUsageCustom";
|
|
1063
|
+
|
|
1064
|
+
// Dans la section Utilisation :
|
|
1065
|
+
<Card>
|
|
1066
|
+
<CardHeader>
|
|
1067
|
+
<h2>Utilisation</h2>
|
|
1068
|
+
</CardHeader>
|
|
1069
|
+
<CardBody>
|
|
1070
|
+
<DocUsageCustom />
|
|
1071
|
+
</CardBody>
|
|
1072
|
+
</Card>`}</pre>
|
|
1073
|
+
</Alert>
|
|
1074
|
+
<h4 className="font-medium mb-2">
|
|
1075
|
+
Étape 3 : Mettre à jour sans perdre vos modifications
|
|
1076
|
+
</h4>
|
|
1077
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
1078
|
+
Vous pouvez maintenant régénérer la documentation autant de fois que
|
|
1079
|
+
vous voulez, votre fichier{" "}
|
|
1080
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
1081
|
+
DocUsageCustom.tsx
|
|
1082
|
+
</code>{" "}
|
|
1083
|
+
ne sera <strong>jamais écrasé</strong> :
|
|
1084
|
+
</p>
|
|
1085
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
1086
|
+
{`pnpm update:module-docs`}
|
|
1087
|
+
</Snippet>
|
|
1088
|
+
<h3 className="text-lg font-semibold mb-2">
|
|
1089
|
+
Exemple concret : Module AI
|
|
1090
|
+
</h3>
|
|
1091
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
1092
|
+
Le module AI utilise cette approche pour documenter ses composants
|
|
1093
|
+
de génération :
|
|
1094
|
+
</p>
|
|
1095
|
+
<Alert hideIcon color="primary" className="p-4 mb-4">
|
|
1096
|
+
<pre className="whitespace-pre-wrap">{`// packages/module-ai/src/components/DocUsageCustom.tsx
|
|
1097
|
+
import { TextareaGenerative } from "../web/components/TextareaGenerative";
|
|
1098
|
+
import { ImageGenerative } from "../web/components/ImageGenerative";
|
|
1099
|
+
|
|
1100
|
+
export function DocUsageCustom() {
|
|
1101
|
+
return (
|
|
1102
|
+
<Tabs>
|
|
1103
|
+
<Tab key="textarea" title="Génération de Texte">
|
|
1104
|
+
<TextareaGenerative
|
|
1105
|
+
prompt="Écris une courte description..."
|
|
1106
|
+
model="gpt-4o-mini"
|
|
1107
|
+
/>
|
|
1108
|
+
</Tab>
|
|
1109
|
+
<Tab key="image" title="Génération d'Images">
|
|
1110
|
+
<ImageGenerative
|
|
1111
|
+
prompt="Un chat astronaute..."
|
|
1112
|
+
model="dall-e-3"
|
|
1113
|
+
/>
|
|
1114
|
+
</Tab>
|
|
1115
|
+
</Tabs>
|
|
1116
|
+
);
|
|
1117
|
+
}`}</pre>
|
|
1118
|
+
</Alert>
|
|
1119
|
+
<h3 className="text-lg font-semibold mb-2">Structure recommandée</h3>
|
|
1120
|
+
<Alert
|
|
1121
|
+
hideIcon
|
|
1122
|
+
color="primary"
|
|
1123
|
+
className="p-4 mb-4 whitespace-pre-wrap"
|
|
1124
|
+
>{`packages/votre-module/
|
|
1125
|
+
├── src/
|
|
1126
|
+
│ ├── components/
|
|
1127
|
+
│ │ ├── Doc.tsx # ⚠️ AUTO-GÉNÉRÉ - Ne pas modifier
|
|
1128
|
+
│ │ └── DocUsageCustom.tsx # ✅ Votre contenu personnalisé
|
|
1129
|
+
│ ├── web/
|
|
1130
|
+
│ │ └── components/
|
|
1131
|
+
│ │ └── MonComposant.tsx # Vos composants à documenter
|
|
1132
|
+
│ └── votre-module.build.config.ts`}</Alert>
|
|
1133
|
+
<h3 className="text-lg font-semibold mb-2">
|
|
1134
|
+
Créer une documentation
|
|
1135
|
+
</h3>
|
|
1136
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
1137
|
+
Si vous préférez créer une documentation complètement manuelle,
|
|
1138
|
+
créez{" "}
|
|
1139
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
1140
|
+
src/components/Doc.tsx
|
|
1141
|
+
</code>{" "}
|
|
1142
|
+
:
|
|
1143
|
+
</p>
|
|
1144
|
+
<Alert hideIcon color="primary" className="p-4 mb-4">
|
|
1145
|
+
<pre className="whitespace-pre-wrap">{`export function MonModuleDoc() {
|
|
960
1146
|
return (
|
|
961
1147
|
<div>
|
|
962
1148
|
<h1>Mon Module</h1>
|
|
@@ -964,83 +1150,307 @@ function MonComposant() {
|
|
|
964
1150
|
</div>
|
|
965
1151
|
);
|
|
966
1152
|
}`}</pre>
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
<div className="bg-slate-50 dark:bg-slate-900 p-4 rounded-lg text-sm font-mono">
|
|
982
|
-
<pre>{`export { MonModuleDoc } from "./components/Doc.js";`}</pre>
|
|
983
|
-
</div>
|
|
984
|
-
</div>
|
|
1153
|
+
</Alert>
|
|
1154
|
+
<h3 className="text-lg font-semibold mb-2">
|
|
1155
|
+
Exporter la documentation
|
|
1156
|
+
</h3>
|
|
1157
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
1158
|
+
Dans{" "}
|
|
1159
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
1160
|
+
src/index.ts
|
|
1161
|
+
</code>{" "}
|
|
1162
|
+
:
|
|
1163
|
+
</p>
|
|
1164
|
+
<Alert hideIcon color="primary" className="p-4 mb-4">
|
|
1165
|
+
<pre className="whitespace-pre-wrap">{`export { MonModuleDoc } from "./components/Doc.js";`}</pre>
|
|
1166
|
+
</Alert>
|
|
985
1167
|
</CardBody>
|
|
986
1168
|
</Card>
|
|
987
1169
|
|
|
988
1170
|
<Card id="section-links" className="scroll-mt-32">
|
|
989
1171
|
<CardHeader>
|
|
990
1172
|
<h2 className="text-2xl font-semibold flex items-center gap-2">
|
|
991
|
-
<
|
|
992
|
-
Liens utiles
|
|
1173
|
+
<Link size={24} />
|
|
1174
|
+
Liens utiles & remerciements 🙏
|
|
993
1175
|
</h2>
|
|
994
1176
|
</CardHeader>
|
|
995
1177
|
<CardBody>
|
|
996
|
-
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
997
|
-
<
|
|
1178
|
+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
|
1179
|
+
<Card
|
|
1180
|
+
className="hover:shadow-lg transition-shadow"
|
|
1181
|
+
isPressable
|
|
1182
|
+
as="a"
|
|
998
1183
|
href="https://nextjs.org/docs"
|
|
999
1184
|
target="_blank"
|
|
1000
1185
|
rel="noopener noreferrer"
|
|
1001
|
-
className="p-4 border border-slate-200 dark:border-slate-700 rounded-lg hover:bg-slate-50 dark:hover:bg-slate-800 transition-colors"
|
|
1002
1186
|
>
|
|
1003
|
-
<
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1187
|
+
<CardBody>
|
|
1188
|
+
<h3 className="text-lg font-semibold mb-2">Next.js</h3>
|
|
1189
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-3">
|
|
1190
|
+
Documentation officielle
|
|
1191
|
+
</p>
|
|
1192
|
+
<p className="text-xs text-blue-600 dark:text-blue-400 truncate">
|
|
1193
|
+
https://nextjs.org/docs
|
|
1194
|
+
</p>
|
|
1195
|
+
</CardBody>
|
|
1196
|
+
</Card>
|
|
1197
|
+
<Card
|
|
1198
|
+
className="hover:shadow-lg transition-shadow"
|
|
1199
|
+
isPressable
|
|
1200
|
+
as="a"
|
|
1201
|
+
href="https://supabase.com/docs"
|
|
1202
|
+
target="_blank"
|
|
1203
|
+
rel="noopener noreferrer"
|
|
1204
|
+
>
|
|
1205
|
+
<CardBody>
|
|
1206
|
+
<h3 className="text-lg font-semibold mb-2">Supabase</h3>
|
|
1207
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-3">
|
|
1208
|
+
Documentation officielle
|
|
1209
|
+
</p>
|
|
1210
|
+
<p className="text-xs text-blue-600 dark:text-blue-400 truncate">
|
|
1211
|
+
https://supabase.com/docs
|
|
1212
|
+
</p>
|
|
1213
|
+
</CardBody>
|
|
1214
|
+
</Card>
|
|
1215
|
+
<Card
|
|
1216
|
+
className="hover:shadow-lg transition-shadow"
|
|
1217
|
+
isPressable
|
|
1218
|
+
as="a"
|
|
1219
|
+
href="https://www.heroui.com/docs"
|
|
1220
|
+
target="_blank"
|
|
1221
|
+
rel="noopener noreferrer"
|
|
1222
|
+
>
|
|
1223
|
+
<CardBody>
|
|
1224
|
+
<h3 className="text-lg font-semibold mb-2">Heroui</h3>
|
|
1225
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-3">
|
|
1226
|
+
Composants UI
|
|
1227
|
+
</p>
|
|
1228
|
+
<p className="text-xs text-blue-600 dark:text-blue-400 truncate">
|
|
1229
|
+
https://www.heroui.com/docs
|
|
1230
|
+
</p>
|
|
1231
|
+
</CardBody>
|
|
1232
|
+
</Card>
|
|
1233
|
+
<Card
|
|
1234
|
+
className="hover:shadow-lg transition-shadow"
|
|
1235
|
+
isPressable
|
|
1236
|
+
as="a"
|
|
1237
|
+
href="https://tailwindcss.com/docs"
|
|
1238
|
+
target="_blank"
|
|
1239
|
+
rel="noopener noreferrer"
|
|
1240
|
+
>
|
|
1241
|
+
<CardBody>
|
|
1242
|
+
<h3 className="text-lg font-semibold mb-2">Tailwind CSS</h3>
|
|
1243
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-3">
|
|
1244
|
+
Framework CSS
|
|
1245
|
+
</p>
|
|
1246
|
+
<p className="text-xs text-blue-600 dark:text-blue-400 truncate">
|
|
1247
|
+
https://tailwindcss.com/docs
|
|
1248
|
+
</p>
|
|
1249
|
+
</CardBody>
|
|
1250
|
+
</Card>
|
|
1251
|
+
<Card
|
|
1252
|
+
className="hover:shadow-lg transition-shadow"
|
|
1253
|
+
isPressable
|
|
1254
|
+
as="a"
|
|
1255
|
+
href="https://lucide.dev/"
|
|
1256
|
+
target="_blank"
|
|
1257
|
+
rel="noopener noreferrer"
|
|
1258
|
+
>
|
|
1259
|
+
<CardBody>
|
|
1260
|
+
<h3 className="text-lg font-semibold mb-2">Lucide Icons</h3>
|
|
1261
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-3">
|
|
1262
|
+
Icones SVG
|
|
1263
|
+
</p>
|
|
1264
|
+
<p className="text-xs text-blue-600 dark:text-blue-400 truncate">
|
|
1265
|
+
https://lucide.dev/
|
|
1266
|
+
</p>
|
|
1267
|
+
</CardBody>
|
|
1268
|
+
</Card>
|
|
1269
|
+
<Card
|
|
1270
|
+
className="hover:shadow-lg transition-shadow"
|
|
1271
|
+
isPressable
|
|
1272
|
+
as="a"
|
|
1273
|
+
href="https://stripe.com/docs"
|
|
1274
|
+
target="_blank"
|
|
1275
|
+
rel="noopener noreferrer"
|
|
1276
|
+
>
|
|
1277
|
+
<CardBody>
|
|
1278
|
+
<h3 className="text-lg font-semibold mb-2">Stripe</h3>
|
|
1279
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-3">
|
|
1280
|
+
Système de paiement
|
|
1281
|
+
</p>
|
|
1282
|
+
<p className="text-xs text-blue-600 dark:text-blue-400 truncate">
|
|
1283
|
+
https://stripe.com/docs
|
|
1284
|
+
</p>
|
|
1285
|
+
</CardBody>
|
|
1286
|
+
</Card>
|
|
1287
|
+
</div>
|
|
1288
|
+
</CardBody>
|
|
1289
|
+
</Card>
|
|
1008
1290
|
|
|
1291
|
+
<Card id="section-modules" className="scroll-mt-32">
|
|
1292
|
+
<CardHeader>
|
|
1293
|
+
<h2 className="text-2xl font-semibold flex items-center gap-2">
|
|
1294
|
+
<FileText size={24} />
|
|
1295
|
+
Modules
|
|
1296
|
+
</h2>
|
|
1297
|
+
</CardHeader>
|
|
1298
|
+
<CardBody className="space-y-4">
|
|
1299
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
1300
|
+
Les modules LastBrain permettent d'ajouter des fonctionnalités
|
|
1301
|
+
complètes à votre application de manière modulaire.
|
|
1302
|
+
</p>
|
|
1303
|
+
<h3 className="text-lg font-semibold mb-2">Modules Disponibles</h3>
|
|
1304
|
+
<h4 className="font-medium mb-2">
|
|
1305
|
+
[module-ai](../packages/module-ai/README.md)
|
|
1306
|
+
</h4>
|
|
1307
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
1308
|
+
@lastbrain/module-ai
|
|
1309
|
+
</p>
|
|
1310
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
1311
|
+
<strong>Pages</strong>: 1 auth, 1 admin
|
|
1312
|
+
</p>
|
|
1313
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
1314
|
+
<strong>Tables</strong>: user_token_ledger, user_prompts
|
|
1315
|
+
</p>
|
|
1316
|
+
<h4 className="font-medium mb-2">Installation du module ai</h4>
|
|
1317
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
1318
|
+
{`pnpm lastbrain add-module ai`}
|
|
1319
|
+
</Snippet>
|
|
1320
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
1009
1321
|
<a
|
|
1010
|
-
href="
|
|
1322
|
+
href="../packages/module-ai/README.md"
|
|
1323
|
+
className="text-blue-600 hover:underline"
|
|
1011
1324
|
target="_blank"
|
|
1012
1325
|
rel="noopener noreferrer"
|
|
1013
|
-
className="p-4 border border-slate-200 dark:border-slate-700 rounded-lg hover:bg-slate-50 dark:hover:bg-slate-800 transition-colors"
|
|
1014
1326
|
>
|
|
1015
|
-
|
|
1016
|
-
<p className="text-sm text-slate-600 dark:text-slate-400">
|
|
1017
|
-
Documentation officielle
|
|
1018
|
-
</p>
|
|
1327
|
+
📖 Documentation complète →
|
|
1019
1328
|
</a>
|
|
1020
|
-
|
|
1329
|
+
</p>
|
|
1330
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">---</p>
|
|
1331
|
+
<h4 className="font-medium mb-2">
|
|
1332
|
+
[module-auth](../packages/module-auth/README.md)
|
|
1333
|
+
</h4>
|
|
1334
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
1335
|
+
@lastbrain/module-auth
|
|
1336
|
+
</p>
|
|
1337
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
1338
|
+
<strong>Pages</strong>: 3 publique(s), 4 auth, 2 admin
|
|
1339
|
+
</p>
|
|
1340
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
1341
|
+
<strong>Tables</strong>: user_profil, user_address,
|
|
1342
|
+
user_notifications
|
|
1343
|
+
</p>
|
|
1344
|
+
<h4 className="font-medium mb-2">Installation du module auth</h4>
|
|
1345
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
1346
|
+
{`pnpm lastbrain add-module auth`}
|
|
1347
|
+
</Snippet>
|
|
1348
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
1021
1349
|
<a
|
|
1022
|
-
href="
|
|
1350
|
+
href="../packages/module-auth/README.md"
|
|
1351
|
+
className="text-blue-600 hover:underline"
|
|
1023
1352
|
target="_blank"
|
|
1024
1353
|
rel="noopener noreferrer"
|
|
1025
|
-
className="p-4 border border-slate-200 dark:border-slate-700 rounded-lg hover:bg-slate-50 dark:hover:bg-slate-800 transition-colors"
|
|
1026
1354
|
>
|
|
1027
|
-
|
|
1028
|
-
<p className="text-sm text-slate-600 dark:text-slate-400">
|
|
1029
|
-
Composants UI
|
|
1030
|
-
</p>
|
|
1355
|
+
📖 Documentation complète →
|
|
1031
1356
|
</a>
|
|
1032
|
-
|
|
1357
|
+
</p>
|
|
1358
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">---</p>
|
|
1359
|
+
<h4 className="font-medium mb-2">
|
|
1360
|
+
[module-tasks](../packages/module-tasks/README.md)
|
|
1361
|
+
</h4>
|
|
1362
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
1363
|
+
@lastbrain/module-tasks
|
|
1364
|
+
</p>
|
|
1365
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
1366
|
+
<strong>Pages</strong>: 2 auth, 1 admin
|
|
1367
|
+
</p>
|
|
1368
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
1369
|
+
<strong>Tables</strong>: tasks, tasks_logs
|
|
1370
|
+
</p>
|
|
1371
|
+
<h4 className="font-medium mb-2">Installation du module tasks</h4>
|
|
1372
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
1373
|
+
{`pnpm lastbrain add-module tasks`}
|
|
1374
|
+
</Snippet>
|
|
1375
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
1033
1376
|
<a
|
|
1034
|
-
href="
|
|
1377
|
+
href="../packages/module-tasks/README.md"
|
|
1378
|
+
className="text-blue-600 hover:underline"
|
|
1379
|
+
target="_blank"
|
|
1380
|
+
rel="noopener noreferrer"
|
|
1381
|
+
>
|
|
1382
|
+
📖 Documentation complète →
|
|
1383
|
+
</a>
|
|
1384
|
+
</p>
|
|
1385
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">---</p>
|
|
1386
|
+
<h3 className="text-lg font-semibold mb-2">Commandes</h3>
|
|
1387
|
+
<h4 className="font-medium mb-2">Installer un module</h4>
|
|
1388
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
1389
|
+
{`pnpm lastbrain add-module nom-du-module`}
|
|
1390
|
+
</Snippet>
|
|
1391
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
1392
|
+
{`pnpm build:modules`}
|
|
1393
|
+
</Snippet>
|
|
1394
|
+
<h4 className="font-medium mb-2">Créer un nouveau module</h4>
|
|
1395
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
1396
|
+
{`pnpm lastbrain create-module nom-du-module`}
|
|
1397
|
+
</Snippet>
|
|
1398
|
+
<h4 className="font-medium mb-2">
|
|
1399
|
+
Générer la documentation des modules
|
|
1400
|
+
</h4>
|
|
1401
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
1402
|
+
{`pnpm generate:module-docs`}
|
|
1403
|
+
</Snippet>
|
|
1404
|
+
<h4 className="font-medium mb-2">Supprimer un module</h4>
|
|
1405
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
1406
|
+
{`pnpm lastbrain remove-module nom-du-module`}
|
|
1407
|
+
</Snippet>
|
|
1408
|
+
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
1409
|
+
{`pnpm build:modules`}
|
|
1410
|
+
</Snippet>
|
|
1411
|
+
<h3 className="text-lg font-semibold mb-2">
|
|
1412
|
+
Développement de modules
|
|
1413
|
+
</h3>
|
|
1414
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
1415
|
+
Pour créer un nouveau module, consultez la{" "}
|
|
1416
|
+
<a
|
|
1417
|
+
href="./004_CREATE_MODULE.md"
|
|
1418
|
+
className="text-blue-600 hover:underline"
|
|
1035
1419
|
target="_blank"
|
|
1036
1420
|
rel="noopener noreferrer"
|
|
1037
|
-
className="p-4 border border-slate-200 dark:border-slate-700 rounded-lg hover:bg-slate-50 dark:hover:bg-slate-800 transition-colors"
|
|
1038
1421
|
>
|
|
1039
|
-
|
|
1040
|
-
<p className="text-sm text-slate-600 dark:text-slate-400">
|
|
1041
|
-
Framework CSS
|
|
1042
|
-
</p>
|
|
1422
|
+
documentation de création de modules
|
|
1043
1423
|
</a>
|
|
1424
|
+
.
|
|
1425
|
+
</p>
|
|
1426
|
+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
|
|
1427
|
+
La documentation de chaque module est générée automatiquement depuis
|
|
1428
|
+
:
|
|
1429
|
+
</p>
|
|
1430
|
+
<div className="space-y-2">
|
|
1431
|
+
<div className="flex items-start gap-2">
|
|
1432
|
+
<span className="text-green-600">✅</span>
|
|
1433
|
+
<span>
|
|
1434
|
+
Le fichier{" "}
|
|
1435
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
1436
|
+
module-name.build.config.ts
|
|
1437
|
+
</code>{" "}
|
|
1438
|
+
pour les pages et APIs
|
|
1439
|
+
</span>
|
|
1440
|
+
</div>
|
|
1441
|
+
<div className="flex items-start gap-2">
|
|
1442
|
+
<span className="text-green-600">✅</span>
|
|
1443
|
+
<span>Les fichiers de migration SQL pour les tables</span>
|
|
1444
|
+
</div>
|
|
1445
|
+
<div className="flex items-start gap-2">
|
|
1446
|
+
<span className="text-green-600">✅</span>
|
|
1447
|
+
<span>
|
|
1448
|
+
Le README.md est auto-généré avec{" "}
|
|
1449
|
+
<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
|
|
1450
|
+
pnpm generate:module-docs
|
|
1451
|
+
</code>
|
|
1452
|
+
</span>
|
|
1453
|
+
</div>
|
|
1044
1454
|
</div>
|
|
1045
1455
|
</CardBody>
|
|
1046
1456
|
</Card>
|