@lastbrain/module-auth 0.1.12 → 0.1.15
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 +1 -0
- package/dist/auth.build.config.d.ts.map +1 -1
- package/dist/auth.build.config.js +25 -1
- package/dist/components/Doc.d.ts.map +1 -1
- package/dist/components/Doc.js +2 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/web/admin/user-detail.d.ts +10 -1
- package/dist/web/admin/user-detail.d.ts.map +1 -1
- package/dist/web/admin/user-detail.js +10 -2
- package/dist/web/admin/users/[id].d.ts.map +1 -1
- package/dist/web/admin/users/[id].js +2 -1
- package/dist/web/auth/dashboard.d.ts.map +1 -1
- package/dist/web/auth/folder.d.ts +2 -0
- package/dist/web/auth/folder.d.ts.map +1 -0
- package/dist/web/auth/folder.js +43 -0
- package/dist/web/public/SignInPage.js +1 -1
- package/dist/web/public/SignUpPage.js +1 -1
- package/package.json +2 -2
- package/src/auth.build.config.ts +25 -1
- package/src/components/Doc.tsx +13 -4
- package/src/index.ts +2 -0
- package/src/web/admin/user-detail.tsx +38 -1
- package/src/web/admin/users/[id].tsx +3 -1
- package/src/web/auth/dashboard.tsx +1 -0
- package/src/web/auth/folder.tsx +101 -0
- package/src/web/public/SignInPage.tsx +1 -1
- package/src/web/public/SignUpPage.tsx +1 -1
package/README.md
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.build.config.d.ts","sourceRoot":"","sources":["../src/auth.build.config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,QAAA,MAAM,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"auth.build.config.d.ts","sourceRoot":"","sources":["../src/auth.build.config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,QAAA,MAAM,eAAe,EAAE,iBA6NtB,CAAC;AAEF,eAAe,eAAe,CAAC"}
|
|
@@ -21,6 +21,11 @@ const authBuildConfig = {
|
|
|
21
21
|
path: "/dashboard",
|
|
22
22
|
componentExport: "DashboardPage",
|
|
23
23
|
},
|
|
24
|
+
{
|
|
25
|
+
section: "auth",
|
|
26
|
+
path: "/folder",
|
|
27
|
+
componentExport: "FolderPage",
|
|
28
|
+
},
|
|
24
29
|
{
|
|
25
30
|
section: "auth",
|
|
26
31
|
path: "/reglage",
|
|
@@ -136,22 +141,39 @@ const authBuildConfig = {
|
|
|
136
141
|
icon: "Users2",
|
|
137
142
|
path: "/admin/auth/users",
|
|
138
143
|
order: 1,
|
|
144
|
+
shortcut: "cmd+shift+u",
|
|
145
|
+
shortcutDisplay: "⌘⇧U",
|
|
139
146
|
},
|
|
140
147
|
],
|
|
141
|
-
|
|
148
|
+
auth: [
|
|
142
149
|
{
|
|
143
150
|
title: "Tableau de bord",
|
|
144
151
|
description: "Accédez à votre tableau de bord",
|
|
145
152
|
icon: "LayoutDashboard",
|
|
146
153
|
path: "/auth/dashboard",
|
|
147
154
|
order: 1,
|
|
155
|
+
shortcut: "cmd+shift+d",
|
|
156
|
+
shortcutDisplay: "⌘⇧D",
|
|
148
157
|
},
|
|
158
|
+
{
|
|
159
|
+
title: "Dossier",
|
|
160
|
+
description: "Accédez à votre dossier personnel",
|
|
161
|
+
icon: "FolderOpen",
|
|
162
|
+
path: "/auth/folder",
|
|
163
|
+
order: 2,
|
|
164
|
+
shortcut: "cmd+shift+f",
|
|
165
|
+
shortcutDisplay: "⌘⇧F",
|
|
166
|
+
},
|
|
167
|
+
],
|
|
168
|
+
account: [
|
|
149
169
|
{
|
|
150
170
|
title: "Mon profil",
|
|
151
171
|
description: "Gérez vos informations personnelles",
|
|
152
172
|
icon: "User2",
|
|
153
173
|
path: "/auth/profile",
|
|
154
174
|
order: 1,
|
|
175
|
+
shortcut: "cmd+shift+p",
|
|
176
|
+
shortcutDisplay: "⌘⇧P",
|
|
155
177
|
},
|
|
156
178
|
{
|
|
157
179
|
title: "Paramètres",
|
|
@@ -159,6 +181,8 @@ const authBuildConfig = {
|
|
|
159
181
|
icon: "Settings",
|
|
160
182
|
path: "/auth/reglage",
|
|
161
183
|
order: 2,
|
|
184
|
+
shortcut: "cmd+shift+s",
|
|
185
|
+
shortcutDisplay: "⌘⇧S",
|
|
162
186
|
},
|
|
163
187
|
{
|
|
164
188
|
title: "Déconnexion",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Doc.d.ts","sourceRoot":"","sources":["../../src/components/Doc.tsx"],"names":[],"mappings":"AAgBA;;;;;;GAMG;AACH,wBAAgB,GAAG,
|
|
1
|
+
{"version":3,"file":"Doc.d.ts","sourceRoot":"","sources":["../../src/components/Doc.tsx"],"names":[],"mappings":"AAgBA;;;;;;GAMG;AACH,wBAAgB,GAAG,4CAkWlB"}
|
package/dist/components/Doc.js
CHANGED
|
@@ -14,9 +14,9 @@ import { FileText, Zap, Database, Package, BookOpen, AlertTriangle, } from "luci
|
|
|
14
14
|
* pnpm update:module-docs
|
|
15
15
|
*/
|
|
16
16
|
export function Doc() {
|
|
17
|
-
return (_jsxs("div", { className: "container mx-auto p-6 space-y-6", children: [_jsxs(Card, { children: [_jsx(CardHeader, { children: _jsxs("div", { children: [_jsx("h1", { className: "text-3xl font-bold mb-2", children: "\uD83D\uDCE6 Module auth" }), _jsx("p", { className: "text-slate-600 dark:text-slate-400", children: "@lastbrain/module-auth" })] }) }), _jsx(CardBody, { children: _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-4", children: [_jsxs("div", { children: [_jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400", children: "Package" }), _jsx("code", { className: "text-sm font-semibold", children: "@lastbrain/module-auth" })] }), _jsxs("div", { children: [_jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400", children: "Slug" }), _jsx("code", { className: "text-sm font-semibold", children: "module-auth" })] }), _jsxs("div", { children: [_jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400", children: "Type" }), _jsx("code", { className: "text-sm font-semibold", children: "Module LastBrain" })] })] }) })] }), _jsxs(Card, { children: [_jsx(CardHeader, { children: _jsxs("h2", { className: "text-2xl font-semibold flex items-center gap-2", children: [_jsx(FileText, { size: 24 }), "Pages Disponibles"] }) }), _jsxs(CardBody, { className: "space-y-4", children: [_jsxs("div", { children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: "Pages Publiques" }), _jsxs("div", { className: "space-y-2", children: [_jsxs("div", { className: "flex items-start gap-2", children: [_jsx(Chip, { size: "sm", color: "success", variant: "flat", children: "GET" }), _jsx("code", { className: "text-sm", children: "/signin" }), _jsx("span", { className: "text-sm text-slate-600 dark:text-slate-400", children: "- SignInPage" })] }), _jsxs("div", { className: "flex items-start gap-2", children: [_jsx(Chip, { size: "sm", color: "success", variant: "flat", children: "GET" }), _jsx("code", { className: "text-sm", children: "/signup" }), _jsx("span", { className: "text-sm text-slate-600 dark:text-slate-400", children: "- SignUpPage" })] }), _jsxs("div", { className: "flex items-start gap-2", children: [_jsx(Chip, { size: "sm", color: "success", variant: "flat", children: "GET" }), _jsx("code", { className: "text-sm", children: "/reset-password" }), _jsx("span", { className: "text-sm text-slate-600 dark:text-slate-400", children: "- ResetPassword" })] })] })] }), _jsxs("div", { children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: "Pages Prot\u00E9g\u00E9es (Auth)" }), _jsxs("div", { className: "space-y-2", children: [_jsxs("div", { className: "flex items-start gap-2", children: [_jsx(Chip, { size: "sm", color: "primary", variant: "flat", children: "GET" }), _jsx("code", { className: "text-sm", children: "/dashboard" }), _jsx("span", { className: "text-sm text-slate-600 dark:text-slate-400", children: "- DashboardPage" })] }), _jsxs("div", { className: "flex items-start gap-2", children: [_jsx(Chip, { size: "sm", color: "primary", variant: "flat", children: "GET" }), _jsx("code", { className: "text-sm", children: "/reglage" }), _jsx("span", { className: "text-sm text-slate-600 dark:text-slate-400", children: "- ReglagePage" })] }), _jsxs("div", { className: "flex items-start gap-2", children: [_jsx(Chip, { size: "sm", color: "primary", variant: "flat", children: "GET" }), _jsx("code", { className: "text-sm", children: "/profile" }), _jsx("span", { className: "text-sm text-slate-600 dark:text-slate-400", children: "- ProfilePage" })] })] })] }), _jsxs("div", { children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: "Pages Admin" }), _jsx("div", { className: "space-y-2", children: _jsxs("div", { className: "flex items-start gap-2", children: [_jsx(Chip, { size: "sm", color: "secondary", variant: "flat", children: "GET" }), _jsx("code", { className: "text-sm", children: "/users" }), _jsx("span", { className: "text-sm text-slate-600 dark:text-slate-400", children: "- AdminUsersPage" })] }) })] })] })] }), _jsxs(Card, { children: [_jsx(CardHeader, { children: _jsxs("h2", { className: "text-2xl font-semibold flex items-center gap-2", children: [_jsx(Zap, { size: 24 }), "API Routes"] }) }), _jsxs(CardBody, { className: "space-y-4", children: [_jsxs("div", { children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: _jsx("code", { children: "/api/auth/signin" }) }), _jsxs("div", { className: "flex gap-2", children: [_jsx(Chip, { size: "sm", color: "success", variant: "flat", children: "GET" }), _jsx(Chip, { size: "sm", color: "primary", variant: "flat", children: "POST" }), _jsx(Chip, { size: "sm", color: "warning", variant: "flat", children: "PUT" }), _jsx(Chip, { size: "sm", color: "danger", variant: "flat", children: "DELETE" })] })] }), _jsxs("div", { children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: _jsx("code", { children: "/api/auth/profile" }) }), _jsxs("div", { className: "flex gap-2", children: [_jsx(Chip, { size: "sm", color: "success", variant: "flat", children: "GET" }), _jsx(Chip, { size: "sm", color: "primary", variant: "flat", children: "POST" }), _jsx(Chip, { size: "sm", color: "warning", variant: "flat", children: "PUT" }), _jsx(Chip, { size: "sm", color: "danger", variant: "flat", children: "DELETE" })] })] }), _jsxs("div", { children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: _jsx("code", { children: "/api/auth/me" }) }), _jsxs("div", { className: "flex gap-2", children: [_jsx(Chip, { size: "sm", color: "success", variant: "flat", children: "GET" }), _jsx(Chip, { size: "sm", color: "primary", variant: "flat", children: "POST" }), _jsx(Chip, { size: "sm", color: "warning", variant: "flat", children: "PUT" }), _jsx(Chip, { size: "sm", color: "danger", variant: "flat", children: "DELETE" })] })] }), _jsxs("div", { children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: _jsx("code", { children: "/api/admin/users" }) }), _jsxs("div", { className: "flex gap-2", children: [_jsx(Chip, { size: "sm", color: "success", variant: "flat", children: "GET" }), _jsx(Chip, { size: "sm", color: "primary", variant: "flat", children: "POST" }), _jsx(Chip, { size: "sm", color: "warning", variant: "flat", children: "PUT" }), _jsx(Chip, { size: "sm", color: "danger", variant: "flat", children: "DELETE" })] })] })] })] }), _jsxs(Card, { children: [_jsx(CardHeader, { children: _jsxs("h2", { className: "text-2xl font-semibold flex items-center gap-2", children: [_jsx(Database, { size: 24 }), "Base de Donn\u00E9es"] }) }), _jsxs(CardBody, { className: "space-y-6", children: [_jsx(TableStructure, { tableName: "user_profil", title: "user_profil", description: "Table user_profil du module auth" }), _jsx(TableStructure, { tableName: "user_address", title: "user_address", description: "Table user_address du module auth" }), _jsx(TableStructure, { tableName: "user_notifications", title: "user_notifications", description: "Table user_notifications du module auth" })] })] }), _jsxs(Card, { children: [_jsx(CardHeader, { children: _jsxs("h2", { className: "text-2xl font-semibold flex items-center gap-2", children: [_jsx(Package, { size: 24 }), "Installation"] }) }), _jsxs(CardBody, { className: "space-y-4", children: [_jsxs("div", { children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: "Ajouter le module" }), _jsx(Snippet, { symbol: "", hideSymbol: true, className: "text-sm mb-2", children: "pnpm lastbrain add-module auth" }), _jsx(Snippet, { symbol: "", hideSymbol: true, className: "text-sm mb-2", children: "pnpm build:modules" })] }), _jsxs("div", { children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: "Appliquer les migrations" }), _jsx(Snippet, { symbol: "", hideSymbol: true, className: "text-sm mb-2", children: "cd apps/votre-app" }), _jsx(Snippet, { symbol: "", hideSymbol: true, className: "text-sm mb-2", children: "supabase migration up" })] })] })] }), _jsxs(Card, { children: [_jsx(CardHeader, { children: _jsxs("h2", { className: "text-2xl font-semibold flex items-center gap-2", children: [_jsx(BookOpen, { size: 24 }), "Utilisation"] }) }), _jsxs(CardBody, { className: "space-y-4", children: [_jsxs(Alert, { color: "default", className: "mb-4", children: [_jsxs("p", { className: "text-sm", children: ["\uD83D\uDCDD ", _jsx("strong", { children: "Section \u00E0 compl\u00E9ter par l'auteur du module" })] }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400 mt-2", children: "Ajoutez ici des exemples d'utilisation, des configurations sp\u00E9cifiques, et toute information utile pour les d\u00E9veloppeurs utilisant ce module." })] }), _jsxs("div", { children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: "Exemple d'utilisation" }), _jsx(Alert, { color: "primary", className: "p-4 mb-4", children: _jsx("pre", { className: "whitespace-pre-wrap", children: `// Importez les composants depuis le module
|
|
17
|
+
return (_jsxs("div", { className: "container mx-auto p-6 space-y-6", children: [_jsxs(Card, { children: [_jsx(CardHeader, { children: _jsxs("div", { children: [_jsx("h1", { className: "text-3xl font-bold mb-2", children: "\uD83D\uDCE6 Module auth" }), _jsx("p", { className: "text-slate-600 dark:text-slate-400", children: "@lastbrain/module-auth" })] }) }), _jsx(CardBody, { children: _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-4", children: [_jsxs("div", { children: [_jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400", children: "Package" }), _jsx("code", { className: "text-sm font-semibold", children: "@lastbrain/module-auth" })] }), _jsxs("div", { children: [_jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400", children: "Slug" }), _jsx("code", { className: "text-sm font-semibold", children: "module-auth" })] }), _jsxs("div", { children: [_jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400", children: "Type" }), _jsx("code", { className: "text-sm font-semibold", children: "Module LastBrain" })] })] }) })] }), _jsxs(Card, { children: [_jsx(CardHeader, { children: _jsxs("h2", { className: "text-2xl font-semibold flex items-center gap-2", children: [_jsx(FileText, { size: 24 }), "Pages Disponibles"] }) }), _jsxs(CardBody, { className: "space-y-4", children: [_jsxs("div", { children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: "Pages Publiques" }), _jsxs("div", { className: "space-y-2", children: [_jsxs("div", { className: "flex items-start gap-2", children: [_jsx(Chip, { size: "sm", color: "success", variant: "flat", children: "GET" }), _jsx("code", { className: "text-sm", children: "/signin" }), _jsx("span", { className: "text-sm text-slate-600 dark:text-slate-400", children: "- SignInPage" })] }), _jsxs("div", { className: "flex items-start gap-2", children: [_jsx(Chip, { size: "sm", color: "success", variant: "flat", children: "GET" }), _jsx("code", { className: "text-sm", children: "/signup" }), _jsx("span", { className: "text-sm text-slate-600 dark:text-slate-400", children: "- SignUpPage" })] }), _jsxs("div", { className: "flex items-start gap-2", children: [_jsx(Chip, { size: "sm", color: "success", variant: "flat", children: "GET" }), _jsx("code", { className: "text-sm", children: "/reset-password" }), _jsx("span", { className: "text-sm text-slate-600 dark:text-slate-400", children: "- ResetPassword" })] })] })] }), _jsxs("div", { children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: "Pages Prot\u00E9g\u00E9es (Auth)" }), _jsxs("div", { className: "space-y-2", children: [_jsxs("div", { className: "flex items-start gap-2", children: [_jsx(Chip, { size: "sm", color: "primary", variant: "flat", children: "GET" }), _jsx("code", { className: "text-sm", children: "/dashboard" }), _jsx("span", { className: "text-sm text-slate-600 dark:text-slate-400", children: "- DashboardPage" })] }), _jsxs("div", { className: "flex items-start gap-2", children: [_jsx(Chip, { size: "sm", color: "primary", variant: "flat", children: "GET" }), _jsx("code", { className: "text-sm", children: "/folder" }), _jsx("span", { className: "text-sm text-slate-600 dark:text-slate-400", children: "- FolderPage" })] }), _jsxs("div", { className: "flex items-start gap-2", children: [_jsx(Chip, { size: "sm", color: "primary", variant: "flat", children: "GET" }), _jsx("code", { className: "text-sm", children: "/reglage" }), _jsx("span", { className: "text-sm text-slate-600 dark:text-slate-400", children: "- ReglagePage" })] }), _jsxs("div", { className: "flex items-start gap-2", children: [_jsx(Chip, { size: "sm", color: "primary", variant: "flat", children: "GET" }), _jsx("code", { className: "text-sm", children: "/profile" }), _jsx("span", { className: "text-sm text-slate-600 dark:text-slate-400", children: "- ProfilePage" })] })] })] }), _jsxs("div", { children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: "Pages Admin" }), _jsx("div", { className: "space-y-2", children: _jsxs("div", { className: "flex items-start gap-2", children: [_jsx(Chip, { size: "sm", color: "secondary", variant: "flat", children: "GET" }), _jsx("code", { className: "text-sm", children: "/users" }), _jsx("span", { className: "text-sm text-slate-600 dark:text-slate-400", children: "- AdminUsersPage" })] }) })] })] })] }), _jsxs(Card, { children: [_jsx(CardHeader, { children: _jsxs("h2", { className: "text-2xl font-semibold flex items-center gap-2", children: [_jsx(Zap, { size: 24 }), "API Routes"] }) }), _jsxs(CardBody, { className: "space-y-4", children: [_jsxs("div", { children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: _jsx("code", { children: "/api/auth/signin" }) }), _jsxs("div", { className: "flex gap-2", children: [_jsx(Chip, { size: "sm", color: "success", variant: "flat", children: "GET" }), _jsx(Chip, { size: "sm", color: "primary", variant: "flat", children: "POST" }), _jsx(Chip, { size: "sm", color: "warning", variant: "flat", children: "PUT" }), _jsx(Chip, { size: "sm", color: "danger", variant: "flat", children: "DELETE" })] })] }), _jsxs("div", { children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: _jsx("code", { children: "/api/auth/profile" }) }), _jsxs("div", { className: "flex gap-2", children: [_jsx(Chip, { size: "sm", color: "success", variant: "flat", children: "GET" }), _jsx(Chip, { size: "sm", color: "primary", variant: "flat", children: "POST" }), _jsx(Chip, { size: "sm", color: "warning", variant: "flat", children: "PUT" }), _jsx(Chip, { size: "sm", color: "danger", variant: "flat", children: "DELETE" })] })] }), _jsxs("div", { children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: _jsx("code", { children: "/api/auth/me" }) }), _jsxs("div", { className: "flex gap-2", children: [_jsx(Chip, { size: "sm", color: "success", variant: "flat", children: "GET" }), _jsx(Chip, { size: "sm", color: "primary", variant: "flat", children: "POST" }), _jsx(Chip, { size: "sm", color: "warning", variant: "flat", children: "PUT" }), _jsx(Chip, { size: "sm", color: "danger", variant: "flat", children: "DELETE" })] })] }), _jsxs("div", { children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: _jsx("code", { children: "/api/admin/users" }) }), _jsxs("div", { className: "flex gap-2", children: [_jsx(Chip, { size: "sm", color: "success", variant: "flat", children: "GET" }), _jsx(Chip, { size: "sm", color: "primary", variant: "flat", children: "POST" }), _jsx(Chip, { size: "sm", color: "warning", variant: "flat", children: "PUT" }), _jsx(Chip, { size: "sm", color: "danger", variant: "flat", children: "DELETE" })] })] })] })] }), _jsxs(Card, { children: [_jsx(CardHeader, { children: _jsxs("h2", { className: "text-2xl font-semibold flex items-center gap-2", children: [_jsx(Database, { size: 24 }), "Base de Donn\u00E9es"] }) }), _jsxs(CardBody, { className: "space-y-6", children: [_jsx(TableStructure, { tableName: "user_profil", title: "user_profil", description: "Table user_profil du module auth" }), _jsx(TableStructure, { tableName: "user_address", title: "user_address", description: "Table user_address du module auth" }), _jsx(TableStructure, { tableName: "user_notifications", title: "user_notifications", description: "Table user_notifications du module auth" })] })] }), _jsxs(Card, { children: [_jsx(CardHeader, { children: _jsxs("h2", { className: "text-2xl font-semibold flex items-center gap-2", children: [_jsx(Package, { size: 24 }), "Installation"] }) }), _jsxs(CardBody, { className: "space-y-4", children: [_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: "Ajouter le module" }), _jsx(Snippet, { symbol: "", hideSymbol: true, className: "text-sm mb-2", children: "pnpm lastbrain add-module auth" }), _jsx(Snippet, { symbol: "", hideSymbol: true, className: "text-sm mb-2", children: "pnpm build:modules" })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: "Appliquer les migrations" }), _jsx(Snippet, { symbol: "", hideSymbol: true, className: "text-sm mb-2", children: "cd apps/votre-app" }), _jsx(Snippet, { symbol: "", hideSymbol: true, className: "text-sm mb-2", children: "supabase migration up" })] })] })] }), _jsxs(Card, { children: [_jsx(CardHeader, { children: _jsxs("h2", { className: "text-2xl font-semibold flex items-center gap-2", children: [_jsx(BookOpen, { size: 24 }), "Utilisation"] }) }), _jsxs(CardBody, { className: "space-y-4", children: [_jsxs(Alert, { color: "default", className: "mb-4", children: [_jsxs("p", { className: "text-sm", children: ["\uD83D\uDCDD ", _jsx("strong", { children: "Section \u00E0 compl\u00E9ter par l'auteur du module" })] }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400 mt-2", children: "Ajoutez ici des exemples d'utilisation, des configurations sp\u00E9cifiques, et toute information utile pour les d\u00E9veloppeurs utilisant ce module." })] }), _jsxs("div", { children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: "Exemple d'utilisation" }), _jsx(Alert, { color: "primary", className: "p-4 mb-4", children: _jsx("pre", { className: "whitespace-pre-wrap", children: `// Importez les composants depuis le module
|
|
18
18
|
import { SignInPage } from "@lastbrain/module-auth";
|
|
19
19
|
|
|
20
20
|
// Utilisez-les dans votre application
|
|
21
|
-
<SignInPage />` }) })] })] })] }), _jsxs(Card, { children: [_jsx(CardHeader, { children: _jsxs("h2", { className: "text-2xl font-semibold flex items-center gap-2 text-danger", children: [_jsx(AlertTriangle, { size: 24 }), "Danger Zone"] }) }), _jsxs(CardBody, { className: "space-y-4", children: [_jsxs(Alert, { color: "danger", className: "mb-4", children: [_jsx("p", { className: "text-sm font-semibold", children: "
|
|
21
|
+
<SignInPage />` }) })] })] })] }), _jsxs(Card, { children: [_jsx(CardHeader, { children: _jsxs("h2", { className: "text-2xl font-semibold flex items-center gap-2 text-danger", children: [_jsx(AlertTriangle, { size: 24 }), "Danger Zone"] }) }), _jsxs(CardBody, { className: "space-y-4", children: [_jsxs(Alert, { color: "danger", className: "mb-4", children: [_jsx("p", { className: "text-sm font-semibold", children: "Cette action est irr\u00E9versible" }), _jsx("p", { className: "text-sm mt-2", children: "La suppression du module supprimera toutes les pages, routes API et migrations associ\u00E9es." })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: "Supprimer le module" }), _jsx(Snippet, { symbol: "", hideSymbol: true, color: "danger", className: "text-sm mb-2", children: "pnpm lastbrain remove-module auth" }), _jsx(Snippet, { symbol: "", hideSymbol: true, color: "danger", className: "text-sm mb-2", children: "pnpm build:modules" })] })] })] })] }));
|
|
22
22
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,10 +2,12 @@ export { SignInPage } from "./web/public/SignInPage.js";
|
|
|
2
2
|
export { SignUpPage } from "./web/public/SignUpPage.js";
|
|
3
3
|
export { ResetPassword } from "./web/public/ResetPassword.js";
|
|
4
4
|
export { DashboardPage } from "./web/auth/dashboard.js";
|
|
5
|
+
export { FolderPage } from "./web/auth/folder.js";
|
|
5
6
|
export { ProfilePage } from "./web/auth/profile.js";
|
|
6
7
|
export { ReglagePage } from "./web/auth/reglage.js";
|
|
7
8
|
export { AdminUsersPage } from "./web/admin/users.js";
|
|
8
9
|
export { default as UserPage } from "./web/admin/users/[id].js";
|
|
10
|
+
export { UserDetailPage } from "./web/admin/user-detail.js";
|
|
9
11
|
export { Doc } from "./components/Doc.js";
|
|
10
12
|
export { Doc as AuthModuleDoc } from "./components/Doc.js";
|
|
11
13
|
export { default as authBuildConfig } from "./auth.build.config.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE5D,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAC1C,OAAO,EAAE,GAAG,IAAI,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAE3D,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,wBAAwB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -3,10 +3,12 @@ export { SignInPage } from "./web/public/SignInPage.js";
|
|
|
3
3
|
export { SignUpPage } from "./web/public/SignUpPage.js";
|
|
4
4
|
export { ResetPassword } from "./web/public/ResetPassword.js";
|
|
5
5
|
export { DashboardPage } from "./web/auth/dashboard.js";
|
|
6
|
+
export { FolderPage } from "./web/auth/folder.js";
|
|
6
7
|
export { ProfilePage } from "./web/auth/profile.js";
|
|
7
8
|
export { ReglagePage } from "./web/auth/reglage.js";
|
|
8
9
|
export { AdminUsersPage } from "./web/admin/users.js";
|
|
9
10
|
export { default as UserPage } from "./web/admin/users/[id].js";
|
|
11
|
+
export { UserDetailPage } from "./web/admin/user-detail.js";
|
|
10
12
|
// Documentation
|
|
11
13
|
export { Doc } from "./components/Doc.js";
|
|
12
14
|
export { Doc as AuthModuleDoc } from "./components/Doc.js";
|
|
@@ -1,6 +1,15 @@
|
|
|
1
|
+
interface ModuleUserTab {
|
|
2
|
+
key: string;
|
|
3
|
+
title: string;
|
|
4
|
+
icon?: string;
|
|
5
|
+
component: React.ComponentType<{
|
|
6
|
+
userId: string;
|
|
7
|
+
}>;
|
|
8
|
+
}
|
|
1
9
|
interface UserDetailPageProps {
|
|
2
10
|
userId: string;
|
|
11
|
+
moduleUserTabs?: ModuleUserTab[];
|
|
3
12
|
}
|
|
4
|
-
export declare function UserDetailPage({ userId }: UserDetailPageProps): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
export declare function UserDetailPage({ userId, moduleUserTabs, }: UserDetailPageProps): import("react/jsx-runtime").JSX.Element;
|
|
5
14
|
export {};
|
|
6
15
|
//# sourceMappingURL=user-detail.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-detail.d.ts","sourceRoot":"","sources":["../../../src/web/admin/user-detail.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"user-detail.d.ts","sourceRoot":"","sources":["../../../src/web/admin/user-detail.tsx"],"names":[],"mappings":"AAwBA,UAAU,aAAa;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpD;AAaD,UAAU,mBAAmB;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,aAAa,EAAE,CAAC;CAClC;AAED,wBAAgB,cAAc,CAAC,EAC7B,MAAM,EACN,cAAmB,GACpB,EAAE,mBAAmB,2CA8UrB"}
|
|
@@ -4,10 +4,12 @@ import { useState, useEffect, useCallback } from "react";
|
|
|
4
4
|
import { Card, CardHeader, CardBody, Tabs, Tab, Avatar, Chip, Button, Input, Textarea, Select, SelectItem, Spinner, addToast, } from "@lastbrain/ui";
|
|
5
5
|
import { User, Bell, Settings } from "lucide-react";
|
|
6
6
|
import { useAuth } from "@lastbrain/core";
|
|
7
|
-
|
|
7
|
+
import * as LucideIcons from "lucide-react";
|
|
8
|
+
export function UserDetailPage({ userId, moduleUserTabs = [], }) {
|
|
8
9
|
const { user: _currentUser } = useAuth();
|
|
9
10
|
const [userProfile, setUserProfile] = useState(null);
|
|
10
11
|
const [loading, setLoading] = useState(true);
|
|
12
|
+
// Les onglets modules sont passés via props (injection serveur)
|
|
11
13
|
const [notificationTitle, setNotificationTitle] = useState("");
|
|
12
14
|
const [notificationMessage, setNotificationMessage] = useState("");
|
|
13
15
|
const [notificationType, setNotificationType] = useState("info");
|
|
@@ -102,5 +104,11 @@ export function UserDetailPage({ userId }) {
|
|
|
102
104
|
: "N/A"] })] })] }), _jsxs("div", { children: [_jsx("h3", { className: "font-semibold mb-2", children: "R\u00F4les et permissions" }), _jsx("div", { className: "space-y-2", children: _jsx(Chip, { color: isAdmin ? "danger" : "default", children: isAdmin ? "Administrateur" : "Utilisateur standard" }) })] })] }) }) }, "profile"), _jsx(Tab, { title: _jsxs("div", { className: "flex items-center space-x-2", children: [_jsx(Bell, { size: 16 }), _jsx("span", { children: "Notifications" })] }), children: _jsxs("div", { className: "space-y-4 mt-4", children: [_jsx("h3", { className: "font-semibold", children: "Envoyer une notification" }), _jsxs("div", { className: "space-y-4", children: [_jsx(Input, { label: "Titre de la notification", placeholder: "Ex: Nouveau message important", value: notificationTitle, onChange: (e) => setNotificationTitle(e.target.value), maxLength: 100 }), _jsx(Textarea, { label: "Message", placeholder: "Contenu de la notification...", value: notificationMessage, onChange: (e) => setNotificationMessage(e.target.value), maxLength: 500, minRows: 3 }), _jsxs(Select, { label: "Type de notification", selectedKeys: [notificationType], onSelectionChange: (keys) => setNotificationType(Array.from(keys)[0]), children: [_jsx(SelectItem, { children: "Information" }, "info"), _jsx(SelectItem, { children: "Avertissement" }, "warning"), _jsx(SelectItem, { children: "Danger" }, "danger"), _jsx(SelectItem, { children: "Succ\u00E8s" }, "success")] }), _jsx(Button, { color: "primary", onPress: handleSendNotification, isLoading: sendingNotification, startContent: _jsx(Bell, { size: 16 }), isDisabled: !notificationTitle.trim() || !notificationMessage.trim(), children: "Envoyer la notification" })] })] }) }, "notifications"), _jsx(Tab, { title: _jsxs("div", { className: "flex items-center space-x-2", children: [_jsx(Settings, { size: 16 }), _jsx("span", { children: "Param\u00E8tres" })] }), children: _jsxs("div", { className: "space-y-4 mt-4", children: [_jsx("h3", { className: "font-semibold", children: "Actions administrateur" }), _jsxs("div", { className: "space-y-3 space-x-5", children: [_jsx(Button, { color: "warning", variant: "bordered", size: "sm", children: "R\u00E9initialiser le mot de passe" }), _jsx(Button, { color: "danger", variant: "bordered", size: "sm", children: "Suspendre le compte" }), _jsx(Button, { color: "secondary", variant: "bordered", size: "sm", children: "Promouvoir en administrateur" })] }), _jsxs("div", { className: "mt-6 p-4 bg-gray-50 dark:bg-gray-800 rounded-lg", children: [_jsx("h4", { className: "font-medium mb-2", children: "M\u00E9tadonn\u00E9es techniques" }), _jsx("pre", { className: "text-xs text-gray-600 dark:text-gray-400 overflow-auto", children: JSON.stringify({
|
|
103
105
|
app_metadata: userProfile.raw_app_meta_data,
|
|
104
106
|
user_metadata: userProfile.raw_user_meta_data,
|
|
105
|
-
}, null, 2) })] })] }) }, "settings")
|
|
107
|
+
}, null, 2) })] })] }) }, "settings"), moduleUserTabs.map((tab) => {
|
|
108
|
+
const TabComponent = tab.component;
|
|
109
|
+
const IconComponent = tab.icon
|
|
110
|
+
? LucideIcons[tab.icon]
|
|
111
|
+
: null;
|
|
112
|
+
return (_jsx(Tab, { title: _jsxs("div", { className: "flex items-center space-x-2", children: [IconComponent && _jsx(IconComponent, { size: 16 }), _jsx("span", { children: tab.title })] }), children: _jsx(TabComponent, { userId: userId }) }, tab.key));
|
|
113
|
+
})] }) }) })] }));
|
|
106
114
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"[id].d.ts","sourceRoot":"","sources":["../../../../src/web/admin/users/[id].tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"[id].d.ts","sourceRoot":"","sources":["../../../../src/web/admin/users/[id].tsx"],"names":[],"mappings":"AAGA,UAAU,aAAa;IACrB,MAAM,EAAE,OAAO,CAAC;QACd,EAAE,EAAE,MAAM,CAAC;KACZ,CAAC,CAAC;CACJ;AAED,wBAA8B,QAAQ,CAAC,EAAE,MAAM,EAAE,EAAE,aAAa,oDAI/D"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { UserDetailPage } from "../user-detail.js";
|
|
3
|
+
import { moduleUserTabs } from "@lastbrain/core";
|
|
3
4
|
export default async function UserPage({ params }) {
|
|
4
5
|
const { id } = await params;
|
|
5
|
-
return _jsx(UserDetailPage, { userId: id });
|
|
6
|
+
return _jsx(UserDetailPage, { userId: id, moduleUserTabs: moduleUserTabs });
|
|
6
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../../src/web/auth/dashboard.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../../src/web/auth/dashboard.tsx"],"names":[],"mappings":"AA6BA,wBAAgB,aAAa,mDAoL5B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"folder.d.ts","sourceRoot":"","sources":["../../../src/web/auth/folder.tsx"],"names":[],"mappings":"AA4BA,wBAAgB,UAAU,mDAwEzB"}
|
|
@@ -0,0 +1,43 @@
|
|
|
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, Spinner, } from "@lastbrain/ui";
|
|
5
|
+
import { FileManager } from "@lastbrain/ui";
|
|
6
|
+
export function FolderPage() {
|
|
7
|
+
const [userData, setUserData] = useState(null);
|
|
8
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
9
|
+
const [error, setError] = useState(null);
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
fetchUserData();
|
|
12
|
+
}, []);
|
|
13
|
+
const fetchUserData = async () => {
|
|
14
|
+
try {
|
|
15
|
+
setIsLoading(true);
|
|
16
|
+
const response = await fetch("/api/auth/me");
|
|
17
|
+
if (!response.ok) {
|
|
18
|
+
throw new Error("Failed to fetch user data");
|
|
19
|
+
}
|
|
20
|
+
const result = await response.json();
|
|
21
|
+
setUserData(result.data);
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
setError(err instanceof Error ? err.message : "An error occurred");
|
|
25
|
+
}
|
|
26
|
+
finally {
|
|
27
|
+
setIsLoading(false);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
if (isLoading) {
|
|
31
|
+
return (_jsx("div", { className: "flex justify-center items-center min-h-[400px]", children: _jsxs(Spinner, { color: "primary", size: "lg", children: [" ", _jsx("span", { className: "text-xs text-default-700", children: "Loading folder..." })] }) }));
|
|
32
|
+
}
|
|
33
|
+
if (error) {
|
|
34
|
+
return (_jsx("div", { className: "pt-12", children: _jsx(Card, { className: "max-w-2xl mx-auto", children: _jsx(CardBody, { children: _jsxs("p", { className: "text-danger", children: ["Error: ", error] }) }) }) }));
|
|
35
|
+
}
|
|
36
|
+
if (!userData) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
const fullName = userData.profile?.first_name && userData.profile?.last_name
|
|
40
|
+
? `${userData.profile.first_name} ${userData.profile.last_name}`
|
|
41
|
+
: "User";
|
|
42
|
+
return (_jsxs("div", { className: "pt-4 pb-12 max-w-8xl mx-auto px-4", children: [_jsx("h1", { className: "text-3xl font-bold mb-8", children: "Dossier" }), _jsx(FileManager, { bucket: "app", basePath: userData.id, allowUpload: true, allowCreateFolder: true, className: "min-h-[80vh]" })] }));
|
|
43
|
+
}
|
|
@@ -93,7 +93,7 @@ function SignInForm() {
|
|
|
93
93
|
// </Card>
|
|
94
94
|
// </div>
|
|
95
95
|
// );
|
|
96
|
-
return (_jsxs("div", { className: "
|
|
96
|
+
return (_jsxs("div", { className: "relative min-h-screen w-full overflow-hidden bg-gradient-to-br from-primary-50/30 to-secondary-50/30 dark:from-primary-950/50 dark:to-secondary-950/50", children: [_jsx("div", { className: "absolute inset-0 bg-grid-slate-100 dark:bg-grid-slate-800/20 mask-[linear-gradient(0deg,white,rgba(255,255,255,0.6))] dark:mask-[linear-gradient(0deg,rgba(255,255,255,0.1),rgba(255,255,255,0.05))]" }), _jsx("div", { className: "relative flex min-h-[60vh] items-center justify-center px-4 py-12", children: _jsxs("div", { className: "w-full max-w-md", children: [_jsxs("div", { className: "mb-8 text-center", children: [_jsx(Chip, { color: "primary", variant: "flat", startContent: _jsx(Sparkles, { className: "w-4 h-4" }), className: "mb-4 p-2", children: "Espace membre" }), _jsx("h1", { className: "mb-3 text-4xl font-bold", children: _jsx("span", { className: "bg-gradient-to-r from-primary-600 to-secondary-600 bg-clip-text text-transparent", children: "Bon retour" }) }), _jsx("p", { className: "text-default-600 dark:text-default-400", children: "Connectez-vous pour acc\u00E9der \u00E0 votre espace" })] }), _jsx(Card, { className: "border border-default-200/60 bg-background/60 backdrop-blur-md backdrop-saturate-150 shadow-xl", children: _jsxs(CardBody, { className: "gap-6 p-8", children: [_jsxs("form", { onSubmit: handleSubmit, className: "flex flex-col gap-6", children: [_jsx(Input, { label: "Email", type: "email", placeholder: "votre@email.com", value: email, onChange: (e) => setEmail(e.target.value), required: true, startContent: _jsx(Mail, { className: "h-4 w-4 text-default-400" }), classNames: {
|
|
97
97
|
input: "text-base",
|
|
98
98
|
inputWrapper: "border border-default-200/60 hover:border-primary-400 focus-within:border-primary-500",
|
|
99
99
|
} }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Input, { label: "Mot de passe", type: "password", placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", value: password, onChange: (e) => setPassword(e.target.value), required: true, minLength: 6, startContent: _jsx(Lock, { className: "h-4 w-4 text-default-400" }), classNames: {
|
|
@@ -81,7 +81,7 @@ function SignUpForm() {
|
|
|
81
81
|
setLoading(false);
|
|
82
82
|
}
|
|
83
83
|
};
|
|
84
|
-
return (_jsxs("div", { className: "
|
|
84
|
+
return (_jsxs("div", { className: " relative min-h-screen w-full overflow-hidden bg-gradient-to-br from-secondary-50/30 to-primary-50/30 dark:from-secondary-950/50 dark:to-primary-950/50", children: [_jsx("div", { className: "absolute inset-0 bg-grid-slate-100 dark:bg-grid-slate-800/20 mask-[linear-gradient(0deg,white,rgba(255,255,255,0.6))] dark:mask-[linear-gradient(0deg,rgba(255,255,255,0.1),rgba(255,255,255,0.05))]" }), _jsx("div", { className: "relative flex min-h-screen items-center justify-center px-4 py-12", children: _jsxs("div", { className: "w-full max-w-md", children: [_jsxs("div", { className: "mb-8 text-center", children: [_jsx(Chip, { color: "secondary", variant: "flat", startContent: _jsx(Sparkles, { className: "w-4 h-4" }), className: "mb-4 p-2", children: "Rejoignez-nous" }), _jsx("h1", { className: "mb-3 text-4xl font-bold", children: _jsx("span", { className: "bg-gradient-to-r from-secondary-600 to-primary-600 bg-clip-text text-transparent", children: "Commencer gratuitement" }) }), _jsx("p", { className: "text-default-600 dark:text-default-400", children: "Cr\u00E9ez votre compte en quelques secondes" })] }), _jsx(Card, { className: "border border-default-200/60 bg-background/60 backdrop-blur-md backdrop-saturate-150 shadow-xl", children: _jsxs(CardBody, { className: "gap-6 p-8", children: [_jsxs("form", { onSubmit: handleSubmit, className: "flex flex-col gap-6", children: [_jsx(Input, { label: "Nom complet", type: "text", placeholder: "Jean Dupont", value: fullName, onChange: (e) => setFullName(e.target.value), startContent: _jsx(User, { className: "h-4 w-4 text-default-400" }), classNames: {
|
|
85
85
|
input: "text-base",
|
|
86
86
|
inputWrapper: "border border-default-200/60 hover:border-secondary-400 focus-within:border-secondary-500",
|
|
87
87
|
} }), _jsx(Input, { label: "Email", type: "email", placeholder: "votre@email.com", value: email, onChange: (e) => setEmail(e.target.value), required: true, startContent: _jsx(Mail, { className: "h-4 w-4 text-default-400" }), classNames: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lastbrain/module-auth",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.15",
|
|
4
4
|
"description": "Module d'authentification complet pour LastBrain avec Supabase",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"next": ">=15.0.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"next": "^
|
|
42
|
+
"next": "^16.0.4",
|
|
43
43
|
"typescript": "^5.4.0"
|
|
44
44
|
},
|
|
45
45
|
"exports": {
|
package/src/auth.build.config.ts
CHANGED
|
@@ -23,6 +23,11 @@ const authBuildConfig: ModuleBuildConfig = {
|
|
|
23
23
|
path: "/dashboard",
|
|
24
24
|
componentExport: "DashboardPage",
|
|
25
25
|
},
|
|
26
|
+
{
|
|
27
|
+
section: "auth",
|
|
28
|
+
path: "/folder",
|
|
29
|
+
componentExport: "FolderPage",
|
|
30
|
+
},
|
|
26
31
|
{
|
|
27
32
|
section: "auth",
|
|
28
33
|
path: "/reglage",
|
|
@@ -138,22 +143,39 @@ const authBuildConfig: ModuleBuildConfig = {
|
|
|
138
143
|
icon: "Users2",
|
|
139
144
|
path: "/admin/auth/users",
|
|
140
145
|
order: 1,
|
|
146
|
+
shortcut: "cmd+shift+u",
|
|
147
|
+
shortcutDisplay: "⌘⇧U",
|
|
141
148
|
},
|
|
142
149
|
],
|
|
143
|
-
|
|
150
|
+
auth: [
|
|
144
151
|
{
|
|
145
152
|
title: "Tableau de bord",
|
|
146
153
|
description: "Accédez à votre tableau de bord",
|
|
147
154
|
icon: "LayoutDashboard",
|
|
148
155
|
path: "/auth/dashboard",
|
|
149
156
|
order: 1,
|
|
157
|
+
shortcut: "cmd+shift+d",
|
|
158
|
+
shortcutDisplay: "⌘⇧D",
|
|
150
159
|
},
|
|
160
|
+
{
|
|
161
|
+
title: "Dossier",
|
|
162
|
+
description: "Accédez à votre dossier personnel",
|
|
163
|
+
icon: "FolderOpen",
|
|
164
|
+
path: "/auth/folder",
|
|
165
|
+
order: 2,
|
|
166
|
+
shortcut: "cmd+shift+f",
|
|
167
|
+
shortcutDisplay: "⌘⇧F",
|
|
168
|
+
},
|
|
169
|
+
],
|
|
170
|
+
account: [
|
|
151
171
|
{
|
|
152
172
|
title: "Mon profil",
|
|
153
173
|
description: "Gérez vos informations personnelles",
|
|
154
174
|
icon: "User2",
|
|
155
175
|
path: "/auth/profile",
|
|
156
176
|
order: 1,
|
|
177
|
+
shortcut: "cmd+shift+p",
|
|
178
|
+
shortcutDisplay: "⌘⇧P",
|
|
157
179
|
},
|
|
158
180
|
{
|
|
159
181
|
title: "Paramètres",
|
|
@@ -161,6 +183,8 @@ const authBuildConfig: ModuleBuildConfig = {
|
|
|
161
183
|
icon: "Settings",
|
|
162
184
|
path: "/auth/reglage",
|
|
163
185
|
order: 2,
|
|
186
|
+
shortcut: "cmd+shift+s",
|
|
187
|
+
shortcutDisplay: "⌘⇧S",
|
|
164
188
|
},
|
|
165
189
|
{
|
|
166
190
|
title: "Déconnexion",
|
package/src/components/Doc.tsx
CHANGED
|
@@ -109,6 +109,15 @@ export function Doc() {
|
|
|
109
109
|
- DashboardPage
|
|
110
110
|
</span>
|
|
111
111
|
</div>
|
|
112
|
+
<div className="flex items-start gap-2">
|
|
113
|
+
<Chip size="sm" color="primary" variant="flat">
|
|
114
|
+
GET
|
|
115
|
+
</Chip>
|
|
116
|
+
<code className="text-sm">/folder</code>
|
|
117
|
+
<span className="text-sm text-slate-600 dark:text-slate-400">
|
|
118
|
+
- FolderPage
|
|
119
|
+
</span>
|
|
120
|
+
</div>
|
|
112
121
|
<div className="flex items-start gap-2">
|
|
113
122
|
<Chip size="sm" color="primary" variant="flat">
|
|
114
123
|
GET
|
|
@@ -267,7 +276,7 @@ export function Doc() {
|
|
|
267
276
|
</h2>
|
|
268
277
|
</CardHeader>
|
|
269
278
|
<CardBody className="space-y-4">
|
|
270
|
-
<div>
|
|
279
|
+
<div className="flex flex-col gap-2">
|
|
271
280
|
<h3 className="text-lg font-semibold mb-2">Ajouter le module</h3>
|
|
272
281
|
<Snippet symbol="" hideSymbol className="text-sm mb-2">
|
|
273
282
|
pnpm lastbrain add-module auth
|
|
@@ -277,7 +286,7 @@ export function Doc() {
|
|
|
277
286
|
</Snippet>
|
|
278
287
|
</div>
|
|
279
288
|
|
|
280
|
-
<div>
|
|
289
|
+
<div className="flex flex-col gap-2">
|
|
281
290
|
<h3 className="text-lg font-semibold mb-2">
|
|
282
291
|
Appliquer les migrations
|
|
283
292
|
</h3>
|
|
@@ -335,7 +344,7 @@ import { SignInPage } from "@lastbrain/module-auth";
|
|
|
335
344
|
<CardBody className="space-y-4">
|
|
336
345
|
<Alert color="danger" className="mb-4">
|
|
337
346
|
<p className="text-sm font-semibold">
|
|
338
|
-
|
|
347
|
+
Cette action est irréversible
|
|
339
348
|
</p>
|
|
340
349
|
<p className="text-sm mt-2">
|
|
341
350
|
La suppression du module supprimera toutes les pages, routes API
|
|
@@ -343,7 +352,7 @@ import { SignInPage } from "@lastbrain/module-auth";
|
|
|
343
352
|
</p>
|
|
344
353
|
</Alert>
|
|
345
354
|
|
|
346
|
-
<div>
|
|
355
|
+
<div className="flex flex-col gap-2">
|
|
347
356
|
<h3 className="text-lg font-semibold mb-2">Supprimer le module</h3>
|
|
348
357
|
<Snippet
|
|
349
358
|
symbol=""
|
package/src/index.ts
CHANGED
|
@@ -3,10 +3,12 @@ export { SignInPage } from "./web/public/SignInPage.js";
|
|
|
3
3
|
export { SignUpPage } from "./web/public/SignUpPage.js";
|
|
4
4
|
export { ResetPassword } from "./web/public/ResetPassword.js";
|
|
5
5
|
export { DashboardPage } from "./web/auth/dashboard.js";
|
|
6
|
+
export { FolderPage } from "./web/auth/folder.js";
|
|
6
7
|
export { ProfilePage } from "./web/auth/profile.js";
|
|
7
8
|
export { ReglagePage } from "./web/auth/reglage.js";
|
|
8
9
|
export { AdminUsersPage } from "./web/admin/users.js";
|
|
9
10
|
export { default as UserPage } from "./web/admin/users/[id].js";
|
|
11
|
+
export { UserDetailPage } from "./web/admin/user-detail.js";
|
|
10
12
|
// Documentation
|
|
11
13
|
export { Doc } from "./components/Doc.js";
|
|
12
14
|
export { Doc as AuthModuleDoc } from "./components/Doc.js";
|
|
@@ -20,6 +20,14 @@ import {
|
|
|
20
20
|
} from "@lastbrain/ui";
|
|
21
21
|
import { User, Bell, Settings, Save } from "lucide-react";
|
|
22
22
|
import { useAuth } from "@lastbrain/core";
|
|
23
|
+
import * as LucideIcons from "lucide-react";
|
|
24
|
+
|
|
25
|
+
interface ModuleUserTab {
|
|
26
|
+
key: string;
|
|
27
|
+
title: string;
|
|
28
|
+
icon?: string;
|
|
29
|
+
component: React.ComponentType<{ userId: string }>;
|
|
30
|
+
}
|
|
23
31
|
|
|
24
32
|
interface UserProfile {
|
|
25
33
|
id: string;
|
|
@@ -34,12 +42,17 @@ interface UserProfile {
|
|
|
34
42
|
|
|
35
43
|
interface UserDetailPageProps {
|
|
36
44
|
userId: string;
|
|
45
|
+
moduleUserTabs?: ModuleUserTab[];
|
|
37
46
|
}
|
|
38
47
|
|
|
39
|
-
export function UserDetailPage({
|
|
48
|
+
export function UserDetailPage({
|
|
49
|
+
userId,
|
|
50
|
+
moduleUserTabs = [],
|
|
51
|
+
}: UserDetailPageProps) {
|
|
40
52
|
const { user: _currentUser } = useAuth();
|
|
41
53
|
const [userProfile, setUserProfile] = useState<UserProfile | null>(null);
|
|
42
54
|
const [loading, setLoading] = useState(true);
|
|
55
|
+
// Les onglets modules sont passés via props (injection serveur)
|
|
43
56
|
const [notificationTitle, setNotificationTitle] = useState("");
|
|
44
57
|
const [notificationMessage, setNotificationMessage] = useState("");
|
|
45
58
|
const [notificationType, setNotificationType] = useState("info");
|
|
@@ -179,6 +192,8 @@ export function UserDetailPage({ userId }: UserDetailPageProps) {
|
|
|
179
192
|
{/* Tabs */}
|
|
180
193
|
<Card>
|
|
181
194
|
<CardBody>
|
|
195
|
+
{/* moduleUserTabs injectés (debug retiré) */}
|
|
196
|
+
|
|
182
197
|
<Tabs
|
|
183
198
|
aria-label="Options utilisateur"
|
|
184
199
|
color="primary"
|
|
@@ -340,6 +355,28 @@ export function UserDetailPage({ userId }: UserDetailPageProps) {
|
|
|
340
355
|
</div>
|
|
341
356
|
</div>
|
|
342
357
|
</Tab>
|
|
358
|
+
{/* Tabs dynamiques depuis les modules */}
|
|
359
|
+
{moduleUserTabs.map((tab) => {
|
|
360
|
+
const TabComponent = tab.component;
|
|
361
|
+
const IconComponent = tab.icon
|
|
362
|
+
? (LucideIcons as any)[tab.icon]
|
|
363
|
+
: null;
|
|
364
|
+
|
|
365
|
+
return (
|
|
366
|
+
<Tab
|
|
367
|
+
key={tab.key}
|
|
368
|
+
title={
|
|
369
|
+
<div className="flex items-center space-x-2">
|
|
370
|
+
{IconComponent && <IconComponent size={16} />}
|
|
371
|
+
<span>{tab.title}</span>
|
|
372
|
+
</div>
|
|
373
|
+
}
|
|
374
|
+
>
|
|
375
|
+
<TabComponent userId={userId} />
|
|
376
|
+
</Tab>
|
|
377
|
+
);
|
|
378
|
+
})}
|
|
379
|
+
{/* Pas d'état de chargement : injection directe */}
|
|
343
380
|
</Tabs>
|
|
344
381
|
</CardBody>
|
|
345
382
|
</Card>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { UserDetailPage } from "../user-detail.js";
|
|
2
|
+
import { moduleUserTabs } from "@lastbrain/core";
|
|
2
3
|
|
|
3
4
|
interface UserPageProps {
|
|
4
5
|
params: Promise<{
|
|
@@ -8,5 +9,6 @@ interface UserPageProps {
|
|
|
8
9
|
|
|
9
10
|
export default async function UserPage({ params }: UserPageProps) {
|
|
10
11
|
const { id } = await params;
|
|
11
|
-
|
|
12
|
+
|
|
13
|
+
return <UserDetailPage userId={id} moduleUserTabs={moduleUserTabs} />;
|
|
12
14
|
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import {
|
|
5
|
+
Card,
|
|
6
|
+
CardBody,
|
|
7
|
+
CardHeader,
|
|
8
|
+
Spinner,
|
|
9
|
+
Chip,
|
|
10
|
+
Divider,
|
|
11
|
+
Avatar,
|
|
12
|
+
} from "@lastbrain/ui";
|
|
13
|
+
import { FileManager } from "@lastbrain/ui";
|
|
14
|
+
|
|
15
|
+
interface UserData {
|
|
16
|
+
id: string;
|
|
17
|
+
email: string;
|
|
18
|
+
created_at: string;
|
|
19
|
+
profile: {
|
|
20
|
+
first_name?: string;
|
|
21
|
+
last_name?: string;
|
|
22
|
+
avatar_url?: string;
|
|
23
|
+
bio?: string;
|
|
24
|
+
company?: string;
|
|
25
|
+
location?: string;
|
|
26
|
+
} | null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function FolderPage() {
|
|
30
|
+
const [userData, setUserData] = useState<UserData | null>(null);
|
|
31
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
32
|
+
const [error, setError] = useState<string | null>(null);
|
|
33
|
+
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
fetchUserData();
|
|
36
|
+
}, []);
|
|
37
|
+
|
|
38
|
+
const fetchUserData = async () => {
|
|
39
|
+
try {
|
|
40
|
+
setIsLoading(true);
|
|
41
|
+
const response = await fetch("/api/auth/me");
|
|
42
|
+
|
|
43
|
+
if (!response.ok) {
|
|
44
|
+
throw new Error("Failed to fetch user data");
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const result = await response.json();
|
|
48
|
+
setUserData(result.data);
|
|
49
|
+
} catch (err) {
|
|
50
|
+
setError(err instanceof Error ? err.message : "An error occurred");
|
|
51
|
+
} finally {
|
|
52
|
+
setIsLoading(false);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
if (isLoading) {
|
|
57
|
+
return (
|
|
58
|
+
<div className="flex justify-center items-center min-h-[400px]">
|
|
59
|
+
<Spinner color="primary" size="lg">
|
|
60
|
+
{" "}
|
|
61
|
+
<span className="text-xs text-default-700">Loading folder...</span>
|
|
62
|
+
</Spinner>
|
|
63
|
+
</div>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (error) {
|
|
68
|
+
return (
|
|
69
|
+
<div className="pt-12">
|
|
70
|
+
<Card className="max-w-2xl mx-auto">
|
|
71
|
+
<CardBody>
|
|
72
|
+
<p className="text-danger">Error: {error}</p>
|
|
73
|
+
</CardBody>
|
|
74
|
+
</Card>
|
|
75
|
+
</div>
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (!userData) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const fullName =
|
|
84
|
+
userData.profile?.first_name && userData.profile?.last_name
|
|
85
|
+
? `${userData.profile.first_name} ${userData.profile.last_name}`
|
|
86
|
+
: "User";
|
|
87
|
+
|
|
88
|
+
return (
|
|
89
|
+
<div className="pt-4 pb-12 max-w-8xl mx-auto px-4">
|
|
90
|
+
<h1 className="text-3xl font-bold mb-8">Dossier</h1>
|
|
91
|
+
|
|
92
|
+
<FileManager
|
|
93
|
+
bucket="app"
|
|
94
|
+
basePath={userData.id}
|
|
95
|
+
allowUpload={true}
|
|
96
|
+
allowCreateFolder={true}
|
|
97
|
+
className="min-h-[80vh]"
|
|
98
|
+
/>
|
|
99
|
+
</div>
|
|
100
|
+
);
|
|
101
|
+
}
|
|
@@ -112,7 +112,7 @@ function SignInForm() {
|
|
|
112
112
|
// );
|
|
113
113
|
|
|
114
114
|
return (
|
|
115
|
-
<div className="
|
|
115
|
+
<div className="relative min-h-screen w-full overflow-hidden bg-gradient-to-br from-primary-50/30 to-secondary-50/30 dark:from-primary-950/50 dark:to-secondary-950/50">
|
|
116
116
|
{/* Background decoration */}
|
|
117
117
|
<div className="absolute inset-0 bg-grid-slate-100 dark:bg-grid-slate-800/20 mask-[linear-gradient(0deg,white,rgba(255,255,255,0.6))] dark:mask-[linear-gradient(0deg,rgba(255,255,255,0.1),rgba(255,255,255,0.05))]" />
|
|
118
118
|
|
|
@@ -110,7 +110,7 @@ function SignUpForm() {
|
|
|
110
110
|
};
|
|
111
111
|
|
|
112
112
|
return (
|
|
113
|
-
<div className="
|
|
113
|
+
<div className=" relative min-h-screen w-full overflow-hidden bg-gradient-to-br from-secondary-50/30 to-primary-50/30 dark:from-secondary-950/50 dark:to-primary-950/50">
|
|
114
114
|
{/* Background decoration */}
|
|
115
115
|
<div className="absolute inset-0 bg-grid-slate-100 dark:bg-grid-slate-800/20 mask-[linear-gradient(0deg,white,rgba(255,255,255,0.6))] dark:mask-[linear-gradient(0deg,rgba(255,255,255,0.1),rgba(255,255,255,0.05))]" />
|
|
116
116
|
|