@lastbrain/module-auth 0.1.16 → 0.1.19

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 (33) hide show
  1. package/README.md +1 -0
  2. package/dist/auth.build.config.d.ts.map +1 -1
  3. package/dist/auth.build.config.js +114 -10
  4. package/dist/components/AccountButton.d.ts +18 -0
  5. package/dist/components/AccountButton.d.ts.map +1 -0
  6. package/dist/components/AccountButton.js +40 -0
  7. package/dist/components/NotificationButton.d.ts +18 -0
  8. package/dist/components/NotificationButton.d.ts.map +1 -0
  9. package/dist/components/NotificationButton.js +8 -0
  10. package/dist/components/ThemeSwitcherButton.d.ts +9 -0
  11. package/dist/components/ThemeSwitcherButton.d.ts.map +1 -0
  12. package/dist/components/ThemeSwitcherButton.js +6 -0
  13. package/dist/index.d.ts +3 -0
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +4 -0
  16. package/dist/web/admin/user-detail.d.ts.map +1 -1
  17. package/dist/web/admin/user-detail.js +27 -6
  18. package/dist/web/admin/users.d.ts.map +1 -1
  19. package/dist/web/admin/users.js +6 -6
  20. package/dist/web/auth/profile.js +17 -17
  21. package/package.json +2 -1
  22. package/src/auth.build.config.ts +114 -10
  23. package/src/components/AccountButton.tsx +157 -0
  24. package/src/components/NotificationButton.tsx +41 -0
  25. package/src/components/ThemeSwitcherButton.tsx +14 -0
  26. package/src/index.ts +6 -0
  27. package/src/web/admin/user-detail.tsx +244 -51
  28. package/src/web/admin/users.tsx +21 -3
  29. package/src/web/auth/profile.tsx +34 -34
  30. package/supabase/migrations/20251112000000_user_init.sql +6 -1
  31. package/supabase/migrations/20251112000001_auto_profile_and_admin_view.sql +6 -1
  32. package/supabase/migrations/20251124000001_add_get_admin_user_details.sql +1 -0
  33. package/supabase/migrations/20251127100000_rename_body_to_message.sql +9 -0
