@hexclave/next 1.0.125 → 1.0.126
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/{admin-app-impl-Bxad6t8m.d.ts → admin-app-impl-CjDjJ3PS.d.ts} +29 -13
- package/dist/admin-app-impl-CjDjJ3PS.d.ts.map +1 -0
- package/dist/clickmap/clickmap-core.d.ts +1 -1
- package/dist/clickmap/index.d.ts +1 -1
- package/dist/{client-app-B0cTytS5.d.ts → client-app-jAjrgwSh.d.ts} +34 -6
- package/dist/client-app-jAjrgwSh.d.ts.map +1 -0
- package/dist/{common-B2gkWlXX.d.ts → common-BjAI7WW6.d.ts} +15 -3
- package/dist/common-BjAI7WW6.d.ts.map +1 -0
- package/dist/{common-BK_sydxF.d.ts → common-DWfeER0s.d.ts} +2 -2
- package/dist/{common-BK_sydxF.d.ts.map → common-DWfeER0s.d.ts.map} +1 -1
- package/dist/components/message-cards/predefined-message-card.js +4 -2
- package/dist/components/message-cards/predefined-message-card.js.map +1 -1
- package/dist/components/selected-team-switcher.d.ts +1 -1
- package/dist/components/team-icon.d.ts +1 -1
- package/dist/components/team-switcher.d.ts +1 -1
- package/dist/components/user-button.js +9 -9
- package/dist/components/user-button.js.map +1 -1
- package/dist/components/user-button.test.d.ts +1 -0
- package/dist/components/user-button.test.js +71 -0
- package/dist/components/user-button.test.js.map +1 -0
- package/dist/components-page/account-settings/payments/payments-page.d.ts +1 -1
- package/dist/components-page/account-settings/payments/payments-panel.d.ts +1 -1
- package/dist/components-page/account-settings/settings/sign-out-section.d.ts +1 -1
- package/dist/components-page/account-settings/settings/sign-out-section.d.ts.map +1 -1
- package/dist/components-page/account-settings/settings/sign-out-section.js +4 -1
- package/dist/components-page/account-settings/settings/sign-out-section.js.map +1 -1
- package/dist/components-page/account-settings/teams/leave-team-section.d.ts +1 -1
- package/dist/components-page/account-settings/teams/team-api-keys-section.d.ts +1 -1
- package/dist/components-page/account-settings/teams/team-display-name-section.d.ts +1 -1
- package/dist/components-page/account-settings/teams/team-member-invitation-section.d.ts +1 -1
- package/dist/components-page/account-settings/teams/team-member-list-section.d.ts +1 -1
- package/dist/components-page/account-settings/teams/team-page.d.ts +1 -1
- package/dist/components-page/account-settings/teams/team-profile-image-section.d.ts +1 -1
- package/dist/components-page/account-settings/teams/team-profile-user-section.d.ts +1 -1
- package/dist/components-page/hexclave-handler-client.d.ts +1 -1
- package/dist/components-page/hexclave-handler.d.ts +1 -1
- package/dist/components-page/onboarding.js +15 -13
- package/dist/components-page/onboarding.js.map +1 -1
- package/dist/components-page/onboarding.test.js +2 -1
- package/dist/components-page/onboarding.test.js.map +1 -1
- package/dist/dev-tool/dev-tool-core.d.ts +1 -1
- package/dist/dev-tool/index.d.ts +1 -1
- package/dist/esm/components/message-cards/predefined-message-card.js +4 -2
- package/dist/esm/components/message-cards/predefined-message-card.js.map +1 -1
- package/dist/esm/components/user-button.js +9 -9
- package/dist/esm/components/user-button.js.map +1 -1
- package/dist/esm/components/user-button.test.d.ts +1 -0
- package/dist/esm/components/user-button.test.js +70 -0
- package/dist/esm/components/user-button.test.js.map +1 -0
- package/dist/esm/components-page/account-settings/settings/sign-out-section.d.ts +1 -1
- package/dist/esm/components-page/account-settings/settings/sign-out-section.d.ts.map +1 -1
- package/dist/esm/components-page/account-settings/settings/sign-out-section.js +4 -1
- package/dist/esm/components-page/account-settings/settings/sign-out-section.js.map +1 -1
- package/dist/esm/components-page/onboarding.js +15 -13
- package/dist/esm/components-page/onboarding.js.map +1 -1
- package/dist/esm/components-page/onboarding.test.js +2 -1
- package/dist/esm/components-page/onboarding.test.js.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +4 -4
- package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.d.ts +18 -2
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.d.ts.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.external-token-store.test.d.ts +1 -0
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.external-token-store.test.js +382 -0
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.external-token-store.test.js.map +1 -0
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.init-analytics.test.d.ts +1 -0
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.init-analytics.test.js +66 -0
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.init-analytics.test.js.map +1 -0
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js +66 -14
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/common.js +2 -2
- package/dist/esm/lib/hexclave-app/apps/implementations/external-token-store-session-adapter.d.ts +31 -0
- package/dist/esm/lib/hexclave-app/apps/implementations/external-token-store-session-adapter.d.ts.map +1 -0
- package/dist/esm/lib/hexclave-app/apps/implementations/external-token-store-session-adapter.js +115 -0
- package/dist/esm/lib/hexclave-app/apps/implementations/external-token-store-session-adapter.js.map +1 -0
- package/dist/esm/lib/hexclave-app/apps/interfaces/client-app.d.ts +16 -1
- package/dist/esm/lib/hexclave-app/apps/interfaces/client-app.d.ts.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/interfaces/client-app.js.map +1 -1
- package/dist/esm/lib/hexclave-app/common.d.ts +14 -2
- package/dist/esm/lib/hexclave-app/common.d.ts.map +1 -1
- package/dist/esm/lib/hexclave-app/common.js +17 -1
- package/dist/esm/lib/hexclave-app/common.js.map +1 -1
- package/dist/esm/lib/hexclave-app/index.d.ts +2 -2
- package/dist/esm/lib/hexclave-app/index.js +2 -2
- package/dist/esm/lib/hexclave-app/users/index.d.ts +14 -1
- package/dist/esm/lib/hexclave-app/users/index.d.ts.map +1 -1
- package/dist/esm/lib/hexclave-app/users/index.js.map +1 -1
- package/dist/{hexclave-provider-w8nX8KDv.d.ts → hexclave-provider-Br8j6WHN.d.ts} +2 -2
- package/dist/{hexclave-provider-w8nX8KDv.d.ts.map → hexclave-provider-Br8j6WHN.d.ts.map} +1 -1
- package/dist/{hooks-nqzRtl9S.d.ts → hooks-DyC8t1Sh.d.ts} +3 -3
- package/dist/{hooks-nqzRtl9S.d.ts.map → hooks-DyC8t1Sh.d.ts.map} +1 -1
- package/dist/{index-DbiyXho6.d.ts → index-CQ4kC6Cu.d.ts} +2 -2
- package/dist/{index-DbiyXho6.d.ts.map → index-CQ4kC6Cu.d.ts.map} +1 -1
- package/dist/{index-BDzsJvkD.d.ts → index-CWaynElx.d.ts} +3 -3
- package/dist/{index-BDzsJvkD.d.ts.map → index-CWaynElx.d.ts.map} +1 -1
- package/dist/{index-BSr2pd22.d.ts → index-FsS-NA9c.d.ts} +2 -2
- package/dist/{index-BSr2pd22.d.ts.map → index-FsS-NA9c.d.ts.map} +1 -1
- package/dist/index.d.ts +7 -7
- package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +1 -1
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.d.ts +1 -1
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.external-token-store.test.d.ts +1 -0
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.external-token-store.test.js +381 -0
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.external-token-store.test.js.map +1 -0
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.init-analytics.test.d.ts +1 -0
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.init-analytics.test.js +65 -0
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.init-analytics.test.js.map +1 -0
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js +65 -13
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
- package/dist/lib/hexclave-app/apps/implementations/common.d.ts +1 -1
- package/dist/lib/hexclave-app/apps/implementations/common.js +2 -2
- package/dist/lib/hexclave-app/apps/implementations/external-token-store-session-adapter.d.ts +31 -0
- package/dist/lib/hexclave-app/apps/implementations/external-token-store-session-adapter.d.ts.map +1 -0
- package/dist/lib/hexclave-app/apps/implementations/external-token-store-session-adapter.js +117 -0
- package/dist/lib/hexclave-app/apps/implementations/external-token-store-session-adapter.js.map +1 -0
- package/dist/lib/hexclave-app/apps/implementations/index.d.ts +1 -1
- package/dist/lib/hexclave-app/apps/implementations/redirect-page-urls.d.ts +1 -1
- package/dist/lib/hexclave-app/apps/implementations/server-app-impl.d.ts +1 -1
- package/dist/lib/hexclave-app/apps/index.d.ts +1 -1
- package/dist/lib/hexclave-app/apps/interfaces/admin-app.d.ts +1 -1
- package/dist/lib/hexclave-app/apps/interfaces/client-app.d.ts +1 -1
- package/dist/lib/hexclave-app/apps/interfaces/client-app.js.map +1 -1
- package/dist/lib/hexclave-app/apps/interfaces/server-app.d.ts +1 -1
- package/dist/lib/hexclave-app/common.d.ts +2 -2
- package/dist/lib/hexclave-app/common.js +19 -0
- package/dist/lib/hexclave-app/common.js.map +1 -1
- package/dist/lib/hexclave-app/customers/index.d.ts +1 -1
- package/dist/lib/hexclave-app/data-vault/index.d.ts +1 -1
- package/dist/lib/hexclave-app/index.d.ts +4 -4
- package/dist/lib/hexclave-app/index.js +18 -0
- package/dist/lib/hexclave-app/projects/index.d.ts +1 -1
- package/dist/lib/hexclave-app/teams/index.d.ts +1 -1
- package/dist/lib/hexclave-app/url-targets.d.ts +1 -1
- package/dist/lib/hexclave-app/users/index.d.ts +1 -1
- package/dist/lib/hexclave-app/users/index.js.map +1 -1
- package/dist/lib/hooks.d.ts +1 -1
- package/dist/providers/hexclave-context.d.ts +1 -1
- package/dist/providers/hexclave-provider-client.d.ts +1 -1
- package/dist/providers/hexclave-provider.d.ts +1 -1
- package/dist/pushed-config-error-overlay/index.d.ts +1 -1
- package/dist/{redirect-page-urls-ofcg3AYr.d.ts → redirect-page-urls-CnGvn0UJ.d.ts} +2 -2
- package/dist/{redirect-page-urls-ofcg3AYr.d.ts.map → redirect-page-urls-CnGvn0UJ.d.ts.map} +1 -1
- package/dist/tanstack-start-server-context.d.ts.map +1 -1
- package/dist/{url-targets-CWO0mjTr.d.ts → url-targets-DbhzuQtY.d.ts} +2 -2
- package/dist/{url-targets-CWO0mjTr.d.ts.map → url-targets-DbhzuQtY.d.ts.map} +1 -1
- package/package.json +4 -4
- package/src/components/message-cards/predefined-message-card.tsx +4 -2
- package/src/components/user-button.test.tsx +87 -0
- package/src/components/user-button.tsx +9 -9
- package/src/components-page/account-settings/settings/sign-out-section.tsx +9 -1
- package/src/components-page/onboarding.test.tsx +1 -0
- package/src/components-page/onboarding.tsx +16 -13
- package/src/lib/hexclave-app/apps/implementations/client-app-impl.external-token-store.test.ts +425 -0
- package/src/lib/hexclave-app/apps/implementations/client-app-impl.init-analytics.test.ts +79 -0
- package/src/lib/hexclave-app/apps/implementations/client-app-impl.ts +124 -13
- package/src/lib/hexclave-app/apps/implementations/external-token-store-session-adapter.ts +190 -0
- package/src/lib/hexclave-app/apps/interfaces/client-app.ts +17 -0
- package/src/lib/hexclave-app/common.ts +33 -0
- package/src/lib/hexclave-app/index.ts +4 -0
- package/src/lib/hexclave-app/users/index.ts +13 -1
- package/dist/admin-app-impl-Bxad6t8m.d.ts.map +0 -1
- package/dist/client-app-B0cTytS5.d.ts.map +0 -1
- package/dist/common-B2gkWlXX.d.ts.map +0 -1
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
const require_rolldown_runtime = require("../rolldown-runtime-D6vf50IK.js");
|
|
2
|
+
let react = require("react");
|
|
3
|
+
react = require_rolldown_runtime.__toESM(react);
|
|
4
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
5
|
+
let react_dom_client = require("react-dom/client");
|
|
6
|
+
let vitest = require("vitest");
|
|
7
|
+
let __user_button_js = require("./user-button.js");
|
|
8
|
+
//#region src/components/user-button.test.tsx
|
|
9
|
+
// @vitest-environment jsdom
|
|
10
|
+
const previousActEnvironment = Reflect.get(globalThis, "IS_REACT_ACT_ENVIRONMENT");
|
|
11
|
+
const state = vitest.vi.hoisted(() => ({
|
|
12
|
+
app: null,
|
|
13
|
+
user: null
|
|
14
|
+
}));
|
|
15
|
+
vitest.vi.mock("..", () => ({
|
|
16
|
+
useStackApp: () => state.app,
|
|
17
|
+
useUser: () => state.user
|
|
18
|
+
}));
|
|
19
|
+
vitest.vi.mock("../lib/translations", () => ({ useTranslation: () => ({ t: (value) => value }) }));
|
|
20
|
+
vitest.vi.mock("./elements/user-avatar", () => ({ UserAvatar: () => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { "data-testid": "user-avatar" }) }));
|
|
21
|
+
vitest.vi.mock("@hexclave/ui", () => ({
|
|
22
|
+
DropdownMenu: (props) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: props.children }),
|
|
23
|
+
DropdownMenuContent: (props) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: props.children }),
|
|
24
|
+
DropdownMenuItem: (props) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
25
|
+
onClick: props.onClick,
|
|
26
|
+
children: props.children
|
|
27
|
+
}),
|
|
28
|
+
DropdownMenuLabel: (props) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: props.children }),
|
|
29
|
+
DropdownMenuSeparator: () => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("hr", {}),
|
|
30
|
+
DropdownMenuTrigger: (props) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: props.children }),
|
|
31
|
+
Skeleton: () => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {}),
|
|
32
|
+
Typography: (props) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: props.children })
|
|
33
|
+
}));
|
|
34
|
+
(0, vitest.describe)("UserButton", () => {
|
|
35
|
+
let root = null;
|
|
36
|
+
let container = null;
|
|
37
|
+
(0, vitest.beforeEach)(() => {
|
|
38
|
+
Reflect.set(globalThis, "IS_REACT_ACT_ENVIRONMENT", true);
|
|
39
|
+
});
|
|
40
|
+
(0, vitest.afterEach)(() => {
|
|
41
|
+
(0, react.act)(() => root?.unmount());
|
|
42
|
+
container?.remove();
|
|
43
|
+
root = null;
|
|
44
|
+
container = null;
|
|
45
|
+
state.app = null;
|
|
46
|
+
state.user = null;
|
|
47
|
+
Reflect.set(globalThis, "IS_REACT_ACT_ENVIRONMENT", previousActEnvironment);
|
|
48
|
+
});
|
|
49
|
+
(0, vitest.it)("hides external-auth sign out while keeping account settings", async () => {
|
|
50
|
+
state.app = {
|
|
51
|
+
isExternalAuthApp: () => true,
|
|
52
|
+
redirectToAccountSettings: vitest.vi.fn(async () => {})
|
|
53
|
+
};
|
|
54
|
+
state.user = {
|
|
55
|
+
displayName: "External user",
|
|
56
|
+
primaryEmail: "user@example.com",
|
|
57
|
+
signOut: vitest.vi.fn(async () => {})
|
|
58
|
+
};
|
|
59
|
+
container = document.createElement("div");
|
|
60
|
+
document.body.append(container);
|
|
61
|
+
root = (0, react_dom_client.createRoot)(container);
|
|
62
|
+
await (0, react.act)(async () => {
|
|
63
|
+
root?.render(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__user_button_js.UserButton, {}));
|
|
64
|
+
});
|
|
65
|
+
(0, vitest.expect)(container.textContent).toContain("Account settings");
|
|
66
|
+
(0, vitest.expect)(container.textContent).not.toContain("Sign out");
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
//#endregion
|
|
70
|
+
|
|
71
|
+
//# sourceMappingURL=user-button.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-button.test.js","names":["vi","UserButton"],"sources":["../../src/components/user-button.test.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n// @vitest-environment jsdom\n\nimport React, { act } from \"react\";\nimport { createRoot, type Root } from \"react-dom/client\";\nimport { afterEach, beforeEach, describe, expect, it, vi } from \"vitest\";\nimport { UserButton } from \"./user-button\";\n\ntype MockState = {\n app: { isExternalAuthApp: () => boolean, redirectToAccountSettings: () => Promise<void> } | null,\n user: { displayName: string, primaryEmail: string, signOut: () => Promise<void> } | null,\n};\n\nconst previousActEnvironment = Reflect.get(globalThis, \"IS_REACT_ACT_ENVIRONMENT\");\n\nconst state = vi.hoisted<MockState>(() => ({\n app: null,\n user: null,\n}));\n\nvi.mock(\"..\", () => ({\n useStackApp: () => state.app,\n useUser: () => state.user,\n}));\n\nvi.mock(\"../lib/translations\", () => ({\n useTranslation: () => ({ t: (value: string) => value }),\n}));\n\nvi.mock(\"./elements/user-avatar\", () => ({\n UserAvatar: () => <div data-testid=\"user-avatar\" />,\n}));\n\nvi.mock(\"@hexclave/ui\", () => ({\n DropdownMenu: (props: { children: React.ReactNode }) => <div>{props.children}</div>,\n DropdownMenuContent: (props: { children: React.ReactNode }) => <div>{props.children}</div>,\n DropdownMenuItem: (props: { children: React.ReactNode, onClick: () => void }) => <button onClick={props.onClick}>{props.children}</button>,\n DropdownMenuLabel: (props: { children: React.ReactNode }) => <div>{props.children}</div>,\n DropdownMenuSeparator: () => <hr />,\n DropdownMenuTrigger: (props: { children: React.ReactNode }) => <div>{props.children}</div>,\n Skeleton: () => <div />,\n Typography: (props: { children: React.ReactNode }) => <div>{props.children}</div>,\n}));\n\ndescribe(\"UserButton\", () => {\n let root: Root | null = null;\n let container: HTMLDivElement | null = null;\n\n beforeEach(() => {\n Reflect.set(globalThis, \"IS_REACT_ACT_ENVIRONMENT\", true);\n });\n\n afterEach(() => {\n act(() => root?.unmount());\n container?.remove();\n root = null;\n container = null;\n state.app = null;\n state.user = null;\n Reflect.set(globalThis, \"IS_REACT_ACT_ENVIRONMENT\", previousActEnvironment);\n });\n\n it(\"hides external-auth sign out while keeping account settings\", async () => {\n state.app = {\n isExternalAuthApp: () => true,\n redirectToAccountSettings: vi.fn(async () => {}),\n };\n state.user = {\n displayName: \"External user\",\n primaryEmail: \"user@example.com\",\n signOut: vi.fn(async () => {}),\n };\n container = document.createElement(\"div\");\n document.body.append(container);\n root = createRoot(container);\n\n await act(async () => {\n root?.render(<UserButton />);\n });\n\n expect(container.textContent).toContain(\"Account settings\");\n expect(container.textContent).not.toContain(\"Sign out\");\n });\n});\n"],"mappings":";;;;;;;;;AAgBA,MAAM,yBAAyB,QAAQ,IAAI,YAAY,0BAA0B;AAEjF,MAAM,QAAQA,OAAAA,GAAG,eAA0B;CACzC,KAAK;CACL,MAAM;AACR,EAAE;AAEFA,OAAAA,GAAG,KAAK,aAAa;CACnB,mBAAmB,MAAM;CACzB,eAAe,MAAM;AACvB,EAAE;AAEFA,OAAAA,GAAG,KAAK,8BAA8B,EACpC,uBAAuB,EAAE,IAAI,UAAkB,MAAM,GACvD,EAAE;AAEFA,OAAAA,GAAG,KAAK,iCAAiC,EACvC,kBAAkB,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD,EAAK,eAAY,cAAe,CAAA,EACpD,EAAE;AAEFA,OAAAA,GAAG,KAAK,uBAAuB;CAC7B,eAAe,UAAyC,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD,EAAA,UAAM,MAAM,SAAc,CAAA;CAClF,sBAAsB,UAAyC,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD,EAAA,UAAM,MAAM,SAAc,CAAA;CACzF,mBAAmB,UAA8D,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;EAAQ,SAAS,MAAM;YAAU,MAAM;CAAiB,CAAA;CACzI,oBAAoB,UAAyC,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD,EAAA,UAAM,MAAM,SAAc,CAAA;CACvF,6BAA6B,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,CAAK,CAAA;CAClC,sBAAsB,UAAyC,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD,EAAA,UAAM,MAAM,SAAc,CAAA;CACzF,gBAAgB,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD,CAAM,CAAA;CACtB,aAAa,UAAyC,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD,EAAA,UAAM,MAAM,SAAc,CAAA;AAClF,EAAE;qBAEO,oBAAoB;CAC3B,IAAI,OAAoB;CACxB,IAAI,YAAmC;CAEvC,CAAA,GAAA,OAAA,WAAA,OAAiB;EACf,QAAQ,IAAI,YAAY,4BAA4B,IAAI;CAC1D,CAAC;CAED,CAAA,GAAA,OAAA,UAAA,OAAgB;EACd,CAAA,GAAA,MAAA,IAAA,OAAU,MAAM,QAAQ,CAAC;EACzB,WAAW,OAAO;EAClB,OAAO;EACP,YAAY;EACZ,MAAM,MAAM;EACZ,MAAM,OAAO;EACb,QAAQ,IAAI,YAAY,4BAA4B,sBAAsB;CAC5E,CAAC;CAED,CAAA,GAAA,OAAA,GAAA,CAAG,+DAA+D,YAAY;EAC5E,MAAM,MAAM;GACV,yBAAyB;GACzB,2BAA2BA,OAAAA,GAAG,GAAG,YAAY,CAAC,CAAC;EACjD;EACA,MAAM,OAAO;GACX,aAAa;GACb,cAAc;GACd,SAASA,OAAAA,GAAG,GAAG,YAAY,CAAC,CAAC;EAC/B;EACA,YAAY,SAAS,cAAc,KAAK;EACxC,SAAS,KAAK,OAAO,SAAS;EAC9B,QAAA,GAAA,iBAAA,WAAA,CAAkB,SAAS;EAE3B,OAAA,GAAA,MAAA,IAAA,CAAU,YAAY;GACpB,MAAM,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAACC,iBAAAA,YAAD,CAAa,CAAA,CAAC;EAC7B,CAAC;EAED,CAAA,GAAA,OAAA,OAAA,CAAO,UAAU,WAAW,CAAC,CAAC,UAAU,kBAAkB;EAC1D,CAAA,GAAA,OAAA,OAAA,CAAO,UAAU,WAAW,CAAC,CAAC,IAAI,UAAU,UAAU;CACxD,CAAC;AACH,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { o as CustomerInvoicesList, s as CustomerInvoicesListOptions } from "../../../index-
|
|
1
|
+
import { o as CustomerInvoicesList, s as CustomerInvoicesListOptions } from "../../../index-CQ4kC6Cu.js";
|
|
2
2
|
|
|
3
3
|
//#region src/components-page/account-settings/payments/payments-panel.d.ts
|
|
4
4
|
type PaymentMethodSummary = {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
//#region src/components-page/account-settings/settings/sign-out-section.d.ts
|
|
2
2
|
declare function SignOutSection(props?: {
|
|
3
3
|
mockMode?: boolean;
|
|
4
|
-
}): import("react/jsx-runtime").JSX.Element;
|
|
4
|
+
}): import("react/jsx-runtime").JSX.Element | null;
|
|
5
5
|
//#endregion
|
|
6
6
|
export { SignOutSection };
|
|
7
7
|
//# sourceMappingURL=sign-out-section.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sign-out-section.d.ts","names":[],"sources":["../../../../src/components-page/account-settings/settings/sign-out-section.tsx"],"mappings":";
|
|
1
|
+
{"version":3,"file":"sign-out-section.d.ts","names":[],"sources":["../../../../src/components-page/account-settings/settings/sign-out-section.tsx"],"mappings":";iBAUgB,cAAA,CAAe,KAAA;EAAU,QAAA;AAAA,gCAAoB,GAAA,CAAA,OAAA"}
|
|
@@ -4,10 +4,13 @@ let react_jsx_runtime = require("react/jsx-runtime");
|
|
|
4
4
|
let _________lib_hooks_js = require("../../../lib/hooks.js");
|
|
5
5
|
let _________lib_translations_js = require("../../../lib/translations.js");
|
|
6
6
|
let ___section_js = require("../section.js");
|
|
7
|
+
let _________index_js = require("../../../index.js");
|
|
7
8
|
//#region src/components-page/account-settings/settings/sign-out-section.tsx
|
|
8
9
|
function SignOutSection(props) {
|
|
9
10
|
const { t } = (0, _________lib_translations_js.useTranslation)();
|
|
10
|
-
const
|
|
11
|
+
const app = (0, _________index_js.useStackApp)();
|
|
12
|
+
const user = (0, _________lib_hooks_js.useUser)({ or: props?.mockMode || app.isExternalAuthApp() ? "return-null" : "throw" });
|
|
13
|
+
if (app.isExternalAuthApp()) return null;
|
|
11
14
|
const handleSignOut = async () => {
|
|
12
15
|
if (props?.mockMode) {
|
|
13
16
|
alert("Mock mode: Sign out clicked");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sign-out-section.js","names":["Section","Button"],"sources":["../../../../src/components-page/account-settings/settings/sign-out-section.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { Button } from \"@hexclave/ui\";\nimport { useUser } from \"../../../lib/hooks\";\nimport { useTranslation } from \"../../../lib/translations\";\nimport { Section } from \"../section\";\n\nexport function SignOutSection(props?: { mockMode?: boolean }) {\n const { t } = useTranslation();\n const user = useUser({ or: props?.mockMode ? \"return-null\" : \"throw\" });\n\n const handleSignOut = async () => {\n if (props?.mockMode) {\n // Mock mode - just show an alert or do nothing\n alert(\"Mock mode: Sign out clicked\");\n return;\n }\n if (user) {\n await user.signOut();\n }\n };\n\n return (\n <Section\n title={t(\"Sign out\")}\n description={t(\"End your current session\")}\n >\n <div>\n <Button\n variant='secondary'\n onClick={handleSignOut}\n >\n {t(\"Sign out\")}\n </Button>\n </div>\n </Section>\n );\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"sign-out-section.js","names":["Section","Button"],"sources":["../../../../src/components-page/account-settings/settings/sign-out-section.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { Button } from \"@hexclave/ui\";\nimport { useStackApp } from \"../../..\";\nimport { useUser } from \"../../../lib/hooks\";\nimport { useTranslation } from \"../../../lib/translations\";\nimport { Section } from \"../section\";\n\nexport function SignOutSection(props?: { mockMode?: boolean }) {\n const { t } = useTranslation();\n const app = useStackApp();\n // External-auth apps render nothing here, and the provider can clear its session (so Hexclave has no user)\n // before this re-renders, so don't throw for them.\n const user = useUser({ or: props?.mockMode || app.isExternalAuthApp() ? \"return-null\" : \"throw\" });\n\n if (app.isExternalAuthApp()) {\n return null;\n }\n\n const handleSignOut = async () => {\n if (props?.mockMode) {\n // Mock mode - just show an alert or do nothing\n alert(\"Mock mode: Sign out clicked\");\n return;\n }\n if (user) {\n await user.signOut();\n }\n };\n\n return (\n <Section\n title={t(\"Sign out\")}\n description={t(\"End your current session\")}\n >\n <div>\n <Button\n variant='secondary'\n onClick={handleSignOut}\n >\n {t(\"Sign out\")}\n </Button>\n </div>\n </Section>\n );\n}\n"],"mappings":";;;;;;;;AAUA,SAAgB,eAAe,OAAgC;CAC7D,MAAM,EAAE,OAAA,GAAA,6BAAA,eAAA,CAAqB;CAC7B,MAAM,OAAA,GAAA,kBAAA,YAAA,CAAkB;CAGxB,MAAM,QAAA,GAAA,sBAAA,QAAA,CAAe,EAAE,IAAI,OAAO,YAAY,IAAI,kBAAkB,IAAI,gBAAgB,QAAQ,CAAC;CAEjG,IAAI,IAAI,kBAAkB,GACxB,OAAO;CAGT,MAAM,gBAAgB,YAAY;EAChC,IAAI,OAAO,UAAU;GAEnB,MAAM,6BAA6B;GACnC;EACF;EACA,IAAI,MACF,MAAM,KAAK,QAAQ;CAEvB;CAEA,OACE,iBAAA,GAAA,kBAAA,IAAA,CAACA,cAAAA,SAAD;EACE,OAAO,EAAE,UAAU;EACnB,aAAa,EAAE,0BAA0B;YAEzC,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD,EAAA,UACE,iBAAA,GAAA,kBAAA,IAAA,CAACC,aAAAA,QAAD;GACE,SAAQ;GACR,SAAS;aAER,EAAE,UAAU;EACP,CAAA,EACL,CAAA;CACE,CAAA;AAEb"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as Team } from "../../../client-app-
|
|
1
|
+
import { $ as Team } from "../../../client-app-jAjrgwSh.js";
|
|
2
2
|
//#region src/components-page/account-settings/teams/team-display-name-section.d.ts
|
|
3
3
|
declare function TeamDisplayNameSection(props: {
|
|
4
4
|
team: Team;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as Team } from "../../../client-app-
|
|
1
|
+
import { $ as Team } from "../../../client-app-jAjrgwSh.js";
|
|
2
2
|
//#region src/components-page/account-settings/teams/team-member-invitation-section.d.ts
|
|
3
3
|
declare function TeamMemberInvitationSection(props: {
|
|
4
4
|
team: Team;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as Team } from "../../../client-app-
|
|
1
|
+
import { $ as Team } from "../../../client-app-jAjrgwSh.js";
|
|
2
2
|
//#region src/components-page/account-settings/teams/team-member-list-section.d.ts
|
|
3
3
|
declare function TeamMemberListSection(props: {
|
|
4
4
|
team: Team;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as Team } from "../../../client-app-
|
|
1
|
+
import { $ as Team } from "../../../client-app-jAjrgwSh.js";
|
|
2
2
|
//#region src/components-page/account-settings/teams/team-profile-image-section.d.ts
|
|
3
3
|
declare function TeamProfileImageSection(props: {
|
|
4
4
|
team: Team;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as Team } from "../../../client-app-
|
|
1
|
+
import { $ as Team } from "../../../client-app-jAjrgwSh.js";
|
|
2
2
|
//#region src/components-page/account-settings/teams/team-profile-user-section.d.ts
|
|
3
3
|
declare function TeamUserProfileSection(props: {
|
|
4
4
|
team: Team;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { b as getRedirectToPageResult, v as BaseHandlerProps, y as HexclaveHandlerClient } from "../index-
|
|
1
|
+
import { b as getRedirectToPageResult, v as BaseHandlerProps, y as HexclaveHandlerClient } from "../index-CWaynElx.js";
|
|
2
2
|
export { BaseHandlerProps, HexclaveHandlerClient, getRedirectToPageResult };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { _ as StackHandler, g as HexclaveHandler } from "../index-
|
|
1
|
+
import { _ as StackHandler, g as HexclaveHandler } from "../index-CWaynElx.js";
|
|
2
2
|
export { HexclaveHandler, StackHandler, StackHandler as default };
|
|
@@ -19,6 +19,7 @@ function Onboarding(props) {
|
|
|
19
19
|
or: "return-null",
|
|
20
20
|
includeRestricted: true
|
|
21
21
|
});
|
|
22
|
+
const canSignOut = !hexclaveApp.isExternalAuthApp();
|
|
22
23
|
if (user && !user.isRestricted) {
|
|
23
24
|
(0, _hexclave_shared_dist_utils_promises.runAsynchronously)(hexclaveApp.redirectToAfterSignIn());
|
|
24
25
|
return null;
|
|
@@ -39,19 +40,19 @@ function Onboarding(props) {
|
|
|
39
40
|
if (restrictedReason?.type === "restricted_by_administrator") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(___components_message_cards_message_card_js.MessageCard, {
|
|
40
41
|
title: t("Your account has been restricted"),
|
|
41
42
|
fullPage: !!props.fullPage,
|
|
42
|
-
secondaryButtonText: t("Sign out"),
|
|
43
|
-
secondaryAction: async () => {
|
|
43
|
+
secondaryButtonText: canSignOut ? t("Sign out") : void 0,
|
|
44
|
+
secondaryAction: canSignOut ? async () => {
|
|
44
45
|
await user.signOut();
|
|
45
|
-
},
|
|
46
|
+
} : void 0,
|
|
46
47
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: user.restrictedByAdminReason ?? t("An administrator has restricted your account. Please reach out to support if you believe this is an error.") })
|
|
47
48
|
});
|
|
48
49
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(___components_message_cards_message_card_js.MessageCard, {
|
|
49
50
|
title: t("Complete your account setup"),
|
|
50
51
|
fullPage: !!props.fullPage,
|
|
51
|
-
secondaryButtonText: t("Sign out"),
|
|
52
|
-
secondaryAction: async () => {
|
|
52
|
+
secondaryButtonText: canSignOut ? t("Sign out") : void 0,
|
|
53
|
+
secondaryAction: canSignOut ? async () => {
|
|
53
54
|
await user.signOut();
|
|
54
|
-
},
|
|
55
|
+
} : void 0,
|
|
55
56
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("You have not yet completed your account setup. Please reach out to support if you believe this is an error.") })
|
|
56
57
|
});
|
|
57
58
|
}
|
|
@@ -61,7 +62,7 @@ function AddEmailForm(props) {
|
|
|
61
62
|
or: "throw",
|
|
62
63
|
includeRestricted: true
|
|
63
64
|
});
|
|
64
|
-
(0, ___index_js.useStackApp)();
|
|
65
|
+
const canSignOut = !(0, ___index_js.useStackApp)().isExternalAuthApp();
|
|
65
66
|
const [loading, setLoading] = (0, react.useState)(false);
|
|
66
67
|
const { register, handleSubmit, formState: { errors } } = (0, react_hook_form.useForm)({ resolver: (0, _hookform_resolvers_yup.yupResolver)((0, _hexclave_shared_dist_schema_fields.yupObject)({ email: (0, _hexclave_shared_dist_schema_fields.strictEmailSchema)(t("Please enter a valid email address")).defined().nonEmpty(t("Email is required")) })) });
|
|
67
68
|
const onSubmit = async (data) => {
|
|
@@ -76,10 +77,10 @@ function AddEmailForm(props) {
|
|
|
76
77
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(___components_message_cards_message_card_js.MessageCard, {
|
|
77
78
|
title: t("Add your email address"),
|
|
78
79
|
fullPage: !!props.fullPage,
|
|
79
|
-
secondaryButtonText: t("Sign out"),
|
|
80
|
-
secondaryAction: async () => {
|
|
80
|
+
secondaryButtonText: canSignOut ? t("Sign out") : void 0,
|
|
81
|
+
secondaryAction: canSignOut ? async () => {
|
|
81
82
|
await user.signOut();
|
|
82
|
-
},
|
|
83
|
+
} : void 0,
|
|
83
84
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_hexclave_ui.Typography, {
|
|
84
85
|
className: "mb-4",
|
|
85
86
|
children: t("Please add an email address to complete your account setup. We'll send you a verification email.")
|
|
@@ -107,6 +108,7 @@ function AddEmailForm(props) {
|
|
|
107
108
|
function VerifyEmailScreen(props) {
|
|
108
109
|
const { t } = (0, ___lib_translations_js.useTranslation)();
|
|
109
110
|
const { user, email } = props;
|
|
111
|
+
const canSignOut = !(0, ___index_js.useStackApp)().isExternalAuthApp();
|
|
110
112
|
const [changingEmail, setChangingEmail] = (0, react.useState)(false);
|
|
111
113
|
if (changingEmail) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AddEmailForm, {
|
|
112
114
|
fullPage: props.fullPage,
|
|
@@ -119,10 +121,10 @@ function VerifyEmailScreen(props) {
|
|
|
119
121
|
primaryAction: async () => {
|
|
120
122
|
await user.sendVerificationEmail();
|
|
121
123
|
},
|
|
122
|
-
secondaryButtonText: t("Sign out"),
|
|
123
|
-
secondaryAction: async () => {
|
|
124
|
+
secondaryButtonText: canSignOut ? t("Sign out") : void 0,
|
|
125
|
+
secondaryAction: canSignOut ? async () => {
|
|
124
126
|
await user.signOut();
|
|
125
|
-
},
|
|
127
|
+
} : void 0,
|
|
126
128
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_hexclave_ui.Typography, { children: [
|
|
127
129
|
t("Please verify your email address "),
|
|
128
130
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"onboarding.js","names":["MessageCard","Typography","Input","FormWarningText","Button"],"sources":["../../src/components-page/onboarding.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { yupResolver } from \"@hookform/resolvers/yup\";\nimport { strictEmailSchema, yupObject } from \"@hexclave/shared/dist/schema-fields\";\nimport { runAsynchronously, runAsynchronouslyWithAlert } from \"@hexclave/shared/dist/utils/promises\";\nimport { Button, Input, Typography } from \"@hexclave/ui\";\nimport { useState } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport * as yup from \"yup\";\nimport { useStackApp, useUser } from \"..\";\nimport { FormWarningText } from \"../components/elements/form-warning\";\nimport { MessageCard } from \"../components/message-cards/message-card\";\nimport { useTranslation } from \"../lib/translations\";\n\nexport function Onboarding(props: {\n fullPage?: boolean,\n}) {\n const { t } = useTranslation();\n const hexclaveApp = useStackApp();\n const user = useUser({ or: \"return-null\", includeRestricted: true });\n\n // If user is not restricted anymore, redirect to the intended destination\n // redirectToAfterSignIn automatically checks for after_auth_return_to in the URL\n if (user && !user.isRestricted) {\n runAsynchronously(hexclaveApp.redirectToAfterSignIn());\n // TODO: This should return a loading indicator, not just null\n return null;\n }\n\n // If user is anonymous or not logged in, redirect to sign-in\n if (!user || user.isAnonymous) {\n runAsynchronously(hexclaveApp.redirectToSignIn());\n // TODO: This should return a loading indicator, not just null\n return null;\n }\n\n // User is restricted - show appropriate onboarding step based on restricted reason\n const restrictedReason = user.restrictedReason;\n\n if (restrictedReason?.type === \"email_not_verified\") {\n // Check if user has a primary email\n const hasPrimaryEmail = !!user.primaryEmail;\n\n if (!hasPrimaryEmail) {\n // User needs to add an email first\n return <AddEmailForm fullPage={props.fullPage} />;\n }\n\n // User has email but it's not verified\n return <VerifyEmailScreen user={user} email={user.primaryEmail} fullPage={props.fullPage} />;\n }\n\n if (restrictedReason?.type === \"restricted_by_administrator\") {\n return (\n <MessageCard\n title={t(\"Your account has been restricted\")}\n fullPage={!!props.fullPage}\n secondaryButtonText={t(\"Sign out\")}\n secondaryAction={async () => {\n await user.signOut();\n }}\n >\n {/* The public reason is set by the project's administrators (sign-up rules or manually), so it's the most\n helpful thing we can show; the generic sentence is only a fallback for when they didn't provide one. */}\n <p>{user.restrictedByAdminReason ?? t(\"An administrator has restricted your account. Please reach out to support if you believe this is an error.\")}</p>\n </MessageCard>\n );\n }\n\n // Unknown restricted reason - show generic message\n return (\n <MessageCard\n title={t(\"Complete your account setup\")}\n fullPage={!!props.fullPage}\n secondaryButtonText={t(\"Sign out\")}\n secondaryAction={async () => {\n await user.signOut();\n }}\n >\n <p>{t(\"You have not yet completed your account setup. Please reach out to support if you believe this is an error.\")}</p>\n </MessageCard>\n );\n}\n\nfunction AddEmailForm(props: {\n fullPage?: boolean,\n onEmailAdded?: () => void,\n}) {\n const { t } = useTranslation();\n const user = useUser({ or: \"throw\", includeRestricted: true });\n const hexclaveApp = useStackApp();\n const [loading, setLoading] = useState(false);\n\n const emailSchema = yupObject({\n email: strictEmailSchema(t('Please enter a valid email address'))\n .defined()\n .nonEmpty(t('Email is required')),\n });\n\n const { register, handleSubmit, formState: { errors } } = useForm({\n resolver: yupResolver(emailSchema)\n });\n\n const onSubmit = async (data: yup.InferType<typeof emailSchema>) => {\n setLoading(true);\n try {\n await user.update({ primaryEmail: data.email });\n props.onEmailAdded?.();\n } finally {\n setLoading(false);\n }\n };\n\n return (\n <MessageCard\n title={t(\"Add your email address\")}\n fullPage={!!props.fullPage}\n secondaryButtonText={t(\"Sign out\")}\n secondaryAction={async () => {\n await user.signOut();\n }}\n >\n <Typography className=\"mb-4\">\n {t(\"Please add an email address to complete your account setup. We'll send you a verification email.\")}\n </Typography>\n <form\n onSubmit={e => runAsynchronouslyWithAlert(handleSubmit(onSubmit)(e))}\n noValidate\n className='flex flex-col gap-2'\n >\n <Input\n {...register(\"email\")}\n placeholder={t(\"Enter your email\")}\n type=\"email\"\n />\n {errors.email && <FormWarningText text={errors.email.message} />}\n <Button type=\"submit\" loading={loading} className=\"w-full\">\n {t(\"Continue\")}\n </Button>\n </form>\n </MessageCard>\n );\n}\n\nfunction VerifyEmailScreen(props: {\n user: NonNullable<ReturnType<typeof useUser>>,\n email: string,\n fullPage?: boolean,\n}) {\n const { t } = useTranslation();\n const { user, email } = props;\n const [changingEmail, setChangingEmail] = useState(false);\n\n if (changingEmail) {\n return <AddEmailForm fullPage={props.fullPage} onEmailAdded={() => setChangingEmail(false)} />;\n }\n\n return (\n <MessageCard\n title={t(\"Please check your email inbox\")}\n fullPage={!!props.fullPage}\n primaryButtonText={t(\"Resend verification email\")}\n primaryAction={async () => {\n await user.sendVerificationEmail();\n }}\n secondaryButtonText={t(\"Sign out\")}\n secondaryAction={async () => {\n await user.signOut();\n }}\n >\n <Typography>\n {t(\"Please verify your email address \")}\n <span className=\"font-semibold\">{email}</span>\n {\" (\"}\n <button\n type=\"button\"\n className=\"text-primary hover:underline\"\n onClick={() => setChangingEmail(true)}\n >\n {t(\"change\")}\n </button>\n {\"). \"}\n {t(\"Click the button below to resend the verification link.\")}\n </Typography>\n </MessageCard>\n );\n}\n\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"onboarding.js","names":["MessageCard","Typography","Input","FormWarningText","Button"],"sources":["../../src/components-page/onboarding.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { yupResolver } from \"@hookform/resolvers/yup\";\nimport { strictEmailSchema, yupObject } from \"@hexclave/shared/dist/schema-fields\";\nimport { runAsynchronously, runAsynchronouslyWithAlert } from \"@hexclave/shared/dist/utils/promises\";\nimport { Button, Input, Typography } from \"@hexclave/ui\";\nimport { useState } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport * as yup from \"yup\";\nimport { useStackApp, useUser } from \"..\";\nimport { FormWarningText } from \"../components/elements/form-warning\";\nimport { MessageCard } from \"../components/message-cards/message-card\";\nimport { useTranslation } from \"../lib/translations\";\n\nexport function Onboarding(props: {\n fullPage?: boolean,\n}) {\n const { t } = useTranslation();\n const hexclaveApp = useStackApp();\n const user = useUser({ or: \"return-null\", includeRestricted: true });\n const canSignOut = !hexclaveApp.isExternalAuthApp();\n\n // If user is not restricted anymore, redirect to the intended destination\n // redirectToAfterSignIn automatically checks for after_auth_return_to in the URL\n if (user && !user.isRestricted) {\n runAsynchronously(hexclaveApp.redirectToAfterSignIn());\n // TODO: This should return a loading indicator, not just null\n return null;\n }\n\n // If user is anonymous or not logged in, redirect to sign-in\n if (!user || user.isAnonymous) {\n runAsynchronously(hexclaveApp.redirectToSignIn());\n // TODO: This should return a loading indicator, not just null\n return null;\n }\n\n // User is restricted - show appropriate onboarding step based on restricted reason\n const restrictedReason = user.restrictedReason;\n\n if (restrictedReason?.type === \"email_not_verified\") {\n // Check if user has a primary email\n const hasPrimaryEmail = !!user.primaryEmail;\n\n if (!hasPrimaryEmail) {\n // User needs to add an email first\n return <AddEmailForm fullPage={props.fullPage} />;\n }\n\n // User has email but it's not verified\n return <VerifyEmailScreen user={user} email={user.primaryEmail} fullPage={props.fullPage} />;\n }\n\n if (restrictedReason?.type === \"restricted_by_administrator\") {\n return (\n <MessageCard\n title={t(\"Your account has been restricted\")}\n fullPage={!!props.fullPage}\n secondaryButtonText={canSignOut ? t(\"Sign out\") : undefined}\n secondaryAction={canSignOut ? async () => {\n await user.signOut();\n } : undefined}\n >\n {/* The public reason is set by the project's administrators (sign-up rules or manually), so it's the most\n helpful thing we can show; the generic sentence is only a fallback for when they didn't provide one. */}\n <p>{user.restrictedByAdminReason ?? t(\"An administrator has restricted your account. Please reach out to support if you believe this is an error.\")}</p>\n </MessageCard>\n );\n }\n\n // Unknown restricted reason - show generic message\n return (\n <MessageCard\n title={t(\"Complete your account setup\")}\n fullPage={!!props.fullPage}\n secondaryButtonText={canSignOut ? t(\"Sign out\") : undefined}\n secondaryAction={canSignOut ? async () => {\n await user.signOut();\n } : undefined}\n >\n <p>{t(\"You have not yet completed your account setup. Please reach out to support if you believe this is an error.\")}</p>\n </MessageCard>\n );\n}\n\nfunction AddEmailForm(props: {\n fullPage?: boolean,\n onEmailAdded?: () => void,\n}) {\n const { t } = useTranslation();\n const user = useUser({ or: \"throw\", includeRestricted: true });\n const hexclaveApp = useStackApp();\n const canSignOut = !hexclaveApp.isExternalAuthApp();\n const [loading, setLoading] = useState(false);\n\n const emailSchema = yupObject({\n email: strictEmailSchema(t('Please enter a valid email address'))\n .defined()\n .nonEmpty(t('Email is required')),\n });\n\n const { register, handleSubmit, formState: { errors } } = useForm({\n resolver: yupResolver(emailSchema)\n });\n\n const onSubmit = async (data: yup.InferType<typeof emailSchema>) => {\n setLoading(true);\n try {\n await user.update({ primaryEmail: data.email });\n props.onEmailAdded?.();\n } finally {\n setLoading(false);\n }\n };\n\n return (\n <MessageCard\n title={t(\"Add your email address\")}\n fullPage={!!props.fullPage}\n secondaryButtonText={canSignOut ? t(\"Sign out\") : undefined}\n secondaryAction={canSignOut ? async () => {\n await user.signOut();\n } : undefined}\n >\n <Typography className=\"mb-4\">\n {t(\"Please add an email address to complete your account setup. We'll send you a verification email.\")}\n </Typography>\n <form\n onSubmit={e => runAsynchronouslyWithAlert(handleSubmit(onSubmit)(e))}\n noValidate\n className='flex flex-col gap-2'\n >\n <Input\n {...register(\"email\")}\n placeholder={t(\"Enter your email\")}\n type=\"email\"\n />\n {errors.email && <FormWarningText text={errors.email.message} />}\n <Button type=\"submit\" loading={loading} className=\"w-full\">\n {t(\"Continue\")}\n </Button>\n </form>\n </MessageCard>\n );\n}\n\nfunction VerifyEmailScreen(props: {\n user: NonNullable<ReturnType<typeof useUser>>,\n email: string,\n fullPage?: boolean,\n}) {\n const { t } = useTranslation();\n const { user, email } = props;\n const hexclaveApp = useStackApp();\n const canSignOut = !hexclaveApp.isExternalAuthApp();\n const [changingEmail, setChangingEmail] = useState(false);\n\n if (changingEmail) {\n return <AddEmailForm fullPage={props.fullPage} onEmailAdded={() => setChangingEmail(false)} />;\n }\n\n return (\n <MessageCard\n title={t(\"Please check your email inbox\")}\n fullPage={!!props.fullPage}\n primaryButtonText={t(\"Resend verification email\")}\n primaryAction={async () => {\n await user.sendVerificationEmail();\n }}\n secondaryButtonText={canSignOut ? t(\"Sign out\") : undefined}\n secondaryAction={canSignOut ? async () => {\n await user.signOut();\n } : undefined}\n >\n <Typography>\n {t(\"Please verify your email address \")}\n <span className=\"font-semibold\">{email}</span>\n {\" (\"}\n <button\n type=\"button\"\n className=\"text-primary hover:underline\"\n onClick={() => setChangingEmail(true)}\n >\n {t(\"change\")}\n </button>\n {\"). \"}\n {t(\"Click the button below to resend the verification link.\")}\n </Typography>\n </MessageCard>\n );\n}\n"],"mappings":"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"}
|
|
@@ -36,7 +36,8 @@ const previousActEnvironment = Reflect.get(globalThis, "IS_REACT_ACT_ENVIRONMENT
|
|
|
36
36
|
function createAppTestDouble() {
|
|
37
37
|
return {
|
|
38
38
|
redirectToSignIn: vitest.vi.fn(async () => {}),
|
|
39
|
-
redirectToAfterSignIn: vitest.vi.fn(async () => {})
|
|
39
|
+
redirectToAfterSignIn: vitest.vi.fn(async () => {}),
|
|
40
|
+
isExternalAuthApp: vitest.vi.fn(() => false)
|
|
40
41
|
};
|
|
41
42
|
}
|
|
42
43
|
function createUserTestDouble(user) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"onboarding.test.js","names":["vi","TranslationProviderClient","Onboarding"],"sources":["../../src/components-page/onboarding.test.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n// @vitest-environment jsdom\n\nimport React, { act } from \"react\";\nimport { createRoot, type Root } from \"react-dom/client\";\nimport { afterEach, beforeEach, describe, expect, it, vi } from \"vitest\";\nimport type { CurrentUser } from \"../lib/hexclave-app\";\nimport type { StackClientApp } from \"../lib/hexclave-app/apps/interfaces/client-app\";\nimport { TranslationProviderClient } from \"../providers/translation-provider-client\";\nimport { Onboarding } from \"./onboarding\";\n\nconst appMockState = vi.hoisted(() => ({\n app: null as unknown,\n user: null as unknown,\n}));\n\nvi.mock(\"..\", () => ({\n useStackApp: () => {\n if (appMockState.app == null) {\n throw new Error(\"Expected test app to be set before rendering.\");\n }\n return appMockState.app;\n },\n useUser: () => appMockState.user,\n}));\n\nvi.mock(\"@hexclave/ui\", async () => {\n const React = await import(\"react\");\n return {\n Button: (props: { children: React.ReactNode, onClick?: () => void }) => (\n <button type=\"button\" onClick={props.onClick}>{props.children}</button>\n ),\n Input: (props: Record<string, unknown>) => <input {...props} />,\n Typography: (props: { children: React.ReactNode }) => <div>{props.children}</div>,\n cn: (...classes: (string | false | null | undefined)[]) => classes.filter(Boolean).join(\" \"),\n };\n});\n\nconst previousActEnvironment = Reflect.get(globalThis, \"IS_REACT_ACT_ENVIRONMENT\");\n\nfunction createAppTestDouble() {\n const app = {\n redirectToSignIn: vi.fn(async () => {}),\n redirectToAfterSignIn: vi.fn(async () => {}),\n };\n\n // This test double intentionally implements only the StackClientApp surface that Onboarding touches.\n return app as unknown as StackClientApp<true> & {\n redirectToSignIn: ReturnType<typeof vi.fn>,\n redirectToAfterSignIn: ReturnType<typeof vi.fn>,\n };\n}\n\nfunction createUserTestDouble(user: Partial<CurrentUser>) {\n // Same as the app test double: only the surface Onboarding touches.\n return {\n isAnonymous: false,\n isRestricted: true,\n restrictedReason: null,\n restrictedByAdmin: false,\n restrictedByAdminReason: null,\n primaryEmail: \"user@example.com\",\n signOut: vi.fn(async () => {}),\n ...user,\n } as unknown as CurrentUser;\n}\n\nlet root: Root | null = null;\nlet container: HTMLDivElement | null = null;\n\nasync function renderOnboarding(options: {\n app: StackClientApp<true>,\n user: unknown,\n}) {\n appMockState.app = options.app;\n appMockState.user = options.user;\n container = document.createElement(\"div\");\n document.body.append(container);\n root = createRoot(container);\n await act(async () => {\n root?.render(\n <TranslationProviderClient quetzalKeys={new Map()} quetzalLocale={new Map()}>\n <Onboarding />\n </TranslationProviderClient>\n );\n });\n return container;\n}\n\ndescribe(\"Onboarding\", () => {\n beforeEach(() => {\n Reflect.set(globalThis, \"IS_REACT_ACT_ENVIRONMENT\", true);\n });\n\n afterEach(() => {\n act(() => {\n root?.unmount();\n });\n container?.remove();\n root = null;\n container = null;\n appMockState.app = null;\n appMockState.user = null;\n vi.restoreAllMocks();\n Reflect.set(globalThis, \"IS_REACT_ACT_ENVIRONMENT\", previousActEnvironment);\n });\n\n it(\"redirects signed-out users to sign-in\", async () => {\n const app = createAppTestDouble();\n\n const container = await renderOnboarding({ app, user: null });\n\n expect(app.redirectToSignIn).toHaveBeenCalled();\n expect(container.textContent).toBe(\"\");\n });\n\n it(\"redirects anonymous users to sign-in\", async () => {\n const app = createAppTestDouble();\n\n const container = await renderOnboarding({ app, user: createUserTestDouble({ isAnonymous: true, restrictedReason: { type: \"anonymous\" } }) });\n\n expect(app.redirectToSignIn).toHaveBeenCalled();\n expect(container.textContent).toBe(\"\");\n });\n\n it(\"redirects users that are no longer restricted to their destination\", async () => {\n const app = createAppTestDouble();\n\n await renderOnboarding({ app, user: createUserTestDouble({ isRestricted: false }) });\n\n expect(app.redirectToAfterSignIn).toHaveBeenCalled();\n expect(app.redirectToSignIn).not.toHaveBeenCalled();\n });\n\n it(\"shows the administrator's public reason to admin-restricted users\", async () => {\n const app = createAppTestDouble();\n\n const container = await renderOnboarding({\n app,\n user: createUserTestDouble({\n restrictedReason: { type: \"restricted_by_administrator\" },\n restrictedByAdmin: true,\n restrictedByAdminReason: \"Your sign-up was flagged by our fraud prevention rules.\",\n }),\n });\n\n expect(container.textContent).toContain(\"Your account has been restricted\");\n expect(container.textContent).toContain(\"Your sign-up was flagged by our fraud prevention rules.\");\n expect(container.textContent).not.toContain(\"Complete your account setup\");\n });\n\n it(\"falls back to a generic restricted message when no public reason is set\", async () => {\n const app = createAppTestDouble();\n\n const container = await renderOnboarding({\n app,\n user: createUserTestDouble({\n restrictedReason: { type: \"restricted_by_administrator\" },\n restrictedByAdmin: true,\n restrictedByAdminReason: null,\n }),\n });\n\n expect(container.textContent).toContain(\"Your account has been restricted\");\n expect(container.textContent).toContain(\"An administrator has restricted your account.\");\n });\n\n it(\"shows the setup-required message for unknown restricted reasons\", async () => {\n const app = createAppTestDouble();\n\n const container = await renderOnboarding({\n app,\n // The reason types are a closed union, so an unknown reason can only come from a newer backend.\n user: createUserTestDouble({ restrictedReason: { type: \"some_future_reason\" } as unknown as CurrentUser[\"restrictedReason\"] }),\n });\n\n expect(container.textContent).toContain(\"Complete your account setup\");\n });\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"onboarding.test.js","names":["vi","TranslationProviderClient","Onboarding"],"sources":["../../src/components-page/onboarding.test.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n// @vitest-environment jsdom\n\nimport React, { act } from \"react\";\nimport { createRoot, type Root } from \"react-dom/client\";\nimport { afterEach, beforeEach, describe, expect, it, vi } from \"vitest\";\nimport type { CurrentUser } from \"../lib/hexclave-app\";\nimport type { StackClientApp } from \"../lib/hexclave-app/apps/interfaces/client-app\";\nimport { TranslationProviderClient } from \"../providers/translation-provider-client\";\nimport { Onboarding } from \"./onboarding\";\n\nconst appMockState = vi.hoisted(() => ({\n app: null as unknown,\n user: null as unknown,\n}));\n\nvi.mock(\"..\", () => ({\n useStackApp: () => {\n if (appMockState.app == null) {\n throw new Error(\"Expected test app to be set before rendering.\");\n }\n return appMockState.app;\n },\n useUser: () => appMockState.user,\n}));\n\nvi.mock(\"@hexclave/ui\", async () => {\n const React = await import(\"react\");\n return {\n Button: (props: { children: React.ReactNode, onClick?: () => void }) => (\n <button type=\"button\" onClick={props.onClick}>{props.children}</button>\n ),\n Input: (props: Record<string, unknown>) => <input {...props} />,\n Typography: (props: { children: React.ReactNode }) => <div>{props.children}</div>,\n cn: (...classes: (string | false | null | undefined)[]) => classes.filter(Boolean).join(\" \"),\n };\n});\n\nconst previousActEnvironment = Reflect.get(globalThis, \"IS_REACT_ACT_ENVIRONMENT\");\n\nfunction createAppTestDouble() {\n const app = {\n redirectToSignIn: vi.fn(async () => {}),\n redirectToAfterSignIn: vi.fn(async () => {}),\n isExternalAuthApp: vi.fn(() => false),\n };\n\n // This test double intentionally implements only the StackClientApp surface that Onboarding touches.\n return app as unknown as StackClientApp<true> & {\n redirectToSignIn: ReturnType<typeof vi.fn>,\n redirectToAfterSignIn: ReturnType<typeof vi.fn>,\n };\n}\n\nfunction createUserTestDouble(user: Partial<CurrentUser>) {\n // Same as the app test double: only the surface Onboarding touches.\n return {\n isAnonymous: false,\n isRestricted: true,\n restrictedReason: null,\n restrictedByAdmin: false,\n restrictedByAdminReason: null,\n primaryEmail: \"user@example.com\",\n signOut: vi.fn(async () => {}),\n ...user,\n } as unknown as CurrentUser;\n}\n\nlet root: Root | null = null;\nlet container: HTMLDivElement | null = null;\n\nasync function renderOnboarding(options: {\n app: StackClientApp<true>,\n user: unknown,\n}) {\n appMockState.app = options.app;\n appMockState.user = options.user;\n container = document.createElement(\"div\");\n document.body.append(container);\n root = createRoot(container);\n await act(async () => {\n root?.render(\n <TranslationProviderClient quetzalKeys={new Map()} quetzalLocale={new Map()}>\n <Onboarding />\n </TranslationProviderClient>\n );\n });\n return container;\n}\n\ndescribe(\"Onboarding\", () => {\n beforeEach(() => {\n Reflect.set(globalThis, \"IS_REACT_ACT_ENVIRONMENT\", true);\n });\n\n afterEach(() => {\n act(() => {\n root?.unmount();\n });\n container?.remove();\n root = null;\n container = null;\n appMockState.app = null;\n appMockState.user = null;\n vi.restoreAllMocks();\n Reflect.set(globalThis, \"IS_REACT_ACT_ENVIRONMENT\", previousActEnvironment);\n });\n\n it(\"redirects signed-out users to sign-in\", async () => {\n const app = createAppTestDouble();\n\n const container = await renderOnboarding({ app, user: null });\n\n expect(app.redirectToSignIn).toHaveBeenCalled();\n expect(container.textContent).toBe(\"\");\n });\n\n it(\"redirects anonymous users to sign-in\", async () => {\n const app = createAppTestDouble();\n\n const container = await renderOnboarding({ app, user: createUserTestDouble({ isAnonymous: true, restrictedReason: { type: \"anonymous\" } }) });\n\n expect(app.redirectToSignIn).toHaveBeenCalled();\n expect(container.textContent).toBe(\"\");\n });\n\n it(\"redirects users that are no longer restricted to their destination\", async () => {\n const app = createAppTestDouble();\n\n await renderOnboarding({ app, user: createUserTestDouble({ isRestricted: false }) });\n\n expect(app.redirectToAfterSignIn).toHaveBeenCalled();\n expect(app.redirectToSignIn).not.toHaveBeenCalled();\n });\n\n it(\"shows the administrator's public reason to admin-restricted users\", async () => {\n const app = createAppTestDouble();\n\n const container = await renderOnboarding({\n app,\n user: createUserTestDouble({\n restrictedReason: { type: \"restricted_by_administrator\" },\n restrictedByAdmin: true,\n restrictedByAdminReason: \"Your sign-up was flagged by our fraud prevention rules.\",\n }),\n });\n\n expect(container.textContent).toContain(\"Your account has been restricted\");\n expect(container.textContent).toContain(\"Your sign-up was flagged by our fraud prevention rules.\");\n expect(container.textContent).not.toContain(\"Complete your account setup\");\n });\n\n it(\"falls back to a generic restricted message when no public reason is set\", async () => {\n const app = createAppTestDouble();\n\n const container = await renderOnboarding({\n app,\n user: createUserTestDouble({\n restrictedReason: { type: \"restricted_by_administrator\" },\n restrictedByAdmin: true,\n restrictedByAdminReason: null,\n }),\n });\n\n expect(container.textContent).toContain(\"Your account has been restricted\");\n expect(container.textContent).toContain(\"An administrator has restricted your account.\");\n });\n\n it(\"shows the setup-required message for unknown restricted reasons\", async () => {\n const app = createAppTestDouble();\n\n const container = await renderOnboarding({\n app,\n // The reason types are a closed union, so an unknown reason can only come from a newer backend.\n user: createUserTestDouble({ restrictedReason: { type: \"some_future_reason\" } as unknown as CurrentUser[\"restrictedReason\"] }),\n });\n\n expect(container.textContent).toContain(\"Complete your account setup\");\n });\n});\n"],"mappings":"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"}
|
package/dist/dev-tool/index.d.ts
CHANGED
|
@@ -18,9 +18,11 @@ function PredefinedMessageCard({ type, fullPage = false }) {
|
|
|
18
18
|
case "signedIn":
|
|
19
19
|
title = t("You are already signed in");
|
|
20
20
|
primaryAction = () => hexclaveApp.redirectToHome();
|
|
21
|
-
|
|
21
|
+
if (!hexclaveApp.isExternalAuthApp()) {
|
|
22
|
+
secondaryAction = () => hexclaveApp.redirectToSignOut();
|
|
23
|
+
secondaryButton = t("Sign out");
|
|
24
|
+
}
|
|
22
25
|
primaryButton = t("Go home");
|
|
23
|
-
secondaryButton = t("Sign out");
|
|
24
26
|
break;
|
|
25
27
|
case "signedOut":
|
|
26
28
|
title = t("You are not currently signed in.");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"predefined-message-card.js","names":[],"sources":["../../../../src/components/message-cards/predefined-message-card.tsx"],"sourcesContent":["\"use client\";\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { Typography } from \"@hexclave/ui\";\nimport { useStackApp } from \"../..\";\nimport { useTranslation } from \"../../lib/translations\";\nimport { MessageCard } from \"./message-card\";\n\nexport function PredefinedMessageCard({\n type,\n fullPage=false,\n}: {\n type: 'signedIn' | 'signedOut' | 'emailSent' | 'passwordReset' | 'unknownError' | 'signUpDisabled',\n fullPage?: boolean,\n}) {\n const hexclaveApp = useStackApp();\n const { t } = useTranslation();\n\n let title: string;\n let message: string | null = null;\n let primaryButton: string | null = null;\n let secondaryButton: string | null = null;\n let primaryAction: (() => Promise<void> | void) | null = null;\n let secondaryAction: (() => Promise<void> | void) | null = null;\n\n switch (type) {\n case 'signedIn': {\n title = t(\"You are already signed in\");\n primaryAction = () => hexclaveApp.redirectToHome();\n secondaryAction = () => hexclaveApp.redirectToSignOut();\n
|
|
1
|
+
{"version":3,"file":"predefined-message-card.js","names":[],"sources":["../../../../src/components/message-cards/predefined-message-card.tsx"],"sourcesContent":["\"use client\";\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { Typography } from \"@hexclave/ui\";\nimport { useStackApp } from \"../..\";\nimport { useTranslation } from \"../../lib/translations\";\nimport { MessageCard } from \"./message-card\";\n\nexport function PredefinedMessageCard({\n type,\n fullPage=false,\n}: {\n type: 'signedIn' | 'signedOut' | 'emailSent' | 'passwordReset' | 'unknownError' | 'signUpDisabled',\n fullPage?: boolean,\n}) {\n const hexclaveApp = useStackApp();\n const { t } = useTranslation();\n\n let title: string;\n let message: string | null = null;\n let primaryButton: string | null = null;\n let secondaryButton: string | null = null;\n let primaryAction: (() => Promise<void> | void) | null = null;\n let secondaryAction: (() => Promise<void> | void) | null = null;\n\n switch (type) {\n case 'signedIn': {\n title = t(\"You are already signed in\");\n primaryAction = () => hexclaveApp.redirectToHome();\n if (!hexclaveApp.isExternalAuthApp()) {\n secondaryAction = () => hexclaveApp.redirectToSignOut();\n secondaryButton = t(\"Sign out\");\n }\n primaryButton = t(\"Go home\");\n break;\n }\n case 'signedOut': {\n title = t(\"You are not currently signed in.\");\n primaryAction = () => hexclaveApp.redirectToSignIn();\n primaryButton = t(\"Sign in\");\n break;\n }\n case 'signUpDisabled': {\n title = t(\"Sign up for new users is not enabled at the moment.\");\n primaryAction = () => hexclaveApp.redirectToHome();\n secondaryAction = () => hexclaveApp.redirectToSignIn();\n primaryButton = t(\"Go home\");\n secondaryButton = t(\"Sign in\");\n break;\n }\n case 'emailSent': {\n title = t(\"Email sent!\");\n message = t(\"If the user with this e-mail address exists, an e-mail was sent to your inbox. Make sure to check your spam folder.\");\n primaryAction = () => hexclaveApp.redirectToHome();\n primaryButton = t(\"Go home\");\n break;\n }\n case 'passwordReset': {\n title = t(\"Password reset successfully!\");\n message = t(\"Your password has been reset. You can now sign in with your new password.\");\n primaryAction = () => hexclaveApp.redirectToSignIn({ noRedirectBack: true });\n primaryButton = t(\"Sign in\");\n break;\n }\n case 'unknownError': {\n title = t(\"An unknown error occurred\");\n message = t(\"Please try again and if the problem persists, contact support.\");\n primaryAction = () => hexclaveApp.redirectToHome();\n primaryButton = t(\"Go home\");\n break;\n }\n }\n\n return (\n <MessageCard\n title={title}\n fullPage={fullPage}\n primaryButtonText={primaryButton}\n primaryAction={primaryAction}\n secondaryButtonText={secondaryButton || undefined}\n secondaryAction={secondaryAction || undefined}\n >\n {message && <Typography>{message}</Typography>}\n </MessageCard>\n );\n}\n"],"mappings":";;;;;;;AAYA,SAAgB,sBAAsB,EACpC,MACA,WAAS,SAIR;CACD,MAAM,cAAc,YAAY;CAChC,MAAM,EAAE,MAAM,eAAe;CAE7B,IAAI;CACJ,IAAI,UAAyB;CAC7B,IAAI,gBAA+B;CACnC,IAAI,kBAAiC;CACrC,IAAI,gBAAqD;CACzD,IAAI,kBAAuD;CAE3D,QAAQ,MAAR;EACE,KAAK;GACH,QAAQ,EAAE,2BAA2B;GACrC,sBAAsB,YAAY,eAAe;GACjD,IAAI,CAAC,YAAY,kBAAkB,GAAG;IACpC,wBAAwB,YAAY,kBAAkB;IACtD,kBAAkB,EAAE,UAAU;GAChC;GACA,gBAAgB,EAAE,SAAS;GAC3B;EAEF,KAAK;GACH,QAAQ,EAAE,kCAAkC;GAC5C,sBAAsB,YAAY,iBAAiB;GACnD,gBAAgB,EAAE,SAAS;GAC3B;EAEF,KAAK;GACH,QAAQ,EAAE,qDAAqD;GAC/D,sBAAsB,YAAY,eAAe;GACjD,wBAAwB,YAAY,iBAAiB;GACrD,gBAAgB,EAAE,SAAS;GAC3B,kBAAkB,EAAE,SAAS;GAC7B;EAEF,KAAK;GACH,QAAQ,EAAE,aAAa;GACvB,UAAU,EAAE,qHAAqH;GACjI,sBAAsB,YAAY,eAAe;GACjD,gBAAgB,EAAE,SAAS;GAC3B;EAEF,KAAK;GACH,QAAQ,EAAE,8BAA8B;GACxC,UAAU,EAAE,2EAA2E;GACvF,sBAAsB,YAAY,iBAAiB,EAAE,gBAAgB,KAAK,CAAC;GAC3E,gBAAgB,EAAE,SAAS;GAC3B;EAEF,KAAK;GACH,QAAQ,EAAE,2BAA2B;GACrC,UAAU,EAAE,gEAAgE;GAC5E,sBAAsB,YAAY,eAAe;GACjD,gBAAgB,EAAE,SAAS;GAC3B;CAEJ;CAEA,OACE,oBAAC,aAAD;EACS;EACG;EACV,mBAAmB;EACJ;EACf,qBAAqB,mBAAmB,KAAA;EACxC,iBAAiB,mBAAmB,KAAA;YAEnC,WAAW,oBAAC,YAAD,EAAA,UAAa,QAAoB,CAAA;CAClC,CAAA;AAEjB"}
|
|
@@ -51,7 +51,7 @@ function UserButtonInnerInner(props) {
|
|
|
51
51
|
className: "outline-none stack-scope rounded-lg hover:bg-muted/50 transition-colors hover:transition-none p-1.5",
|
|
52
52
|
children: /* @__PURE__ */ jsxs("div", {
|
|
53
53
|
className: "flex gap-2 items-center",
|
|
54
|
-
children: [/* @__PURE__ */ jsx(UserAvatar, { user }), user && props.showUserInfo && /* @__PURE__ */ jsxs("div", {
|
|
54
|
+
children: [/* @__PURE__ */ jsx(UserAvatar, { user }), user != null && props.showUserInfo && /* @__PURE__ */ jsxs("div", {
|
|
55
55
|
className: "flex flex-col justify-center text-left min-w-0",
|
|
56
56
|
children: [/* @__PURE__ */ jsx("div", {
|
|
57
57
|
className: "max-w-40 truncate text-sm font-medium",
|
|
@@ -68,21 +68,21 @@ function UserButtonInnerInner(props) {
|
|
|
68
68
|
/* @__PURE__ */ jsx(DropdownMenuLabel, { children: /* @__PURE__ */ jsxs("div", {
|
|
69
69
|
className: "flex gap-2 items-center",
|
|
70
70
|
children: [/* @__PURE__ */ jsx(UserAvatar, { user }), /* @__PURE__ */ jsxs("div", { children: [
|
|
71
|
-
user && /* @__PURE__ */ jsx(Typography, {
|
|
71
|
+
user != null && /* @__PURE__ */ jsx(Typography, {
|
|
72
72
|
className: "max-w-40 truncate",
|
|
73
73
|
children: user.displayName
|
|
74
74
|
}),
|
|
75
|
-
user && /* @__PURE__ */ jsx(Typography, {
|
|
75
|
+
user != null && /* @__PURE__ */ jsx(Typography, {
|
|
76
76
|
className: "max-w-40 truncate",
|
|
77
77
|
variant: "secondary",
|
|
78
78
|
type: "label",
|
|
79
79
|
children: user.primaryEmail
|
|
80
80
|
}),
|
|
81
|
-
|
|
81
|
+
user == null && /* @__PURE__ */ jsx(Typography, { children: t("Not signed in") })
|
|
82
82
|
] })]
|
|
83
83
|
}) }),
|
|
84
84
|
/* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
|
|
85
|
-
user && /* @__PURE__ */ jsx(Item, {
|
|
85
|
+
user != null && /* @__PURE__ */ jsx(Item, {
|
|
86
86
|
text: t("Account settings"),
|
|
87
87
|
onClick: async () => {
|
|
88
88
|
if (props.mockUser) console.log("Mock account settings - no navigation in demo mode");
|
|
@@ -90,7 +90,7 @@ function UserButtonInnerInner(props) {
|
|
|
90
90
|
},
|
|
91
91
|
icon: /* @__PURE__ */ jsx(CircleUser, { ...iconProps })
|
|
92
92
|
}),
|
|
93
|
-
|
|
93
|
+
user == null && /* @__PURE__ */ jsx(Item, {
|
|
94
94
|
text: t("Sign in"),
|
|
95
95
|
onClick: async () => {
|
|
96
96
|
if (props.mockUser) console.log("Mock sign in - no navigation in demo mode");
|
|
@@ -98,7 +98,7 @@ function UserButtonInnerInner(props) {
|
|
|
98
98
|
},
|
|
99
99
|
icon: /* @__PURE__ */ jsx(LogIn, { ...iconProps })
|
|
100
100
|
}),
|
|
101
|
-
|
|
101
|
+
user == null && /* @__PURE__ */ jsx(Item, {
|
|
102
102
|
text: t("Sign up"),
|
|
103
103
|
onClick: async () => {
|
|
104
104
|
if (props.mockUser) console.log("Mock sign up - no navigation in demo mode");
|
|
@@ -106,13 +106,13 @@ function UserButtonInnerInner(props) {
|
|
|
106
106
|
},
|
|
107
107
|
icon: /* @__PURE__ */ jsx(UserPlus, { ...iconProps })
|
|
108
108
|
}),
|
|
109
|
-
user && props.extraItems && props.extraItems.map((item, index) => /* @__PURE__ */ jsx(Item, { ...item }, index)),
|
|
109
|
+
user != null && props.extraItems && props.extraItems.map((item, index) => /* @__PURE__ */ jsx(Item, { ...item }, index)),
|
|
110
110
|
props.colorModeToggle && /* @__PURE__ */ jsx(Item, {
|
|
111
111
|
text: t("Toggle theme"),
|
|
112
112
|
onClick: props.colorModeToggle,
|
|
113
113
|
icon: /* @__PURE__ */ jsx(SunMoon, { ...iconProps })
|
|
114
114
|
}),
|
|
115
|
-
user && /* @__PURE__ */ jsx(Item, {
|
|
115
|
+
user != null && !app.isExternalAuthApp() && /* @__PURE__ */ jsx(Item, {
|
|
116
116
|
text: t("Sign out"),
|
|
117
117
|
onClick: async () => {
|
|
118
118
|
if (props.mockUser) console.log("Mock sign out - no action taken in demo mode");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-button.js","names":[],"sources":["../../../src/components/user-button.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { runAsynchronouslyWithAlert } from \"@hexclave/shared/dist/utils/promises\";\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, Skeleton, Typography } from \"@hexclave/ui\";\nimport { CircleUser, LogIn, LogOut, SunMoon, UserPlus } from \"lucide-react\";\nimport React, { Suspense } from \"react\";\nimport { CurrentUser, useStackApp, useUser } from \"..\";\nimport { useTranslation } from \"../lib/translations\";\nimport { UserAvatar } from \"./elements/user-avatar\";\n\nfunction Item(props: { text: string, icon: React.ReactNode, onClick: () => void | Promise<void> }) {\n return (\n <DropdownMenuItem onClick={() => runAsynchronouslyWithAlert(props.onClick)}>\n <div className=\"flex gap-2 items-center\">\n {props.icon}\n <Typography>{props.text}</Typography>\n </div>\n </DropdownMenuItem>\n );\n}\n\ntype UserButtonProps = {\n showUserInfo?: boolean,\n colorModeToggle?: () => void | Promise<void>,\n extraItems?: {\n text: string,\n icon: React.ReactNode,\n onClick: () => void | Promise<void>,\n }[],\n mockUser?: {\n displayName?: string,\n primaryEmail?: string,\n profileImageUrl?: string,\n },\n};\n\nexport function UserButton(props: UserButtonProps) {\n return (\n <Suspense fallback={<Skeleton className=\"h-[34px] w-[34px] rounded-full stack-scope\" />}>\n <UserButtonInner {...props} />\n </Suspense>\n );\n}\n\nfunction UserButtonInner(props: UserButtonProps) {\n const userFromHook = useUser();\n\n // Use mock user if provided, otherwise use real user\n const user = props.mockUser ? {\n displayName: props.mockUser.displayName || 'Mock User',\n primaryEmail: props.mockUser.primaryEmail || 'mock@example.com',\n profileImageUrl: props.mockUser.profileImageUrl,\n signOut: () => {\n console.log('Mock sign out - no action taken in demo mode');\n return Promise.resolve();\n }\n } as CurrentUser : userFromHook;\n\n return <UserButtonInnerInner {...props} user={user} />;\n}\n\n\nfunction UserButtonInnerInner(props: UserButtonProps & { user: CurrentUser | null }) {\n const { t } = useTranslation();\n const user = props.user;\n const app = useStackApp();\n\n const iconProps = { size: 20, className: 'h-4 w-4' };\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger className=\"outline-none stack-scope rounded-lg hover:bg-muted/50 transition-colors hover:transition-none p-1.5\">\n <div className=\"flex gap-2 items-center\">\n <UserAvatar user={user} />\n {user && props.showUserInfo &&\n <div className=\"flex flex-col justify-center text-left min-w-0\">\n <div className=\"max-w-40 truncate text-sm font-medium\">{user.displayName}</div>\n <div className=\"max-w-40 truncate text-xs text-muted-foreground\">{user.primaryEmail}</div>\n </div>\n }\n </div>\n </DropdownMenuTrigger>\n <DropdownMenuContent className=\"stack-scope\">\n <DropdownMenuLabel>\n <div className=\"flex gap-2 items-center\">\n <UserAvatar user={user} />\n <div>\n {user && <Typography className=\"max-w-40 truncate\">{user.displayName}</Typography>}\n {user && <Typography className=\"max-w-40 truncate\" variant=\"secondary\" type='label'>{user.primaryEmail}</Typography>}\n {
|
|
1
|
+
{"version":3,"file":"user-button.js","names":[],"sources":["../../../src/components/user-button.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { runAsynchronouslyWithAlert } from \"@hexclave/shared/dist/utils/promises\";\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, Skeleton, Typography } from \"@hexclave/ui\";\nimport { CircleUser, LogIn, LogOut, SunMoon, UserPlus } from \"lucide-react\";\nimport React, { Suspense } from \"react\";\nimport { CurrentUser, useStackApp, useUser } from \"..\";\nimport { useTranslation } from \"../lib/translations\";\nimport { UserAvatar } from \"./elements/user-avatar\";\n\nfunction Item(props: { text: string, icon: React.ReactNode, onClick: () => void | Promise<void> }) {\n return (\n <DropdownMenuItem onClick={() => runAsynchronouslyWithAlert(props.onClick)}>\n <div className=\"flex gap-2 items-center\">\n {props.icon}\n <Typography>{props.text}</Typography>\n </div>\n </DropdownMenuItem>\n );\n}\n\ntype UserButtonProps = {\n showUserInfo?: boolean,\n colorModeToggle?: () => void | Promise<void>,\n extraItems?: {\n text: string,\n icon: React.ReactNode,\n onClick: () => void | Promise<void>,\n }[],\n mockUser?: {\n displayName?: string,\n primaryEmail?: string,\n profileImageUrl?: string,\n },\n};\n\nexport function UserButton(props: UserButtonProps) {\n return (\n <Suspense fallback={<Skeleton className=\"h-[34px] w-[34px] rounded-full stack-scope\" />}>\n <UserButtonInner {...props} />\n </Suspense>\n );\n}\n\nfunction UserButtonInner(props: UserButtonProps) {\n const userFromHook = useUser();\n\n // Use mock user if provided, otherwise use real user\n const user = props.mockUser ? {\n displayName: props.mockUser.displayName || 'Mock User',\n primaryEmail: props.mockUser.primaryEmail || 'mock@example.com',\n profileImageUrl: props.mockUser.profileImageUrl,\n signOut: () => {\n console.log('Mock sign out - no action taken in demo mode');\n return Promise.resolve();\n }\n } as CurrentUser : userFromHook;\n\n return <UserButtonInnerInner {...props} user={user} />;\n}\n\n\nfunction UserButtonInnerInner(props: UserButtonProps & { user: CurrentUser | null }) {\n const { t } = useTranslation();\n const user = props.user;\n const app = useStackApp();\n\n const iconProps = { size: 20, className: 'h-4 w-4' };\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger className=\"outline-none stack-scope rounded-lg hover:bg-muted/50 transition-colors hover:transition-none p-1.5\">\n <div className=\"flex gap-2 items-center\">\n <UserAvatar user={user} />\n {user != null && props.showUserInfo &&\n <div className=\"flex flex-col justify-center text-left min-w-0\">\n <div className=\"max-w-40 truncate text-sm font-medium\">{user.displayName}</div>\n <div className=\"max-w-40 truncate text-xs text-muted-foreground\">{user.primaryEmail}</div>\n </div>\n }\n </div>\n </DropdownMenuTrigger>\n <DropdownMenuContent className=\"stack-scope\">\n <DropdownMenuLabel>\n <div className=\"flex gap-2 items-center\">\n <UserAvatar user={user} />\n <div>\n {user != null && <Typography className=\"max-w-40 truncate\">{user.displayName}</Typography>}\n {user != null && <Typography className=\"max-w-40 truncate\" variant=\"secondary\" type='label'>{user.primaryEmail}</Typography>}\n {user == null && <Typography>{t('Not signed in')}</Typography>}\n </div>\n </div>\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n {user != null && <Item\n text={t('Account settings')}\n onClick={async () => {\n if (props.mockUser) {\n console.log('Mock account settings - no navigation in demo mode');\n } else {\n await app.redirectToAccountSettings();\n }\n }}\n icon={<CircleUser {...iconProps} />}\n />}\n {user == null && <Item\n text={t('Sign in')}\n onClick={async () => {\n if (props.mockUser) {\n console.log('Mock sign in - no navigation in demo mode');\n } else {\n await app.redirectToSignIn();\n }\n }}\n icon={<LogIn {...iconProps} />}\n />}\n {user == null && <Item\n text={t('Sign up')}\n onClick={async () => {\n if (props.mockUser) {\n console.log('Mock sign up - no navigation in demo mode');\n } else {\n await app.redirectToSignUp();\n }\n }}\n icon={<UserPlus {...iconProps}/> }\n />}\n {user != null && props.extraItems && props.extraItems.map((item, index) => (\n <Item key={index} {...item} />\n ))}\n {props.colorModeToggle && (\n <Item\n text={t('Toggle theme')}\n onClick={props.colorModeToggle}\n icon={<SunMoon {...iconProps} />}\n />\n )}\n {user != null && !app.isExternalAuthApp() && <Item\n text={t('Sign out')}\n onClick={async () => {\n if (props.mockUser) {\n console.log('Mock sign out - no action taken in demo mode');\n } else {\n await user.signOut();\n }\n }}\n icon={<LogOut {...iconProps} />}\n />}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|