@lastbrain/module-auth 2.0.19 → 2.0.31

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.
Files changed (178) hide show
  1. package/README.md +55 -7
  2. package/dist/api/admin/signup-stats.d.ts.map +1 -1
  3. package/dist/api/admin/signup-stats.js +2 -1
  4. package/dist/api/admin/storage/usage.d.ts +18 -0
  5. package/dist/api/admin/storage/usage.d.ts.map +1 -0
  6. package/dist/api/admin/storage/usage.js +100 -0
  7. package/dist/api/admin/users/[id]/notifications.d.ts.map +1 -1
  8. package/dist/api/admin/users/[id]/notifications.js +3 -2
  9. package/dist/api/admin/users/[id].d.ts.map +1 -1
  10. package/dist/api/admin/users/[id].js +3 -2
  11. package/dist/api/admin/users/reactivate/[id].d.ts +16 -0
  12. package/dist/api/admin/users/reactivate/[id].d.ts.map +1 -0
  13. package/dist/api/admin/users/reactivate/[id].js +59 -0
  14. package/dist/api/admin/users/suspend/[id].d.ts +16 -0
  15. package/dist/api/admin/users/suspend/[id].d.ts.map +1 -0
  16. package/dist/api/admin/users/suspend/[id].js +59 -0
  17. package/dist/api/admin/users-by-source.d.ts.map +1 -1
  18. package/dist/api/admin/users-by-source.js +2 -1
  19. package/dist/api/admin/users.d.ts.map +1 -1
  20. package/dist/api/admin/users.js +53 -2
  21. package/dist/api/auth/account/email-change.d.ts +7 -0
  22. package/dist/api/auth/account/email-change.d.ts.map +1 -0
  23. package/dist/api/auth/account/email-change.js +39 -0
  24. package/dist/api/auth/account/reset-password.d.ts +7 -0
  25. package/dist/api/auth/account/reset-password.d.ts.map +1 -0
  26. package/dist/api/auth/account/reset-password.js +36 -0
  27. package/dist/api/auth/check-username.d.ts +9 -0
  28. package/dist/api/auth/check-username.d.ts.map +1 -0
  29. package/dist/api/auth/check-username.js +35 -0
  30. package/dist/api/auth/establish-session.d.ts +2 -0
  31. package/dist/api/auth/establish-session.d.ts.map +1 -0
  32. package/dist/api/auth/establish-session.js +23 -0
  33. package/dist/api/auth/me.d.ts +4 -4
  34. package/dist/api/auth/me.d.ts.map +1 -1
  35. package/dist/api/auth/me.js +28 -6
  36. package/dist/api/auth/profile.d.ts.map +1 -1
  37. package/dist/api/auth/profile.js +6 -3
  38. package/dist/api/auth/storage/recalculate.d.ts +15 -0
  39. package/dist/api/auth/storage/recalculate.d.ts.map +1 -0
  40. package/dist/api/auth/storage/recalculate.js +68 -0
  41. package/dist/api/auth/storage/usage.d.ts +10 -0
  42. package/dist/api/auth/storage/usage.d.ts.map +1 -0
  43. package/dist/api/auth/storage/usage.js +86 -0
  44. package/dist/api/public/add-welcome-bonus.d.ts +16 -0
  45. package/dist/api/public/add-welcome-bonus.d.ts.map +1 -0
  46. package/dist/api/public/add-welcome-bonus.js +177 -0
  47. package/dist/api/public/callback.d.ts +3 -0
  48. package/dist/api/public/callback.d.ts.map +1 -0
  49. package/dist/api/public/callback.js +197 -0
  50. package/dist/api/public/reset-password.d.ts +3 -0
  51. package/dist/api/public/reset-password.d.ts.map +1 -0
  52. package/dist/api/public/reset-password.js +43 -0
  53. package/dist/api/public/set-session.d.ts +7 -0
  54. package/dist/api/public/set-session.d.ts.map +1 -0
  55. package/dist/api/public/set-session.js +55 -0
  56. package/dist/api/public/signin.d.ts.map +1 -1
  57. package/dist/api/public/signin.js +31 -0
  58. package/dist/api/public/signup.d.ts.map +1 -1
  59. package/dist/api/public/signup.js +38 -27
  60. package/dist/api/public/webhook/storage-addon.d.ts +9 -0
  61. package/dist/api/public/webhook/storage-addon.d.ts.map +1 -0
  62. package/dist/api/public/webhook/storage-addon.js +155 -0
  63. package/dist/api/storage.js +2 -2
  64. package/dist/auth.build.config.d.ts.map +1 -1
  65. package/dist/auth.build.config.js +134 -14
  66. package/dist/components/AccountButton.d.ts.map +1 -1
  67. package/dist/components/AccountButton.js +54 -28
  68. package/dist/components/Doc.d.ts.map +1 -1
  69. package/dist/components/Doc.js +1 -1
  70. package/dist/components/HasProfil.d.ts +4 -0
  71. package/dist/components/HasProfil.d.ts.map +1 -0
  72. package/dist/components/HasProfil.js +39 -0
  73. package/dist/{web → components}/auth/dashboard.d.ts +1 -1
  74. package/dist/components/auth/dashboard.d.ts.map +1 -0
  75. package/dist/components/auth/dashboard.js +74 -0
  76. package/dist/index.d.ts +3 -1
  77. package/dist/index.d.ts.map +1 -1
  78. package/dist/index.js +3 -1
  79. package/dist/lib/app-branding-data.d.ts +22 -0
  80. package/dist/lib/app-branding-data.d.ts.map +1 -0
  81. package/dist/lib/app-branding-data.js +49 -0
  82. package/dist/lib/auth-email-service.d.ts +57 -0
  83. package/dist/lib/auth-email-service.d.ts.map +1 -0
  84. package/dist/lib/auth-email-service.js +382 -0
  85. package/dist/lib/auth-email-templates.d.ts +2 -0
  86. package/dist/lib/auth-email-templates.d.ts.map +1 -0
  87. package/dist/lib/auth-email-templates.js +1 -0
  88. package/dist/lib/site-url.d.ts +3 -0
  89. package/dist/lib/site-url.d.ts.map +1 -0
  90. package/dist/lib/site-url.js +11 -0
  91. package/dist/sitemap/manifest.d.ts +9 -0
  92. package/dist/sitemap/manifest.d.ts.map +1 -0
  93. package/dist/sitemap/manifest.js +14 -0
  94. package/dist/web/admin/signup-stats.js +3 -3
  95. package/dist/web/admin/user-detail.d.ts.map +1 -1
  96. package/dist/web/admin/user-detail.js +135 -14
  97. package/dist/web/admin/users-by-signup-source.js +2 -2
  98. package/dist/web/admin/users.d.ts.map +1 -1
  99. package/dist/web/admin/users.js +26 -7
  100. package/dist/web/auth/folder.d.ts.map +1 -1
  101. package/dist/web/auth/folder.js +4 -3
  102. package/dist/web/auth/profile.d.ts.map +1 -1
  103. package/dist/web/auth/profile.js +132 -13
  104. package/dist/web/auth/reglage.d.ts.map +1 -1
  105. package/dist/web/auth/reglage.js +15 -8
  106. package/dist/web/public/ResetPassword.d.ts.map +1 -1
  107. package/dist/web/public/ResetPassword.js +172 -2
  108. package/dist/web/public/SignInPage.d.ts.map +1 -1
  109. package/dist/web/public/SignInPage.js +39 -3
  110. package/dist/web/public/SignUpPage.d.ts.map +1 -1
  111. package/dist/web/public/SignUpPage.js +7 -2
  112. package/dist/web/public/auth-code-error.d.ts +2 -0
  113. package/dist/web/public/auth-code-error.d.ts.map +1 -0
  114. package/dist/web/public/auth-code-error.js +14 -0
  115. package/dist/web/public/confirm.d.ts +2 -0
  116. package/dist/web/public/confirm.d.ts.map +1 -0
  117. package/dist/web/public/confirm.js +157 -0
  118. package/package.json +10 -5
  119. package/src/api/admin/signup-stats.ts +2 -1
  120. package/src/api/admin/storage/usage.ts +141 -0
  121. package/src/api/admin/users/[id]/notifications.ts +3 -2
  122. package/src/api/admin/users/[id].ts +3 -2
  123. package/src/api/admin/users/reactivate/[id].ts +88 -0
  124. package/src/api/admin/users/suspend/[id].ts +85 -0
  125. package/src/api/admin/users-by-source.ts +2 -1
  126. package/src/api/admin/users.ts +59 -2
  127. package/src/api/auth/account/email-change.ts +54 -0
  128. package/src/api/auth/account/reset-password.ts +47 -0
  129. package/src/api/auth/check-username.ts +52 -0
  130. package/src/api/auth/establish-session.ts +32 -0
  131. package/src/api/auth/me.ts +29 -7
  132. package/src/api/auth/profile.ts +6 -2
  133. package/src/api/auth/storage/recalculate.ts +108 -0
  134. package/src/api/auth/storage/usage.ts +113 -0
  135. package/src/api/public/add-welcome-bonus.ts +229 -0
  136. package/src/api/public/callback.ts +307 -0
  137. package/src/api/public/reset-password.ts +52 -0
  138. package/src/api/public/set-session.ts +73 -0
  139. package/src/api/public/signin.ts +36 -0
  140. package/src/api/public/signup.ts +44 -37
  141. package/src/api/public/webhook/storage-addon.ts +267 -0
  142. package/src/api/storage.ts +2 -2
  143. package/src/auth.build.config.ts +134 -14
  144. package/src/components/AccountButton.tsx +114 -90
  145. package/src/components/Doc.tsx +47 -9
  146. package/src/components/HasProfil.tsx +63 -0
  147. package/src/{web → components}/auth/dashboard.tsx +64 -20
  148. package/src/i18n/en.json +78 -8
  149. package/src/i18n/es.json +330 -0
  150. package/src/i18n/fr.json +75 -8
  151. package/src/index.ts +3 -1
  152. package/src/lib/app-branding-data.ts +90 -0
  153. package/src/lib/auth-email-service.ts +508 -0
  154. package/src/lib/auth-email-templates.ts +5 -0
  155. package/src/lib/site-url.ts +17 -0
  156. package/src/sitemap/manifest.ts +26 -0
  157. package/src/web/admin/signup-stats.tsx +3 -3
  158. package/src/web/admin/user-detail.tsx +314 -15
  159. package/src/web/admin/users-by-signup-source.tsx +2 -2
  160. package/src/web/admin/users.tsx +50 -14
  161. package/src/web/auth/folder.tsx +23 -5
  162. package/src/web/auth/profile.tsx +227 -13
  163. package/src/web/auth/reglage.tsx +55 -24
  164. package/src/web/public/ResetPassword.tsx +301 -1
  165. package/src/web/public/SignInPage.tsx +43 -3
  166. package/src/web/public/SignUpPage.tsx +14 -5
  167. package/src/web/public/auth-code-error.tsx +49 -0
  168. package/src/web/public/confirm.tsx +195 -0
  169. package/supabase/migrations/20251112000001_auto_profile_and_admin_view.sql +3 -1
  170. package/supabase/migrations/20251127100000_rename_body_to_message.sql +8 -3
  171. package/supabase/migrations/20260120150001_add_user_storage.sql +105 -0
  172. package/supabase/migrations/20260122131200_add_global_addons_system.sql +305 -0
  173. package/supabase/migrations/20260123100000_enable_vector_extension.sql +9 -0
  174. package/supabase/migrations/20260123140000_module_auth_fix_get_user_limits_null.sql +93 -0
  175. package/supabase/migrations/20260123145000_module_auth_fix_circular_storage_base.sql +89 -0
  176. package/supabase/migrations/20260129400000_add_username_to_user_profil.sql +33 -0
  177. package/dist/web/auth/dashboard.d.ts.map +0 -1
  178. package/dist/web/auth/dashboard.js +0 -48
