@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.
Files changed (114) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/components/credential-sign-in.js +4 -2
  3. package/dist/components/credential-sign-in.js.map +1 -1
  4. package/dist/components/credential-sign-up.d.mts +3 -1
  5. package/dist/components/credential-sign-up.d.ts +3 -1
  6. package/dist/components/credential-sign-up.js +23 -17
  7. package/dist/components/credential-sign-up.js.map +1 -1
  8. package/dist/components/elements/sidebar-layout.js +19 -11
  9. package/dist/components/elements/sidebar-layout.js.map +1 -1
  10. package/dist/components/elements/user-avatar.js +1 -1
  11. package/dist/components/elements/user-avatar.js.map +1 -1
  12. package/dist/components/magic-link-sign-in.js +82 -30
  13. package/dist/components/magic-link-sign-in.js.map +1 -1
  14. package/dist/components/message-cards/predefined-message-card.js +22 -20
  15. package/dist/components/message-cards/predefined-message-card.js.map +1 -1
  16. package/dist/components/oauth-button.js +32 -25
  17. package/dist/components/oauth-button.js.map +1 -1
  18. package/dist/components/profile-image-editor.js +2 -2
  19. package/dist/components/profile-image-editor.js.map +1 -1
  20. package/dist/components/selected-team-switcher.js +1 -1
  21. package/dist/components/selected-team-switcher.js.map +1 -1
  22. package/dist/components-page/account-settings.d.mts +4 -2
  23. package/dist/components-page/account-settings.d.ts +4 -2
  24. package/dist/components-page/account-settings.js +365 -188
  25. package/dist/components-page/account-settings.js.map +1 -1
  26. package/dist/components-page/auth-page.d.mts +1 -0
  27. package/dist/components-page/auth-page.d.ts +1 -0
  28. package/dist/components-page/auth-page.js +5 -5
  29. package/dist/components-page/auth-page.js.map +1 -1
  30. package/dist/components-page/email-verification.js +10 -8
  31. package/dist/components-page/email-verification.js.map +1 -1
  32. package/dist/components-page/error-page.js +19 -4
  33. package/dist/components-page/error-page.js.map +1 -1
  34. package/dist/components-page/magic-link-callback.js +11 -9
  35. package/dist/components-page/magic-link-callback.js.map +1 -1
  36. package/dist/components-page/oauth-callback.js +1 -1
  37. package/dist/components-page/oauth-callback.js.map +1 -1
  38. package/dist/components-page/password-reset.js +13 -11
  39. package/dist/components-page/password-reset.js.map +1 -1
  40. package/dist/components-page/sign-up.d.mts +1 -0
  41. package/dist/components-page/sign-up.d.ts +1 -0
  42. package/dist/components-page/sign-up.js +10 -1
  43. package/dist/components-page/sign-up.js.map +1 -1
  44. package/dist/components-page/stack-handler.d.mts +1 -0
  45. package/dist/components-page/stack-handler.d.ts +1 -0
  46. package/dist/esm/components/credential-sign-in.js +4 -2
  47. package/dist/esm/components/credential-sign-in.js.map +1 -1
  48. package/dist/esm/components/credential-sign-up.js +24 -18
  49. package/dist/esm/components/credential-sign-up.js.map +1 -1
  50. package/dist/esm/components/elements/sidebar-layout.js +19 -11
  51. package/dist/esm/components/elements/sidebar-layout.js.map +1 -1
  52. package/dist/esm/components/elements/user-avatar.js +1 -1
  53. package/dist/esm/components/elements/user-avatar.js.map +1 -1
  54. package/dist/esm/components/magic-link-sign-in.js +84 -32
  55. package/dist/esm/components/magic-link-sign-in.js.map +1 -1
  56. package/dist/esm/components/message-cards/predefined-message-card.js +22 -20
  57. package/dist/esm/components/message-cards/predefined-message-card.js.map +1 -1
  58. package/dist/esm/components/oauth-button.js +32 -25
  59. package/dist/esm/components/oauth-button.js.map +1 -1
  60. package/dist/esm/components/profile-image-editor.js +2 -2
  61. package/dist/esm/components/profile-image-editor.js.map +1 -1
  62. package/dist/esm/components/selected-team-switcher.js +1 -1
  63. package/dist/esm/components/selected-team-switcher.js.map +1 -1
  64. package/dist/esm/components-page/account-settings.js +365 -189
  65. package/dist/esm/components-page/account-settings.js.map +1 -1
  66. package/dist/esm/components-page/auth-page.js +5 -5
  67. package/dist/esm/components-page/auth-page.js.map +1 -1
  68. package/dist/esm/components-page/email-verification.js +10 -8
  69. package/dist/esm/components-page/email-verification.js.map +1 -1
  70. package/dist/esm/components-page/error-page.js +19 -4
  71. package/dist/esm/components-page/error-page.js.map +1 -1
  72. package/dist/esm/components-page/magic-link-callback.js +11 -9
  73. package/dist/esm/components-page/magic-link-callback.js.map +1 -1
  74. package/dist/esm/components-page/oauth-callback.js +1 -1
  75. package/dist/esm/components-page/oauth-callback.js.map +1 -1
  76. package/dist/esm/components-page/password-reset.js +13 -11
  77. package/dist/esm/components-page/password-reset.js.map +1 -1
  78. package/dist/esm/components-page/sign-up.js +10 -1
  79. package/dist/esm/components-page/sign-up.js.map +1 -1
  80. package/dist/esm/generated/global-css.js +1 -1
  81. package/dist/esm/generated/global-css.js.map +1 -1
  82. package/dist/esm/generated/quetzal-translations.js +1764 -1356
  83. package/dist/esm/generated/quetzal-translations.js.map +1 -1
  84. package/dist/esm/lib/auth.js +4 -3
  85. package/dist/esm/lib/auth.js.map +1 -1
  86. package/dist/esm/lib/stack-app.js +54 -45
  87. package/dist/esm/lib/stack-app.js.map +1 -1
  88. package/dist/esm/lib/translations.js +6 -2
  89. package/dist/esm/lib/translations.js.map +1 -1
  90. package/dist/esm/utils/browser-script.js +9 -7
  91. package/dist/esm/utils/browser-script.js.map +1 -1
  92. package/dist/generated/global-css.d.mts +1 -1
  93. package/dist/generated/global-css.d.ts +1 -1
  94. package/dist/generated/global-css.js +1 -1
  95. package/dist/generated/global-css.js.map +1 -1
  96. package/dist/generated/quetzal-translations.d.mts +2 -2
  97. package/dist/generated/quetzal-translations.d.ts +2 -2
  98. package/dist/generated/quetzal-translations.js +1764 -1356
  99. package/dist/generated/quetzal-translations.js.map +1 -1
  100. package/dist/lib/auth.d.mts +16 -6
  101. package/dist/lib/auth.d.ts +16 -6
  102. package/dist/lib/auth.js +4 -3
  103. package/dist/lib/auth.js.map +1 -1
  104. package/dist/lib/stack-app.d.mts +21 -12
  105. package/dist/lib/stack-app.d.ts +21 -12
  106. package/dist/lib/stack-app.js +53 -44
  107. package/dist/lib/stack-app.js.map +1 -1
  108. package/dist/lib/translations.d.mts +1 -1
  109. package/dist/lib/translations.d.ts +1 -1
  110. package/dist/lib/translations.js +6 -2
  111. package/dist/lib/translations.js.map +1 -1
  112. package/dist/utils/browser-script.js +9 -7
  113. package/dist/utils/browser-script.js.map +1 -1
  114. 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)(ProfileSection, {})
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
- content: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col gap-8", children: [
85
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EmailVerificationSection, {}),
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("Sign Out"),
92
- subpath: "/sign-out",
89
+ title: t("Settings"),
93
90
  type: "item",
