@lastbrain/module-auth 2.0.16 → 2.0.27
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/dist/auth.build.config.d.ts.map +1 -1
- package/dist/auth.build.config.js +42 -51
- package/dist/components/AccountButton.d.ts.map +1 -1
- package/dist/components/AccountButton.js +9 -5
- package/dist/components/auth/dashboard.d.ts +2 -0
- package/dist/components/auth/dashboard.d.ts.map +1 -0
- package/dist/components/auth/dashboard.js +47 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/web/admin/signup-stats.d.ts.map +1 -1
- package/dist/web/admin/signup-stats.js +4 -2
- package/dist/web/admin/user-detail.d.ts.map +1 -1
- package/dist/web/admin/user-detail.js +42 -17
- package/dist/web/admin/users-by-signup-source.d.ts.map +1 -1
- package/dist/web/admin/users-by-signup-source.js +18 -7
- package/dist/web/admin/users.d.ts.map +1 -1
- package/dist/web/admin/users.js +11 -6
- package/dist/web/auth/dashboard.d.ts.map +1 -1
- package/dist/web/auth/dashboard.js +7 -3
- package/dist/web/auth/folder.d.ts.map +1 -1
- package/dist/web/auth/folder.js +5 -3
- package/dist/web/auth/profile.d.ts.map +1 -1
- package/dist/web/auth/profile.js +13 -6
- package/dist/web/auth/reglage.d.ts.map +1 -1
- package/dist/web/auth/reglage.js +11 -6
- package/dist/web/public/SignInPage.d.ts.map +1 -1
- package/dist/web/public/SignInPage.js +14 -56
- package/dist/web/public/SignUpPage.d.ts.map +1 -1
- package/dist/web/public/SignUpPage.js +18 -11
- package/package.json +4 -3
- package/src/auth.build.config.ts +43 -52
- package/src/components/AccountButton.tsx +17 -10
- package/src/{web → components}/auth/dashboard.tsx +33 -14
- package/src/i18n/en.json +265 -0
- package/src/i18n/fr.json +262 -0
- package/src/index.ts +1 -1
- package/src/web/admin/signup-stats.tsx +10 -3
- package/src/web/admin/user-detail.tsx +135 -56
- package/src/web/admin/users-by-signup-source.tsx +60 -21
- package/src/web/admin/users.tsx +41 -18
- package/src/web/auth/folder.tsx +11 -3
- package/src/web/auth/profile.tsx +63 -29
- package/src/web/auth/reglage.tsx +43 -19
- package/src/web/public/SignInPage.tsx +32 -70
- package/src/web/public/SignUpPage.tsx +48 -26
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { useEffect, useState } from "react";
|
|
4
|
+
import { useModuleTranslation } from "@lastbrain/core";
|
|
4
5
|
import { Card, CardBody, CardHeader, Chip, Input, Pagination, Select, SelectItem, Spinner, Table, TableBody, TableCell, TableColumn, TableHeader, TableRow, } from "@lastbrain/ui";
|
|
5
6
|
import { Search, Users } from "lucide-react";
|
|
6
7
|
export function UsersBySignupSourcePage() {
|
|
8
|
+
const t = useModuleTranslation("auth");
|
|
7
9
|
const [users, setUsers] = useState([]);
|
|
8
10
|
const [loading, setLoading] = useState(true);
|
|
9
11
|
const [error, setError] = useState(null);
|
|
@@ -27,7 +29,8 @@ export function UsersBySignupSourcePage() {
|
|
|
27
29
|
}
|
|
28
30
|
const response = await fetch(url);
|
|
29
31
|
if (!response.ok) {
|
|
30
|
-
throw new Error("
|
|
32
|
+
throw new Error(t("users_by_source.loading_error") ||
|
|
33
|
+
"Erreur lors du chargement des utilisateurs");
|
|
31
34
|
}
|
|
32
35
|
const result = await response.json();
|
|
33
36
|
// Filter by search query if provided
|
|
@@ -40,7 +43,10 @@ export function UsersBySignupSourcePage() {
|
|
|
40
43
|
setPagination(result.pagination);
|
|
41
44
|
}
|
|
42
45
|
catch (err) {
|
|
43
|
-
setError(err instanceof Error
|
|
46
|
+
setError(err instanceof Error
|
|
47
|
+
? err.message
|
|
48
|
+
: t("users_by_source.loading_error_generic") ||
|
|
49
|
+
"Erreur lors du chargement");
|
|
44
50
|
}
|
|
45
51
|
finally {
|
|
46
52
|
setLoading(false);
|
|
@@ -64,16 +70,21 @@ export function UsersBySignupSourcePage() {
|
|
|
64
70
|
if (error) {
|
|
65
71
|
return (_jsx("div", { className: "p-6", children: _jsx(Card, { className: "border border-danger-200 bg-danger-50/50", children: _jsx(CardBody, { children: _jsx("p", { className: "text-danger-600", children: error }) }) }) }));
|
|
66
72
|
}
|
|
67
|
-
return (_jsxs("div", { className: "space-y-6 p-6", children: [_jsxs("div", { className: "flex items-center gap-2 mb-8", children: [_jsx(Users, { size: 28, className: "text-primary-600" }), _jsx("h1", { className: "text-3xl font-bold", children:
|
|
73
|
+
return (_jsxs("div", { className: "space-y-6 p-6", children: [_jsxs("div", { className: "flex items-center gap-2 mb-8", children: [_jsx(Users, { size: 28, className: "text-primary-600" }), _jsx("h1", { className: "text-3xl font-bold", children: t("users_by_source.title") ||
|
|
74
|
+
"Utilisateurs par source d'inscription" })] }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [_jsx(Input, { placeholder: t("users_by_source.search_placeholder") ||
|
|
75
|
+
"Rechercher par email ou nom...", value: searchQuery, onChange: handleSearch, startContent: _jsx(Search, { size: 16 }), isClearable: true, onClear: () => {
|
|
68
76
|
setSearchQuery("");
|
|
69
77
|
fetchUsers(1, source, "");
|
|
70
|
-
} }), _jsxs(Select, { label: "Filtrer par source", selectedKeys: [source], onChange: (e) => handleSourceChange(e.target.value), children: [_jsx(SelectItem, { children: "Toutes les sources" }, ""), _jsx(SelectItem, { children: "LastBrain" }, "lastbrain"), _jsx(SelectItem, { children: "Recipe" }, "recipe")] })] }), _jsxs("div", { className: "text-sm text-default-600", children: ["Affichage de", " ", _jsxs("span", { className: "font-semibold", children: [(pagination.page - 1) * pagination.limit + 1, "-", Math.min(pagination.page * pagination.limit, pagination.total)] }), " ", "sur ", _jsx("span", { className: "font-semibold", children: pagination.total }), " ", "utilisateurs"] }), _jsxs(Card, { children: [_jsx(CardHeader, { children: _jsx("h3", { className: "text-lg font-semibold", children: "Liste des utilisateurs" }) }), _jsx(CardBody, { children: loading ? (_jsx("div", { className: "flex justify-center py-8", children: _jsx(Spinner, { size: "lg", label: "Chargement..." }) })) : (_jsxs(_Fragment, { children: [_jsxs(Table, { "aria-label":
|
|
71
|
-
|
|
72
|
-
|
|
78
|
+
} }), _jsxs(Select, { label: t("users_by_source.filter_label") || "Filtrer par source", selectedKeys: [source], onChange: (e) => handleSourceChange(e.target.value), children: [_jsx(SelectItem, { children: t("users_by_source.all_sources") || "Toutes les sources" }, ""), _jsx(SelectItem, { children: t("users_by_source.source_lastbrain") || "LastBrain" }, "lastbrain"), _jsx(SelectItem, { children: t("users_by_source.source_recipe") || "Recipe" }, "recipe")] })] }), _jsxs("div", { className: "text-sm text-default-600", children: [t("users_by_source.showing") || "Affichage de", " ", _jsxs("span", { className: "font-semibold", children: [(pagination.page - 1) * pagination.limit + 1, "-", Math.min(pagination.page * pagination.limit, pagination.total)] }), " ", t("users_by_source.of") || "sur", " ", _jsx("span", { className: "font-semibold", children: pagination.total }), " ", t("users_by_source.users") || "utilisateurs"] }), _jsxs(Card, { children: [_jsx(CardHeader, { children: _jsx("h3", { className: "text-lg font-semibold", children: t("users_by_source.list_title") || "Liste des utilisateurs" }) }), _jsx(CardBody, { children: loading ? (_jsx("div", { className: "flex justify-center py-8", children: _jsx(Spinner, { size: "lg", label: t("users_by_source.loading") || "Chargement..." }) })) : (_jsxs(_Fragment, { children: [_jsxs(Table, { "aria-label": t("users_by_source.table_aria_label") ||
|
|
79
|
+
"Tableau des utilisateurs", children: [_jsxs(TableHeader, { children: [_jsx(TableColumn, { children: t("users_by_source.column_name") || "Nom" }), _jsx(TableColumn, { children: t("users_by_source.column_email") || "Email" }), _jsx(TableColumn, { children: t("users_by_source.column_source") || "Source" }), _jsx(TableColumn, { children: t("users_by_source.column_signup_date") ||
|
|
80
|
+
"Date d'inscription" })] }), _jsx(TableBody, { children: users.length > 0 ? (users.map((user) => (_jsxs(TableRow, { children: [_jsx(TableCell, { children: _jsx("span", { className: "font-medium", children: user.name }) }), _jsx(TableCell, { children: _jsx("span", { className: "text-sm text-default-600", children: user.email }) }), _jsx(TableCell, { children: _jsx(Chip, { size: "sm", color: getSourceColor(user.signup_source), variant: "flat", children: user.signup_source.toLowerCase() === "recipe"
|
|
81
|
+
? `🍳 ${t("users_by_source.recipe") || "Recipe"}`
|
|
82
|
+
: `🧠 ${t("users_by_source.lastbrain") || "LastBrain"}` }) }), _jsx(TableCell, { children: _jsx("span", { className: "text-sm text-default-500", children: new Date(user.created_at).toLocaleDateString("fr-FR", {
|
|
73
83
|
year: "2-digit",
|
|
74
84
|
month: "2-digit",
|
|
75
85
|
day: "2-digit",
|
|
76
86
|
hour: "2-digit",
|
|
77
87
|
minute: "2-digit",
|
|
78
|
-
}) }) })] }, user.id)))) : (_jsx(TableRow, { children: _jsx(TableCell, { colSpan: 4, className: "text-center py-8", children: _jsx("p", { className: "text-default-500", children: "
|
|
88
|
+
}) }) })] }, user.id)))) : (_jsx(TableRow, { children: _jsx(TableCell, { colSpan: 4, className: "text-center py-8", children: _jsx("p", { className: "text-default-500", children: t("users_by_source.no_users") ||
|
|
89
|
+
"Aucun utilisateur trouvé" }) }) })) })] }), pagination.totalPages > 1 && (_jsx("div", { className: "flex justify-center mt-6", children: _jsx(Pagination, { total: pagination.totalPages, page: pagination.page, onChange: handlePageChange, showControls: true }) }))] })) })] })] }));
|
|
79
90
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"users.d.ts","sourceRoot":"","sources":["../../../src/web/admin/users.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"users.d.ts","sourceRoot":"","sources":["../../../src/web/admin/users.tsx"],"names":[],"mappings":"AA8CA,wBAAgB,cAAc,4CAyQ7B"}
|
package/dist/web/admin/users.js
CHANGED
|
@@ -3,9 +3,11 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
3
3
|
import { useCallback, useEffect, useState, useId } from "react";
|
|
4
4
|
import { Card, CardBody, CardHeader, Table, TableHeader, TableColumn, TableBody, TableRow, TableCell, Spinner, Chip, Input, Button, Pagination, Avatar, } from "@lastbrain/ui";
|
|
5
5
|
import { Search, RefreshCw, Eye, Users2 } from "lucide-react";
|
|
6
|
-
import {
|
|
6
|
+
import { useModuleTranslation } from "@lastbrain/core";
|
|
7
|
+
import { useLocalizedRouter } from "@lastbrain/core";
|
|
7
8
|
export function AdminUsersPage() {
|
|
8
|
-
const router =
|
|
9
|
+
const router = useLocalizedRouter();
|
|
10
|
+
const t = useModuleTranslation("auth");
|
|
9
11
|
const searchInputId = useId();
|
|
10
12
|
const [users, setUsers] = useState([]);
|
|
11
13
|
const [isLoading, setIsLoading] = useState(true);
|
|
@@ -76,16 +78,19 @@ export function AdminUsersPage() {
|
|
|
76
78
|
if (error && users.length === 0) {
|
|
77
79
|
return (_jsx("div", { className: "pt-12 pb-12 max-w-7xl mx-auto px-4", children: _jsx(Card, { children: _jsx(CardBody, { children: _jsx("p", { className: "text-danger", children: error }) }) }) }));
|
|
78
80
|
}
|
|
79
|
-
return (_jsxs("div", { className: "pt-12 pb-12 max-w-7xl mx-auto px-4", children: [_jsxs("div", { className: "flex items-center gap-2 mb-8", children: [_jsx(Users2, { className: "w-8 h-8" }), _jsx("h1", { className: "text-3xl font-bold", children: "User Management" })] }), _jsxs(Card, { children: [_jsx(CardHeader, { children: _jsxs("div", { className: "flex flex-col md:flex-row gap-4 w-full", children: [_jsxs("div", { className: "flex gap-2 flex-1", children: [_jsx(Input, { id: searchInputId, placeholder: "Search by email or name...", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), onKeyPress: (e) => {
|
|
81
|
+
return (_jsxs("div", { className: "pt-12 pb-12 max-w-7xl mx-auto px-4", children: [_jsxs("div", { className: "flex items-center gap-2 mb-8", children: [_jsx(Users2, { className: "w-8 h-8" }), _jsx("h1", { className: "text-3xl font-bold", children: t("users.title") || "User Management" })] }), _jsxs(Card, { children: [_jsx(CardHeader, { children: _jsxs("div", { className: "flex flex-col md:flex-row gap-4 w-full", children: [_jsxs("div", { className: "flex gap-2 flex-1", children: [_jsx(Input, { id: searchInputId, placeholder: t("users.search_placeholder") || "Search by email or name...", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), onKeyPress: (e) => {
|
|
80
82
|
if (e.key === "Enter") {
|
|
81
83
|
handleSearch();
|
|
82
84
|
}
|
|
83
|
-
}, startContent: _jsx(Search, { className: "w-4 h-4 text-default-400" }), className: "flex-1" }), _jsx(Button, { color: "primary", onPress: handleSearch, isDisabled: isLoading, children: "Search" })] }), _jsx(Button, { variant: "flat", onPress: fetchUsers, isDisabled: isLoading, startContent: _jsx(RefreshCw, { className: "w-4 h-4" }), children: "Refresh" })] }) }), _jsx(CardBody, { children: isLoading ? (_jsx("div", { className: "flex justify-center items-center py-12", children: _jsx(Spinner, { size: "lg", label: "Loading users..." }) })) : users.length === 0 ? (_jsx("div", { className: "text-center py-12 text-default-500", children: "No users found" })) : (_jsxs(_Fragment, { children: [_jsxs(Table, { isStriped: true, "aria-label": "Users table", children: [_jsxs(TableHeader, { children: [_jsx(TableColumn, { children: "USER" }), _jsx(TableColumn, { children: "EMAIL" }), _jsx(TableColumn, { children: "ROLE" }), _jsx(TableColumn, { children: "LAST SIGN IN" }), _jsx(TableColumn, { children: "CREATED" }), _jsx(TableColumn, { children: "ACTIONS" })] }), _jsx(TableBody, { children: users.map((user) => {
|
|
85
|
+
}, startContent: _jsx(Search, { className: "w-4 h-4 text-default-400" }), className: "flex-1" }), _jsx(Button, { color: "primary", onPress: handleSearch, isDisabled: isLoading, children: t("users.search_button") || "Search" })] }), _jsx(Button, { variant: "flat", onPress: fetchUsers, isDisabled: isLoading, startContent: _jsx(RefreshCw, { className: "w-4 h-4" }), children: t("users.refresh_button") || "Refresh" })] }) }), _jsx(CardBody, { children: isLoading ? (_jsx("div", { className: "flex justify-center items-center py-12", children: _jsx(Spinner, { size: "lg", label: t("users.loading_users") || "Loading users..." }) })) : users.length === 0 ? (_jsx("div", { className: "text-center py-12 text-default-500", children: t("users.no_users_found") || "No users found" })) : (_jsxs(_Fragment, { children: [_jsxs(Table, { isStriped: true, "aria-label": t("users.table_aria_label") || "Users table", children: [_jsxs(TableHeader, { children: [_jsx(TableColumn, { children: t("users.column_user") || "USER" }), _jsx(TableColumn, { children: t("users.column_email") || "EMAIL" }), _jsx(TableColumn, { children: t("users.column_role") || "ROLE" }), _jsx(TableColumn, { children: t("users.column_last_sign_in") || "LAST SIGN IN" }), _jsx(TableColumn, { children: t("users.column_created") || "CREATED" }), _jsx(TableColumn, { children: t("users.column_actions") || "ACTIONS" })] }), _jsx(TableBody, { children: users.map((user) => {
|
|
84
86
|
const displayName = user.full_name || user.email;
|
|
85
87
|
return (_jsxs(TableRow, { children: [_jsx(TableCell, { children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Avatar, { isBordered: true, src: user.avatar_url
|
|
86
88
|
? `/api/storage/${user.avatar_url}`
|
|
87
89
|
: undefined, name: displayName, size: "sm" }), _jsx("span", { className: "text-small font-medium", children: displayName })] }) }), _jsx(TableCell, { children: _jsx("span", { className: "text-small", children: user.email }) }), _jsx(TableCell, { children: _jsx(Chip, { size: "sm", variant: "flat", color: user.role === "admin" ? "danger" : "default", children: user.role || "user" }) }), _jsx(TableCell, { children: _jsx("span", { className: "text-small", children: user.last_sign_in_at
|
|
88
90
|
? formatDate(user.last_sign_in_at)
|
|
89
|
-
: "Jamais" }) }), _jsx(TableCell, { children: _jsx("span", { className: "text-small", children: formatDate(user.created_at) }) }), _jsx(TableCell, { children: _jsx(Button, { size: "sm", variant: "flat", color: "primary", onPress: () => handleViewUser(user.id), startContent: _jsx(Eye, { size: 14 }), children: "Voir" }) })] }, user.id));
|
|
90
|
-
}) })] }), pagination.total_pages > 1 && (_jsx("div", { className: "flex justify-center mt-4", children: _jsx(Pagination, { total: pagination.total_pages, page: pagination.page, onChange: handlePageChange, showControls: true }) })),
|
|
91
|
+
: t("users.never") || "Jamais" }) }), _jsx(TableCell, { children: _jsx("span", { className: "text-small", children: formatDate(user.created_at) }) }), _jsx(TableCell, { children: _jsx(Button, { size: "sm", variant: "flat", color: "primary", onPress: () => handleViewUser(user.id), startContent: _jsx(Eye, { size: 14 }), children: t("users.view_button") || "Voir" }) })] }, user.id));
|
|
92
|
+
}) })] }), pagination.total_pages > 1 && (_jsx("div", { className: "flex justify-center mt-4", children: _jsx(Pagination, { total: pagination.total_pages, page: pagination.page, onChange: handlePageChange, showControls: true }) })), _jsx("div", { className: "mt-4 text-small text-default-500 text-center", children: t("users.showing_results")
|
|
93
|
+
?.replace("{{count}}", users.length.toString())
|
|
94
|
+
.replace("{{total}}", pagination.total.toString()) ||
|
|
95
|
+
`Showing ${users.length} of ${pagination.total} users` })] })) })] })] }));
|
|
91
96
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../../src/web/auth/dashboard.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../../src/web/auth/dashboard.tsx"],"names":[],"mappings":"AA8BA,wBAAgB,aAAa,mDAmM5B"}
|
|
@@ -3,7 +3,9 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { useEffect, useState } from "react";
|
|
4
4
|
import { Card, CardBody, CardHeader, Spinner, Chip, Divider, Avatar, } from "@lastbrain/ui";
|
|
5
5
|
import { User, Mail, Calendar, Shield } from "lucide-react";
|
|
6
|
+
import { useModuleTranslation } from "@lastbrain/core";
|
|
6
7
|
export function DashboardPage() {
|
|
8
|
+
const t = useModuleTranslation("auth");
|
|
7
9
|
const [userData, setUserData] = useState(null);
|
|
8
10
|
const [isLoading, setIsLoading] = useState(true);
|
|
9
11
|
const [error, setError] = useState(null);
|
|
@@ -28,10 +30,10 @@ export function DashboardPage() {
|
|
|
28
30
|
}
|
|
29
31
|
};
|
|
30
32
|
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 dashboard..." })] }) }));
|
|
33
|
+
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..." })] }) }));
|
|
32
34
|
}
|
|
33
35
|
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] }) }) }) }));
|
|
36
|
+
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] }) }) }) }));
|
|
35
37
|
}
|
|
36
38
|
if (!userData) {
|
|
37
39
|
return null;
|
|
@@ -39,6 +41,8 @@ export function DashboardPage() {
|
|
|
39
41
|
const fullName = userData.profile?.first_name && userData.profile?.last_name
|
|
40
42
|
? `${userData.profile.first_name} ${userData.profile.last_name}`
|
|
41
43
|
: "User";
|
|
42
|
-
return (_jsxs("div", { className: "pt-12 pb-12 max-w-6xl mx-auto px-4", children: [_jsx("h1", { className: "text-3xl font-bold mb-8", children: "Dashboard" }), _jsxs("div", { className: "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: ["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: "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: "Status" }), _jsx(Chip, { color: "success", size: "sm", variant: "flat", children: "Active" })] }), _jsxs("div", { className: "flex justify-between items-center", children: [_jsx("span", { className: "text-small", children: "Profile" }), _jsx(Chip, { color: userData.profile ? "success" : "warning", size: "sm", variant: "flat", children: userData.profile
|
|
44
|
+
return (_jsxs("div", { className: "pt-12 pb-12 max-w-6xl mx-auto px-4", children: [_jsx("h1", { className: "text-3xl font-bold mb-8", children: t("dashboard.title") || "Dashboard" }), _jsxs("div", { className: "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" }), _jsx(Chip, { color: userData.profile ? "success" : "warning", size: "sm", variant: "flat", children: userData.profile
|
|
45
|
+
? t("dashboard.complete") || "Complete"
|
|
46
|
+
: 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 }) })] })), _jsxs(Card, { className: "col-span-full", children: [_jsx(CardHeader, { children: _jsx("h3", { className: "text-lg font-semibold", children: "Quick Stats" }) }), _jsx(Divider, {}), _jsx(CardBody, { children: _jsxs("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-4", children: [_jsxs("div", { className: "text-center", children: [_jsx("p", { className: "text-2xl font-bold text-primary", children: "0" }), _jsx("p", { className: "text-small text-default-500", children: "Projects" })] }), _jsxs("div", { className: "text-center", children: [_jsx("p", { className: "text-2xl font-bold text-success", children: "0" }), _jsx("p", { className: "text-small text-default-500", children: "Tasks" })] }), _jsxs("div", { className: "text-center", children: [_jsx("p", { className: "text-2xl font-bold text-warning", children: "0" }), _jsx("p", { className: "text-small text-default-500", children: "Notifications" })] }), _jsxs("div", { className: "text-center", children: [_jsx("p", { className: "text-2xl font-bold text-secondary", children: Math.floor((Date.now() - new Date(userData.created_at).getTime()) /
|
|
43
47
|
(1000 * 60 * 60 * 24)) }), _jsx("p", { className: "text-small text-default-500", children: "Days active" })] })] }) })] })] })] }));
|
|
44
48
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"folder.d.ts","sourceRoot":"","sources":["../../../src/web/auth/folder.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"folder.d.ts","sourceRoot":"","sources":["../../../src/web/auth/folder.tsx"],"names":[],"mappings":"AAqBA,wBAAgB,UAAU,mDA2EzB"}
|
package/dist/web/auth/folder.js
CHANGED
|
@@ -3,7 +3,9 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { useEffect, useState } from "react";
|
|
4
4
|
import { Card, CardBody, Spinner } from "@lastbrain/ui";
|
|
5
5
|
import { FileManager } from "@lastbrain/ui";
|
|
6
|
+
import { useModuleTranslation } from "@lastbrain/core";
|
|
6
7
|
export function FolderPage() {
|
|
8
|
+
const t = useModuleTranslation("auth");
|
|
7
9
|
const [userData, setUserData] = useState(null);
|
|
8
10
|
const [isLoading, setIsLoading] = useState(true);
|
|
9
11
|
const [error, setError] = useState(null);
|
|
@@ -28,13 +30,13 @@ export function FolderPage() {
|
|
|
28
30
|
}
|
|
29
31
|
};
|
|
30
32
|
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..." })] }) }));
|
|
33
|
+
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("folder.loading") || "Loading folder..." })] }) }));
|
|
32
34
|
}
|
|
33
35
|
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] }) }) }) }));
|
|
36
|
+
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("folder.error") || "Error", ": ", error] }) }) }) }));
|
|
35
37
|
}
|
|
36
38
|
if (!userData) {
|
|
37
39
|
return null;
|
|
38
40
|
}
|
|
39
|
-
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, allowAIImageGeneration: false, className: "min-h-[80vh]" })] }));
|
|
41
|
+
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: t("folder.title") || "Dossier" }), _jsx(FileManager, { bucket: "app", basePath: userData.id, allowUpload: true, allowCreateFolder: true, allowAIImageGeneration: false, className: "min-h-[80vh]" })] }));
|
|
40
42
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"profile.d.ts","sourceRoot":"","sources":["../../../src/web/auth/profile.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"profile.d.ts","sourceRoot":"","sources":["../../../src/web/auth/profile.tsx"],"names":[],"mappings":"AA0CA,wBAAgB,WAAW,4CA8Z1B"}
|
package/dist/web/auth/profile.js
CHANGED
|
@@ -3,9 +3,11 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { useEffect, useState } from "react";
|
|
4
4
|
import { Card, CardBody, CardHeader, Input, Textarea, Button, Spinner, Divider, addToast, AvatarUploader, } from "@lastbrain/ui";
|
|
5
5
|
import { Save, User } from "lucide-react";
|
|
6
|
+
import { useModuleTranslation } from "@lastbrain/core";
|
|
6
7
|
import { uploadFile, deleteFilesWithPrefix } from "../../api/storage";
|
|
7
8
|
import { supabaseBrowserClient } from "@lastbrain/core";
|
|
8
9
|
export function ProfilePage() {
|
|
10
|
+
const t = useModuleTranslation("auth");
|
|
9
11
|
const [profile, setProfile] = useState({});
|
|
10
12
|
const [isLoading, setIsLoading] = useState(true);
|
|
11
13
|
const [isSaving, setIsSaving] = useState(false);
|
|
@@ -64,8 +66,8 @@ export function ProfilePage() {
|
|
|
64
66
|
throw new Error("Failed to update profile");
|
|
65
67
|
}
|
|
66
68
|
addToast({
|
|
67
|
-
title: "Success",
|
|
68
|
-
description: "Profile updated successfully",
|
|
69
|
+
title: t("profile.success") || "Success",
|
|
70
|
+
description: t("profile.updated") || "Profile updated successfully",
|
|
69
71
|
color: "success",
|
|
70
72
|
});
|
|
71
73
|
}
|
|
@@ -73,8 +75,8 @@ export function ProfilePage() {
|
|
|
73
75
|
console.error("Error updating profile:", err);
|
|
74
76
|
setError(err instanceof Error ? err.message : "An error occurred");
|
|
75
77
|
addToast({
|
|
76
|
-
title: "Error",
|
|
77
|
-
description: "Failed to update profile",
|
|
78
|
+
title: t("profile.error") || "Error",
|
|
79
|
+
description: t("profile.update_failed") || "Failed to update profile",
|
|
78
80
|
color: "danger",
|
|
79
81
|
});
|
|
80
82
|
}
|
|
@@ -172,7 +174,7 @@ export function ProfilePage() {
|
|
|
172
174
|
setProfile((prev) => ({ ...prev, avatar_url: "" }));
|
|
173
175
|
};
|
|
174
176
|
if (isLoading) {
|
|
175
|
-
return (_jsx("div", { className: "flex justify-center items-center min-h-[400px]", children: _jsx(Spinner, { size: "lg", label: "Loading profile..." }) }));
|
|
177
|
+
return (_jsx("div", { className: "flex justify-center items-center min-h-[400px]", children: _jsx(Spinner, { size: "lg", label: t("profile.loading") || "Loading profile..." }) }));
|
|
176
178
|
}
|
|
177
179
|
return (_jsx("div", { className: "pt-12 pb-12 max-w-4xl mx-auto px-4", children: _jsx("form", { onSubmit: handleSubmit, children: _jsxs("div", { className: "space-y-6", children: [_jsx("div", { className: "flex justify-center", children: _jsx(AvatarUploader, { userId: currentUser?.id, bucket: "avatar", shape: "circle", onUpload: handleAvatarUpload, onDelete: handleAvatarDelete, initialAvatarPath: currentUser?.user_metadata?.avatar ||
|
|
178
180
|
profile.avatar_url ||
|
|
@@ -190,5 +192,10 @@ export function ProfilePage() {
|
|
|
190
192
|
setProfile((prev) => ({ ...prev, avatar_url: urls.large }));
|
|
191
193
|
}, onDeleted: () => {
|
|
192
194
|
setProfile((prev) => ({ ...prev, avatar_url: "" }));
|
|
193
|
-
} }) }), _jsxs("div", { className: "flex items-center gap-2 mb-4", children: [_jsx(User, { className: "w-8 h-8" }), _jsx("h1", { className: "text-3xl font-bold", children:
|
|
195
|
+
} }) }), _jsxs("div", { className: "flex items-center gap-2 mb-4", children: [_jsx(User, { className: "w-8 h-8" }), _jsx("h1", { className: "text-3xl font-bold", children: t("profile.edit") || "Edit Profile" })] }), _jsxs(Card, { children: [_jsx(CardHeader, { children: _jsx("h3", { className: "text-lg font-semibold", children: t("profile.personal_info") || "Personal Information" }) }), _jsx(Divider, {}), _jsx(CardBody, { children: _jsxs("div", { className: "grid gap-4 md:grid-cols-2", children: [_jsx(Input, { label: t("profile.first_name") || "First Name", placeholder: t("profile.first_name_placeholder") ||
|
|
196
|
+
"Enter your first name", value: profile.first_name || "", onChange: (e) => handleChange("first_name", e.target.value) }), _jsx(Input, { label: t("profile.last_name") || "Last Name", placeholder: t("profile.last_name_placeholder") || "Enter your last name", value: profile.last_name || "", onChange: (e) => handleChange("last_name", e.target.value) }), _jsx(Input, { label: t("profile.phone") || "Phone", placeholder: t("profile.phone_placeholder") || "Enter your phone number", type: "tel", value: profile.phone || "", onChange: (e) => handleChange("phone", e.target.value), className: "md:col-span-2" }), _jsx(Textarea, { label: t("profile.bio") || "Bio", placeholder: t("profile.bio_placeholder") || "Tell us about yourself", value: profile.bio || "", onChange: (e) => handleChange("bio", e.target.value), minRows: 3, className: "md:col-span-2" })] }) })] }), _jsxs(Card, { children: [_jsx(CardHeader, { children: _jsx("h3", { className: "text-lg font-semibold", children: t("profile.professional_info") || "Professional Information" }) }), _jsx(Divider, {}), _jsx(CardBody, { children: _jsxs("div", { className: "grid gap-4 md:grid-cols-2", children: [_jsx(Input, { label: t("profile.company") || "Company", placeholder: t("profile.company_placeholder") ||
|
|
197
|
+
"Enter your company name", value: profile.company || "", onChange: (e) => handleChange("company", e.target.value) }), _jsx(Input, { label: t("profile.website") || "Website", placeholder: t("profile.website_placeholder") || "https://example.com", type: "url", value: profile.website || "", onChange: (e) => handleChange("website", e.target.value) }), _jsx(Input, { label: t("profile.location") || "Location", placeholder: t("profile.location_placeholder") || "City, Country", value: profile.location || "", onChange: (e) => handleChange("location", e.target.value), className: "md:col-span-2" })] }) })] }), _jsxs(Card, { children: [_jsx(CardHeader, { children: _jsx("h3", { className: "text-lg font-semibold", children: t("profile.preferences") || "Preferences" }) }), _jsx(Divider, {}), _jsx(CardBody, { children: _jsxs("div", { className: "grid gap-4 md:grid-cols-2", children: [_jsx(Input, { label: t("profile.language") || "Language", placeholder: t("profile.language_placeholder") || "en, fr, es...", value: profile.language || "", onChange: (e) => handleChange("language", e.target.value) }), _jsx(Input, { label: t("profile.timezone") || "Timezone", placeholder: t("profile.timezone_placeholder") ||
|
|
198
|
+
"Europe/Paris, America/New_York...", value: profile.timezone || "", onChange: (e) => handleChange("timezone", e.target.value) })] }) })] }), _jsxs("div", { className: "flex justify-end gap-3", children: [_jsx(Button, { type: "button", variant: "flat", onPress: () => fetchProfile(), isDisabled: isSaving, children: t("profile.cancel_button") || "Cancel" }), _jsx(Button, { type: "submit", color: "primary", isLoading: isSaving, startContent: !isSaving && _jsx(Save, { className: "w-4 h-4" }), children: isSaving
|
|
199
|
+
? t("profile.saving") || "Saving..."
|
|
200
|
+
: t("profile.save_button") || "Save Changes" })] })] }) }) }));
|
|
194
201
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reglage.d.ts","sourceRoot":"","sources":["../../../src/web/auth/reglage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"reglage.d.ts","sourceRoot":"","sources":["../../../src/web/auth/reglage.tsx"],"names":[],"mappings":"AAiCA,wBAAgB,WAAW,4CAoR1B"}
|
package/dist/web/auth/reglage.js
CHANGED
|
@@ -3,7 +3,9 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { useEffect, useState } from "react";
|
|
4
4
|
import { Card, CardBody, CardHeader, Switch, Button, Spinner, Divider, Select, SelectItem, addToast, } from "@lastbrain/ui";
|
|
5
5
|
import { Settings, Save } from "lucide-react";
|
|
6
|
+
import { useModuleTranslation } from "@lastbrain/core";
|
|
6
7
|
export function ReglagePage() {
|
|
8
|
+
const t = useModuleTranslation("auth");
|
|
7
9
|
const [preferences, setPreferences] = useState({
|
|
8
10
|
email_notifications: true,
|
|
9
11
|
push_notifications: false,
|
|
@@ -70,16 +72,16 @@ export function ReglagePage() {
|
|
|
70
72
|
throw new Error("Failed to update settings");
|
|
71
73
|
}
|
|
72
74
|
addToast({
|
|
73
|
-
title: "Success",
|
|
74
|
-
description: "Settings updated successfully",
|
|
75
|
+
title: t("settings.success") || "Success",
|
|
76
|
+
description: t("settings.updated") || "Settings updated successfully",
|
|
75
77
|
color: "success",
|
|
76
78
|
});
|
|
77
79
|
}
|
|
78
80
|
catch (err) {
|
|
79
81
|
console.error("Error updating settings:", err);
|
|
80
82
|
addToast({
|
|
81
|
-
title: "Error",
|
|
82
|
-
description: "Failed to update settings",
|
|
83
|
+
title: t("settings.error") || "Error",
|
|
84
|
+
description: t("settings.update_failed") || "Failed to update settings",
|
|
83
85
|
color: "danger",
|
|
84
86
|
});
|
|
85
87
|
}
|
|
@@ -94,7 +96,10 @@ export function ReglagePage() {
|
|
|
94
96
|
setPreferences((prev) => ({ ...prev, [key]: value }));
|
|
95
97
|
};
|
|
96
98
|
if (isLoading) {
|
|
97
|
-
return (_jsx("div", { className: "flex justify-center items-center min-h-[400px]", children: _jsx(Spinner, { size: "lg", label: "Loading settings..." }) }));
|
|
99
|
+
return (_jsx("div", { className: "flex justify-center items-center min-h-[400px]", children: _jsx(Spinner, { size: "lg", label: t("settings.loading") || "Loading settings..." }) }));
|
|
98
100
|
}
|
|
99
|
-
return (_jsxs("div", { className: "pt-12 pb-12 max-w-4xl mx-auto px-4", children: [_jsxs("div", { className: "flex items-center gap-2 mb-8", children: [_jsx(Settings, { className: "w-8 h-8" }), _jsx("h1", { className: "text-3xl font-bold", children: "Account Settings" })] }), _jsxs("div", { className: "space-y-6", children: [_jsxs(Card, { children: [_jsx(CardHeader, { children: _jsx("h3", { className: "text-lg font-semibold", children: "Notifications" }) }), _jsx(Divider, {}), _jsx(CardBody, { children: _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "flex justify-between items-center", children: [_jsxs("div", { children: [_jsx("p", { className: "font-medium", children:
|
|
101
|
+
return (_jsxs("div", { className: "pt-12 pb-12 max-w-4xl mx-auto px-4", children: [_jsxs("div", { className: "flex items-center gap-2 mb-8", children: [_jsx(Settings, { className: "w-8 h-8" }), _jsx("h1", { className: "text-3xl font-bold", children: t("settings.account") || "Account Settings" })] }), _jsxs("div", { className: "space-y-6", children: [_jsxs(Card, { children: [_jsx(CardHeader, { children: _jsx("h3", { className: "text-lg font-semibold", children: t("settings.notifications") || "Notifications" }) }), _jsx(Divider, {}), _jsx(CardBody, { children: _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "flex justify-between items-center", children: [_jsxs("div", { children: [_jsx("p", { className: "font-medium", children: t("settings.email_notifications") || "Email Notifications" }), _jsx("p", { className: "text-small text-default-500", children: t("settings.email_notifications_desc") ||
|
|
102
|
+
"Receive email notifications for important updates" })] }), _jsx(Switch, { isSelected: preferences.email_notifications, onValueChange: (value) => handleToggle("email_notifications", value) })] }), _jsx(Divider, {}), _jsxs("div", { className: "flex justify-between items-center", children: [_jsxs("div", { children: [_jsx("p", { className: "font-medium", children: t("settings.push_notifications") || "Push Notifications" }), _jsx("p", { className: "text-small text-default-500", children: t("settings.push_notifications_desc") ||
|
|
103
|
+
"Receive push notifications in your browser" })] }), _jsx(Switch, { isSelected: preferences.push_notifications, onValueChange: (value) => handleToggle("push_notifications", value) })] }), _jsx(Divider, {}), _jsxs("div", { className: "flex justify-between items-center", children: [_jsxs("div", { children: [_jsx("p", { className: "font-medium", children: t("settings.marketing_emails") || "Marketing Emails" }), _jsx("p", { className: "text-small text-default-500", children: t("settings.marketing_emails_desc") ||
|
|
104
|
+
"Receive emails about new features and updates" })] }), _jsx(Switch, { isSelected: preferences.marketing_emails, onValueChange: (value) => handleToggle("marketing_emails", value) })] })] }) })] }), _jsxs(Card, { children: [_jsx(CardHeader, { children: _jsx("h3", { className: "text-lg font-semibold", children: t("settings.appearance") || "Appearance" }) }), _jsx(Divider, {}), _jsx(CardBody, { children: _jsxs(Select, { label: t("settings.theme") || "Theme", placeholder: t("settings.select_theme") || "Select a theme", selectedKeys: preferences.theme ? [preferences.theme] : [], onChange: (e) => handleSelect("theme", e.target.value), children: [_jsx(SelectItem, { children: t("settings.light") || "Light" }, "light"), _jsx(SelectItem, { children: t("settings.dark") || "Dark" }, "dark"), _jsx(SelectItem, { children: t("settings.system") || "System" }, "system")] }) })] }), _jsxs(Card, { children: [_jsx(CardHeader, { children: _jsx("h3", { className: "text-lg font-semibold", children: "Language & Region" }) }), _jsx(Divider, {}), _jsx(CardBody, { children: _jsxs("div", { className: "grid gap-4 md:grid-cols-2", children: [_jsxs(Select, { label: "Language", placeholder: "Select a language", selectedKeys: preferences.language ? [preferences.language] : [], onChange: (e) => handleSelect("language", e.target.value), children: [_jsx(SelectItem, { children: "English" }, "en"), _jsx(SelectItem, { children: "Fran\u00E7ais" }, "fr"), _jsx(SelectItem, { children: "Espa\u00F1ol" }, "es"), _jsx(SelectItem, { children: "Deutsch" }, "de")] }), _jsxs(Select, { label: "Timezone", placeholder: "Select a timezone", selectedKeys: preferences.timezone ? [preferences.timezone] : [], onChange: (e) => handleSelect("timezone", e.target.value), children: [_jsx(SelectItem, { children: "UTC" }, "UTC"), _jsx(SelectItem, { children: "Europe/Paris" }, "Europe/Paris"), _jsx(SelectItem, { children: "America/New_York" }, "America/New_York"), _jsx(SelectItem, { children: "America/Los_Angeles" }, "America/Los_Angeles"), _jsx(SelectItem, { children: "Asia/Tokyo" }, "Asia/Tokyo")] })] }) })] }), _jsxs("div", { className: "flex justify-end gap-3", children: [_jsx(Button, { type: "button", variant: "flat", onPress: () => fetchSettings(), isDisabled: isSaving, children: "Reset" }), _jsx(Button, { type: "button", color: "primary", isLoading: isSaving, onPress: handleSave, startContent: !isSaving && _jsx(Save, { className: "w-4 h-4" }), children: isSaving ? "Saving..." : "Save Settings" })] })] })] }));
|
|
100
105
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SignInPage.d.ts","sourceRoot":"","sources":["../../../src/web/public/SignInPage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SignInPage.d.ts","sourceRoot":"","sources":["../../../src/web/public/SignInPage.tsx"],"names":[],"mappings":"AAiNA,wBAAgB,UAAU,4CAMzB"}
|
|
@@ -4,15 +4,18 @@ import { Suspense, useState } from "react";
|
|
|
4
4
|
import { supabaseBrowserClient } from "@lastbrain/core";
|
|
5
5
|
import { addToast, Button, Card, CardBody, Chip, Input, Link, } from "@lastbrain/ui";
|
|
6
6
|
import { ArrowRight, Lock, Mail, Sparkles } from "lucide-react";
|
|
7
|
-
import {
|
|
7
|
+
import { useSearchParams } from "next/navigation";
|
|
8
|
+
import { useModuleTranslation } from "@lastbrain/core";
|
|
9
|
+
import { useLocalizedRouter } from "@lastbrain/core";
|
|
8
10
|
function SignInForm() {
|
|
9
11
|
const searchParams = useSearchParams();
|
|
12
|
+
const t = useModuleTranslation("auth");
|
|
13
|
+
const router = useLocalizedRouter();
|
|
10
14
|
const [email, setEmail] = useState("");
|
|
11
15
|
const [password, setPassword] = useState("");
|
|
12
16
|
const [isLoading, setIsLoading] = useState(false);
|
|
13
17
|
const [error, _setError] = useState(null);
|
|
14
18
|
const redirectUrl = searchParams.get("redirect");
|
|
15
|
-
const router = useRouter();
|
|
16
19
|
const handleSubmit = async (event) => {
|
|
17
20
|
event.preventDefault();
|
|
18
21
|
setIsLoading(true);
|
|
@@ -24,18 +27,17 @@ function SignInForm() {
|
|
|
24
27
|
if (error) {
|
|
25
28
|
addToast({
|
|
26
29
|
color: "danger",
|
|
27
|
-
title: "Erreur de connexion",
|
|
30
|
+
title: t("signin.error_title") || "Erreur de connexion",
|
|
28
31
|
description: error.message,
|
|
29
32
|
});
|
|
30
33
|
setIsLoading(false);
|
|
31
34
|
return;
|
|
32
35
|
}
|
|
33
36
|
setIsLoading(false);
|
|
34
|
-
console.log("Signed in user:", data.user);
|
|
35
37
|
addToast({
|
|
36
38
|
color: "success",
|
|
37
|
-
title: "Connecté avec succès !",
|
|
38
|
-
description:
|
|
39
|
+
title: t("signin.success_title") || "Connecté avec succès !",
|
|
40
|
+
description: `${t("signin.success_welcome") || "Bienvenue"} ${data.user?.email}`,
|
|
39
41
|
});
|
|
40
42
|
router.push(redirectUrl || "/auth/dashboard");
|
|
41
43
|
}
|
|
@@ -43,65 +45,21 @@ function SignInForm() {
|
|
|
43
45
|
setIsLoading(false);
|
|
44
46
|
addToast({
|
|
45
47
|
color: "danger",
|
|
46
|
-
title: "Erreur de connexion",
|
|
48
|
+
title: t("signin.error_title") || "Erreur de connexion",
|
|
47
49
|
description: `${err instanceof Error ? err.message : String(err)}`,
|
|
48
50
|
});
|
|
49
51
|
}
|
|
50
52
|
};
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
// <Card className="w-full max-w-md">
|
|
54
|
-
// <CardHeader className="flex flex-col">
|
|
55
|
-
// <h1 className="text-2xl font-semibold text-slate-900 dark:text-white">
|
|
56
|
-
// Connexion
|
|
57
|
-
// </h1>
|
|
58
|
-
// <p className="mt-1 text-sm text-slate-500">
|
|
59
|
-
// Utilisez votre adresse email pour vous connecter.
|
|
60
|
-
// </p>
|
|
61
|
-
// </CardHeader>
|
|
62
|
-
// <CardBody>
|
|
63
|
-
// <form onSubmit={handleSubmit}>
|
|
64
|
-
// <div className="space-y-6">
|
|
65
|
-
// <Input
|
|
66
|
-
// label="Email"
|
|
67
|
-
// type="email"
|
|
68
|
-
// className="mb-6"
|
|
69
|
-
// required
|
|
70
|
-
// value={email}
|
|
71
|
-
// onChange={(event) => setEmail(event.target.value)}
|
|
72
|
-
// />
|
|
73
|
-
// <Input
|
|
74
|
-
// label="Mot de passe"
|
|
75
|
-
// type="password"
|
|
76
|
-
// required
|
|
77
|
-
// placeholder="Password"
|
|
78
|
-
// className="mb-6"
|
|
79
|
-
// value={password}
|
|
80
|
-
// onChange={(event) => setPassword(event.target.value)}
|
|
81
|
-
// />
|
|
82
|
-
// <Button
|
|
83
|
-
// size="lg"
|
|
84
|
-
// type="submit"
|
|
85
|
-
// className="w-full"
|
|
86
|
-
// isLoading={isLoading}
|
|
87
|
-
// >
|
|
88
|
-
// Se connecter
|
|
89
|
-
// </Button>
|
|
90
|
-
// </div>
|
|
91
|
-
// </form>
|
|
92
|
-
// </CardBody>
|
|
93
|
-
// </Card>
|
|
94
|
-
// </div>
|
|
95
|
-
// );
|
|
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: {
|
|
53
|
+
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: t("signin.chip_label") || "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: t("signin.title") || "Bon retour" }) }), _jsx("p", { className: "text-default-600 dark:text-default-700", children: t("signin.subtitle") ||
|
|
54
|
+
"Connectez-vous pour accéder à 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: t("email") || "Email", type: "email", placeholder: t("signin.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
55
|
input: "text-base",
|
|
98
56
|
inputWrapper: "border border-default-200/60 hover:border-primary-400 focus-within:border-primary-500",
|
|
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: {
|
|
57
|
+
} }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Input, { label: t("password") || "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: {
|
|
100
58
|
input: "text-base",
|
|
101
59
|
inputWrapper: "border border-default-200/60 hover:border-primary-400 focus-within:border-primary-500",
|
|
102
|
-
} }), _jsx(Link, { href: "/forgot-password", className: "text-xs text-default-500 hover:text-primary-500 self-end", children: "Mot de passe
|
|
60
|
+
} }), _jsx(Link, { href: "/forgot-password", className: "text-xs text-default-500 hover:text-primary-500 self-end", children: t("signin.forgot_password") || "Mot de passe oublié ?" })] }), error && (_jsx("div", { className: "rounded-lg border border-danger-200 bg-danger-50/50 px-4 py-3 dark:border-danger-800 dark:bg-danger-950/50", children: _jsx("p", { className: "text-sm text-danger-600 dark:text-danger-400", children: error }) })), _jsx(Button, { type: "submit", color: "primary", size: "lg", className: "w-full font-semibold", endContent: isLoading ? null : _jsx(ArrowRight, { className: "h-5 w-5" }), isLoading: isLoading, children: t("signin.submit") || "Se connecter" })] }), _jsxs("div", { className: "relative flex items-center gap-4 py-2", children: [_jsx("div", { className: "h-px flex-1 bg-default-200" }), _jsx("span", { className: "text-xs text-default-400", children: t("or") || "OU" }), _jsx("div", { className: "h-px flex-1 bg-default-200" })] }), _jsx("div", { className: "text-center", children: _jsxs("p", { className: "text-sm text-default-600", children: [t("signin.no_account") || "Pas encore de compte ?", " ", _jsx(Link, { href: redirectUrl
|
|
103
61
|
? `/signup?redirect=${encodeURIComponent(redirectUrl)}`
|
|
104
|
-
: "/signup", className: "font-semibold text-primary-600 hover:text-primary-700", children: "
|
|
62
|
+
: "/signup", className: "font-semibold text-primary-600 hover:text-primary-700", children: t("signin.sign_up") || "Créer un compte" })] }) })] }) }), _jsxs("p", { className: "mt-8 text-center text-sm text-default-700", children: [t("signin.accept_terms"), " ", _jsx(Link, { href: "/legal/terms", className: "underline hover:text-primary-500", children: t("signin.term") })] })] }) })] }));
|
|
105
63
|
}
|
|
106
64
|
export function SignInPage() {
|
|
107
65
|
return (_jsx(Suspense, { fallback: _jsx("div", { children: "Chargement..." }), children: _jsx(SignInForm, {}) }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SignUpPage.d.ts","sourceRoot":"","sources":["../../../src/web/public/SignUpPage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SignUpPage.d.ts","sourceRoot":"","sources":["../../../src/web/public/SignUpPage.tsx"],"names":[],"mappings":"AA2SA,wBAAgB,UAAU,4CAMzB"}
|