@@ -1,4 +1,4 @@
1
- import { supabaseBrowserClient } from "@lastbrain/core";
1
+ import { logger, supabaseBrowserClient } from "@lastbrain/core";
2
2
  /**
3
3
  * Upload a file to Supabase Storage and return proxy URL
4
4
  */
@@ -37,7 +37,7 @@ export async function deleteFilesWithPrefix(bucket, prefix) {
37
37
  search: prefix,
38
38
  });
39
39
  if (listError) {
40
- console.warn("Failed to list files for deletion:", listError);
40
+ logger.warn("Failed to list files for deletion:", listError);
41
41
  return;
42
42
  }
43
43
  if (files && files.length > 0) {
@@ -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,iBAkVtB,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,iBA0ctB,CAAC;AAEF,eAAe,eAAe,CAAC"}
@@ -17,9 +17,14 @@ const authBuildConfig = {
17
17
  componentExport: "ResetPassword",
18
18
  },
19
19
  {
20
- section: "auth",
21
- path: "/dashboard",
22
- componentExport: "DashboardPage",
20
+ section: "public",
21
+ path: "/confirm",
22
+ componentExport: "ConfirmPage",
23
+ },
24
+ {
25
+ section: "public",
26
+ path: "/auth-code-error",
27
+ componentExport: "AuthCodeErrorPage",
23
28
  },
24
29
  {
25
30
  section: "auth",
@@ -67,6 +72,34 @@ const authBuildConfig = {
67
72
  entryPoint: "api/public/signup",
68
73
  authRequired: false,
69
74
  },
75
+ {
76
+ method: "POST",
77
+ path: "/api/public/set-session",
78
+ handlerExport: "POST",
79
+ entryPoint: "api/public/set-session",
80
+ authRequired: false,
81
+ },
82
+ {
83
+ method: "POST",
84
+ path: "/api/public/add-welcome-bonus",
85
+ handlerExport: "POST",
86
+ entryPoint: "api/public/add-welcome-bonus",
87
+ authRequired: true,
88
+ },
89
+ {
90
+ method: "POST",
91
+ path: "/api/public/reset-password",
92
+ handlerExport: "POST",
93
+ entryPoint: "api/public/reset-password",
94
+ authRequired: false,
95
+ },
96
+ {
97
+ method: "GET",
98
+ path: "/api/public/callback",
99
+ handlerExport: "GET",
100
+ entryPoint: "api/public/callback",
101
+ authRequired: false,
102
+ },
70
103
  {
71
104
  method: "GET",
72
105
  path: "/api/auth/profile",
@@ -88,6 +121,13 @@ const authBuildConfig = {
88
121
  entryPoint: "api/auth/profile",
89
122
  authRequired: true,
90
123
  },
124
+ {
125
+ method: "GET",
126
+ path: "/api/auth/check-username",
127
+ handlerExport: "GET",
128
+ entryPoint: "api/auth/check-username",
129
+ authRequired: false,
130
+ },
91
131
  {
92
132
  method: "GET",
93
133
  path: "/api/auth/me",
@@ -95,6 +135,20 @@ const authBuildConfig = {
95
135
  entryPoint: "api/auth/me",
96
136
  authRequired: true,
97
137
  },
138
+ {
139
+ method: "POST",
140
+ path: "/api/auth/account/email-change",
141
+ handlerExport: "POST",
142
+ entryPoint: "api/auth/account/email-change",
143
+ authRequired: true,
144
+ },
145
+ {
146
+ method: "POST",
147
+ path: "/api/auth/account/reset-password",
148
+ handlerExport: "POST",
149
+ entryPoint: "api/auth/account/reset-password",
150
+ authRequired: true,
151
+ },
98
152
  {
99
153
  method: "GET",
100
154
  path: "/api/admin/users",
@@ -116,6 +170,20 @@ const authBuildConfig = {
116
170
  entryPoint: "api/admin/users/[id]/notifications",
117
171
  authRequired: true,
118
172
  },
173
+ {
174
+ method: "POST",
175
+ path: "/api/admin/users/suspend/[id]",
176
+ handlerExport: "POST",
177
+ entryPoint: "api/admin/users/suspend/[id]",
178
+ authRequired: true,
179
+ },
180
+ {
181
+ method: "POST",
182
+ path: "/api/admin/users/reactivate/[id]",
183
+ handlerExport: "POST",
184
+ entryPoint: "api/admin/users/reactivate/[id]",
185
+ authRequired: true,
186
+ },
119
187
  {
120
188
  method: "GET",
121
189
  path: "/api/admin/signup-stats",
@@ -123,6 +191,34 @@ const authBuildConfig = {
123
191
  entryPoint: "api/admin/signup-stats",
124
192
  authRequired: true,
125
193
  },
194
+ {
195
+ method: "GET",
196
+ path: "/api/admin/storage/usage",
197
+ handlerExport: "GET",
198
+ entryPoint: "api/admin/storage/usage",
199
+ authRequired: true,
200
+ },
201
+ {
202
+ method: "GET",
203
+ path: "/api/auth/storage/usage",
204
+ handlerExport: "GET",
205
+ entryPoint: "api/auth/storage/usage",
206
+ authRequired: true,
207
+ },
208
+ {
209
+ method: "POST",
210
+ path: "/api/auth/storage/recalculate",
211
+ handlerExport: "POST",
212
+ entryPoint: "api/auth/storage/recalculate",
213
+ authRequired: true,
214
+ },
215
+ {
216
+ method: "POST",
217
+ path: "/api/auth/webhook/storage-addon",
218
+ handlerExport: "POST",
219
+ entryPoint: "api/public/webhook/storage-addon",
220
+ authRequired: false,
221
+ },
126
222
  ],
127
223
  migrations: {
128
224
  enabled: true,
@@ -133,6 +229,13 @@ const authBuildConfig = {
133
229
  "20251112000001_auto_profile_and_admin_view.sql",
134
230
  "20251112000002_sync_avatars.sql",
135
231
  "20251124000001_add_get_admin_user_details.sql",
232
+ "20251127100000_rename_body_to_message.sql",
233
+ "20260120150001_add_user_storage.sql",
234
+ "20260122131200_add_global_addons_system.sql",
235
+ "20260123100000_enable_vector_extension.sql",
236
+ "20260123140000_module_auth_fix_get_user_limits_null.sql",
237
+ "20260123145000_module_auth_fix_circular_storage_base.sql",
238
+ "20260129400000_add_username_to_user_profil.sql"
136
239
  ],
137
240
  migrationsDownPath: "supabase/migrations-down",
138
241
  },
@@ -158,16 +261,16 @@ const authBuildConfig = {
158
261
  position: "end",
159
262
  componentExport: "AccountButton",
160
263
  },
161
- {
162
- title: "module-auth.menu.theme",
163
- description: "module-auth.menu.theme_desc",
164
- icon: "Palette",
165
- path: "#",
166
- order: 9999,
167
- type: "icon",
168
- position: "end",
169
- componentExport: "ThemeSwitcherButton",
170
- },
264
+ // {
265
+ // title: "module-auth.menu.theme",
266
+ // description: "module-auth.menu.theme_desc",
267
+ // icon: "Palette",
268
+ // path: "#",
269
+ // order: 9999,
270
+ // type: "icon",
271
+ // position: "end",
272
+ // componentExport: "ThemeSwitcherButton",
273
+ // },
171
274
  ],
172
275
  admin: [
173
276
  {
@@ -282,7 +385,7 @@ const authBuildConfig = {
282
385
  description: "module-auth.menu.settings_desc",
283
386
  icon: "Settings",
284
387
  path: "/auth/reglage",
285
- order: 2,
388
+ order: 70,
286
389
  shortcut: "cmd+shift+s",
287
390
  shortcutDisplay: "⌘⇧S",
288
391
  },
@@ -305,8 +408,25 @@ const authBuildConfig = {
305
408
  filter: "owner_id=eq.${USER_ID}",
306
409
  broadcast: "user_notifications_updated",
307
410
  },
411
+ {
412
+ schema: "public",
413
+ table: "user_profil",
414
+ event: "*",
415
+ filter: "owner_id=eq.${USER_ID}",
416
+ broadcast: "user_profile_updated",
417
+ },
308
418
  ],
309
419
  },
420
+ authDashboard: [
421
+ {
422
+ key: "user",
423
+ title: "auth",
424
+ icon: "Dashboard",
425
+ componentExport: "DashboardPage",
426
+ entryPoint: "components/auth/dashboard",
427
+ order: 1,
428
+ },
429
+ ],
310
430
  storage: {
311
431
  buckets: [
312
432
  {
@@ -1 +1 @@
1
- {"version":3,"file":"AccountButton.d.ts","sourceRoot":"","sources":["../../src/components/AccountButton.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAIlD,UAAU,kBAAkB;IAC1B,IAAI,EAAE;QACJ,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACnB,WAAW,CAAC,EAAE,KAAK,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;KACd,CAAC,CAAC;IACH,QAAQ,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AASD,eAAO,MAAM,aAAa,GAAI,kCAI3B,kBAAkB,4CAmIpB,CAAC"}
1
+ {"version":3,"file":"AccountButton.d.ts","sourceRoot":"","sources":["../../src/components/AccountButton.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAKlD,UAAU,kBAAkB;IAC1B,IAAI,EAAE;QACJ,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACnB,WAAW,CAAC,EAAE,KAAK,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;KACd,CAAC,CAAC;IACH,QAAQ,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AASD,eAAO,MAAM,aAAa,GAAI,kCAI3B,kBAAkB,4CA0JpB,CAAC"}
@@ -1,11 +1,12 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
- import { AppLink, Button } from "@lastbrain/ui";
3
+ import { AppLink, Button, ThemeSwitcher } from "@lastbrain/ui";
4
4
  import { Avatar } from "@lastbrain/ui";
5
5
  import { Dropdown, DropdownItem, DropdownMenu, DropdownTrigger, } from "@lastbrain/ui";
6
6
  import * as LucideIcons from "lucide-react";
7
- import { useModuleTranslation, langHref } from "@lastbrain/app";
7
+ import { useModuleTranslation } from "@lastbrain/app";
8
8
  import { useLanguage } from "@lastbrain/app";
9
+ import { useLocalizedRouter, supabaseBrowserClient } from "@lastbrain/core";
9
10
  // Fonction pour récupérer l'icône Lucide
10
11
  const getIcon = (iconName) => {
11
12
  if (!iconName)
@@ -16,31 +17,56 @@ const getIcon = (iconName) => {
16
17
  export const AccountButton = ({ user, accountMenu = [], onLogout, }) => {
17
18
  const { lang } = useLanguage();
18
19
  const t = useModuleTranslation("auth");
20
+ const router = useLocalizedRouter();
19
21
  if (!user)
20
- return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "block md:hidden", children: [_jsx(Button, { as: AppLink, href: "/signin", radius: "full", isIconOnly: true, variant: "light", color: "primary", children: _jsx(LucideIcons.LogIn, { size: 16 }) }), _jsx(Button, { as: AppLink, href: "/signup", radius: "full", isIconOnly: true, variant: "flat", className: "ml-2", color: "secondary", children: _jsx(LucideIcons.UserPlus2, { size: 16 }) })] }), _jsxs("div", { className: "hidden md:block", children: [_jsx(Button, { as: AppLink, href: "/signin", startContent: _jsx(LucideIcons.LogIn, { size: 16 }), variant: "light", color: "primary", children: t("signin") }), _jsx(Button, { as: AppLink, href: "/signup", variant: "flat", className: "ml-2", color: "secondary", startContent: _jsx(LucideIcons.UserPlus2, { size: 16 }), children: t("signup") })] })] }));
21
- return (_jsxs(Dropdown, { children: [_jsx(DropdownTrigger, { children: user?.user_metadata.avatar ? (_jsx(Avatar, { size: "sm", src: user?.user_metadata.avatar
22
- ? `/api/storage/${user?.user_metadata.avatar}`
23
- : undefined, title: user.email, fallback: _jsx(LucideIcons.User2, { size: 18 }), classNames: {
24
- base: "cursor-pointer bg-white/0",
25
- icon: "text-default-700",
26
- } })) : (_jsx(Button, { size: "sm", variant: "flat", radius: "full", isIconOnly: true, children: _jsx(LucideIcons.User2, { size: 16 }) })) }), _jsx(DropdownMenu, { items: [
27
- {
28
- key: "hello",
29
- label: `${t("hello")} ${user?.user_metadata?.full_name || user.email}`,
30
- isReadOnly: true,
31
- },
32
- ...accountMenu.map((item) => ({
33
- key: item.path,
34
- label: item.title,
35
- description: item.description,
36
- icon: item.icon,
37
- isLogout: item.path.includes("signout") || item.path.includes("logout"),
38
- href: item.path.includes("signout") || item.path.includes("logout")
39
- ? undefined
40
- : langHref(item.path, lang),
41
- })),
42
- ], children: (item) => {
43
- const Icon = item.icon ? getIcon(item.icon) : null;
44
- return (_jsx(DropdownItem, { href: item.href, onPress: item.isLogout ? () => onLogout?.() : undefined, color: item.isLogout ? "danger" : "default", description: !item.isLogout && item.description, startContent: Icon && _jsx(Icon, { size: 16 }), isDisabled: item.isReadOnly, isReadOnly: item.isReadOnly, children: item.label }, item.key));
45
- } })] }));
22
+ return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "block sm:hidden flex flex-inline gap-2 item-center", children: [_jsx(Button, { as: AppLink, href: "/signin", radius: "full", isIconOnly: true, variant: "flat", color: "primary", children: _jsx(LucideIcons.UserPlus2, { size: 16 }) }), _jsx("div", { className: "ms-2", children: _jsx(ThemeSwitcher, {}) })] }), _jsxs("div", { className: "hidden sm:block flex flex-inline gap-2 item-center", children: [_jsx(Button, { as: AppLink, href: "/signin", startContent: _jsx(LucideIcons.LogIn, { size: 16 }), variant: "light", color: "primary", radius: "full", size: "sm", children: t("signin") }), _jsx(Button, { as: AppLink, href: "/signup", variant: "bordered", className: "ml-2", color: "secondary", radius: "full", size: "sm", startContent: _jsx(LucideIcons.UserPlus2, { size: 16 }), children: t("signup") })] })] }));
23
+ return (_jsxs("div", { className: "flex flex-inline gap-2", children: [_jsxs(Dropdown, { children: [_jsx(DropdownTrigger, { children: user?.user_metadata.avatar ? (_jsx(Avatar, { size: "sm", src: user?.user_metadata.avatar
24
+ ? `/api/storage/${user?.user_metadata.avatar}`
25
+ : undefined, title: user.email, fallback: _jsx(LucideIcons.User2, { size: 18 }), classNames: {
26
+ base: "cursor-pointer bg-white/0",
27
+ icon: "text-default-700",
28
+ } })) : (_jsx(Button, { size: "sm", variant: "flat", radius: "full", isIconOnly: true, children: _jsx(LucideIcons.User2, { size: 16 }) })) }), _jsx(DropdownMenu, { className: "relative", items: [
29
+ {
30
+ key: "hello",
31
+ label: `${t("hello")} ${user?.user_metadata?.full_name || user.email}`,
32
+ isReadOnly: true,
33
+ },
34
+ ...accountMenu.map((item) => ({
35
+ key: item.path,
36
+ label: item.title,
37
+ description: item.description,
38
+ icon: item.icon,
39
+ isLogout: item.path.includes("signout") || item.path.includes("logout"),
40
+ href: item.path.includes("signout") || item.path.includes("logout")
41
+ ? undefined
42
+ : item.path,
43
+ })),
44
+ ], children: (item) => {
45
+ const Icon = item.icon ? getIcon(item.icon) : null;
46
+ const handleLogout = async () => {
47
+ try {
48
+ if (onLogout) {
49
+ await onLogout();
50
+ }
51
+ else {
52
+ // default fallback: sign out via supabase client
53
+ try {
54
+ await supabaseBrowserClient.auth.signOut();
55
+ }
56
+ catch (_e) {
57
+ // ignore
58
+ }
59
+ }
60
+ }
61
+ finally {
62
+ try {
63
+ router.push("/");
64
+ }
65
+ catch (_e) {
66
+ // ignore routing errors
67
+ }
68
+ }
69
+ };
70
+ return (_jsx(DropdownItem, { as: AppLink, href: item.href, onPress: item.isLogout ? handleLogout : undefined, color: item.isLogout ? "danger" : "default", description: !item.isLogout && item.description, startContent: Icon && _jsx(Icon, { size: 16 }), isDisabled: item.isReadOnly, isReadOnly: item.isReadOnly, children: item.label }, item.key));
71
+ } })] }), _jsx(ThemeSwitcher, {})] }));
46
72
  };