94
- icon: import_lucide_react.LogOut,
95
- content: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SignOutSection, {})
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.jsxs)("div", { className: "flex flex-col gap-8", children: [
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 ProfileSection() {
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)("div", { className: "flex flex-col gap-8", children: [
140
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col items-start", children: [
141
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Label, { className: "mb-2", children: t("Profile image") }),
142
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
143
- import_profile_image_editor.ProfileImageEditor,
144
- {
145
- user,
146
- onProfileImageUrlChange: async (profileImageUrl) => {
147
- await user.update({ profileImageUrl });
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.jsxs)("div", { className: "flex flex-col", children: [
153
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Label, { children: t("Display name") }),
154
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.EditableText, { value: user.displayName || "", onSave: async (newDisplayName) => {
155
- await user.update({ displayName: newDisplayName });
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 EmailVerificationSection() {
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)(import_jsx_runtime.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
168
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Label, { children: t("Email Verification") }),
169
- 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.jsxs)(import_jsx_runtime.Fragment, { children: [
170
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "destructive", children: t("Your email has not been verified.") }),
171
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex mt-4", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
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 PasswordSection() {
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 MfaSection() {
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)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
317
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Label, { children: t("Multi-factor Authentication") }),
318
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
319
- isEnabled ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "success", children: t("Multi-factor authentication is currently enabled.") }) : generatedSecret ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col gap-4 items-center", children: [
320
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { children: t("Scan this QR code with your authenticator app:") }),
321
- /* @__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") }),
322
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { children: t("Then, enter your six-digit MFA code:") }),
323
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
324
- import_stack_ui.Input,
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
- value: mfaCode,
327
- onChange: (e) => {
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
- } else if (!generatedSecret) {
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
- } else {
353
- setGeneratedSecret(null);
354
- setQrCodeUrl(null);
355
- setMfaCode("");
356
- }
357
- },
358
- children: isEnabled ? t("Disable") : generatedSecret ? t("Cancel") : t("Enable")
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 SignOutSection() {
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)("div", { className: "flex flex-col gap-2", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
372
- import_stack_ui.Button,
430
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
431
+ Section,
373
432
  {
374
- variant: "secondary",
375
- onClick: () => user.signOut(),
376
- children: t("Sign Out")
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 UserSettings(props) {
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)("div", { className: "flex flex-col gap-2", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: !leaving ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
385
- import_stack_ui.Button,
466
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
467
+ Section,
386
468
  {
387
- variant: "secondary",
388
- onClick: async () => setLeaving(true),
389
- children: t("Leave team")
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
- ) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "", children: [
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 ManagementSettings(props) {
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.jsxs)(import_jsx_runtime.Fragment, { children: [
410
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col", children: [
411
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Label, { children: t("Team display name") }),
412
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
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
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col", children: [
423
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Label, { children: t("Team display name") }),
424
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
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 ProfileSettings(props) {
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)("div", { className: "flex flex-col", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col", children: [
439
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_stack_ui.Label, { className: "flex gap-2", children: [
440
- t("User display name"),
441
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.SimpleTooltip, { tooltip: "This overwrites your user display name in the account setting", type: "info" })
442
- ] }),
443
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
444
- import_stack_ui.EditableText,
445
- {
446
- value: profile.displayName || "",
447
- onSave: async (newDisplayName) => {
448
- await profile.update({ displayName: newDisplayName });
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 MemberInvitation(props) {
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.jsxs)("div", { children: [
482
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Label, { children: t("Invite a user to team") }),
483
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
484
- "form",
485
- {
486
- onSubmit: (e) => (0, import_promises.runAsynchronouslyWithAlert)(handleSubmit(onSubmit)(e)),
487
- noValidate: true,
488
- children: [
489
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col gap-4 md:flex-row", children: [
490
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
491
- import_stack_ui.Input,
492
- {
493
- placeholder: t("Email"),
494
- ...register("email")
495
- }
496
- ) }),
497
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Button, { type: "submit", loading, children: t("Invite User") })
498
- ] }),
499
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_form_warning.FormWarningText, { text: errors.email?.message?.toString() }),
500
- invitedEmail && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_stack_ui.Typography, { type: "label", variant: "secondary", children: [
501
- "Invited ",
502
- invitedEmail
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 MembersSettings(props) {
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.Label, { children: t("Members") }),
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
- const team = await user.createTeam({ displayName: data.displayName });
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)("div", { className: "stack-scope flex flex-col items-stretch", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mb-6", children: /* @__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
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-end gap-4", children: [
565
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
566
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Label, { htmlFor: "email", className: "mb-1", children: t("Display name") }),
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: "email",
571
- type: "email",
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)(import_form_warning.FormWarningText, { text: errors.displayName?.message?.toString() }),
577
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Button, { type: "submit", className: "mt-6", loading, children: t("Create") })
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