@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 CHANGED
@@ -19,6 +19,7 @@
19
19
  ### Pages Protégées (Auth)
20
20
 
21
21
  - **GET** `/dashboard` - DashboardPage
22
+ - **GET** `/folder` - FolderPage
22
23
  - **GET** `/reglage` - ReglagePage
23
24
  - **GET** `/profile` - ProfilePage
24
25
 
@@ -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,iBAqMtB,CAAC;AAEF,eAAe,eAAe,CAAC"}
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
- account: [
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,4CAyVlB"}
1
+ {"version":3,"file":"Doc.d.ts","sourceRoot":"","sources":["../../src/components/Doc.tsx"],"names":[],"mappings":"AAgBA;;;;;;GAMG;AACH,wBAAgB,GAAG,4CAkWlB"}
@@ -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: "\u26A0\uFE0F 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", { 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" })] })] })] })] }));
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";
@@ -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;AAEhE,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"}
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":"AAkCA,UAAU,mBAAmB;IAC3B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,cAAc,CAAC,EAAE,MAAM,EAAE,EAAE,mBAAmB,2CAqT7D"}
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
- export function UserDetailPage({ userId }) {
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":"AAEA,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,oDAG/D"}
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":"AA4BA,wBAAgB,aAAa,mDAoL5B"}
1
+ {"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../../src/web/auth/dashboard.tsx"],"names":[],"mappings":"AA6BA,wBAAgB,aAAa,mDAoL5B"}
@@ -0,0 +1,2 @@
1
+ export declare function FolderPage(): import("react/jsx-runtime").JSX.Element | null;
2
+ //# sourceMappingURL=folder.d.ts.map
@@ -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: "pt-12 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: {
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: "pt-12 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: {
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.12",
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": "^15.5.6",
42
+ "next": "^16.0.4",
43
43
  "typescript": "^5.4.0"
44
44
  },
45
45
  "exports": {
@@ -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
- account: [
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",
@@ -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
- ⚠️ Cette action est irréversible
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({ userId }: UserDetailPageProps) {
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
- return <UserDetailPage userId={id} />;
12
+
13
+ return <UserDetailPage userId={id} moduleUserTabs={moduleUserTabs} />;
12
14
  }
@@ -10,6 +10,7 @@ import {
10
10
  Divider,
11
11
  Avatar,
12
12
  } from "@lastbrain/ui";
13
+
13
14
  import { User, Mail, Calendar, Shield } from "lucide-react";
14
15
 
15
16
  interface UserData {
@@ -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="pt-12 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">
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="pt-12 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">
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