@@ -1 +1 @@
1
- {"version":3,"file":"Doc.d.ts","sourceRoot":"","sources":["../../src/components/Doc.tsx"],"names":[],"mappings":"AAgBA;;;;;;GAMG;AACH,wBAAgB,GAAG,4CAqXlB"}
1
+ {"version":3,"file":"Doc.d.ts","sourceRoot":"","sources":["../../src/components/Doc.tsx"],"names":[],"mappings":"AAgBA;;;;;;GAMG;AACH,wBAAgB,GAAG,4CA2ZlB"}
@@ -14,7 +14,7 @@ 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: "/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/signup" }) }), _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
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", { className: "flex items-start gap-2", children: [_jsx(Chip, { size: "sm", color: "success", variant: "flat", children: "GET" }), _jsx("code", { className: "text-sm", children: "/confirm" }), _jsx("span", { className: "text-sm text-slate-600 dark:text-slate-400", children: "- ConfirmPage" })] }), _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: "/auth-code-error" }), _jsx("span", { className: "text-sm text-slate-600 dark:text-slate-400", children: "- AuthCodeErrorPage" })] })] })] }), _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: "/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/signup" }) }), _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/public/callback" }) }), _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" }), _jsx(TableStructure, { tableName: "global_addons", title: "global_addons", description: "Table global_addons du module auth" }), _jsx(TableStructure, { tableName: "user_global_addons", title: "user_global_addons", description: "Table user_global_addons 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
@@ -0,0 +1,4 @@
1
+ export declare const HasProfil: ({ hasUpdate, }: {
2
+ hasUpdate?: (value: boolean | null) => void;
3
+ }) => import("react/jsx-runtime").JSX.Element;
4
+ //# sourceMappingURL=HasProfil.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HasProfil.d.ts","sourceRoot":"","sources":["../../src/components/HasProfil.tsx"],"names":[],"mappings":"AAIA,eAAO,MAAM,SAAS,GAAI,gBAEvB;IACD,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,KAAK,IAAI,CAAC;CAC7C,4CAsDA,CAAC"}
@@ -0,0 +1,39 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { logger, useModuleTranslation } from "@lastbrain/core";
3
+ import { Alert, AppLink, Skeleton } from "@lastbrain/ui";
4
+ import { useEffect, useState } from "react";
5
+ export const HasProfil = ({ hasUpdate, }) => {
6
+ const [profil, setProfil] = useState(null);
7
+ const t = useModuleTranslation("auth");
8
+ const [loading, setLoading] = useState(true);
9
+ useEffect(() => {
10
+ const fetchStats = async () => {
11
+ try {
12
+ const responseProfil = await fetch("/api/auth/profile");
13
+ if (!responseProfil.ok) {
14
+ throw new Error("Failed to load stats");
15
+ }
16
+ const jsonProfil = await responseProfil.json();
17
+ setProfil(jsonProfil.data);
18
+ if (jsonProfil.data && jsonProfil.data.first_name) {
19
+ hasUpdate?.(true);
20
+ }
21
+ else {
22
+ hasUpdate?.(false);
23
+ }
24
+ }
25
+ catch (error) {
26
+ logger.error("[HasProfil] stats error", error);
27
+ }
28
+ finally {
29
+ setLoading(false);
30
+ }
31
+ };
32
+ fetchStats();
33
+ }, []);
34
+ if (loading) {
35
+ return (_jsx("div", { className: "mb-6 mt-6", children: _jsx(Skeleton, { className: "w-full h-12 w-full rounded-md" }) }));
36
+ }
37
+ return (_jsx("div", { className: "mb-6 mt-6", children: !profil ||
38
+ (!profil.first_name ? (_jsx(Alert, { color: "danger", endContent: _jsx(AppLink, { className: "underline", href: "/auth/profile", children: "Go" }), children: t("please_complete_your_profile") })) : null) }));
39
+ };
@@ -1,2 +1,2 @@
1
- export declare function DashboardPage(): import("react/jsx-runtime").JSX.Element | null;
1
+ export declare function DashboardPage(): import("react/jsx-runtime").JSX.Element;
2
2
  //# sourceMappingURL=dashboard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../../src/components/auth/dashboard.tsx"],"names":[],"mappings":"AAiCA,wBAAgB,aAAa,4CA4O5B"}
