@stackframe/stack 2.6.15 → 2.6.17
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/CHANGELOG.md +21 -0
- package/README.md +18 -21
- package/dist/components/message-cards/predefined-message-card.d.mts +1 -1
- package/dist/components/message-cards/predefined-message-card.d.ts +1 -1
- package/dist/components/message-cards/predefined-message-card.js +0 -13
- package/dist/components/message-cards/predefined-message-card.js.map +1 -1
- package/dist/components/selected-team-switcher.js +6 -0
- package/dist/components/selected-team-switcher.js.map +1 -1
- package/dist/components/user-button.js +1 -7
- package/dist/components/user-button.js.map +1 -1
- package/dist/components-page/account-settings.js +6 -6
- package/dist/components-page/account-settings.js.map +1 -1
- package/dist/components-page/auth-page.d.mts +3 -2
- package/dist/components-page/auth-page.d.ts +3 -2
- package/dist/components-page/auth-page.js +15 -1
- package/dist/components-page/auth-page.js.map +1 -1
- package/dist/components-page/email-verification.js +41 -15
- package/dist/components-page/email-verification.js.map +1 -1
- package/dist/components-page/magic-link-callback.d.mts +1 -1
- package/dist/components-page/magic-link-callback.d.ts +1 -1
- package/dist/components-page/magic-link-callback.js +41 -12
- package/dist/components-page/magic-link-callback.js.map +1 -1
- package/dist/esm/components/message-cards/predefined-message-card.js +1 -14
- package/dist/esm/components/message-cards/predefined-message-card.js.map +1 -1
- package/dist/esm/components/selected-team-switcher.js +8 -1
- package/dist/esm/components/selected-team-switcher.js.map +1 -1
- package/dist/esm/components/user-button.js +1 -7
- package/dist/esm/components/user-button.js.map +1 -1
- package/dist/esm/components-page/account-settings.js +6 -6
- package/dist/esm/components-page/account-settings.js.map +1 -1
- package/dist/esm/components-page/auth-page.js +17 -3
- package/dist/esm/components-page/auth-page.js.map +1 -1
- package/dist/esm/components-page/email-verification.js +42 -16
- package/dist/esm/components-page/email-verification.js.map +1 -1
- package/dist/esm/components-page/magic-link-callback.js +41 -12
- package/dist/esm/components-page/magic-link-callback.js.map +1 -1
- package/dist/esm/generated/global-css.js +1 -1
- package/dist/esm/generated/global-css.js.map +1 -1
- package/dist/esm/generated/quetzal-translations.js +1949 -1913
- package/dist/esm/generated/quetzal-translations.js.map +1 -1
- package/dist/esm/lib/stack-app.js +15 -13
- package/dist/esm/lib/stack-app.js.map +1 -1
- package/dist/generated/global-css.d.mts +1 -1
- package/dist/generated/global-css.d.ts +1 -1
- package/dist/generated/global-css.js +1 -1
- package/dist/generated/global-css.js.map +1 -1
- package/dist/generated/quetzal-translations.d.mts +2 -2
- package/dist/generated/quetzal-translations.d.ts +2 -2
- package/dist/generated/quetzal-translations.js +1949 -1913
- package/dist/generated/quetzal-translations.js.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/lib/stack-app.d.mts +22 -4
- package/dist/lib/stack-app.d.ts +22 -4
- package/dist/lib/stack-app.js +15 -13
- package/dist/lib/stack-app.js.map +1 -1
- package/package.json +4 -4
|
@@ -40,9 +40,9 @@ var import__ = require("..");
|
|
|
40
40
|
var import_message_card = require("../components/message-cards/message-card");
|
|
41
41
|
var import_predefined_message_card = require("../components/message-cards/predefined-message-card");
|
|
42
42
|
var import_stack_shared = require("@stackframe/stack-shared");
|
|
43
|
-
var import_promises = require("@stackframe/stack-shared/dist/utils/promises");
|
|
44
43
|
var import_caches = require("@stackframe/stack-shared/dist/utils/caches");
|
|
45
44
|
var import_translations = require("../lib/translations");
|
|
45
|
+
var import_errors = require("@stackframe/stack-shared/dist/utils/errors");
|
|
46
46
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
47
47
|
var cacheSignInWithMagicLink = (0, import_caches.cacheFunction)(async (stackApp, code) => {
|
|
48
48
|
return await stackApp.signInWithMagicLink(code);
|
|
@@ -51,6 +51,7 @@ function MagicLinkCallback(props) {
|
|
|
51
51
|
const { t } = (0, import_translations.useTranslation)();
|
|
52
52
|
const stackApp = (0, import__.useStackApp)();
|
|
53
53
|
const user = (0, import__.useUser)();
|
|
54
|
+
const [result, setResult] = import_react.default.useState(null);
|
|
54
55
|
if (user) {
|
|
55
56
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_predefined_message_card.PredefinedMessageCard, { type: "signedIn", fullPage: !!props.fullPage });
|
|
56
57
|
}
|
|
@@ -60,19 +61,47 @@ function MagicLinkCallback(props) {
|
|
|
60
61
|
if (!props.searchParams?.code) {
|
|
61
62
|
return invalidJsx;
|
|
62
63
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
64
|
+
if (!result) {
|
|
65
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
66
|
+
import_message_card.MessageCard,
|
|
67
|
+
{
|
|
68
|
+
title: t("Do you want to sign in?"),
|
|
69
|
+
fullPage: !!props.fullPage,
|
|
70
|
+
primaryButtonText: t("Sign in"),
|
|
71
|
+
primaryAction: async () => {
|
|
72
|
+
const result2 = await stackApp.signInWithMagicLink(props.searchParams?.code || (0, import_errors.throwErr)("No magic link provided"));
|
|
73
|
+
setResult(result2);
|
|
74
|
+
},
|
|
75
|
+
secondaryButtonText: t("Cancel"),
|
|
76
|
+
secondaryAction: async () => {
|
|
77
|
+
await stackApp.redirectToHome();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
);
|
|
81
|
+
} else {
|
|
82
|
+
if (result.status === "error") {
|
|
83
|
+
if (result.error instanceof import_stack_shared.KnownErrors.VerificationCodeNotFound) {
|
|
84
|
+
return invalidJsx;
|
|
85
|
+
} else if (result.error instanceof import_stack_shared.KnownErrors.VerificationCodeExpired) {
|
|
86
|
+
return expiredJsx;
|
|
87
|
+
} else if (result.error instanceof import_stack_shared.KnownErrors.VerificationCodeAlreadyUsed) {
|
|
88
|
+
return alreadyUsedJsx;
|
|
89
|
+
} else {
|
|
90
|
+
throw result.error;
|
|
91
|
+
}
|
|
73
92
|
}
|
|
93
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
94
|
+
import_message_card.MessageCard,
|
|
95
|
+
{
|
|
96
|
+
title: t("Signed in successfully!"),
|
|
97
|
+
fullPage: !!props.fullPage,
|
|
98
|
+
primaryButtonText: t("Go to home"),
|
|
99
|
+
primaryAction: async () => {
|
|
100
|
+
await stackApp.redirectToHome();
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
);
|
|
74
104
|
}
|
|
75
|
-
import_react.default.use((0, import_promises.neverResolve)());
|
|
76
105
|
}
|
|
77
106
|
// Annotate the CommonJS export names for ESM import in node:
|
|
78
107
|
0 && (module.exports = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components-page/magic-link-callback.tsx"],"sourcesContent":["'use client';\n\nimport React from \"react\";\nimport { StackClientApp, useStackApp, useUser } from \"..\";\nimport { MessageCard } from \"../components/message-cards/message-card\";\nimport { PredefinedMessageCard } from \"../components/message-cards/predefined-message-card\";\nimport { KnownErrors } from \"@stackframe/stack-shared\";\nimport { neverResolve } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { cacheFunction } from \"@stackframe/stack-shared/dist/utils/caches\";\nimport { useTranslation } from \"../lib/translations\";\n\nconst cacheSignInWithMagicLink = cacheFunction(async (stackApp: StackClientApp<true>, code: string) => {\n return await stackApp.signInWithMagicLink(code);\n});\n\nexport function MagicLinkCallback(props: {\n searchParams?: Record<string, string>,\n fullPage?: boolean,\n}) {\n const { t } = useTranslation();\n const stackApp = useStackApp();\n const user = useUser();\n\n if (user) {\n return <PredefinedMessageCard type='signedIn' fullPage={!!props.fullPage} />;\n }\n\n const invalidJsx = (\n <MessageCard title={t(\"Invalid Magic Link\")} fullPage={!!props.fullPage}>\n <p>{t(\"Please check if you have the correct link. If you continue to have issues, please contact support.\")}</p>\n </MessageCard>\n );\n\n const expiredJsx = (\n <MessageCard title={t(\"Expired Magic Link\")} fullPage={!!props.fullPage}>\n <p>{t(\"Your magic link has expired. Please request a new magic link if you need to sign-in.\")}</p>\n </MessageCard>\n );\n\n const alreadyUsedJsx = (\n <MessageCard title={t(\"Magic Link Already Used\")} fullPage={!!props.fullPage}>\n <p>{t(\"The magic link has already been used. The link can only be used once. Please request a new magic link if you need to sign-in again.\")}</p>\n </MessageCard>\n );\n\n if (!props.searchParams?.code) {\n return invalidJsx;\n }\n\n
|
|
1
|
+
{"version":3,"sources":["../../src/components-page/magic-link-callback.tsx"],"sourcesContent":["'use client';\n\nimport React from \"react\";\nimport { StackClientApp, useStackApp, useUser } from \"..\";\nimport { MessageCard } from \"../components/message-cards/message-card\";\nimport { PredefinedMessageCard } from \"../components/message-cards/predefined-message-card\";\nimport { KnownErrors } from \"@stackframe/stack-shared\";\nimport { neverResolve } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { cacheFunction } from \"@stackframe/stack-shared/dist/utils/caches\";\nimport { useTranslation } from \"../lib/translations\";\nimport { throwErr } from \"@stackframe/stack-shared/dist/utils/errors\";\n\nconst cacheSignInWithMagicLink = cacheFunction(async (stackApp: StackClientApp<true>, code: string) => {\n return await stackApp.signInWithMagicLink(code);\n});\n\nexport function MagicLinkCallback(props: {\n searchParams?: Record<string, string>,\n fullPage?: boolean,\n}) {\n const { t } = useTranslation();\n const stackApp = useStackApp();\n const user = useUser();\n const [result, setResult] = React.useState<Awaited<ReturnType<typeof stackApp.signInWithMagicLink>> | null>(null);\n\n if (user) {\n return <PredefinedMessageCard type='signedIn' fullPage={!!props.fullPage} />;\n }\n\n const invalidJsx = (\n <MessageCard title={t(\"Invalid Magic Link\")} fullPage={!!props.fullPage}>\n <p>{t(\"Please check if you have the correct link. If you continue to have issues, please contact support.\")}</p>\n </MessageCard>\n );\n\n const expiredJsx = (\n <MessageCard title={t(\"Expired Magic Link\")} fullPage={!!props.fullPage}>\n <p>{t(\"Your magic link has expired. Please request a new magic link if you need to sign-in.\")}</p>\n </MessageCard>\n );\n\n const alreadyUsedJsx = (\n <MessageCard title={t(\"Magic Link Already Used\")} fullPage={!!props.fullPage}>\n <p>{t(\"The magic link has already been used. The link can only be used once. Please request a new magic link if you need to sign-in again.\")}</p>\n </MessageCard>\n );\n\n if (!props.searchParams?.code) {\n return invalidJsx;\n }\n\n if (!result) {\n return <MessageCard\n title={t(\"Do you want to sign in?\")}\n fullPage={!!props.fullPage}\n primaryButtonText={t(\"Sign in\")}\n primaryAction={async () => {\n const result = await stackApp.signInWithMagicLink(props.searchParams?.code || throwErr(\"No magic link provided\"));\n setResult(result);\n }}\n secondaryButtonText={t(\"Cancel\")}\n secondaryAction={async () => {\n await stackApp.redirectToHome();\n }}\n />;\n } else {\n if (result.status === 'error') {\n if (result.error instanceof KnownErrors.VerificationCodeNotFound) {\n return invalidJsx;\n } else if (result.error instanceof KnownErrors.VerificationCodeExpired) {\n return expiredJsx;\n } else if (result.error instanceof KnownErrors.VerificationCodeAlreadyUsed) {\n return alreadyUsedJsx;\n } else {\n throw result.error;\n }\n }\n\n return <MessageCard\n title={t(\"Signed in successfully!\")}\n fullPage={!!props.fullPage}\n primaryButtonText={t(\"Go to home\")}\n primaryAction={async () => {\n await stackApp.redirectToHome();\n }}\n />;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,mBAAkB;AAClB,eAAqD;AACrD,0BAA4B;AAC5B,qCAAsC;AACtC,0BAA4B;AAE5B,oBAA8B;AAC9B,0BAA+B;AAC/B,oBAAyB;AAgBd;AAdX,IAAM,+BAA2B,6BAAc,OAAO,UAAgC,SAAiB;AACrG,SAAO,MAAM,SAAS,oBAAoB,IAAI;AAChD,CAAC;AAEM,SAAS,kBAAkB,OAG/B;AACD,QAAM,EAAE,EAAE,QAAI,oCAAe;AAC7B,QAAM,eAAW,sBAAY;AAC7B,QAAM,WAAO,kBAAQ;AACrB,QAAM,CAAC,QAAQ,SAAS,IAAI,aAAAA,QAAM,SAA0E,IAAI;AAEhH,MAAI,MAAM;AACR,WAAO,4CAAC,wDAAsB,MAAK,YAAW,UAAU,CAAC,CAAC,MAAM,UAAU;AAAA,EAC5E;AAEA,QAAM,aACJ,4CAAC,mCAAY,OAAO,EAAE,oBAAoB,GAAG,UAAU,CAAC,CAAC,MAAM,UAC7D,sDAAC,OAAG,YAAE,oGAAoG,GAAE,GAC9G;AAGF,QAAM,aACJ,4CAAC,mCAAY,OAAO,EAAE,oBAAoB,GAAG,UAAU,CAAC,CAAC,MAAM,UAC7D,sDAAC,OAAG,YAAE,sFAAsF,GAAE,GAChG;AAGF,QAAM,iBACJ,4CAAC,mCAAY,OAAO,EAAE,yBAAyB,GAAG,UAAU,CAAC,CAAC,MAAM,UAClE,sDAAC,OAAG,YAAE,qIAAqI,GAAE,GAC/I;AAGF,MAAI,CAAC,MAAM,cAAc,MAAM;AAC7B,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,MAAC;AAAA;AAAA,QACN,OAAO,EAAE,yBAAyB;AAAA,QAClC,UAAU,CAAC,CAAC,MAAM;AAAA,QAClB,mBAAmB,EAAE,SAAS;AAAA,QAC9B,eAAe,YAAY;AACzB,gBAAMC,UAAS,MAAM,SAAS,oBAAoB,MAAM,cAAc,YAAQ,wBAAS,wBAAwB,CAAC;AAChH,oBAAUA,OAAM;AAAA,QAClB;AAAA,QACA,qBAAqB,EAAE,QAAQ;AAAA,QAC/B,iBAAiB,YAAY;AAC3B,gBAAM,SAAS,eAAe;AAAA,QAChC;AAAA;AAAA,IACF;AAAA,EACF,OAAO;AACL,QAAI,OAAO,WAAW,SAAS;AAC7B,UAAI,OAAO,iBAAiB,gCAAY,0BAA0B;AAChE,eAAO;AAAA,MACT,WAAW,OAAO,iBAAiB,gCAAY,yBAAyB;AACtE,eAAO;AAAA,MACT,WAAW,OAAO,iBAAiB,gCAAY,6BAA6B;AAC1E,eAAO;AAAA,MACT,OAAO;AACL,cAAM,OAAO;AAAA,MACf;AAAA,IACF;AAEA,WAAO;AAAA,MAAC;AAAA;AAAA,QACN,OAAO,EAAE,yBAAyB;AAAA,QAClC,UAAU,CAAC,CAAC,MAAM;AAAA,QAClB,mBAAmB,EAAE,YAAY;AAAA,QACjC,eAAe,YAAY;AACzB,gBAAM,SAAS,eAAe;AAAA,QAChC;AAAA;AAAA,IACF;AAAA,EACF;AACF;","names":["React","result"]}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
// src/components/message-cards/predefined-message-card.tsx
|
|
5
5
|
import { Typography } from "@stackframe/stack-ui";
|
|
6
|
-
import { useStackApp
|
|
6
|
+
import { useStackApp } from "../..";
|
|
7
7
|
import { MessageCard } from "./message-card";
|
|
8
8
|
import { useTranslation } from "../../lib/translations";
|
|
9
9
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -12,7 +12,6 @@ function PredefinedMessageCard({
|
|
|
12
12
|
fullPage = false
|
|
13
13
|
}) {
|
|
14
14
|
const stackApp = useStackApp();
|
|
15
|
-
const user = useUser();
|
|
16
15
|
const { t } = useTranslation();
|
|
17
16
|
let title;
|
|
18
17
|
let message = null;
|
|
@@ -57,18 +56,6 @@ function PredefinedMessageCard({
|
|
|
57
56
|
primaryButton = t("Sign in");
|
|
58
57
|
break;
|
|
59
58
|
}
|
|
60
|
-
case "emailVerified": {
|
|
61
|
-
title = t("Email verified!");
|
|
62
|
-
message = t("Your have successfully verified your email.");
|
|
63
|
-
if (user) {
|
|
64
|
-
primaryAction = () => stackApp.redirectToSignIn({ noRedirectBack: true });
|
|
65
|
-
primaryButton = t("Sign in");
|
|
66
|
-
} else {
|
|
67
|
-
primaryAction = () => stackApp.redirectToHome();
|
|
68
|
-
primaryButton = t("Go to home");
|
|
69
|
-
}
|
|
70
|
-
break;
|
|
71
|
-
}
|
|
72
59
|
case "unknownError": {
|
|
73
60
|
title = t("An unknown error occurred");
|
|
74
61
|
message = t("Please try again and if the problem persists, contact support.");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/components/message-cards/predefined-message-card.tsx"],"sourcesContent":["\"use client\";\n\nimport { Typography } from \"@stackframe/stack-ui\";\nimport { useStackApp, useUser } from \"../..\";\nimport { MessageCard } from \"./message-card\";\nimport { useTranslation } from \"../../lib/translations\";\n\nexport function PredefinedMessageCard({\n type,\n fullPage=false,\n}: {\n type: 'signedIn' | 'signedOut' | 'emailSent' | 'passwordReset' | '
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/message-cards/predefined-message-card.tsx"],"sourcesContent":["\"use client\";\n\nimport { Typography } from \"@stackframe/stack-ui\";\nimport { useStackApp, useUser } from \"../..\";\nimport { MessageCard } from \"./message-card\";\nimport { useTranslation } from \"../../lib/translations\";\n\nexport function PredefinedMessageCard({\n type,\n fullPage=false,\n}: {\n type: 'signedIn' | 'signedOut' | 'emailSent' | 'passwordReset' | 'unknownError' | 'signUpDisabled',\n fullPage?: boolean,\n}) {\n const stackApp = 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 = () => stackApp.redirectToHome();\n secondaryAction = () => stackApp.redirectToSignOut();\n primaryButton = t(\"Go to home\");\n secondaryButton = t(\"Sign out\");\n break;\n }\n case 'signedOut': {\n title = t(\"You are not currently signed in.\");\n primaryAction = () => stackApp.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 = () => stackApp.redirectToHome();\n secondaryAction = () => stackApp.redirectToSignIn();\n primaryButton = t(\"Go to 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 = () => stackApp.redirectToHome();\n primaryButton = t(\"Go to 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 = () => stackApp.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 = () => stackApp.redirectToHome();\n primaryButton = t(\"Go to 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":";;;AAEA,SAAS,kBAAkB;AAC3B,SAAS,mBAA4B;AACrC,SAAS,mBAAmB;AAC5B,SAAS,sBAAsB;AA0Eb;AAxEX,SAAS,sBAAsB;AAAA,EACpC;AAAA,EACA,WAAS;AACX,GAGG;AACD,QAAM,WAAW,YAAY;AAC7B,QAAM,EAAE,EAAE,IAAI,eAAe;AAE7B,MAAI;AACJ,MAAI,UAAyB;AAC7B,MAAI,gBAA+B;AACnC,MAAI,kBAAiC;AACrC,MAAI,gBAAqD;AACzD,MAAI,kBAAuD;AAE3D,UAAQ,MAAM;AAAA,IACZ,KAAK,YAAY;AACf,cAAQ,EAAE,2BAA2B;AACrC,sBAAgB,MAAM,SAAS,eAAe;AAC9C,wBAAkB,MAAM,SAAS,kBAAkB;AACnD,sBAAgB,EAAE,YAAY;AAC9B,wBAAkB,EAAE,UAAU;AAC9B;AAAA,IACF;AAAA,IACA,KAAK,aAAa;AAChB,cAAQ,EAAE,kCAAkC;AAC5C,sBAAgB,MAAM,SAAS,iBAAiB;AAChD,sBAAgB,EAAE,SAAS;AAC3B;AAAA,IACF;AAAA,IACA,KAAK,kBAAkB;AACrB,cAAQ,EAAE,qDAAqD;AAC/D,sBAAgB,MAAM,SAAS,eAAe;AAC9C,wBAAkB,MAAM,SAAS,iBAAiB;AAClD,sBAAgB,EAAE,YAAY;AAC9B,wBAAkB,EAAE,SAAS;AAC7B;AAAA,IACF;AAAA,IACA,KAAK,aAAa;AAChB,cAAQ,EAAE,aAAa;AACvB,gBAAU,EAAE,qHAAqH;AACjI,sBAAgB,MAAM,SAAS,eAAe;AAC9C,sBAAgB,EAAE,YAAY;AAC9B;AAAA,IACF;AAAA,IACA,KAAK,iBAAiB;AACpB,cAAQ,EAAE,8BAA8B;AACxC,gBAAU,EAAE,2EAA2E;AACvF,sBAAgB,MAAM,SAAS,iBAAiB,EAAE,gBAAgB,KAAK,CAAC;AACxE,sBAAgB,EAAE,SAAS;AAC3B;AAAA,IACF;AAAA,IACA,KAAK,gBAAgB;AACnB,cAAQ,EAAE,2BAA2B;AACrC,gBAAU,EAAE,gEAAgE;AAC5E,sBAAgB,MAAM,SAAS,eAAe;AAC9C,sBAAgB,EAAE,YAAY;AAC9B;AAAA,IACF;AAAA,EACF;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,mBAAmB;AAAA,MACnB;AAAA,MACA,qBAAqB,mBAAmB;AAAA,MACxC,iBAAiB,mBAAmB;AAAA,MAEnC,qBAAW,oBAAC,cAAY,mBAAQ;AAAA;AAAA,EACnC;AAEJ;","names":[]}
|
|
@@ -13,16 +13,23 @@ import {
|
|
|
13
13
|
SelectSeparator,
|
|
14
14
|
SelectTrigger,
|
|
15
15
|
SelectValue,
|
|
16
|
+
Skeleton,
|
|
16
17
|
Typography
|
|
17
18
|
} from "@stackframe/stack-ui";
|
|
18
19
|
import { PlusCircle, Settings } from "lucide-react";
|
|
19
20
|
import { useRouter } from "next/navigation";
|
|
20
|
-
import { useEffect, useMemo } from "react";
|
|
21
|
+
import { Suspense, useEffect, useMemo } from "react";
|
|
21
22
|
import { useStackApp, useUser } from "..";
|
|
22
23
|
import { useTranslation } from "../lib/translations";
|
|
23
24
|
import { TeamIcon } from "./team-icon";
|
|
24
25
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
25
26
|
function SelectedTeamSwitcher(props) {
|
|
27
|
+
return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(Fallback, {}), children: /* @__PURE__ */ jsx(Inner, { ...props }) });
|
|
28
|
+
}
|
|
29
|
+
function Fallback() {
|
|
30
|
+
return /* @__PURE__ */ jsx(Skeleton, { className: "h-9 w-full max-w-64 stack-scope" });
|
|
31
|
+
}
|
|
32
|
+
function Inner(props) {
|
|
26
33
|
const { t } = useTranslation();
|
|
27
34
|
const app = useStackApp();
|
|
28
35
|
const user = useUser();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/selected-team-switcher.tsx"],"sourcesContent":["'use client';\nimport { runAsynchronouslyWithAlert } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport {\n Button,\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectSeparator,\n SelectTrigger,\n SelectValue,\n Typography\n} from \"@stackframe/stack-ui\";\nimport { PlusCircle, Settings } from \"lucide-react\";\nimport { useRouter } from \"next/navigation\";\nimport { useEffect, useMemo } from \"react\";\nimport { Team, useStackApp, useUser } from \"..\";\nimport { useTranslation } from \"../lib/translations\";\nimport { TeamIcon } from \"./team-icon\";\n\ntype SelectedTeamSwitcherProps = {\n urlMap?: (team: Team) => string,\n selectedTeam?: Team,\n noUpdateSelectedTeam?: boolean,\n};\n\nexport function SelectedTeamSwitcher(props: SelectedTeamSwitcherProps) {\n const { t } = useTranslation();\n const app = useStackApp();\n const user = useUser();\n const project = app.useProject();\n const router = useRouter();\n const selectedTeam = user?.selectedTeam || props.selectedTeam;\n const rawTeams = user?.useTeams();\n const teams = useMemo(() => rawTeams?.sort((a, b) => b.id === selectedTeam?.id ? 1 : -1), [rawTeams, selectedTeam]);\n\n useEffect(() => {\n if (!props.noUpdateSelectedTeam && props.selectedTeam) {\n runAsynchronouslyWithAlert(user?.setSelectedTeam(props.selectedTeam));\n }\n }, [props.noUpdateSelectedTeam, props.selectedTeam]);\n\n return (\n <Select\n value={selectedTeam?.id}\n onValueChange={(value) => {\n runAsynchronouslyWithAlert(async () => {\n const team = teams?.find(team => team.id === value);\n if (!team) {\n throw new Error('Team not found, this should not happen');\n }\n\n if (!props.noUpdateSelectedTeam) {\n await user?.setSelectedTeam(team);\n }\n if (props.urlMap) {\n router.push(props.urlMap(team));\n }\n });\n }}\n >\n <SelectTrigger className=\"stack-scope max-w-64\">\n <SelectValue placeholder=\"Select team\"/>\n </SelectTrigger>\n <SelectContent className=\"stack-scope\">\n {user?.selectedTeam ? <SelectGroup>\n <SelectLabel>\n <div className=\"flex items-center justify-between\">\n <span>\n {t('Current team')}\n </span>\n <Button variant='ghost' size='icon' className=\"h-6 w-6\" onClick={() => router.push(`${app.urls.accountSettings}#team-${user.selectedTeam?.id}`)}>\n <Settings className=\"h-4 w-4\"/>\n </Button>\n </div>\n </SelectLabel>\n <SelectItem value={user.selectedTeam.id}>\n <div className=\"flex items-center gap-2\">\n <TeamIcon team={user.selectedTeam} />\n <Typography className=\"max-w-40 truncate\">{user.selectedTeam.displayName}</Typography>\n </div>\n </SelectItem>\n </SelectGroup> : undefined}\n\n {teams?.length ?\n <SelectGroup>\n <SelectLabel>{t('Other teams')}</SelectLabel>\n {teams.filter(team => team.id !== user?.selectedTeam?.id)\n .map(team => (\n <SelectItem value={team.id} key={team.id}>\n <div className=\"flex items-center gap-2\">\n <TeamIcon team={team} />\n <Typography className=\"max-w-64 truncate\">{team.displayName}</Typography>\n </div>\n </SelectItem>\n ))}\n </SelectGroup> :\n <SelectGroup>\n <SelectLabel>{t('No teams yet')}</SelectLabel>\n </SelectGroup>}\n\n {project.config.clientTeamCreationEnabled && <>\n <SelectSeparator/>\n <div>\n <Button\n onClick={() => router.push(`${app.urls.accountSettings}#team-creation`)}\n className=\"w-full\"\n variant='ghost'\n >\n <PlusCircle className=\"mr-2 h-4 w-4\"/> {t('Create a team')}\n </Button>\n </div>\n </>}\n </SelectContent>\n </Select>\n );\n}\n"],"mappings":";;;AACA,SAAS,kCAAkC;AAC3C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,YAAY,gBAAgB;AACrC,SAAS,iBAAiB;AAC1B,SAAS,WAAW,eAAe;
|
|
1
|
+
{"version":3,"sources":["../../../src/components/selected-team-switcher.tsx"],"sourcesContent":["'use client';\nimport { runAsynchronouslyWithAlert } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport {\n Button,\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectSeparator,\n SelectTrigger,\n SelectValue,\n Skeleton,\n Typography\n} from \"@stackframe/stack-ui\";\nimport { PlusCircle, Settings } from \"lucide-react\";\nimport { useRouter } from \"next/navigation\";\nimport { Suspense, useEffect, useMemo } from \"react\";\nimport { Team, useStackApp, useUser } from \"..\";\nimport { useTranslation } from \"../lib/translations\";\nimport { TeamIcon } from \"./team-icon\";\n\ntype SelectedTeamSwitcherProps = {\n urlMap?: (team: Team) => string,\n selectedTeam?: Team,\n noUpdateSelectedTeam?: boolean,\n};\n\nexport function SelectedTeamSwitcher(props: SelectedTeamSwitcherProps) {\n return <Suspense fallback={<Fallback />}>\n <Inner {...props} />\n </Suspense>;\n}\n\nfunction Fallback() {\n return <Skeleton className=\"h-9 w-full max-w-64 stack-scope\" />;\n}\n\nfunction Inner(props: SelectedTeamSwitcherProps) {\n const { t } = useTranslation();\n const app = useStackApp();\n const user = useUser();\n const project = app.useProject();\n const router = useRouter();\n const selectedTeam = user?.selectedTeam || props.selectedTeam;\n const rawTeams = user?.useTeams();\n const teams = useMemo(() => rawTeams?.sort((a, b) => b.id === selectedTeam?.id ? 1 : -1), [rawTeams, selectedTeam]);\n\n useEffect(() => {\n if (!props.noUpdateSelectedTeam && props.selectedTeam) {\n runAsynchronouslyWithAlert(user?.setSelectedTeam(props.selectedTeam));\n }\n }, [props.noUpdateSelectedTeam, props.selectedTeam]);\n\n return (\n <Select\n value={selectedTeam?.id}\n onValueChange={(value) => {\n runAsynchronouslyWithAlert(async () => {\n const team = teams?.find(team => team.id === value);\n if (!team) {\n throw new Error('Team not found, this should not happen');\n }\n\n if (!props.noUpdateSelectedTeam) {\n await user?.setSelectedTeam(team);\n }\n if (props.urlMap) {\n router.push(props.urlMap(team));\n }\n });\n }}\n >\n <SelectTrigger className=\"stack-scope max-w-64\">\n <SelectValue placeholder=\"Select team\"/>\n </SelectTrigger>\n <SelectContent className=\"stack-scope\">\n {user?.selectedTeam ? <SelectGroup>\n <SelectLabel>\n <div className=\"flex items-center justify-between\">\n <span>\n {t('Current team')}\n </span>\n <Button variant='ghost' size='icon' className=\"h-6 w-6\" onClick={() => router.push(`${app.urls.accountSettings}#team-${user.selectedTeam?.id}`)}>\n <Settings className=\"h-4 w-4\"/>\n </Button>\n </div>\n </SelectLabel>\n <SelectItem value={user.selectedTeam.id}>\n <div className=\"flex items-center gap-2\">\n <TeamIcon team={user.selectedTeam} />\n <Typography className=\"max-w-40 truncate\">{user.selectedTeam.displayName}</Typography>\n </div>\n </SelectItem>\n </SelectGroup> : undefined}\n\n {teams?.length ?\n <SelectGroup>\n <SelectLabel>{t('Other teams')}</SelectLabel>\n {teams.filter(team => team.id !== user?.selectedTeam?.id)\n .map(team => (\n <SelectItem value={team.id} key={team.id}>\n <div className=\"flex items-center gap-2\">\n <TeamIcon team={team} />\n <Typography className=\"max-w-64 truncate\">{team.displayName}</Typography>\n </div>\n </SelectItem>\n ))}\n </SelectGroup> :\n <SelectGroup>\n <SelectLabel>{t('No teams yet')}</SelectLabel>\n </SelectGroup>}\n\n {project.config.clientTeamCreationEnabled && <>\n <SelectSeparator/>\n <div>\n <Button\n onClick={() => router.push(`${app.urls.accountSettings}#team-creation`)}\n className=\"w-full\"\n variant='ghost'\n >\n <PlusCircle className=\"mr-2 h-4 w-4\"/> {t('Create a team')}\n </Button>\n </div>\n </>}\n </SelectContent>\n </Select>\n );\n}\n"],"mappings":"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","names":["team"]}
|
|
@@ -17,13 +17,7 @@ function Item(props) {
|
|
|
17
17
|
] }) });
|
|
18
18
|
}
|
|
19
19
|
function UserButton(props) {
|
|
20
|
-
return /* @__PURE__ */ jsx(
|
|
21
|
-
Suspense,
|
|
22
|
-
{
|
|
23
|
-
fallback: /* @__PURE__ */ jsx(Skeleton, { children: /* @__PURE__ */ jsx(UserButtonInnerInner, { ...props, user: null }) }),
|
|
24
|
-
children: /* @__PURE__ */ jsx(UserButtonInner, { ...props })
|
|
25
|
-
}
|
|
26
|
-
);
|
|
20
|
+
return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(Skeleton, { className: "h-[34px] w-[34px] rounded-full stack-scope" }), children: /* @__PURE__ */ jsx(UserButtonInner, { ...props }) });
|
|
27
21
|
}
|
|
28
22
|
function UserButtonInner(props) {
|
|
29
23
|
const user = useUser();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/user-button.tsx"],"sourcesContent":["'use client';\n\nimport { runAsynchronouslyWithAlert } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, Skeleton, Typography } from \"@stackframe/stack-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};\n\nexport function UserButton(props: UserButtonProps) {\n return (\n <Suspense
|
|
1
|
+
{"version":3,"sources":["../../../src/components/user-button.tsx"],"sourcesContent":["'use client';\n\nimport { runAsynchronouslyWithAlert } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, Skeleton, Typography } from \"@stackframe/stack-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};\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 user = useUser();\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\">\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\">\n <Typography className=\"max-w-40 truncate\">{user.displayName}</Typography>\n <Typography className=\"max-w-40 truncate\" variant=\"secondary\" type='label'>{user.primaryEmail}</Typography>\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 {!user && <Typography>{t('Not signed in')}</Typography>}\n </div>\n </div>\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n {user && <Item\n text={t('Account settings')}\n onClick={async () => await app.redirectToAccountSettings()}\n icon={<CircleUser {...iconProps} />}\n />}\n {!user && <Item\n text={t('Sign in')}\n onClick={async () => await app.redirectToSignIn()}\n icon={<LogIn {...iconProps} />}\n />}\n {!user && <Item\n text={t('Sign up')}\n onClick={async () => await app.redirectToSignUp()}\n icon={<UserPlus {...iconProps}/> }\n />}\n {user && 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 && <Item\n text={t('Sign out')}\n onClick={() => user.signOut()}\n icon={<LogOut {...iconProps} />}\n />}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -305,7 +305,7 @@ function usePasskeySection() {
|
|
|
305
305
|
const stackApp = useStackApp();
|
|
306
306
|
const project = stackApp.useProject();
|
|
307
307
|
const contactChannels = user.useContactChannels();
|
|
308
|
-
const
|
|
308
|
+
const hasPasskey = user.passkeyAuthEnabled;
|
|
309
309
|
const isLastAuth = user.passkeyAuthEnabled && !user.hasPassword && user.oauthProviders.length === 0 && !user.otpAuthEnabled;
|
|
310
310
|
const [showConfirmationModal, setShowConfirmationModal] = useState(false);
|
|
311
311
|
const hasValidEmail = contactChannels.filter((x) => x.type === "email" && x.isVerified && x.usedForAuth).length > 0;
|
|
@@ -319,11 +319,11 @@ function usePasskeySection() {
|
|
|
319
319
|
const handleAddNewPasskey = async () => {
|
|
320
320
|
await user.registerPasskey();
|
|
321
321
|
};
|
|
322
|
-
return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Section, { title: t("Passkey"), description:
|
|
322
|
+
return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Section, { title: t("Passkey"), description: hasPasskey ? t("Passkey registered") : t("Register a passkey"), children: /* @__PURE__ */ jsxs("div", { className: "flex md:justify-end gap-2", children: [
|
|
323
323
|
!hasValidEmail && /* @__PURE__ */ jsx(Typography, { variant: "secondary", type: "label", children: t("To enable Passkey sign-in, please add a verified email and set it as your sign-in email.") }),
|
|
324
|
-
hasValidEmail &&
|
|
325
|
-
!
|
|
326
|
-
hasValidEmail &&
|
|
324
|
+
hasValidEmail && hasPasskey && isLastAuth && /* @__PURE__ */ jsx(Typography, { variant: "secondary", type: "label", children: t("Passkey sign-in is enabled and cannot be disabled as it is currently the only sign-in method") }),
|
|
325
|
+
!hasPasskey && hasValidEmail && /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Button, { onClick: handleAddNewPasskey, variant: "secondary", children: t("Add new passkey") }) }),
|
|
326
|
+
hasValidEmail && hasPasskey && !isLastAuth && !showConfirmationModal && /* @__PURE__ */ jsx(
|
|
327
327
|
Button,
|
|
328
328
|
{
|
|
329
329
|
variant: "secondary",
|
|
@@ -331,7 +331,7 @@ function usePasskeySection() {
|
|
|
331
331
|
children: t("Delete Passkey")
|
|
332
332
|
}
|
|
333
333
|
),
|
|
334
|
-
hasValidEmail &&
|
|
334
|
+
hasValidEmail && hasPasskey && !isLastAuth && showConfirmationModal && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
335
335
|
/* @__PURE__ */ jsx(Typography, { variant: "destructive", children: t("Are you sure you want to disable Passkey sign-in? You will not be able to sign in with your passkey anymore.") }),
|
|
336
336
|
/* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
337
337
|
/* @__PURE__ */ jsx(
|