@burdenoff/microfe-auth 2026.830.1 → 2026.830.2
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/AuthRoot.js +43 -41
- package/dist/auth/AuthRoot.js.map +1 -1
- package/dist/auth/components/AuthLayout.js +65 -67
- package/dist/auth/components/AuthLayout.js.map +1 -1
- package/dist/auth/components/CaptchaV2.js +21 -24
- package/dist/auth/components/CaptchaV2.js.map +1 -1
- package/dist/auth/components/ConfirmActionDialog.js +33 -32
- package/dist/auth/components/ConfirmActionDialog.js.map +1 -1
- package/dist/auth/components/profile/UserProfileMenu.js +44 -46
- package/dist/auth/components/profile/UserProfileMenu.js.map +1 -1
- package/dist/auth/components/workspace/WorkspaceSelector.js +62 -68
- package/dist/auth/components/workspace/WorkspaceSelector.js.map +1 -1
- package/dist/auth/pages/AuditLogPage.js +65 -68
- package/dist/auth/pages/AuditLogPage.js.map +1 -1
- package/dist/auth/pages/EmailVerifyPage.js +51 -54
- package/dist/auth/pages/EmailVerifyPage.js.map +1 -1
- package/dist/auth/pages/LoginPage.js +223 -225
- package/dist/auth/pages/LoginPage.js.map +1 -1
- package/dist/auth/pages/MagicLinkPage.js +67 -69
- package/dist/auth/pages/MagicLinkPage.js.map +1 -1
- package/dist/auth/pages/MfaSetupPage.js +85 -88
- package/dist/auth/pages/MfaSetupPage.js.map +1 -1
- package/dist/auth/pages/MfaVerifyPage.js +60 -63
- package/dist/auth/pages/MfaVerifyPage.js.map +1 -1
- package/dist/auth/pages/OAuthCallbackPage.js +37 -40
- package/dist/auth/pages/OAuthCallbackPage.js.map +1 -1
- package/dist/auth/pages/PasswordResetPage.js +102 -105
- package/dist/auth/pages/PasswordResetPage.js.map +1 -1
- package/dist/auth/pages/ReactivatePage.js +54 -57
- package/dist/auth/pages/ReactivatePage.js.map +1 -1
- package/dist/auth/pages/RegisterPage.js +171 -174
- package/dist/auth/pages/RegisterPage.js.map +1 -1
- package/dist/auth/pages/SSOClearPage.js +21 -20
- package/dist/auth/pages/SSOClearPage.js.map +1 -1
- package/dist/auth/pages/SSODepositPage.js +27 -26
- package/dist/auth/pages/SSODepositPage.js.map +1 -1
- package/dist/auth/pages/SSORelayCallbackPage.js +19 -18
- package/dist/auth/pages/SSORelayCallbackPage.js.map +1 -1
- package/dist/auth/pages/SecurityPage.js +247 -250
- package/dist/auth/pages/SecurityPage.js.map +1 -1
- package/dist/auth/pages/SessionsPage.js +95 -98
- package/dist/auth/pages/SessionsPage.js.map +1 -1
- package/dist/auth/pages/SsoCallbackPage.js +53 -56
- package/dist/auth/pages/SsoCallbackPage.js.map +1 -1
- package/dist/auth/pages/SsoConfigPage.js +296 -299
- package/dist/auth/pages/SsoConfigPage.js.map +1 -1
- package/dist/auth/pages/SsoLoginPage.js +65 -68
- package/dist/auth/pages/SsoLoginPage.js.map +1 -1
- package/dist/auth/pages/UserDetailsPage.js +124 -127
- package/dist/auth/pages/UserDetailsPage.js.map +1 -1
- package/dist/auth/pages/UserProfilePage.js +171 -174
- package/dist/auth/pages/UserProfilePage.js.map +1 -1
- package/dist/auth/pages/UsersPage.js +322 -325
- package/dist/auth/pages/UsersPage.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -1
- package/dist/shared/hooks/index.d.ts +1 -6
- package/dist/shared/hooks/useTr.d.ts +16 -0
- package/dist/shared/hooks/useTr.js +14 -0
- package/dist/shared/hooks/useTr.js.map +1 -0
- package/dist/translations/en.d.ts +806 -248
- package/dist/translations/en.js +870 -0
- package/dist/translations/en.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,68 +1,69 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { useTr as e } from "../../shared/hooks/useTr.js";
|
|
2
|
+
import { AlertCircle as t, AlertTriangle as n, Info as r, Loader2 as i } from "lucide-react";
|
|
3
|
+
import { jsx as a, jsxs as o } from "react/jsx-runtime";
|
|
4
|
+
import { AlertDialog as s, AlertDialogAction as c, AlertDialogCancel as l, AlertDialogContent as u, AlertDialogDescription as d, AlertDialogFooter as f, AlertDialogHeader as p, AlertDialogTitle as m } from "@burdenoff/fe-libs/ui";
|
|
4
5
|
//#region src/auth/components/ConfirmActionDialog.tsx
|
|
5
|
-
var
|
|
6
|
+
var h = {
|
|
6
7
|
default: {
|
|
7
|
-
icon:
|
|
8
|
+
icon: r,
|
|
8
9
|
iconContainerClassName: "bg-[var(--color-status-info-bg-subtle)]",
|
|
9
10
|
iconClassName: "text-[var(--color-status-info-text)]",
|
|
10
11
|
actionClassName: "bg-[var(--color-action-primary-bg)] text-[var(--color-action-primary-text)] hover:opacity-90"
|
|
11
12
|
},
|
|
12
13
|
warning: {
|
|
13
|
-
icon:
|
|
14
|
+
icon: n,
|
|
14
15
|
iconContainerClassName: "bg-[var(--color-status-warning-bg-subtle)]",
|
|
15
16
|
iconClassName: "text-[var(--color-status-warning-text)]",
|
|
16
17
|
actionClassName: "bg-[var(--color-status-warning-bg)] text-[var(--color-text-inverse)] hover:opacity-90"
|
|
17
18
|
},
|
|
18
19
|
danger: {
|
|
19
|
-
icon:
|
|
20
|
+
icon: t,
|
|
20
21
|
iconContainerClassName: "bg-[var(--color-status-error-bg-subtle)]",
|
|
21
22
|
iconClassName: "text-[var(--color-status-error-text)]",
|
|
22
23
|
actionClassName: "bg-[var(--color-status-error-bg)] text-[var(--color-text-inverse)] hover:opacity-90"
|
|
23
24
|
}
|
|
24
25
|
};
|
|
25
|
-
function
|
|
26
|
-
let
|
|
27
|
-
return /* @__PURE__ */
|
|
28
|
-
open:
|
|
29
|
-
onOpenChange:
|
|
30
|
-
children: /* @__PURE__ */
|
|
26
|
+
function g({ open: t, onOpenChange: n, title: r, description: g, confirmText: _, cancelText: v, variant: y = "default", isPending: b = !1, disabled: x = !1, onConfirm: S }) {
|
|
27
|
+
let C = e(), w = _ || C("auth.confirmDialog.confirm", "Confirm"), T = v || C("auth.confirmDialog.cancel", "Cancel"), E = h[y], D = E.icon;
|
|
28
|
+
return /* @__PURE__ */ a(s, {
|
|
29
|
+
open: t,
|
|
30
|
+
onOpenChange: n,
|
|
31
|
+
children: /* @__PURE__ */ o(u, {
|
|
31
32
|
className: "max-w-md border-[var(--color-border-default)] bg-[var(--color-bg-surface)] text-[var(--color-text-primary)]",
|
|
32
|
-
children: [/* @__PURE__ */
|
|
33
|
+
children: [/* @__PURE__ */ a(p, { children: /* @__PURE__ */ o("div", {
|
|
33
34
|
className: "flex items-start gap-4",
|
|
34
|
-
children: [/* @__PURE__ */
|
|
35
|
-
className: `flex size-10 shrink-0 items-center justify-center rounded-full ${
|
|
36
|
-
children: /* @__PURE__ */
|
|
37
|
-
}), /* @__PURE__ */
|
|
35
|
+
children: [/* @__PURE__ */ a("div", {
|
|
36
|
+
className: `flex size-10 shrink-0 items-center justify-center rounded-full ${E.iconContainerClassName}`,
|
|
37
|
+
children: /* @__PURE__ */ a(D, { className: `size-5 ${E.iconClassName}` })
|
|
38
|
+
}), /* @__PURE__ */ o("div", {
|
|
38
39
|
className: "flex-1",
|
|
39
|
-
children: [/* @__PURE__ */
|
|
40
|
+
children: [/* @__PURE__ */ a(m, {
|
|
40
41
|
className: "text-lg text-[var(--color-text-primary)]",
|
|
41
|
-
children:
|
|
42
|
-
}), /* @__PURE__ */
|
|
42
|
+
children: r
|
|
43
|
+
}), /* @__PURE__ */ a(d, {
|
|
43
44
|
className: "mt-2 text-sm text-[var(--color-text-secondary)]",
|
|
44
|
-
children:
|
|
45
|
+
children: g
|
|
45
46
|
})]
|
|
46
47
|
})]
|
|
47
|
-
}) }), /* @__PURE__ */
|
|
48
|
+
}) }), /* @__PURE__ */ o(f, {
|
|
48
49
|
className: "mt-6",
|
|
49
|
-
children: [/* @__PURE__ */
|
|
50
|
-
disabled:
|
|
50
|
+
children: [/* @__PURE__ */ a(l, {
|
|
51
|
+
disabled: b,
|
|
51
52
|
className: "border-[var(--color-border-default)] bg-[var(--color-bg-surface)] text-[var(--color-text-primary)] hover:bg-[var(--color-bg-subtle)]",
|
|
52
|
-
children:
|
|
53
|
-
}), /* @__PURE__ */
|
|
54
|
-
disabled:
|
|
53
|
+
children: T
|
|
54
|
+
}), /* @__PURE__ */ o(c, {
|
|
55
|
+
disabled: x || b,
|
|
55
56
|
onClick: (e) => {
|
|
56
|
-
e.preventDefault(),
|
|
57
|
+
e.preventDefault(), S();
|
|
57
58
|
},
|
|
58
|
-
className:
|
|
59
|
-
children: [
|
|
59
|
+
className: E.actionClassName,
|
|
60
|
+
children: [b ? /* @__PURE__ */ a(i, { className: "size-4 animate-spin" }) : null, w]
|
|
60
61
|
})]
|
|
61
62
|
})]
|
|
62
63
|
})
|
|
63
64
|
});
|
|
64
65
|
}
|
|
65
66
|
//#endregion
|
|
66
|
-
export {
|
|
67
|
+
export { g as ConfirmActionDialog };
|
|
67
68
|
|
|
68
69
|
//# sourceMappingURL=ConfirmActionDialog.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConfirmActionDialog.js","names":[],"sources":["../../../src/auth/components/ConfirmActionDialog.tsx"],"sourcesContent":["import { AlertCircle, AlertTriangle, Info, Loader2 } from \"lucide-react\";\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from \"@burdenoff/fe-libs/ui\";\n\ntype ConfirmActionDialogVariant = \"default\" | \"warning\" | \"danger\";\n\ninterface ConfirmActionDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n title: string;\n description: string;\n confirmText?: string;\n cancelText?: string;\n variant?: ConfirmActionDialogVariant;\n isPending?: boolean;\n disabled?: boolean;\n onConfirm: () => void | Promise<void>;\n}\n\nconst VARIANT_STYLES: Record<\n ConfirmActionDialogVariant,\n {\n icon: typeof Info;\n iconContainerClassName: string;\n iconClassName: string;\n actionClassName: string;\n }\n> = {\n default: {\n icon: Info,\n iconContainerClassName: \"bg-[var(--color-status-info-bg-subtle)]\",\n iconClassName: \"text-[var(--color-status-info-text)]\",\n actionClassName:\n \"bg-[var(--color-action-primary-bg)] text-[var(--color-action-primary-text)] hover:opacity-90\",\n },\n warning: {\n icon: AlertTriangle,\n iconContainerClassName: \"bg-[var(--color-status-warning-bg-subtle)]\",\n iconClassName: \"text-[var(--color-status-warning-text)]\",\n actionClassName:\n \"bg-[var(--color-status-warning-bg)] text-[var(--color-text-inverse)] hover:opacity-90\",\n },\n danger: {\n icon: AlertCircle,\n iconContainerClassName: \"bg-[var(--color-status-error-bg-subtle)]\",\n iconClassName: \"text-[var(--color-status-error-text)]\",\n actionClassName:\n \"bg-[var(--color-status-error-bg)] text-[var(--color-text-inverse)] hover:opacity-90\",\n },\n};\n\nexport function ConfirmActionDialog({\n open,\n onOpenChange,\n title,\n description,\n confirmText
|
|
1
|
+
{"version":3,"file":"ConfirmActionDialog.js","names":[],"sources":["../../../src/auth/components/ConfirmActionDialog.tsx"],"sourcesContent":["import { AlertCircle, AlertTriangle, Info, Loader2 } from \"lucide-react\";\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from \"@burdenoff/fe-libs/ui\";\nimport { useTr } from \"../../shared/hooks/useTr\";\n\ntype ConfirmActionDialogVariant = \"default\" | \"warning\" | \"danger\";\n\ninterface ConfirmActionDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n title: string;\n description: string;\n confirmText?: string;\n cancelText?: string;\n variant?: ConfirmActionDialogVariant;\n isPending?: boolean;\n disabled?: boolean;\n onConfirm: () => void | Promise<void>;\n}\n\nconst VARIANT_STYLES: Record<\n ConfirmActionDialogVariant,\n {\n icon: typeof Info;\n iconContainerClassName: string;\n iconClassName: string;\n actionClassName: string;\n }\n> = {\n default: {\n icon: Info,\n iconContainerClassName: \"bg-[var(--color-status-info-bg-subtle)]\",\n iconClassName: \"text-[var(--color-status-info-text)]\",\n actionClassName:\n \"bg-[var(--color-action-primary-bg)] text-[var(--color-action-primary-text)] hover:opacity-90\",\n },\n warning: {\n icon: AlertTriangle,\n iconContainerClassName: \"bg-[var(--color-status-warning-bg-subtle)]\",\n iconClassName: \"text-[var(--color-status-warning-text)]\",\n actionClassName:\n \"bg-[var(--color-status-warning-bg)] text-[var(--color-text-inverse)] hover:opacity-90\",\n },\n danger: {\n icon: AlertCircle,\n iconContainerClassName: \"bg-[var(--color-status-error-bg-subtle)]\",\n iconClassName: \"text-[var(--color-status-error-text)]\",\n actionClassName:\n \"bg-[var(--color-status-error-bg)] text-[var(--color-text-inverse)] hover:opacity-90\",\n },\n};\n\nexport function ConfirmActionDialog({\n open,\n onOpenChange,\n title,\n description,\n confirmText,\n cancelText,\n variant = \"default\",\n isPending = false,\n disabled = false,\n onConfirm,\n}: ConfirmActionDialogProps) {\n const tr = useTr();\n const resolvedConfirmText =\n confirmText || tr(\"auth.confirmDialog.confirm\", \"Confirm\");\n const resolvedCancelText =\n cancelText || tr(\"auth.confirmDialog.cancel\", \"Cancel\");\n const styles = VARIANT_STYLES[variant];\n const Icon = styles.icon;\n\n return (\n <AlertDialog open={open} onOpenChange={onOpenChange}>\n <AlertDialogContent className=\"max-w-md border-[var(--color-border-default)] bg-[var(--color-bg-surface)] text-[var(--color-text-primary)]\">\n <AlertDialogHeader>\n <div className=\"flex items-start gap-4\">\n <div\n className={`flex size-10 shrink-0 items-center justify-center rounded-full ${styles.iconContainerClassName}`}\n >\n <Icon className={`size-5 ${styles.iconClassName}`} />\n </div>\n <div className=\"flex-1\">\n <AlertDialogTitle className=\"text-lg text-[var(--color-text-primary)]\">\n {title}\n </AlertDialogTitle>\n <AlertDialogDescription className=\"mt-2 text-sm text-[var(--color-text-secondary)]\">\n {description}\n </AlertDialogDescription>\n </div>\n </div>\n </AlertDialogHeader>\n\n <AlertDialogFooter className=\"mt-6\">\n <AlertDialogCancel\n disabled={isPending}\n className=\"border-[var(--color-border-default)] bg-[var(--color-bg-surface)] text-[var(--color-text-primary)] hover:bg-[var(--color-bg-subtle)]\"\n >\n {resolvedCancelText}\n </AlertDialogCancel>\n <AlertDialogAction\n disabled={disabled || isPending}\n onClick={(event) => {\n event.preventDefault();\n void onConfirm();\n }}\n className={styles.actionClassName}\n >\n {isPending ? <Loader2 className=\"size-4 animate-spin\" /> : null}\n {resolvedConfirmText}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n );\n}\n"],"mappings":";;;;;AA4BA,IAAM,IAQF;CACF,SAAS;EACP,MAAM;EACN,wBAAwB;EACxB,eAAe;EACf,iBACE;EACH;CACD,SAAS;EACP,MAAM;EACN,wBAAwB;EACxB,eAAe;EACf,iBACE;EACH;CACD,QAAQ;EACN,MAAM;EACN,wBAAwB;EACxB,eAAe;EACf,iBACE;EACH;CACF;AAED,SAAgB,EAAoB,EAClC,SACA,iBACA,UACA,gBACA,gBACA,eACA,aAAU,WACV,eAAY,IACZ,cAAW,IACX,gBAC2B;CAC3B,IAAM,IAAK,GAAO,EACZ,IACJ,KAAe,EAAG,8BAA8B,UAAU,EACtD,IACJ,KAAc,EAAG,6BAA6B,SAAS,EACnD,IAAS,EAAe,IACxB,IAAO,EAAO;AAEpB,QACE,kBAAC,GAAD;EAAmB;EAAoB;YACrC,kBAAC,GAAD;GAAoB,WAAU;aAA9B,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KACE,WAAW,kEAAkE,EAAO;eAEpF,kBAAC,GAAD,EAAM,WAAW,UAAU,EAAO,iBAAmB,CAAA;KACjD,CAAA,EACN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD;MAAkB,WAAU;gBACzB;MACgB,CAAA,EACnB,kBAAC,GAAD;MAAwB,WAAU;gBAC/B;MACsB,CAAA,CACrB;OACF;OACY,CAAA,EAEpB,kBAAC,GAAD;IAAmB,WAAU;cAA7B,CACE,kBAAC,GAAD;KACE,UAAU;KACV,WAAU;eAET;KACiB,CAAA,EACpB,kBAAC,GAAD;KACE,UAAU,KAAY;KACtB,UAAU,MAAU;AAEb,MADL,EAAM,gBAAgB,EACjB,GAAW;;KAElB,WAAW,EAAO;eANpB,CAQG,IAAY,kBAAC,GAAD,EAAS,WAAU,uBAAwB,CAAA,GAAG,MAC1D,EACiB;OACF;MACD;;EACT,CAAA"}
|
|
@@ -1,77 +1,75 @@
|
|
|
1
1
|
import { useAuthStore as e } from "../../store/authStore.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
2
|
+
import { useTr as t } from "../../../shared/hooks/useTr.js";
|
|
3
|
+
import { useEffect as n, useRef as r, useState as i } from "react";
|
|
4
|
+
import { useNavigate as a } from "react-router";
|
|
5
|
+
import { Building2 as o, ChevronDown as s, LogOut as c, UserPlus as l } from "lucide-react";
|
|
6
6
|
import { jsx as u, jsxs as d } from "react/jsx-runtime";
|
|
7
7
|
//#region src/auth/components/profile/UserProfileMenu.tsx
|
|
8
8
|
function f({ onSwitchWorkspace: f, onLogout: p, position: m = "right" }) {
|
|
9
|
-
let
|
|
10
|
-
|
|
11
|
-
return n === e ? t : n;
|
|
12
|
-
}, [_, v] = r(!1), y = n(null), b = i(), x = e((e) => e.user), S = e((e) => e.currentWorkspaceId);
|
|
13
|
-
t(() => {
|
|
9
|
+
let h = t(), [g, _] = i(!1), v = r(null), y = a(), b = e((e) => e.user), x = e((e) => e.currentWorkspaceId);
|
|
10
|
+
n(() => {
|
|
14
11
|
function e(e) {
|
|
15
|
-
|
|
12
|
+
v.current && !v.current.contains(e.target) && _(!1);
|
|
16
13
|
}
|
|
17
|
-
if (
|
|
18
|
-
}, [
|
|
19
|
-
let
|
|
20
|
-
|
|
21
|
-
},
|
|
22
|
-
|
|
14
|
+
if (g) return document.addEventListener("mousedown", e), () => document.removeEventListener("mousedown", e);
|
|
15
|
+
}, [g]);
|
|
16
|
+
let S = () => {
|
|
17
|
+
_(!1), p();
|
|
18
|
+
}, C = () => {
|
|
19
|
+
_(!1), f?.();
|
|
23
20
|
};
|
|
24
|
-
if (!
|
|
25
|
-
let
|
|
26
|
-
if (
|
|
27
|
-
if (
|
|
28
|
-
let e =
|
|
29
|
-
return e.length >= 2 ? `${e[0][0]}${e[1][0]}`.toUpperCase() :
|
|
21
|
+
if (!b) return null;
|
|
22
|
+
let w = () => {
|
|
23
|
+
if (b.firstName && b.lastName) return `${b.firstName[0]}${b.lastName[0]}`.toUpperCase();
|
|
24
|
+
if (b.name) {
|
|
25
|
+
let e = b.name.split(" ");
|
|
26
|
+
return e.length >= 2 ? `${e[0][0]}${e[1][0]}`.toUpperCase() : b.name.substring(0, 2).toUpperCase();
|
|
30
27
|
}
|
|
31
|
-
return
|
|
32
|
-
},
|
|
28
|
+
return b.username ? b.username.substring(0, 2).toUpperCase() : b.email.substring(0, 2).toUpperCase();
|
|
29
|
+
}, T = b.name || `${b.firstName || ""} ${b.lastName || ""}`.trim() || b.username;
|
|
33
30
|
return /* @__PURE__ */ d("div", {
|
|
34
31
|
className: "relative",
|
|
35
|
-
ref:
|
|
32
|
+
ref: v,
|
|
36
33
|
children: [/* @__PURE__ */ d("button", {
|
|
37
34
|
type: "button",
|
|
38
|
-
onClick: () =>
|
|
35
|
+
onClick: () => _(!g),
|
|
39
36
|
className: "flex items-center gap-2 px-3 py-2 rounded-lg hover:bg-bg-sunken transition-colors",
|
|
40
|
-
"aria-label": "User menu",
|
|
41
|
-
"aria-expanded":
|
|
37
|
+
"aria-label": h("auth.profileMenu.userMenu", "User menu"),
|
|
38
|
+
"aria-expanded": g,
|
|
42
39
|
children: [
|
|
43
40
|
/* @__PURE__ */ u("div", {
|
|
44
41
|
className: "size-8 rounded-full bg-accent-blue flex items-center justify-center text-white text-sm font-medium overflow-hidden",
|
|
45
|
-
children:
|
|
46
|
-
src:
|
|
47
|
-
alt:
|
|
42
|
+
children: b.avatar ? /* @__PURE__ */ u("img", {
|
|
43
|
+
src: b.avatar,
|
|
44
|
+
alt: h("auth.profileMenu.avatarAlt", "Profile picture"),
|
|
48
45
|
className: "size-full object-cover"
|
|
49
|
-
}) :
|
|
46
|
+
}) : w()
|
|
50
47
|
}),
|
|
51
48
|
/* @__PURE__ */ u("span", {
|
|
52
49
|
className: "hidden sm:block text-sm font-medium text-text-secondary",
|
|
53
|
-
children:
|
|
50
|
+
children: T
|
|
54
51
|
}),
|
|
55
|
-
/* @__PURE__ */ u(
|
|
52
|
+
/* @__PURE__ */ u(s, { className: `size-4 text-text-secondary transition-transform ${g ? "rotate-180" : ""}` })
|
|
56
53
|
]
|
|
57
|
-
}),
|
|
54
|
+
}), g && /* @__PURE__ */ d("div", {
|
|
58
55
|
className: `absolute top-full mt-2 w-64 bg-bg-surface rounded-lg shadow-lg border border-border-subtle py-2 z-50 ${m === "right" ? "right-0" : "left-0"}`,
|
|
59
56
|
children: [/* @__PURE__ */ d("div", {
|
|
60
57
|
className: "px-4 py-3 border-b border-border-subtle",
|
|
61
58
|
children: [
|
|
62
59
|
/* @__PURE__ */ u("p", {
|
|
63
60
|
className: "text-sm font-medium text-text-primary truncate",
|
|
64
|
-
children:
|
|
61
|
+
children: T
|
|
65
62
|
}),
|
|
66
63
|
/* @__PURE__ */ u("p", {
|
|
67
64
|
className: "text-xs text-text-secondary truncate",
|
|
68
|
-
children:
|
|
65
|
+
children: b.email
|
|
69
66
|
}),
|
|
70
|
-
|
|
67
|
+
x && /* @__PURE__ */ d("p", {
|
|
71
68
|
className: "text-xs text-text-tertiary mt-1 truncate",
|
|
72
69
|
children: [
|
|
73
|
-
"Workspace:
|
|
74
|
-
|
|
70
|
+
h("auth.profileMenu.workspaceLabel", "Workspace:"),
|
|
71
|
+
" ",
|
|
72
|
+
x.substring(0, 8),
|
|
75
73
|
"..."
|
|
76
74
|
]
|
|
77
75
|
})
|
|
@@ -81,23 +79,23 @@ function f({ onSwitchWorkspace: f, onLogout: p, position: m = "right" }) {
|
|
|
81
79
|
children: [
|
|
82
80
|
f && /* @__PURE__ */ d("button", {
|
|
83
81
|
type: "button",
|
|
84
|
-
onClick:
|
|
82
|
+
onClick: C,
|
|
85
83
|
className: "w-full flex items-center gap-3 px-4 py-2 text-sm text-text-secondary hover:bg-bg-sunken transition-colors",
|
|
86
|
-
children: [/* @__PURE__ */ u(
|
|
84
|
+
children: [/* @__PURE__ */ u(o, { className: "size-4" }), /* @__PURE__ */ u("span", { children: h("auth.profileMenu.switchWorkspace", "Switch Workspace") })]
|
|
87
85
|
}),
|
|
88
86
|
/* @__PURE__ */ d("button", {
|
|
89
87
|
type: "button",
|
|
90
88
|
onClick: () => {
|
|
91
|
-
|
|
89
|
+
_(!1), y(`/auth/login?mode=add-account&returnTo=${encodeURIComponent(window.location.pathname + window.location.search)}`);
|
|
92
90
|
},
|
|
93
91
|
className: "w-full flex items-center gap-3 px-4 py-2 text-sm text-text-secondary hover:bg-bg-sunken transition-colors",
|
|
94
|
-
children: [/* @__PURE__ */ u(
|
|
92
|
+
children: [/* @__PURE__ */ u(l, { className: "size-4" }), /* @__PURE__ */ u("span", { children: h("auth.profileMenu.addAccount", "Add account") })]
|
|
95
93
|
}),
|
|
96
94
|
/* @__PURE__ */ d("button", {
|
|
97
95
|
type: "button",
|
|
98
|
-
onClick:
|
|
96
|
+
onClick: S,
|
|
99
97
|
className: "w-full flex items-center gap-3 px-4 py-2 text-sm text-status-error-text hover:bg-status-error-bg-subtle transition-colors",
|
|
100
|
-
children: [/* @__PURE__ */ u(
|
|
98
|
+
children: [/* @__PURE__ */ u(c, { className: "size-4" }), /* @__PURE__ */ u("span", { children: h("auth.profileMenu.logout", "Logout") })]
|
|
101
99
|
})
|
|
102
100
|
]
|
|
103
101
|
})]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UserProfileMenu.js","names":[],"sources":["../../../../src/auth/components/profile/UserProfileMenu.tsx"],"sourcesContent":["import { useState, useRef, useEffect } from \"react\";\nimport {
|
|
1
|
+
{"version":3,"file":"UserProfileMenu.js","names":[],"sources":["../../../../src/auth/components/profile/UserProfileMenu.tsx"],"sourcesContent":["import { useState, useRef, useEffect } from \"react\";\nimport { useTr } from \"../../../shared/hooks/useTr\";\nimport { LogOut, ChevronDown, Building2, UserPlus } from \"lucide-react\";\nimport { useNavigate } from \"react-router\";\nimport { useAuthStore } from \"../../store/authStore\";\n\nexport interface UserProfileMenuProps {\n /**\n * Callback when workspace switcher should be shown\n */\n onSwitchWorkspace?: () => void;\n\n /**\n * Logout handler (REQUIRED)\n * Should clear auth state and redirect to login\n */\n onLogout: () => void;\n\n /**\n * Position of the dropdown menu\n * @default 'right'\n */\n position?: \"left\" | \"right\";\n}\n\n/**\n * User Profile Menu Component\n *\n * Displays user avatar/icon with dropdown menu containing:\n * - User information\n * - Switch Workspace option\n * - Logout button\n *\n * @example\n * ```tsx\n * import { UserProfileMenu } from '@burdenoff/microfe-auth';\n *\n * function AppHeader() {\n * return (\n * <div className=\"header\">\n * <UserProfileMenu\n * onSwitchWorkspace={() => setShowWorkspaceSwitcher(true)}\n * position=\"right\"\n * />\n * </div>\n * );\n * }\n * ```\n */\nexport function UserProfileMenu({\n onSwitchWorkspace,\n onLogout,\n position = \"right\",\n}: UserProfileMenuProps) {\n const tr = useTr();\n\n const [isOpen, setIsOpen] = useState(false);\n const menuRef = useRef<HTMLDivElement>(null);\n const navigate = useNavigate();\n\n const user = useAuthStore((state) => state.user);\n const currentWorkspaceId = useAuthStore((state) => state.currentWorkspaceId);\n\n // Close dropdown when clicking outside\n useEffect(() => {\n function handleClickOutside(event: MouseEvent) {\n if (menuRef.current && !menuRef.current.contains(event.target as Node)) {\n setIsOpen(false);\n }\n }\n\n if (isOpen) {\n document.addEventListener(\"mousedown\", handleClickOutside);\n return () =>\n document.removeEventListener(\"mousedown\", handleClickOutside);\n }\n }, [isOpen]);\n\n const handleLogout = () => {\n setIsOpen(false);\n onLogout();\n };\n\n const handleSwitchWorkspace = () => {\n setIsOpen(false);\n onSwitchWorkspace?.();\n };\n\n if (!user) {\n return null;\n }\n\n // Get user initials for avatar\n const getInitials = () => {\n if (user.firstName && user.lastName) {\n return `${user.firstName[0]}${user.lastName[0]}`.toUpperCase();\n }\n if (user.name) {\n const parts = user.name.split(\" \");\n if (parts.length >= 2) {\n return `${parts[0][0]}${parts[1][0]}`.toUpperCase();\n }\n return user.name.substring(0, 2).toUpperCase();\n }\n if (user.username) {\n return user.username.substring(0, 2).toUpperCase();\n }\n return user.email.substring(0, 2).toUpperCase();\n };\n\n const displayName =\n user.name ||\n `${user.firstName || \"\"} ${user.lastName || \"\"}`.trim() ||\n user.username;\n\n return (\n <div className=\"relative\" ref={menuRef}>\n {/* Profile Button */}\n <button\n type=\"button\"\n onClick={() => setIsOpen(!isOpen)}\n className=\"flex items-center gap-2 px-3 py-2 rounded-lg hover:bg-bg-sunken transition-colors\"\n aria-label={tr(\"auth.profileMenu.userMenu\", \"User menu\")}\n aria-expanded={isOpen}\n >\n {/* Avatar */}\n <div className=\"size-8 rounded-full bg-accent-blue flex items-center justify-center text-white text-sm font-medium overflow-hidden\">\n {user.avatar ? (\n <img\n src={user.avatar}\n alt={tr(\"auth.profileMenu.avatarAlt\", \"Profile picture\")}\n className=\"size-full object-cover\"\n />\n ) : (\n getInitials()\n )}\n </div>\n\n {/* User Name (optional, hide on small screens) */}\n <span className=\"hidden sm:block text-sm font-medium text-text-secondary\">\n {displayName}\n </span>\n\n {/* Chevron */}\n <ChevronDown\n className={`size-4 text-text-secondary transition-transform ${\n isOpen ? \"rotate-180\" : \"\"\n }`}\n />\n </button>\n\n {/* Dropdown Menu */}\n {isOpen && (\n <div\n className={`absolute top-full mt-2 w-64 bg-bg-surface rounded-lg shadow-lg border border-border-subtle py-2 z-50 ${\n position === \"right\" ? \"right-0\" : \"left-0\"\n }`}\n >\n {/* User Info Section */}\n <div className=\"px-4 py-3 border-b border-border-subtle\">\n <p className=\"text-sm font-medium text-text-primary truncate\">\n {displayName}\n </p>\n <p className=\"text-xs text-text-secondary truncate\">{user.email}</p>\n {currentWorkspaceId && (\n <p className=\"text-xs text-text-tertiary mt-1 truncate\">\n {tr(\"auth.profileMenu.workspaceLabel\", \"Workspace:\")}{\" \"}\n {currentWorkspaceId.substring(0, 8)}...\n </p>\n )}\n </div>\n\n {/* Menu Items */}\n <div className=\"py-1\">\n {/* Switch Workspace */}\n {onSwitchWorkspace && (\n <button\n type=\"button\"\n onClick={handleSwitchWorkspace}\n className=\"w-full flex items-center gap-3 px-4 py-2 text-sm text-text-secondary hover:bg-bg-sunken transition-colors\"\n >\n <Building2 className=\"size-4\" />\n <span>\n {tr(\"auth.profileMenu.switchWorkspace\", \"Switch Workspace\")}\n </span>\n </button>\n )}\n\n {/* Add Account */}\n <button\n type=\"button\"\n onClick={() => {\n setIsOpen(false);\n const returnTo = encodeURIComponent(\n window.location.pathname + window.location.search,\n );\n navigate(`/auth/login?mode=add-account&returnTo=${returnTo}`);\n }}\n className=\"w-full flex items-center gap-3 px-4 py-2 text-sm text-text-secondary hover:bg-bg-sunken transition-colors\"\n >\n <UserPlus className=\"size-4\" />\n <span>{tr(\"auth.profileMenu.addAccount\", \"Add account\")}</span>\n </button>\n\n {/* Logout */}\n <button\n type=\"button\"\n onClick={handleLogout}\n className=\"w-full flex items-center gap-3 px-4 py-2 text-sm text-status-error-text hover:bg-status-error-bg-subtle transition-colors\"\n >\n <LogOut className=\"size-4\" />\n <span>{tr(\"auth.profileMenu.logout\", \"Logout\")}</span>\n </button>\n </div>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,18 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { useTr as e } from "../../../shared/hooks/useTr.js";
|
|
2
|
+
import { useEffect as t, useId as n, useMemo as r, useState as i } from "react";
|
|
3
3
|
import { jsx as a, jsxs as o } from "react/jsx-runtime";
|
|
4
4
|
//#region src/auth/components/workspace/WorkspaceSelector.tsx
|
|
5
5
|
var s = [];
|
|
6
6
|
function c({ isOpen: c, onClose: l, workspaces: u, projects: d = s, onSelect: f, isLoading: p = !1, error: m = null }) {
|
|
7
|
-
let
|
|
8
|
-
let n = h(e);
|
|
9
|
-
return n === e ? t : n;
|
|
10
|
-
}, _ = t(), v = t(), y = t(), [b, x] = r(null), [S, C] = r(null), [w, T] = r(null), E = n(() => {
|
|
7
|
+
let h = e(), g = n(), _ = n(), v = n(), [y, b] = i(null), [x, S] = i(null), [C, w] = i(null), T = r(() => {
|
|
11
8
|
let e = /* @__PURE__ */ new Map();
|
|
12
9
|
return u.forEach((t) => {
|
|
13
10
|
let n = t.organizationId || "default";
|
|
14
11
|
e.has(n) || e.set(n, {
|
|
15
|
-
name: n === "default" ? "Default" :
|
|
12
|
+
name: n === "default" ? h("auth.workspaceSelector.defaultOrg", "Default") : `${h("auth.workspaceSelector.organizationPrefix", "Organization")} ${n.slice(0, 8)}`,
|
|
16
13
|
count: 0
|
|
17
14
|
}), e.get(n).count++;
|
|
18
15
|
}), Array.from(e.entries()).map(([e, { name: t, count: n }]) => ({
|
|
@@ -20,28 +17,28 @@ function c({ isOpen: c, onClose: l, workspaces: u, projects: d = s, onSelect: f,
|
|
|
20
17
|
name: t,
|
|
21
18
|
workspaceCount: n
|
|
22
19
|
}));
|
|
23
|
-
}, [u]),
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}, [
|
|
27
|
-
|
|
28
|
-
}, [
|
|
29
|
-
let
|
|
30
|
-
|
|
20
|
+
}, [u, h]), E = r(() => y ? u.filter((e) => (e.organizationId || "default") === y) : u, [u, y]), D = r(() => x ? d.filter((e) => e.workspaceId === x) : [], [d, x]), O = r(() => u.find((e) => e.id === x), [u, x]), k = r(() => d.find((e) => e.id === C), [d, C]);
|
|
21
|
+
t(() => {
|
|
22
|
+
T.length === 1 && !y && b(T[0].id);
|
|
23
|
+
}, [T, y]), t(() => {
|
|
24
|
+
E.length === 1 && !x && S(E[0].id);
|
|
25
|
+
}, [E, x]);
|
|
26
|
+
let A = (e) => {
|
|
27
|
+
b(e), S(null), w(null);
|
|
28
|
+
}, j = (e) => {
|
|
29
|
+
S(e), w(null);
|
|
31
30
|
}, M = (e) => {
|
|
32
|
-
|
|
33
|
-
}, N = (
|
|
34
|
-
|
|
31
|
+
w(e);
|
|
32
|
+
}, N = () => {
|
|
33
|
+
O && f(O, k);
|
|
35
34
|
}, P = () => {
|
|
36
|
-
|
|
37
|
-
}, F =
|
|
38
|
-
x(null), C(null), T(null), l();
|
|
39
|
-
}, I = S !== null;
|
|
35
|
+
b(null), S(null), w(null), l();
|
|
36
|
+
}, F = x !== null;
|
|
40
37
|
return c ? /* @__PURE__ */ o("div", {
|
|
41
38
|
className: "fixed inset-0 z-50 flex items-center justify-center",
|
|
42
39
|
children: [/* @__PURE__ */ a("div", {
|
|
43
40
|
className: "absolute inset-0 bg-black/50",
|
|
44
|
-
onClick:
|
|
41
|
+
onClick: P,
|
|
45
42
|
"aria-hidden": "true"
|
|
46
43
|
}), /* @__PURE__ */ o("div", {
|
|
47
44
|
className: "relative bg-bg-surface rounded-2xl shadow-xl max-w-2xl w-full mx-4 p-6 space-y-6",
|
|
@@ -50,26 +47,26 @@ function c({ isOpen: c, onClose: l, workspaces: u, projects: d = s, onSelect: f,
|
|
|
50
47
|
className: "space-y-2",
|
|
51
48
|
children: [/* @__PURE__ */ a("h2", {
|
|
52
49
|
className: "text-2xl font-semibold text-text-primary",
|
|
53
|
-
children:
|
|
50
|
+
children: h("auth.workspaceSelector.title", "Select Your Workspace")
|
|
54
51
|
}), /* @__PURE__ */ a("p", {
|
|
55
52
|
className: "text-sm text-text-secondary",
|
|
56
|
-
children:
|
|
53
|
+
children: h("auth.workspaceSelector.subtitle", "Choose the workspace you want to work in. You can switch workspaces later from the header.")
|
|
57
54
|
})]
|
|
58
55
|
}),
|
|
59
56
|
m && /* @__PURE__ */ o("div", {
|
|
60
57
|
className: "rounded-lg bg-status-error-bg-subtle p-4 text-sm text-status-error-text",
|
|
61
58
|
children: [/* @__PURE__ */ a("p", {
|
|
62
59
|
className: "font-medium",
|
|
63
|
-
children:
|
|
60
|
+
children: h("auth.workspaceSelector.error", "Error")
|
|
64
61
|
}), /* @__PURE__ */ a("p", { children: m })]
|
|
65
62
|
}),
|
|
66
63
|
/* @__PURE__ */ o("div", {
|
|
67
64
|
className: "space-y-4",
|
|
68
65
|
children: [
|
|
69
|
-
|
|
66
|
+
T.length > 1 && /* @__PURE__ */ o("div", {
|
|
70
67
|
className: "space-y-2",
|
|
71
68
|
children: [/* @__PURE__ */ a("label", {
|
|
72
|
-
htmlFor:
|
|
69
|
+
htmlFor: g,
|
|
73
70
|
className: "block text-sm font-medium text-text-secondary",
|
|
74
71
|
children: /* @__PURE__ */ o("span", {
|
|
75
72
|
className: "flex items-center gap-2",
|
|
@@ -85,33 +82,30 @@ function c({ isOpen: c, onClose: l, workspaces: u, projects: d = s, onSelect: f,
|
|
|
85
82
|
strokeWidth: 2,
|
|
86
83
|
d: "M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4"
|
|
87
84
|
})
|
|
88
|
-
}), "Organization"]
|
|
85
|
+
}), h("auth.workspaceSelector.organization", "Organization")]
|
|
89
86
|
})
|
|
90
87
|
}), /* @__PURE__ */ o("select", {
|
|
91
|
-
id:
|
|
92
|
-
value:
|
|
93
|
-
onChange: (e) =>
|
|
88
|
+
id: g,
|
|
89
|
+
value: y || "",
|
|
90
|
+
onChange: (e) => A(e.target.value),
|
|
94
91
|
className: "w-full rounded-lg border border-border-default bg-bg-surface px-4 py-2.5 text-sm text-text-primary focus:border-primary focus:ring-2 focus:ring-primary/20",
|
|
95
92
|
children: [/* @__PURE__ */ a("option", {
|
|
96
93
|
value: "",
|
|
97
|
-
children:
|
|
98
|
-
}),
|
|
94
|
+
children: h("auth.workspaceSelector.selectOrg", "Select organization...")
|
|
95
|
+
}), T.map((e) => /* @__PURE__ */ a("option", {
|
|
99
96
|
value: e.id,
|
|
100
|
-
children:
|
|
101
|
-
e.name,
|
|
102
|
-
|
|
103
|
-
e.workspaceCount
|
|
104
|
-
|
|
105
|
-
e.workspaceCount === 1 ? "" : "s",
|
|
106
|
-
")"
|
|
107
|
-
]
|
|
97
|
+
children: h("auth.workspaceSelector.orgOption", "{{name}} ({{count}} workspace{{plural}})", {
|
|
98
|
+
name: e.name,
|
|
99
|
+
count: e.workspaceCount,
|
|
100
|
+
plural: e.workspaceCount === 1 ? "" : "s"
|
|
101
|
+
})
|
|
108
102
|
}, e.id))]
|
|
109
103
|
})]
|
|
110
104
|
}),
|
|
111
105
|
/* @__PURE__ */ o("div", {
|
|
112
106
|
className: "space-y-2",
|
|
113
107
|
children: [/* @__PURE__ */ a("label", {
|
|
114
|
-
htmlFor:
|
|
108
|
+
htmlFor: _,
|
|
115
109
|
className: "block text-sm font-medium text-text-secondary",
|
|
116
110
|
children: /* @__PURE__ */ o("span", {
|
|
117
111
|
className: "flex items-center gap-2",
|
|
@@ -127,18 +121,18 @@ function c({ isOpen: c, onClose: l, workspaces: u, projects: d = s, onSelect: f,
|
|
|
127
121
|
strokeWidth: 2,
|
|
128
122
|
d: "M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z"
|
|
129
123
|
})
|
|
130
|
-
}), "Workspace"]
|
|
124
|
+
}), h("auth.workspaceSelector.workspace", "Workspace")]
|
|
131
125
|
})
|
|
132
126
|
}), /* @__PURE__ */ o("select", {
|
|
133
|
-
id:
|
|
134
|
-
value:
|
|
135
|
-
onChange: (e) =>
|
|
136
|
-
disabled: !
|
|
127
|
+
id: _,
|
|
128
|
+
value: x || "",
|
|
129
|
+
onChange: (e) => j(e.target.value),
|
|
130
|
+
disabled: !y && T.length > 1,
|
|
137
131
|
className: "w-full rounded-lg border border-border-default bg-bg-surface px-4 py-2.5 text-sm text-text-primary focus:border-primary focus:ring-2 focus:ring-primary/20 disabled:opacity-50 disabled:cursor-not-allowed",
|
|
138
132
|
children: [/* @__PURE__ */ a("option", {
|
|
139
133
|
value: "",
|
|
140
|
-
children:
|
|
141
|
-
}),
|
|
134
|
+
children: h("auth.workspaceSelector.selectWorkspace", "Select workspace...")
|
|
135
|
+
}), E.map((e) => /* @__PURE__ */ o("option", {
|
|
142
136
|
value: e.id,
|
|
143
137
|
children: [
|
|
144
138
|
e.name,
|
|
@@ -149,10 +143,10 @@ function c({ isOpen: c, onClose: l, workspaces: u, projects: d = s, onSelect: f,
|
|
|
149
143
|
}, e.id))]
|
|
150
144
|
})]
|
|
151
145
|
}),
|
|
152
|
-
|
|
146
|
+
D.length > 0 && /* @__PURE__ */ o("div", {
|
|
153
147
|
className: "space-y-2",
|
|
154
148
|
children: [/* @__PURE__ */ a("label", {
|
|
155
|
-
htmlFor:
|
|
149
|
+
htmlFor: v,
|
|
156
150
|
className: "block text-sm font-medium text-text-secondary",
|
|
157
151
|
children: /* @__PURE__ */ o("span", {
|
|
158
152
|
className: "flex items-center gap-2",
|
|
@@ -168,27 +162,27 @@ function c({ isOpen: c, onClose: l, workspaces: u, projects: d = s, onSelect: f,
|
|
|
168
162
|
strokeWidth: 2,
|
|
169
163
|
d: "M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
|
|
170
164
|
})
|
|
171
|
-
}), "Project (Optional)"]
|
|
165
|
+
}), h("auth.workspaceSelector.projectOptional", "Project (Optional)")]
|
|
172
166
|
})
|
|
173
167
|
}), /* @__PURE__ */ o("select", {
|
|
174
|
-
id:
|
|
175
|
-
value:
|
|
176
|
-
onChange: (e) =>
|
|
168
|
+
id: v,
|
|
169
|
+
value: C || "",
|
|
170
|
+
onChange: (e) => M(e.target.value),
|
|
177
171
|
className: "w-full rounded-lg border border-border-default bg-bg-surface px-4 py-2.5 text-sm text-text-primary focus:border-primary focus:ring-2 focus:ring-primary/20",
|
|
178
172
|
children: [/* @__PURE__ */ a("option", {
|
|
179
173
|
value: "",
|
|
180
|
-
children:
|
|
181
|
-
}),
|
|
174
|
+
children: h("auth.workspaceSelector.noProject", "No project selected")
|
|
175
|
+
}), D.map((e) => /* @__PURE__ */ a("option", {
|
|
182
176
|
value: e.id,
|
|
183
177
|
children: e.name
|
|
184
178
|
}, e.id))]
|
|
185
179
|
})]
|
|
186
180
|
}),
|
|
187
|
-
|
|
181
|
+
O && /* @__PURE__ */ o("div", {
|
|
188
182
|
className: "rounded-lg bg-bg-sunken p-4 space-y-2",
|
|
189
183
|
children: [/* @__PURE__ */ a("p", {
|
|
190
184
|
className: "text-sm font-medium text-text-primary",
|
|
191
|
-
children:
|
|
185
|
+
children: h("auth.workspaceSelector.selected", "Selected:")
|
|
192
186
|
}), /* @__PURE__ */ o("div", {
|
|
193
187
|
className: "text-sm text-text-secondary space-y-1",
|
|
194
188
|
children: [/* @__PURE__ */ o("div", {
|
|
@@ -204,8 +198,8 @@ function c({ isOpen: c, onClose: l, workspaces: u, projects: d = s, onSelect: f,
|
|
|
204
198
|
strokeWidth: 2,
|
|
205
199
|
d: "M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z"
|
|
206
200
|
})
|
|
207
|
-
}), /* @__PURE__ */ a("span", { children:
|
|
208
|
-
}),
|
|
201
|
+
}), /* @__PURE__ */ a("span", { children: O.name })]
|
|
202
|
+
}), k && /* @__PURE__ */ o("div", {
|
|
209
203
|
className: "flex items-center gap-2",
|
|
210
204
|
children: [/* @__PURE__ */ a("svg", {
|
|
211
205
|
className: "size-3",
|
|
@@ -218,7 +212,7 @@ function c({ isOpen: c, onClose: l, workspaces: u, projects: d = s, onSelect: f,
|
|
|
218
212
|
strokeWidth: 2,
|
|
219
213
|
d: "M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
|
|
220
214
|
})
|
|
221
|
-
}), /* @__PURE__ */ a("span", { children:
|
|
215
|
+
}), /* @__PURE__ */ a("span", { children: k.name })]
|
|
222
216
|
})]
|
|
223
217
|
})]
|
|
224
218
|
})
|
|
@@ -228,16 +222,16 @@ function c({ isOpen: c, onClose: l, workspaces: u, projects: d = s, onSelect: f,
|
|
|
228
222
|
className: "flex items-center justify-end gap-3 pt-4 border-t border-border-subtle",
|
|
229
223
|
children: [/* @__PURE__ */ a("button", {
|
|
230
224
|
type: "button",
|
|
231
|
-
onClick:
|
|
225
|
+
onClick: P,
|
|
232
226
|
disabled: p,
|
|
233
227
|
className: "px-4 py-2 text-sm font-medium text-text-secondary hover:bg-bg-sunken rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed",
|
|
234
|
-
children: "Cancel"
|
|
228
|
+
children: h("auth.workspaceSelector.cancel", "Cancel")
|
|
235
229
|
}), /* @__PURE__ */ a("button", {
|
|
236
230
|
type: "button",
|
|
237
|
-
onClick:
|
|
238
|
-
disabled: !
|
|
231
|
+
onClick: N,
|
|
232
|
+
disabled: !F || p,
|
|
239
233
|
className: "px-4 py-2 text-sm font-medium text-action-primary-text bg-action-primary-bg hover:bg-action-primary-bg/90 rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed",
|
|
240
|
-
children: p ?
|
|
234
|
+
children: p ? h("auth.workspaceSelector.loading", "Loading...") : h("auth.workspaceSelector.continue", "Continue")
|
|
241
235
|
})]
|
|
242
236
|
})
|
|
243
237
|
]
|