@@ -0,0 +1,74 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { useEffect, useState } from "react";
4
+ import { Card, CardBody, CardHeader, Spinner, Chip, Divider, Avatar, Skeleton, } from "@lastbrain/ui";
5
+ import { User, Mail, Calendar, Shield, LayoutDashboard } from "lucide-react";
6
+ import { useModuleTranslation } from "@lastbrain/core";
7
+ import { useRouter } from "next/navigation";
8
+ import { HasProfil } from "../HasProfil";
9
+ export function DashboardPage() {
10
+ const t = useModuleTranslation("auth");
11
+ const [userData, setUserData] = useState(null);
12
+ const [isLoading, setIsLoading] = useState(true);
13
+ const [error, setError] = useState(null);
14
+ const [hasUpdate, setHasUpdate] = useState(null);
15
+ const router = useRouter();
16
+ useEffect(() => {
17
+ fetchUserData();
18
+ }, []);
19
+ const fetchUserData = async () => {
20
+ try {
21
+ setIsLoading(true);
22
+ const response = await fetch("/api/auth/me", { credentials: "include" });
23
+ if (!response.ok) {
24
+ throw new Error("Failed to fetch user data");
25
+ }
26
+ const result = await response.json();
27
+ // Si le serveur a synchronisé la locale côté cookie, rediriger
28
+ // le client vers le même chemin préfixé par la langue du profil.
29
+ if (result?.localeUpdated && result?.profileLang) {
30
+ try {
31
+ const profileLang = result.profileLang;
32
+ const pathname = window.location.pathname;
33
+ const search = window.location.search || "";
34
+ // Retirer un préfixe langue existant
35
+ const pathWithoutLang = pathname.replace(/^\/[a-z]{2}(?=\/|$)/, "") || "/";
36
+ // Éviter de rediriger vers des routes API
37
+ const safePath = pathWithoutLang.startsWith("/api")
38
+ ? "/"
39
+ : pathWithoutLang;
40
+ const target = `${profileLang.startsWith("/") ? profileLang : "/" + profileLang}${safePath}${search}`;
41
+ router.replace(target);
42
+ return;
43
+ }
44
+ catch (e) {
45
+ console.debug("dashboard: locale redirect failed", e);
46
+ }
47
+ }
48
+ setUserData(result.data);
49
+ }
50
+ catch (err) {
51
+ setError(err instanceof Error ? err.message : "An error occurred");
52
+ }
53
+ finally {
54
+ setIsLoading(false);
55
+ }
56
+ };
57
+ if (isLoading) {
58
+ 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: t("dashboard.loading") || "Loading dashboard..." })] }) }));
59
+ }
60
+ if (error) {
61
+ 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: [t("dashboard.error") || "Error", ": ", error] }) }) }) }));
62
+ }
63
+ if (!userData) {
64
+ return (_jsx(_Fragment, { children: _jsx(HasProfil, {}) }));
65
+ }
66
+ const fullName = userData?.profile?.first_name && userData.profile?.last_name
67
+ ? `${userData.profile.first_name} ${userData.profile.last_name}`
68
+ : "User";
69
+ return (_jsxs("div", { className: "max-w-6xl mx-auto", children: [_jsx(HasProfil, { hasUpdate: (v) => {
70
+ setHasUpdate(v);
71
+ } }), _jsxs("div", { className: "flex flex-inline items-center gap-2 mb-4", children: [_jsx(LayoutDashboard, { size: 24 }), _jsx("h1", { className: "text-3xl font-bold ", children: t("dashboard.title") || "Dashboard" })] }), _jsxs("div", { className: "mx-0 px-0 grid gap-6 md:grid-cols-2", children: [_jsxs(Card, { className: "col-span-full md:col-span-1", children: [_jsxs(CardHeader, { className: "flex gap-3", children: [_jsx(Avatar, { src: userData.profile?.avatar_url, icon: _jsx(User, {}), size: "lg", className: "shrink-0" }), _jsxs("div", { className: "flex flex-col", children: [_jsx("p", { className: "text-xl font-semibold", children: fullName }), _jsx("p", { className: "text-small text-default-500", children: userData.email })] })] }), _jsx(Divider, {}), _jsx(CardBody, { children: _jsxs("div", { className: "space-y-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Mail, { className: "w-4 h-4 text-default-400" }), _jsx("span", { className: "text-small", children: userData.email })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Calendar, { className: "w-4 h-4 text-default-400" }), _jsxs("span", { className: "text-small", children: [t("dashboard.member_since") || "Member since", " ", new Date(userData.created_at).toLocaleDateString()] })] }), userData.profile?.company && (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Shield, { className: "w-4 h-4 text-default-400" }), _jsx("span", { className: "text-small", children: userData.profile.company })] }))] }) })] }), _jsxs(Card, { children: [_jsx(CardHeader, { children: _jsx("h3", { className: "text-lg font-semibold", children: t("dashboard.account_status") || "Account Status" }) }), _jsx(Divider, {}), _jsx(CardBody, { children: _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "flex justify-between items-center", children: [_jsx("span", { className: "text-small", children: t("dashboard.status") || "Status" }), _jsx(Chip, { color: "success", size: "sm", variant: "flat", children: t("dashboard.active") || "Active" })] }), _jsxs("div", { className: "flex justify-between items-center", children: [_jsx("span", { className: "text-small", children: t("dashboard.profile") || "Profile" }), hasUpdate === null ? (_jsx(Skeleton, { className: "w-16 h-6 rounded-full" })) : (_jsx(Chip, { color: hasUpdate ? "success" : "warning", size: "sm", variant: "flat", children: hasUpdate
72
+ ? t("dashboard.complete") || "Complete"
73
+ : t("dashboard.incomplete") || "Incomplete" }))] })] }) })] }), userData.profile?.bio && (_jsxs(Card, { className: "col-span-full", children: [_jsx(CardHeader, { children: _jsx("h3", { className: "text-lg font-semibold", children: "Bio" }) }), _jsx(Divider, {}), _jsx(CardBody, { children: _jsx("p", { className: "text-small text-default-600", children: userData.profile.bio }) })] }))] })] }));
74
+ }
package/dist/index.d.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  export { SignInPage } from "./web/public/SignInPage";
2
2
  export { SignUpPage } from "./web/public/SignUpPage";
