@stackframe/stack 2.5.35 → 2.6.0
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 +33 -0
- package/dist/components/credential-sign-in.js +4 -2
- package/dist/components/credential-sign-in.js.map +1 -1
- package/dist/components/credential-sign-up.d.mts +3 -1
- package/dist/components/credential-sign-up.d.ts +3 -1
- package/dist/components/credential-sign-up.js +23 -17
- package/dist/components/credential-sign-up.js.map +1 -1
- package/dist/components/elements/sidebar-layout.js +19 -11
- package/dist/components/elements/sidebar-layout.js.map +1 -1
- package/dist/components/elements/user-avatar.js +1 -1
- package/dist/components/elements/user-avatar.js.map +1 -1
- package/dist/components/magic-link-sign-in.js +82 -30
- package/dist/components/magic-link-sign-in.js.map +1 -1
- package/dist/components/message-cards/predefined-message-card.js +22 -20
- package/dist/components/message-cards/predefined-message-card.js.map +1 -1
- package/dist/components/oauth-button.js +32 -25
- package/dist/components/oauth-button.js.map +1 -1
- package/dist/components/profile-image-editor.js +2 -2
- package/dist/components/profile-image-editor.js.map +1 -1
- package/dist/components/selected-team-switcher.js +1 -1
- package/dist/components/selected-team-switcher.js.map +1 -1
- package/dist/components-page/account-settings.d.mts +4 -2
- package/dist/components-page/account-settings.d.ts +4 -2
- package/dist/components-page/account-settings.js +365 -188
- package/dist/components-page/account-settings.js.map +1 -1
- package/dist/components-page/auth-page.d.mts +1 -0
- package/dist/components-page/auth-page.d.ts +1 -0
- package/dist/components-page/auth-page.js +5 -5
- package/dist/components-page/auth-page.js.map +1 -1
- package/dist/components-page/email-verification.js +10 -8
- package/dist/components-page/email-verification.js.map +1 -1
- package/dist/components-page/error-page.js +19 -4
- package/dist/components-page/error-page.js.map +1 -1
- package/dist/components-page/magic-link-callback.js +11 -9
- package/dist/components-page/magic-link-callback.js.map +1 -1
- package/dist/components-page/oauth-callback.js +1 -1
- package/dist/components-page/oauth-callback.js.map +1 -1
- package/dist/components-page/password-reset.js +13 -11
- package/dist/components-page/password-reset.js.map +1 -1
- package/dist/components-page/sign-up.d.mts +1 -0
- package/dist/components-page/sign-up.d.ts +1 -0
- package/dist/components-page/sign-up.js +10 -1
- package/dist/components-page/sign-up.js.map +1 -1
- package/dist/components-page/stack-handler.d.mts +1 -0
- package/dist/components-page/stack-handler.d.ts +1 -0
- package/dist/esm/components/credential-sign-in.js +4 -2
- package/dist/esm/components/credential-sign-in.js.map +1 -1
- package/dist/esm/components/credential-sign-up.js +24 -18
- package/dist/esm/components/credential-sign-up.js.map +1 -1
- package/dist/esm/components/elements/sidebar-layout.js +19 -11
- package/dist/esm/components/elements/sidebar-layout.js.map +1 -1
- package/dist/esm/components/elements/user-avatar.js +1 -1
- package/dist/esm/components/elements/user-avatar.js.map +1 -1
- package/dist/esm/components/magic-link-sign-in.js +84 -32
- package/dist/esm/components/magic-link-sign-in.js.map +1 -1
- package/dist/esm/components/message-cards/predefined-message-card.js +22 -20
- package/dist/esm/components/message-cards/predefined-message-card.js.map +1 -1
- package/dist/esm/components/oauth-button.js +32 -25
- package/dist/esm/components/oauth-button.js.map +1 -1
- package/dist/esm/components/profile-image-editor.js +2 -2
- package/dist/esm/components/profile-image-editor.js.map +1 -1
- package/dist/esm/components/selected-team-switcher.js +1 -1
- package/dist/esm/components/selected-team-switcher.js.map +1 -1
- package/dist/esm/components-page/account-settings.js +365 -189
- package/dist/esm/components-page/account-settings.js.map +1 -1
- package/dist/esm/components-page/auth-page.js +5 -5
- package/dist/esm/components-page/auth-page.js.map +1 -1
- package/dist/esm/components-page/email-verification.js +10 -8
- package/dist/esm/components-page/email-verification.js.map +1 -1
- package/dist/esm/components-page/error-page.js +19 -4
- package/dist/esm/components-page/error-page.js.map +1 -1
- package/dist/esm/components-page/magic-link-callback.js +11 -9
- package/dist/esm/components-page/magic-link-callback.js.map +1 -1
- package/dist/esm/components-page/oauth-callback.js +1 -1
- package/dist/esm/components-page/oauth-callback.js.map +1 -1
- package/dist/esm/components-page/password-reset.js +13 -11
- package/dist/esm/components-page/password-reset.js.map +1 -1
- package/dist/esm/components-page/sign-up.js +10 -1
- package/dist/esm/components-page/sign-up.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 +1764 -1356
- package/dist/esm/generated/quetzal-translations.js.map +1 -1
- package/dist/esm/lib/auth.js +4 -3
- package/dist/esm/lib/auth.js.map +1 -1
- package/dist/esm/lib/stack-app.js +54 -45
- package/dist/esm/lib/stack-app.js.map +1 -1
- package/dist/esm/lib/translations.js +6 -2
- package/dist/esm/lib/translations.js.map +1 -1
- package/dist/esm/utils/browser-script.js +9 -7
- package/dist/esm/utils/browser-script.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 +1764 -1356
- package/dist/generated/quetzal-translations.js.map +1 -1
- package/dist/lib/auth.d.mts +16 -6
- package/dist/lib/auth.d.ts +16 -6
- package/dist/lib/auth.js +4 -3
- package/dist/lib/auth.js.map +1 -1
- package/dist/lib/stack-app.d.mts +21 -12
- package/dist/lib/stack-app.d.ts +21 -12
- package/dist/lib/stack-app.js +53 -44
- package/dist/lib/stack-app.js.map +1 -1
- package/dist/lib/translations.d.mts +1 -1
- package/dist/lib/translations.d.ts +1 -1
- package/dist/lib/translations.js +6 -2
- package/dist/lib/translations.js.map +1 -1
- package/dist/utils/browser-script.js +9 -7
- package/dist/utils/browser-script.js.map +1 -1
- package/package.json +5 -5
|
@@ -33,7 +33,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
33
33
|
var account_settings_exports = {};
|
|
34
34
|
__export(account_settings_exports, {
|
|
35
35
|
AccountSettings: () => AccountSettings,
|
|
36
|
-
TeamCreation: () => TeamCreation
|
|
36
|
+
TeamCreation: () => TeamCreation,
|
|
37
|
+
useDeleteAccountSection: () => useDeleteAccountSection
|
|
37
38
|
});
|
|
38
39
|
module.exports = __toCommonJS(account_settings_exports);
|
|
39
40
|
var import_yup = require("@hookform/resolvers/yup");
|
|
@@ -45,18 +46,19 @@ var import_errors = require("@stackframe/stack-shared/dist/utils/errors");
|
|
|
45
46
|
var import_promises = require("@stackframe/stack-shared/dist/utils/promises");
|
|
46
47
|
var import_stack_ui = require("@stackframe/stack-ui");
|
|
47
48
|
var import_lucide_react = require("lucide-react");
|
|
49
|
+
var import_navigation = require("next/navigation");
|
|
48
50
|
var import_otp = require("oslo/otp");
|
|
49
51
|
var QRCode = __toESM(require("qrcode"));
|
|
50
|
-
var import_react = require("react");
|
|
52
|
+
var import_react = __toESM(require("react"));
|
|
51
53
|
var import_react_hook_form = require("react-hook-form");
|
|
52
54
|
var yup = __toESM(require("yup"));
|
|
53
55
|
var import__ = require("..");
|
|
54
56
|
var import_form_warning = require("../components/elements/form-warning");
|
|
57
|
+
var import_maybe_full_page = require("../components/elements/maybe-full-page");
|
|
55
58
|
var import_sidebar_layout = require("../components/elements/sidebar-layout");
|
|
56
59
|
var import_user_avatar = require("../components/elements/user-avatar");
|
|
57
60
|
var import_profile_image_editor = require("../components/profile-image-editor");
|
|
58
61
|
var import_team_icon = require("../components/team-icon");
|
|
59
|
-
var import_maybe_full_page = require("../components/elements/maybe-full-page");
|
|
60
62
|
var import_translations = require("../lib/translations");
|
|
61
63
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
62
64
|
function AccountSettings(props) {
|
|
@@ -65,7 +67,7 @@ function AccountSettings(props) {
|
|
|
65
67
|
const teams = user.useTeams();
|
|
66
68
|
const stackApp = (0, import__.useStackApp)();
|
|
67
69
|
const project = stackApp.useProject();
|
|
68
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_maybe_full_page.MaybeFullPage, { fullPage: !!props.fullPage, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { alignSelf: "stretch", flexGrow: 1 }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
70
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_maybe_full_page.MaybeFullPage, { fullPage: !!props.fullPage, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { alignSelf: "stretch", flexGrow: 1, width: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
69
71
|
import_sidebar_layout.SidebarLayout,
|
|
70
72
|
{
|
|
71
73
|
items: [
|
|
@@ -74,25 +76,21 @@ function AccountSettings(props) {
|
|
|
74
76
|
type: "item",
|
|
75
77
|
subpath: "/profile",
|
|
76
78
|
icon: import_lucide_react.Contact,
|
|
77
|
-
content: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
79
|
+
content: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ProfilePage, {})
|
|
78
80
|
},
|
|
79
81
|
{
|
|
80
82
|
title: t("Security"),
|
|
81
83
|
type: "item",
|
|
82
|
-
icon: import_lucide_react.ShieldCheck,
|
|
83
84
|
subpath: "/security",
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(PasswordSection, {}),
|
|
87
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(MfaSection, {})
|
|
88
|
-
] })
|
|
85
|
+
icon: import_lucide_react.ShieldCheck,
|
|
86
|
+
content: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SecurityPage, {})
|
|
89
87
|
},
|
|
90
88
|
{
|
|
91
|
-
title: t("
|
|
92
|
-
subpath: "/sign-out",
|
|
89
|
+
title: t("Settings"),
|
|
93
90
|
type: "item",
|
|
94
|
-
|
|
95
|
-
|
|
91
|
+
subpath: "/settings",
|
|
92
|
+
icon: import_lucide_react.Settings,
|
|
93
|
+
content: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SettingsPage, {})
|
|
96
94
|
},
|
|
97
95
|
...props.extraItems?.map((item) => ({
|
|
98
96
|
title: item.title,
|
|
@@ -106,19 +104,13 @@ function AccountSettings(props) {
|
|
|
106
104
|
type: "divider"
|
|
107
105
|
}] : [],
|
|
108
106
|
...teams.map((team) => ({
|
|
109
|
-
title: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex gap-2 items-center", children: [
|
|
107
|
+
title: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex gap-2 items-center w-full", children: [
|
|
110
108
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_team_icon.TeamIcon, { team }),
|
|
111
|
-
team.displayName
|
|
109
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { className: "max-w-[320px] md:w-[90%] truncate", children: team.displayName })
|
|
112
110
|
] }),
|
|
113
111
|
type: "item",
|
|
114
112
|
subpath: `/teams/${team.id}`,
|
|
115
|
-
content: /* @__PURE__ */ (0, import_jsx_runtime.
|
|
116
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ProfileSettings, { team }),
|
|
117
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ManagementSettings, { team }),
|
|
118
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(MemberInvitation, { team }),
|
|
119
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(MembersSettings, { team }),
|
|
120
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(UserSettings, { team })
|
|
121
|
-
] })
|
|
113
|
+
content: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TeamPage, { team })
|
|
122
114
|
})),
|
|
123
115
|
...project.config.clientTeamCreationEnabled ? [{
|
|
124
116
|
title: t("Create a team"),
|
|
@@ -133,42 +125,93 @@ function AccountSettings(props) {
|
|
|
133
125
|
}
|
|
134
126
|
) }) });
|
|
135
127
|
}
|
|
136
|
-
function
|
|
128
|
+
function Section(props) {
|
|
129
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col sm:flex-row gap-2", children: [
|
|
130
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "sm:flex-1 flex flex-col justify-center", children: [
|
|
131
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { className: "font-medium", children: props.title }),
|
|
132
|
+
props.description && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "secondary", type: "footnote", children: props.description })
|
|
133
|
+
] }),
|
|
134
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "sm:flex-1 sm:items-end flex flex-col gap-2 ", children: props.children })
|
|
135
|
+
] });
|
|
136
|
+
}
|
|
137
|
+
function PageLayout(props) {
|
|
138
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col gap-6", children: [
|
|
139
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Separator, {}),
|
|
140
|
+
import_react.default.Children.map(props.children, (child) => child && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
141
|
+
child,
|
|
142
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Separator, {})
|
|
143
|
+
] }))
|
|
144
|
+
] });
|
|
145
|
+
}
|
|
146
|
+
function ProfilePage() {
|
|
137
147
|
const { t } = (0, import_translations.useTranslation)();
|
|
138
148
|
const user = (0, import__.useUser)({ or: "redirect" });
|
|
139
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
140
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
149
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(PageLayout, { children: [
|
|
150
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
151
|
+
Section,
|
|
152
|
+
{
|
|
153
|
+
title: t("User name"),
|
|
154
|
+
description: t("This is a display name and is not used for authentication"),
|
|
155
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
156
|
+
import_stack_ui.EditableText,
|
|
157
|
+
{
|
|
158
|
+
value: user.displayName || "",
|
|
159
|
+
onSave: async (newDisplayName) => {
|
|
160
|
+
await user.update({ displayName: newDisplayName });
|
|
161
|
+
}
|
|
148
162
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
163
|
+
)
|
|
164
|
+
}
|
|
165
|
+
),
|
|
166
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
167
|
+
Section,
|
|
168
|
+
{
|
|
169
|
+
title: t("Profile image"),
|
|
170
|
+
description: t("Upload your own image as your avatar"),
|
|
171
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
172
|
+
import_profile_image_editor.ProfileImageEditor,
|
|
173
|
+
{
|
|
174
|
+
user,
|
|
175
|
+
onProfileImageUrlChange: async (profileImageUrl) => {
|
|
176
|
+
await user.update({ profileImageUrl });
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
)
|
|
180
|
+
}
|
|
181
|
+
)
|
|
158
182
|
] });
|
|
159
183
|
}
|
|
160
|
-
function
|
|
184
|
+
function SecurityPage() {
|
|
185
|
+
const emailVerificationSection = useEmailVerificationSection();
|
|
186
|
+
const passwordSection = usePasswordSection();
|
|
187
|
+
const mfaSection = useMfaSection();
|
|
188
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(PageLayout, { children: [
|
|
189
|
+
emailVerificationSection,
|
|
190
|
+
passwordSection,
|
|
191
|
+
mfaSection
|
|
192
|
+
] });
|
|
193
|
+
}
|
|
194
|
+
function SettingsPage() {
|
|
195
|
+
const deleteAccountSection = useDeleteAccountSection();
|
|
196
|
+
const signOutSection = useSignOutSection();
|
|
197
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(PageLayout, { children: [
|
|
198
|
+
deleteAccountSection,
|
|
199
|
+
signOutSection
|
|
200
|
+
] });
|
|
201
|
+
}
|
|
202
|
+
function useEmailVerificationSection() {
|
|
161
203
|
const { t } = (0, import_translations.useTranslation)();
|
|
162
204
|
const user = (0, import__.useUser)({ or: "redirect" });
|
|
163
205
|
const [emailSent, setEmailSent] = (0, import_react.useState)(false);
|
|
164
206
|
if (!user.primaryEmail) {
|
|
165
207
|
return null;
|
|
166
208
|
}
|
|
167
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
209
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
210
|
+
Section,
|
|
211
|
+
{
|
|
212
|
+
title: t("Email Verification"),
|
|
213
|
+
description: t("Verify your email address to secure your account"),
|
|
214
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: user.primaryEmailVerified ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "success", children: t("Your email has been verified.") }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
172
215
|
import_stack_ui.Button,
|
|
173
216
|
{
|
|
174
217
|
disabled: emailSent,
|
|
@@ -178,11 +221,11 @@ function EmailVerificationSection() {
|
|
|
178
221
|
},
|
|
179
222
|
children: emailSent ? t("Email sent!") : t("Send Verification Email")
|
|
180
223
|
}
|
|
181
|
-
) })
|
|
182
|
-
|
|
183
|
-
|
|
224
|
+
) }) })
|
|
225
|
+
}
|
|
226
|
+
);
|
|
184
227
|
}
|
|
185
|
-
function
|
|
228
|
+
function usePasswordSection() {
|
|
186
229
|
const { t } = (0, import_translations.useTranslation)();
|
|
187
230
|
const passwordSchema = (0, import_schema_fields.yupObject)({
|
|
188
231
|
oldPassword: (0, import_schema_fields.yupString)().required(t("Please enter your old password")),
|
|
@@ -287,7 +330,7 @@ function PasswordSection() {
|
|
|
287
330
|
) })
|
|
288
331
|
] });
|
|
289
332
|
}
|
|
290
|
-
function
|
|
333
|
+
function useMfaSection() {
|
|
291
334
|
const { t } = (0, import_translations.useTranslation)();
|
|
292
335
|
const project = (0, import__.useStackApp)().useProject();
|
|
293
336
|
const user = (0, import__.useUser)({ or: "throw" });
|
|
@@ -313,103 +356,165 @@ function MfaSection() {
|
|
|
313
356
|
setIsMaybeWrong(true);
|
|
314
357
|
});
|
|
315
358
|
}, [mfaCode, generatedSecret, handleSubmit]);
|
|
316
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
323
|
-
|
|
324
|
-
|
|
359
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
360
|
+
Section,
|
|
361
|
+
{
|
|
362
|
+
title: t("Multi-factor Authentication"),
|
|
363
|
+
description: isEnabled ? t("Multi-factor authentication is currently enabled.") : t("Multi-factor authentication is currently disabled."),
|
|
364
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col gap-4", children: [
|
|
365
|
+
!isEnabled && generatedSecret && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
366
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { children: t("Scan this QR code with your authenticator app:") }),
|
|
367
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", { width: 200, height: 200, src: qrCodeUrl ?? (0, import_errors.throwErr)("TOTP QR code failed to generate"), alt: t("TOTP multi-factor authentication QR code") }),
|
|
368
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { children: t("Then, enter your six-digit MFA code:") }),
|
|
369
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
370
|
+
import_stack_ui.Input,
|
|
371
|
+
{
|
|
372
|
+
value: mfaCode,
|
|
373
|
+
onChange: (e) => {
|
|
374
|
+
setIsMaybeWrong(false);
|
|
375
|
+
setMfaCode(e.target.value);
|
|
376
|
+
},
|
|
377
|
+
placeholder: "123456",
|
|
378
|
+
maxLength: 6,
|
|
379
|
+
disabled: isLoading
|
|
380
|
+
}
|
|
381
|
+
),
|
|
382
|
+
isMaybeWrong && mfaCode.length === 6 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "destructive", children: t("Incorrect code. Please try again.") }),
|
|
383
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
384
|
+
import_stack_ui.Button,
|
|
385
|
+
{
|
|
386
|
+
variant: "secondary",
|
|
387
|
+
onClick: () => {
|
|
388
|
+
setGeneratedSecret(null);
|
|
389
|
+
setQrCodeUrl(null);
|
|
390
|
+
setMfaCode("");
|
|
391
|
+
},
|
|
392
|
+
children: t("Cancel")
|
|
393
|
+
}
|
|
394
|
+
) })
|
|
395
|
+
] }),
|
|
396
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex gap-2", children: isEnabled ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
397
|
+
import_stack_ui.Button,
|
|
325
398
|
{
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
setIsMaybeWrong(false);
|
|
329
|
-
setMfaCode(e.target.value);
|
|
330
|
-
},
|
|
331
|
-
placeholder: "123456",
|
|
332
|
-
maxLength: 6,
|
|
333
|
-
disabled: isLoading
|
|
334
|
-
}
|
|
335
|
-
),
|
|
336
|
-
isMaybeWrong && mfaCode.length === 6 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "destructive", children: t("Incorrect code. Please try again.") })
|
|
337
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "destructive", children: t("Multi-factor authentication is currently disabled.") }),
|
|
338
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
339
|
-
import_stack_ui.Button,
|
|
340
|
-
{
|
|
341
|
-
className: "mt-4",
|
|
342
|
-
variant: isEnabled ? "secondary" : "default",
|
|
343
|
-
onClick: async () => {
|
|
344
|
-
if (isEnabled) {
|
|
399
|
+
variant: "secondary",
|
|
400
|
+
onClick: async () => {
|
|
345
401
|
await user.update({
|
|
346
402
|
totpMultiFactorSecret: null
|
|
347
403
|
});
|
|
348
|
-
}
|
|
404
|
+
},
|
|
405
|
+
children: t("Disable")
|
|
406
|
+
}
|
|
407
|
+
) : !generatedSecret && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
408
|
+
import_stack_ui.Button,
|
|
409
|
+
{
|
|
410
|
+
variant: "default",
|
|
411
|
+
onClick: async () => {
|
|
349
412
|
const secret = (0, import_crypto.generateRandomValues)(new Uint8Array(20));
|
|
350
413
|
setQrCodeUrl(await generateTotpQrCode(project, user, secret));
|
|
351
414
|
setGeneratedSecret(secret);
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
}
|
|
360
|
-
)
|
|
361
|
-
] })
|
|
362
|
-
] }) });
|
|
415
|
+
},
|
|
416
|
+
children: t("Enable")
|
|
417
|
+
}
|
|
418
|
+
) })
|
|
419
|
+
] })
|
|
420
|
+
}
|
|
421
|
+
);
|
|
363
422
|
}
|
|
364
423
|
async function generateTotpQrCode(project, user, secret) {
|
|
365
424
|
const uri = (0, import_otp.createTOTPKeyURI)(project.displayName, user.primaryEmail ?? user.id, secret);
|
|
366
425
|
return await QRCode.toDataURL(uri);
|
|
367
426
|
}
|
|
368
|
-
function
|
|
427
|
+
function useSignOutSection() {
|
|
369
428
|
const { t } = (0, import_translations.useTranslation)();
|
|
370
429
|
const user = (0, import__.useUser)({ or: "throw" });
|
|
371
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
372
|
-
|
|
430
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
431
|
+
Section,
|
|
373
432
|
{
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
children:
|
|
433
|
+
title: t("Sign out"),
|
|
434
|
+
description: t("End your current session"),
|
|
435
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
436
|
+
import_stack_ui.Button,
|
|
437
|
+
{
|
|
438
|
+
variant: "secondary",
|
|
439
|
+
onClick: () => user.signOut(),
|
|
440
|
+
children: t("Sign out")
|
|
441
|
+
}
|
|
442
|
+
) })
|
|
377
443
|
}
|
|
378
|
-
)
|
|
444
|
+
);
|
|
379
445
|
}
|
|
380
|
-
function
|
|
446
|
+
function TeamPage(props) {
|
|
447
|
+
const teamUserProfileSection = useTeamUserProfileSection(props);
|
|
448
|
+
const teamProfileImageSection = useTeamProfileImageSection(props);
|
|
449
|
+
const teamDisplayNameSection = useTeamDisplayNameSection(props);
|
|
450
|
+
const leaveTeamSection = useLeaveTeamSection(props);
|
|
451
|
+
const memberInvitationSection = useMemberInvitationSection(props);
|
|
452
|
+
const memberListSection = useMemberListSection(props);
|
|
453
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(PageLayout, { children: [
|
|
454
|
+
teamUserProfileSection,
|
|
455
|
+
memberInvitationSection,
|
|
456
|
+
memberListSection,
|
|
457
|
+
teamProfileImageSection,
|
|
458
|
+
teamDisplayNameSection,
|
|
459
|
+
leaveTeamSection
|
|
460
|
+
] });
|
|
461
|
+
}
|
|
462
|
+
function useLeaveTeamSection(props) {
|
|
381
463
|
const { t } = (0, import_translations.useTranslation)();
|
|
382
464
|
const user = (0, import__.useUser)({ or: "redirect" });
|
|
383
465
|
const [leaving, setLeaving] = (0, import_react.useState)(false);
|
|
384
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
385
|
-
|
|
466
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
467
|
+
Section,
|
|
386
468
|
{
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
children:
|
|
469
|
+
title: t("Leave Team"),
|
|
470
|
+
description: t("leave this team and remove your team profile"),
|
|
471
|
+
children: !leaving ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
472
|
+
import_stack_ui.Button,
|
|
473
|
+
{
|
|
474
|
+
variant: "secondary",
|
|
475
|
+
onClick: () => setLeaving(true),
|
|
476
|
+
children: t("Leave team")
|
|
477
|
+
}
|
|
478
|
+
) }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col gap-2", children: [
|
|
479
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "destructive", children: t("Are you sure you want to leave the team?") }),
|
|
480
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex gap-2", children: [
|
|
481
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
482
|
+
import_stack_ui.Button,
|
|
483
|
+
{
|
|
484
|
+
variant: "destructive",
|
|
485
|
+
onClick: async () => {
|
|
486
|
+
await user.leaveTeam(props.team);
|
|
487
|
+
window.location.reload();
|
|
488
|
+
},
|
|
489
|
+
children: t("Leave")
|
|
490
|
+
}
|
|
491
|
+
),
|
|
492
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
493
|
+
import_stack_ui.Button,
|
|
494
|
+
{
|
|
495
|
+
variant: "secondary",
|
|
496
|
+
onClick: () => setLeaving(false),
|
|
497
|
+
children: t("Cancel")
|
|
498
|
+
}
|
|
499
|
+
)
|
|
500
|
+
] })
|
|
501
|
+
] })
|
|
390
502
|
}
|
|
391
|
-
)
|
|
392
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "destructive", children: t("Are you sure you want to leave the team?") }),
|
|
393
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex gap-2", children: [
|
|
394
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Button, { variant: "destructive", onClick: async () => {
|
|
395
|
-
await user.leaveTeam(props.team);
|
|
396
|
-
window.location.reload();
|
|
397
|
-
}, children: t("Leave") }),
|
|
398
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Button, { variant: "secondary", onClick: () => setLeaving(false), children: t("Cancel") })
|
|
399
|
-
] })
|
|
400
|
-
] }) }) });
|
|
503
|
+
);
|
|
401
504
|
}
|
|
402
|
-
function
|
|
505
|
+
function useTeamProfileImageSection(props) {
|
|
403
506
|
const { t } = (0, import_translations.useTranslation)();
|
|
404
507
|
const user = (0, import__.useUser)({ or: "redirect" });
|
|
405
508
|
const updateTeamPermission = user.usePermission(props.team, "$update_team");
|
|
406
509
|
if (!updateTeamPermission) {
|
|
407
510
|
return null;
|
|
408
511
|
}
|
|
409
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
512
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
513
|
+
Section,
|
|
514
|
+
{
|
|
515
|
+
title: t("Team profile image"),
|
|
516
|
+
description: t("Upload an image for your team"),
|
|
517
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
413
518
|
import_profile_image_editor.ProfileImageEditor,
|
|
414
519
|
{
|
|
415
520
|
user: props.team,
|
|
@@ -418,40 +523,53 @@ function ManagementSettings(props) {
|
|
|
418
523
|
}
|
|
419
524
|
}
|
|
420
525
|
)
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
526
|
+
}
|
|
527
|
+
);
|
|
528
|
+
}
|
|
529
|
+
function useTeamDisplayNameSection(props) {
|
|
530
|
+
const { t } = (0, import_translations.useTranslation)();
|
|
531
|
+
const user = (0, import__.useUser)({ or: "redirect" });
|
|
532
|
+
const updateTeamPermission = user.usePermission(props.team, "$update_team");
|
|
533
|
+
if (!updateTeamPermission) {
|
|
534
|
+
return null;
|
|
535
|
+
}
|
|
536
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
537
|
+
Section,
|
|
538
|
+
{
|
|
539
|
+
title: t("Team display name"),
|
|
540
|
+
description: t("Change the display name of your team"),
|
|
541
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
425
542
|
import_stack_ui.EditableText,
|
|
426
543
|
{
|
|
427
544
|
value: props.team.displayName,
|
|
428
545
|
onSave: async (newDisplayName) => await props.team.update({ displayName: newDisplayName })
|
|
429
546
|
}
|
|
430
547
|
)
|
|
431
|
-
|
|
432
|
-
|
|
548
|
+
}
|
|
549
|
+
);
|
|
433
550
|
}
|
|
434
|
-
function
|
|
551
|
+
function useTeamUserProfileSection(props) {
|
|
435
552
|
const { t } = (0, import_translations.useTranslation)();
|
|
436
553
|
const user = (0, import__.useUser)({ or: "redirect" });
|
|
437
554
|
const profile = user.useTeamProfile(props.team);
|
|
438
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
555
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
556
|
+
Section,
|
|
557
|
+
{
|
|
558
|
+
title: t("Team user name"),
|
|
559
|
+
description: t("Overwrite your user display name in this team"),
|
|
560
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
561
|
+
import_stack_ui.EditableText,
|
|
562
|
+
{
|
|
563
|
+
value: profile.displayName || "",
|
|
564
|
+
onSave: async (newDisplayName) => {
|
|
565
|
+
await profile.update({ displayName: newDisplayName });
|
|
566
|
+
}
|
|
449
567
|
}
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
568
|
+
)
|
|
569
|
+
}
|
|
570
|
+
);
|
|
453
571
|
}
|
|
454
|
-
function
|
|
572
|
+
function useMemberInvitationSection(props) {
|
|
455
573
|
const { t } = (0, import_translations.useTranslation)();
|
|
456
574
|
const invitationSchema = (0, import_schema_fields.yupObject)({
|
|
457
575
|
email: (0, import_schema_fields.yupString)().email().required(t("Please enter an email address"))
|
|
@@ -478,35 +596,40 @@ function MemberInvitation(props) {
|
|
|
478
596
|
(0, import_react.useEffect)(() => {
|
|
479
597
|
setInvitedEmail(null);
|
|
480
598
|
}, [watch("email")]);
|
|
481
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
"
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
599
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
600
|
+
Section,
|
|
601
|
+
{
|
|
602
|
+
title: t("Invite member"),
|
|
603
|
+
description: t("Invite a user to your team through email"),
|
|
604
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
605
|
+
"form",
|
|
606
|
+
{
|
|
607
|
+
onSubmit: (e) => (0, import_promises.runAsynchronouslyWithAlert)(handleSubmit(onSubmit)(e)),
|
|
608
|
+
noValidate: true,
|
|
609
|
+
className: "w-full",
|
|
610
|
+
children: [
|
|
611
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col gap-4 sm:flex-row w-full", children: [
|
|
612
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
613
|
+
import_stack_ui.Input,
|
|
614
|
+
{
|
|
615
|
+
placeholder: t("Email"),
|
|
616
|
+
...register("email")
|
|
617
|
+
}
|
|
618
|
+
),
|
|
619
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Button, { type: "submit", loading, children: t("Invite User") })
|
|
620
|
+
] }),
|
|
621
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_form_warning.FormWarningText, { text: errors.email?.message?.toString() }),
|
|
622
|
+
invitedEmail && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_stack_ui.Typography, { type: "label", variant: "secondary", children: [
|
|
623
|
+
"Invited ",
|
|
624
|
+
invitedEmail
|
|
625
|
+
] })
|
|
626
|
+
]
|
|
627
|
+
}
|
|
628
|
+
)
|
|
629
|
+
}
|
|
630
|
+
);
|
|
508
631
|
}
|
|
509
|
-
function
|
|
632
|
+
function useMemberListSection(props) {
|
|
510
633
|
const { t } = (0, import_translations.useTranslation)();
|
|
511
634
|
const user = (0, import__.useUser)({ or: "redirect" });
|
|
512
635
|
const readMemberPermission = user.usePermission(props.team, "$read_members");
|
|
@@ -519,8 +642,8 @@ function MembersSettings(props) {
|
|
|
519
642
|
return null;
|
|
520
643
|
}
|
|
521
644
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
522
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.
|
|
523
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_stack_ui.Table, { children: [
|
|
645
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { className: "font-medium mb-2", children: t("Members") }),
|
|
646
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "border rounded-md", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_stack_ui.Table, { children: [
|
|
524
647
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.TableHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_stack_ui.TableRow, { children: [
|
|
525
648
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.TableHead, { className: "w-[100px]", children: t("User") }),
|
|
526
649
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.TableHead, { className: "w-[200px]", children: t("Name") })
|
|
@@ -529,7 +652,7 @@ function MembersSettings(props) {
|
|
|
529
652
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.TableCell, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_user_avatar.UserAvatar, { user: teamProfile }) }),
|
|
530
653
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.TableCell, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { children: teamProfile.displayName }) })
|
|
531
654
|
] }, id)) })
|
|
532
|
-
] })
|
|
655
|
+
] }) })
|
|
533
656
|
] });
|
|
534
657
|
}
|
|
535
658
|
function TeamCreation() {
|
|
@@ -543,45 +666,99 @@ function TeamCreation() {
|
|
|
543
666
|
const app = (0, import__.useStackApp)();
|
|
544
667
|
const project = app.useProject();
|
|
545
668
|
const user = (0, import__.useUser)({ or: "redirect" });
|
|
669
|
+
const router = (0, import_navigation.useRouter)();
|
|
546
670
|
const [loading, setLoading] = (0, import_react.useState)(false);
|
|
547
671
|
if (!project.config.clientTeamCreationEnabled) {
|
|
548
672
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.MessageCard, { title: t("Team creation is not enabled") });
|
|
549
673
|
}
|
|
550
674
|
const onSubmit = async (data) => {
|
|
551
675
|
setLoading(true);
|
|
676
|
+
let team;
|
|
552
677
|
try {
|
|
553
|
-
|
|
678
|
+
team = await user.createTeam({ displayName: data.displayName });
|
|
554
679
|
} finally {
|
|
555
680
|
setLoading(false);
|
|
556
681
|
}
|
|
682
|
+
router.push(app.urls.accountSettings + `/teams/${team.id}`);
|
|
557
683
|
};
|
|
558
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
684
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PageLayout, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Section, { title: t("Create a Team"), description: t("Enter a display name for your new team"), children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
559
685
|
"form",
|
|
560
686
|
{
|
|
561
|
-
className: "flex flex-col items-stretch stack-scope",
|
|
562
687
|
onSubmit: (e) => (0, import_promises.runAsynchronouslyWithAlert)(handleSubmit(onSubmit)(e)),
|
|
563
688
|
noValidate: true,
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
689
|
+
className: "flex gap-2 flex-col sm:flex-row",
|
|
690
|
+
children: [
|
|
691
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col flex-1", children: [
|
|
567
692
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
568
693
|
import_stack_ui.Input,
|
|
569
694
|
{
|
|
570
|
-
id: "
|
|
571
|
-
type: "
|
|
695
|
+
id: "displayName",
|
|
696
|
+
type: "text",
|
|
572
697
|
...register("displayName")
|
|
573
698
|
}
|
|
574
|
-
)
|
|
699
|
+
),
|
|
700
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_form_warning.FormWarningText, { text: errors.displayName?.message?.toString() })
|
|
575
701
|
] }),
|
|
576
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
577
|
-
|
|
578
|
-
] })
|
|
702
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Button, { type: "submit", loading, children: t("Create") })
|
|
703
|
+
]
|
|
579
704
|
}
|
|
580
705
|
) }) });
|
|
581
706
|
}
|
|
707
|
+
function useDeleteAccountSection() {
|
|
708
|
+
const { t } = (0, import_translations.useTranslation)();
|
|
709
|
+
const user = (0, import__.useUser)({ or: "redirect" });
|
|
710
|
+
const app = (0, import__.useStackApp)();
|
|
711
|
+
const project = app.useProject();
|
|
712
|
+
const [deleting, setDeleting] = (0, import_react.useState)(false);
|
|
713
|
+
if (!project.config.clientUserDeletionEnabled) {
|
|
714
|
+
return null;
|
|
715
|
+
}
|
|
716
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
717
|
+
Section,
|
|
718
|
+
{
|
|
719
|
+
title: t("Delete Account"),
|
|
720
|
+
description: t("Permanently remove your account and all associated data"),
|
|
721
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "stack-scope flex flex-col items-stretch", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Accordion, { type: "single", collapsible: true, className: "w-full", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_stack_ui.AccordionItem, { value: "item-1", children: [
|
|
722
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.AccordionTrigger, { children: t("Danger zone") }),
|
|
723
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.AccordionContent, { children: !deleting ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
724
|
+
import_stack_ui.Button,
|
|
725
|
+
{
|
|
726
|
+
variant: "destructive",
|
|
727
|
+
onClick: () => setDeleting(true),
|
|
728
|
+
children: t("Delete account")
|
|
729
|
+
}
|
|
730
|
+
) }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col gap-2", children: [
|
|
731
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "destructive", children: t("Are you sure you want to delete your account? This action is IRREVERSIBLE and will delete ALL associated data.") }),
|
|
732
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex gap-2", children: [
|
|
733
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
734
|
+
import_stack_ui.Button,
|
|
735
|
+
{
|
|
736
|
+
variant: "destructive",
|
|
737
|
+
onClick: async () => {
|
|
738
|
+
await user.delete();
|
|
739
|
+
await app.redirectToHome();
|
|
740
|
+
},
|
|
741
|
+
children: t("Delete Account")
|
|
742
|
+
}
|
|
743
|
+
),
|
|
744
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
745
|
+
import_stack_ui.Button,
|
|
746
|
+
{
|
|
747
|
+
variant: "secondary",
|
|
748
|
+
onClick: () => setDeleting(false),
|
|
749
|
+
children: t("Cancel")
|
|
750
|
+
}
|
|
751
|
+
)
|
|
752
|
+
] })
|
|
753
|
+
] }) })
|
|
754
|
+
] }) }) })
|
|
755
|
+
}
|
|
756
|
+
);
|
|
757
|
+
}
|
|
582
758
|
// Annotate the CommonJS export names for ESM import in node:
|
|
583
759
|
0 && (module.exports = {
|
|
584
760
|
AccountSettings,
|
|
585
|
-
TeamCreation
|
|
761
|
+
TeamCreation,
|
|
762
|
+
useDeleteAccountSection
|
|
586
763
|
});
|
|
587
764
|
//# sourceMappingURL=account-settings.js.map
|