@@ -122,18 +122,34 @@ const authBuildConfig: ModuleBuildConfig = {
122
122
  menu: {
123
123
  public: [
124
124
  {
125
- title: "Connexion",
126
- description: "Connectez-vous à votre compte",
127
- icon: "LogIn",
128
- path: "/signin",
129
- order: 1,
125
+ title: "Notifications",
126
+ description: "Vos notifications",
127
+ icon: "Bell",
128
+ path: "#",
129
+ order: 998,
130
+ type: "icon",
131
+ position: "end",
132
+ componentExport: "NotificationButton",
130
133
  },
131
134
  {
132
- title: "Inscription",
133
- description: "Créez votre compte",
134
- icon: "UserPlus2",
135
- path: "/signup",
136
- order: 2,
135
+ title: "Compte",
136
+ description: "Gérer votre compte",
137
+ icon: "User",
138
+ path: "#",
139
+ order: 999,
140
+ type: "icon",
141
+ position: "end",
142
+ componentExport: "AccountButton",
143
+ },
144
+ {
145
+ title: "Theme",
146
+ description: "Changer le thème",
147
+ icon: "Palette",
148
+ path: "#",
149
+ order: 9999,
150
+ type: "icon",
151
+ position: "end",
152
+ componentExport: "ThemeSwitcherButton",
137
153
  },
138
154
  ],
139
155
  admin: [
@@ -146,6 +162,36 @@ const authBuildConfig: ModuleBuildConfig = {
146
162
  shortcut: "cmd+shift+u",
147
163
  shortcutDisplay: "⌘⇧U",
148
164
  },
165
+ {
166
+ title: "Notifications",
167
+ description: "Vos notifications",
168
+ icon: "Bell",
169
+ path: "#",
170
+ order: 998,
171
+ type: "icon",
172
+ position: "end",
173
+ componentExport: "NotificationButton",
174
+ },
175
+ {
176
+ title: "Compte",
177
+ description: "Gérer votre compte",
178
+ icon: "User",
179
+ path: "#",
180
+ order: 999,
181
+ type: "icon",
182
+ position: "end",
183
+ componentExport: "AccountButton",
184
+ },
185
+ {
186
+ title: "Theme",
187
+ description: "Changer le thème",
188
+ icon: "Palette",
189
+ path: "#",
190
+ order: 9999,
191
+ type: "icon",
192
+ position: "end",
193
+ componentExport: "ThemeSwitcherButton",
194
+ },
149
195
  ],
150
196
  auth: [
151
197
  {
@@ -166,6 +212,36 @@ const authBuildConfig: ModuleBuildConfig = {
166
212
  shortcut: "cmd+shift+f",
167
213
  shortcutDisplay: "⌘⇧F",
168
214
  },
215
+ {
216
+ title: "Notifications",
217
+ description: "Vos notifications",
218
+ icon: "Bell",
219
+ path: "#",
220
+ order: 998,
221
+ type: "icon",
222
+ position: "end",
223
+ componentExport: "NotificationButton",
224
+ },
225
+ {
226
+ title: "Compte",
227
+ description: "Gérer votre compte",
228
+ icon: "User",
229
+ path: "#",
230
+ order: 999,
231
+ type: "icon",
232
+ position: "end",
233
+ componentExport: "AccountButton",
234
+ },
235
+ {
236
+ title: "Theme",
237
+ description: "Changer le thème",
238
+ icon: "Palette",
239
+ path: "#",
240
+ order: 9999,
241
+ type: "icon",
242
+ position: "end",
243
+ componentExport: "ThemeSwitcherButton",
244
+ },
169
245
  ],
170
246
  account: [
171
247
  {
@@ -221,6 +297,34 @@ const authBuildConfig: ModuleBuildConfig = {
221
297
  },
222
298
  ],
223
299
  },
300
+ storage: {
301
+ buckets: [
302
+ {
303
+ name: "app",
304
+ public: false,
305
+ description: "Private user files and documents /{userId}/...",
306
+ maxFileSize: 100 * 1024 * 1024, // 100MB
307
+ customAccessControl: (userId: string, filePath: string) => {
308
+ // Users can only access files in their own folder (app/{userId}/...)
309
+ return filePath.startsWith(`${userId}/`);
310
+ },
311
+ },
312
+ {
313
+ name: "avatar",
314
+ public: true,
315
+ description: "Public user avatar images",
316
+ allowedMimeTypes: [
317
+ "image/jpeg",
318
+ "image/jpg",
319
+ "image/png",
320
+ "image/webp",
321
+ "image/gif",
322
+ ],
323
+ maxFileSize: 5242880, // 5MB
324
+ fileSizeLimit: "5MB",
325
+ },
326
+ ],
327
+ },
224
328
  };
225
329
 
226
330
  export default authBuildConfig;
@@ -0,0 +1,157 @@
1
+ "use client";
2
+
3
+ import { Button, Link } from "@lastbrain/ui";
4
+ import { Avatar } from "@lastbrain/ui";
5
+ import {
6
+ Dropdown,
7
+ DropdownItem,
8
+ DropdownMenu,
9
+ DropdownTrigger,
10
+ } from "@lastbrain/ui";
11
+ import * as LucideIcons from "lucide-react";
12
+ import type { User } from "@supabase/supabase-js";
13
+ import { use } from "react";
14
+
15
+ interface AccountButtonProps {
16
+ item: {
17
+ path: string;
18
+ title: string;
19
+ };
20
+ user?: User | null;
21
+ accountMenu?: Array<{
22
+ title: string;
23
+ description?: string;
24
+ icon?: string;
25
+ path: string;
26
+ }>;
27
+ onLogout?: () => void | Promise<void>;
28
+ }
29
+
30
+ // Fonction pour récupérer l'icône Lucide
31
+ const getIcon = (iconName?: string) => {
32
+ if (!iconName) return null;
33
+ const Icon = (LucideIcons as any)[iconName];
34
+ return Icon ? Icon : null;
35
+ };
36
+
37
+ export const AccountButton = ({
38
+ user,
39
+ accountMenu = [],
40
+ onLogout,
41
+ }: AccountButtonProps) => {
42
+ if (!user)
43
+ return (
44
+ <>
45
+ <div className="block md:hidden">
46
+ <Button
47
+ as={Link}
48
+ href="/signin"
49
+ radius="full"
50
+ isIconOnly
51
+ variant="light"
52
+ color="primary"
53
+ >
54
+ <LucideIcons.LogIn size={16} />
55
+ </Button>
56
+ <Button
57
+ as={Link}
58
+ href="/signup"
59
+ radius="full"
60
+ isIconOnly
61
+ variant="flat"
62
+ className="ml-2"
63
+ color="secondary"
64
+ >
65
+ <LucideIcons.UserPlus2 size={16} />
66
+ </Button>
67
+ </div>
68
+ <div className="hidden md:block">
69
+ <Button
70
+ as={Link}
71
+ href="/signin"
72
+ startContent={<LucideIcons.LogIn size={16} />}
73
+ variant="light"
74
+ color="primary"
75
+ >
76
+ Se connecter
77
+ </Button>
78
+ <Button
79
+ as={Link}
80
+ href="/signup"
81
+ variant="flat"
82
+ className="ml-2"
83
+ color="secondary"
84
+ startContent={<LucideIcons.UserPlus2 size={16} />}
85
+ >
86
+ S'inscrire
87
+ </Button>
88
+ </div>
89
+ </>
90
+ );
91
+
92
+ return (
93
+ <Dropdown>
94
+ <DropdownTrigger>
95
+ <Avatar
96
+ size="sm"
97
+ src={`/api/storage/${user?.user_metadata.avatar}`}
98
+ title={user.email}
99
+ fallback={<LucideIcons.User2 size={18} />}
100
+ classNames={{
101
+ base: "bg-white/0",
102
+ icon: "text-default-700",
103
+ }}
104
+ />
105
+ </DropdownTrigger>
106
+
107
+ <DropdownMenu
108
+ items={[
109
+ {
110
+ key: "hello",
111
+ label: `Bonjour ${user?.user_metadata?.full_name || user.email}`,
112
+ isReadOnly: true,
113
+ },
114
+ ...accountMenu.map((item) => ({
115
+ key: item.path,
116
+ label: item.title,
117
+ description: item.description,
118
+ icon: item.icon,
119
+ isLogout:
120
+ item.path.includes("signout") || item.path.includes("logout"),
121
+ href:
122
+ item.path.includes("signout") || item.path.includes("logout")
123
+ ? undefined
124
+ : item.path,
125
+ })),
126
+ ]}
127
+ >
128
+ {(item: {
129
+ key: string;
130
+ label: string;
131
+ description?: string;
132
+ icon?: string;
133
+ isLogout?: boolean;
134
+ href?: string;
135
+ isReadOnly?: boolean;
136
+ }) => {
137
+ const Icon = item.icon ? getIcon(item.icon) : null;
138
+
139
+ return (
140
+ <DropdownItem
141
+ key={item.key}
142
+ href={item.href}
143
+ onPress={item.isLogout ? () => onLogout?.() : undefined}
144
+ color={item.isLogout ? "danger" : "default"}
145
+ description={item.description}
146
+ startContent={Icon && <Icon size={16} />}
147
+ isDisabled={item.isReadOnly}
148
+ isReadOnly={item.isReadOnly}
149
+ >
150
+ {item.label}
151
+ </DropdownItem>
152
+ );
153
+ }}
154
+ </DropdownMenu>
155
+ </Dropdown>
156
+ );
157
+ };
@@ -0,0 +1,41 @@
1
+ "use client";
2
+
3
+ import { Notification, type UserNotification } from "@lastbrain/ui";
4
+ import type { User } from "@supabase/supabase-js";
5
+
6
+ interface NotificationButtonProps {
7
+ item: {
8
+ path: string;
9
+ title: string;
10
+ };
11
+ user?: User | null;
12
+ notifications?: UserNotification[];
13
+ unreadCount?: number;
14
+ notificationsLoading?: boolean;
15
+ onMarkAsRead?: (id: string) => void;
16
+ onMarkAllAsRead?: () => void;
17
+ onDeleteNotification?: (id: string) => void;
18
+ }
19
+
20
+ export const NotificationButton = ({
21
+ user,
22
+ notifications = [],
23
+ unreadCount = 0,
24
+ notificationsLoading = false,
25
+ onMarkAsRead = () => {},
26
+ onMarkAllAsRead = () => {},
27
+ onDeleteNotification = () => {},
28
+ }: NotificationButtonProps) => {
29
+ if (!user) return null;
30
+
31
+ return (
32
+ <Notification
33
+ notifications={notifications}
34
+ unreadCount={unreadCount}
35
+ loading={notificationsLoading}
36
+ onMarkAsRead={onMarkAsRead}
37
+ onMarkAllAsRead={onMarkAllAsRead}
38
+ onDelete={onDeleteNotification}
39
+ />
40
+ );
41
+ };
@@ -0,0 +1,14 @@
1
+ "use client";
2
+
3
+ import { ThemeSwitcher } from "@lastbrain/ui";
4
+
5
+ interface ThemeSwitcherButtonProps {
6
+ item: {
7
+ path: string;
8
+ title: string;
9
+ };
10
+ }
11
+
12
+ export const ThemeSwitcherButton = (_props: ThemeSwitcherButtonProps) => {
13
+ return <ThemeSwitcher />;
14
+ };
package/src/index.ts CHANGED
@@ -9,6 +9,12 @@ export { ReglagePage } from "./web/auth/reglage.js";
9
9
  export { AdminUsersPage } from "./web/admin/users.js";
10
10
  export { default as UserPage } from "./web/admin/users/[id].js";
11
11
  export { UserDetailPage } from "./web/admin/user-detail.js";
12
+
13
+ // Header Components
14
+ export { AccountButton } from "./components/AccountButton.js";
15
+ export { NotificationButton } from "./components/NotificationButton.js";
16
+ export { ThemeSwitcherButton } from "./components/ThemeSwitcherButton.js";
17
+
12
18
  // Documentation
13
19
  export { Doc } from "./components/Doc.js";
14
20
  export { Doc as AuthModuleDoc } from "./components/Doc.js";