3
3
  export { ResetPassword } from "./web/public/ResetPassword";
4
- export { DashboardPage } from "./web/auth/dashboard";
4
+ export { default as ConfirmPage } from "./web/public/confirm";
5
+ export { default as AuthCodeErrorPage } from "./web/public/auth-code-error";
6
+ export { DashboardPage } from "./components/auth/dashboard";
5
7
  export { FolderPage } from "./web/auth/folder";
6
8
  export { ProfilePage } from "./web/auth/profile";
7
9
  export { ReglagePage } from "./web/auth/reglage";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAG3D,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAGvE,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,GAAG,IAAI,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAC5E,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAG3D,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAGvE,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,GAAG,IAAI,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,qBAAqB,CAAC"}
package/dist/index.js CHANGED
@@ -2,7 +2,9 @@
2
2
  export { SignInPage } from "./web/public/SignInPage";
3
3
  export { SignUpPage } from "./web/public/SignUpPage";
4
4
  export { ResetPassword } from "./web/public/ResetPassword";
5
- export { DashboardPage } from "./web/auth/dashboard";
5
+ export { default as ConfirmPage } from "./web/public/confirm";
6
+ export { default as AuthCodeErrorPage } from "./web/public/auth-code-error";
7
+ export { DashboardPage } from "./components/auth/dashboard";
6
8
  export { FolderPage } from "./web/auth/folder";
7
9
  export { ProfilePage } from "./web/auth/profile";
8
10
  export { ReglagePage } from "./web/auth/reglage";
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Branding configuration for emails
3
+ * Loaded dynamically from app i18n files (app.name, app.icon, etc.)
4
+ */
5
+ export interface AppBrandingData {
6
+ appName: string;
7
+ logo?: string;
8
+ description?: string;
9
+ tagline?: string;
10
+ icon?: string;
11
+ twitterCreator?: string;
12
+ twitterSite?: string;
13
+ supportEmail?: string;
14
+ primaryColor?: string;
15
+ secondaryColor?: string;
16
+ }
17
+ /**
18
+ * Récupère le branding depuis les clés i18n de l'app
19
+ * Utilise les clés : app.name, app.icon, app.description, app.tagline, etc.
20
+ */
21
+ export declare function getAppBranding(locale?: string): AppBrandingData;
22
+ //# sourceMappingURL=app-branding-data.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-branding-data.d.ts","sourceRoot":"","sources":["../../src/lib/app-branding-data.ts"],"names":[],"mappings":"AAGA;;;GAGG;AAEH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAkDD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,GAAE,MAAa,GAAG,eAAe,CAgBrE"}