@stackframe/stack 2.5.33 → 2.5.37

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 (148) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/dist/components/credential-sign-in.js +14 -12
  3. package/dist/components/credential-sign-in.js.map +1 -1
  4. package/dist/components/credential-sign-up.js +17 -15
  5. package/dist/components/credential-sign-up.js.map +1 -1
  6. package/dist/components/elements/maybe-full-page.d.mts +2 -2
  7. package/dist/components/elements/maybe-full-page.d.ts +2 -2
  8. package/dist/components/elements/sidebar-layout.d.mts +5 -5
  9. package/dist/components/elements/sidebar-layout.d.ts +5 -5
  10. package/dist/components/elements/sidebar-layout.js +15 -7
  11. package/dist/components/elements/sidebar-layout.js.map +1 -1
  12. package/dist/components/elements/user-avatar.js +1 -1
  13. package/dist/components/elements/user-avatar.js.map +1 -1
  14. package/dist/components/magic-link-sign-in.js +11 -9
  15. package/dist/components/magic-link-sign-in.js.map +1 -1
  16. package/dist/components/message-cards/message-card.d.mts +2 -2
  17. package/dist/components/message-cards/message-card.d.ts +2 -2
  18. package/dist/components/oauth-button-group.js.map +1 -1
  19. package/dist/components/oauth-button.js +46 -2
  20. package/dist/components/oauth-button.js.map +1 -1
  21. package/dist/components/profile-image-editor.js +7 -5
  22. package/dist/components/profile-image-editor.js.map +1 -1
  23. package/dist/components/selected-team-switcher.js +7 -4
  24. package/dist/components/selected-team-switcher.js.map +1 -1
  25. package/dist/components/team-icon.js.map +1 -1
  26. package/dist/components/user-button.d.mts +2 -2
  27. package/dist/components/user-button.d.ts +2 -2
  28. package/dist/components/user-button.js +11 -11
  29. package/dist/components/user-button.js.map +1 -1
  30. package/dist/components-page/account-settings.d.mts +4 -2
  31. package/dist/components-page/account-settings.d.ts +4 -2
  32. package/dist/components-page/account-settings.js +406 -221
  33. package/dist/components-page/account-settings.js.map +1 -1
  34. package/dist/components-page/auth-page.js +11 -7
  35. package/dist/components-page/auth-page.js.map +1 -1
  36. package/dist/components-page/email-verification.js +4 -2
  37. package/dist/components-page/email-verification.js.map +1 -1
  38. package/dist/components-page/error-page.js +6 -4
  39. package/dist/components-page/error-page.js.map +1 -1
  40. package/dist/components-page/forgot-password.js +12 -8
  41. package/dist/components-page/forgot-password.js.map +1 -1
  42. package/dist/components-page/magic-link-callback.js +5 -3
  43. package/dist/components-page/magic-link-callback.js.map +1 -1
  44. package/dist/components-page/oauth-callback.js +6 -5
  45. package/dist/components-page/oauth-callback.js.map +1 -1
  46. package/dist/components-page/password-reset.js +25 -22
  47. package/dist/components-page/password-reset.js.map +1 -1
  48. package/dist/components-page/stack-handler.d.mts +1 -0
  49. package/dist/components-page/stack-handler.d.ts +1 -0
  50. package/dist/components-page/team-creation.js +9 -7
  51. package/dist/components-page/team-creation.js.map +1 -1
  52. package/dist/components-page/team-invitation.js +14 -11
  53. package/dist/components-page/team-invitation.js.map +1 -1
  54. package/dist/esm/components/credential-sign-in.js +14 -12
  55. package/dist/esm/components/credential-sign-in.js.map +1 -1
  56. package/dist/esm/components/credential-sign-up.js +17 -15
  57. package/dist/esm/components/credential-sign-up.js.map +1 -1
  58. package/dist/esm/components/elements/sidebar-layout.js +15 -7
  59. package/dist/esm/components/elements/sidebar-layout.js.map +1 -1
  60. package/dist/esm/components/elements/user-avatar.js +1 -1
  61. package/dist/esm/components/elements/user-avatar.js.map +1 -1
  62. package/dist/esm/components/magic-link-sign-in.js +11 -9
  63. package/dist/esm/components/magic-link-sign-in.js.map +1 -1
  64. package/dist/esm/components/oauth-button-group.js.map +1 -1
  65. package/dist/esm/components/oauth-button.js +46 -2
  66. package/dist/esm/components/oauth-button.js.map +1 -1
  67. package/dist/esm/components/profile-image-editor.js +7 -5
  68. package/dist/esm/components/profile-image-editor.js.map +1 -1
  69. package/dist/esm/components/selected-team-switcher.js +7 -4
  70. package/dist/esm/components/selected-team-switcher.js.map +1 -1
  71. package/dist/esm/components/team-icon.js.map +1 -1
  72. package/dist/esm/components/user-button.js +12 -15
  73. package/dist/esm/components/user-button.js.map +1 -1
  74. package/dist/esm/components-page/account-settings.js +406 -222
  75. package/dist/esm/components-page/account-settings.js.map +1 -1
  76. package/dist/esm/components-page/auth-page.js +11 -7
  77. package/dist/esm/components-page/auth-page.js.map +1 -1
  78. package/dist/esm/components-page/email-verification.js +4 -2
  79. package/dist/esm/components-page/email-verification.js.map +1 -1
  80. package/dist/esm/components-page/error-page.js +6 -4
  81. package/dist/esm/components-page/error-page.js.map +1 -1
  82. package/dist/esm/components-page/forgot-password.js +12 -8
  83. package/dist/esm/components-page/forgot-password.js.map +1 -1
  84. package/dist/esm/components-page/magic-link-callback.js +5 -3
  85. package/dist/esm/components-page/magic-link-callback.js.map +1 -1
  86. package/dist/esm/components-page/oauth-callback.js +6 -5
  87. package/dist/esm/components-page/oauth-callback.js.map +1 -1
  88. package/dist/esm/components-page/password-reset.js +25 -22
  89. package/dist/esm/components-page/password-reset.js.map +1 -1
  90. package/dist/esm/components-page/team-creation.js +9 -7
  91. package/dist/esm/components-page/team-creation.js.map +1 -1
  92. package/dist/esm/components-page/team-invitation.js +14 -11
  93. package/dist/esm/components-page/team-invitation.js.map +1 -1
  94. package/dist/esm/generated/global-css.js +1 -1
  95. package/dist/esm/generated/global-css.js.map +1 -1
  96. package/dist/esm/generated/quetzal-translations.js +1629 -0
  97. package/dist/esm/generated/quetzal-translations.js.map +1 -0
  98. package/dist/esm/lib/stack-app.js +8 -1
  99. package/dist/esm/lib/stack-app.js.map +1 -1
  100. package/dist/esm/lib/translations.js +20 -0
  101. package/dist/esm/lib/translations.js.map +1 -0
  102. package/dist/esm/providers/stack-provider.js +4 -2
  103. package/dist/esm/providers/stack-provider.js.map +1 -1
  104. package/dist/esm/providers/theme-provider.js.map +1 -1
  105. package/dist/esm/providers/translation-provider-client.js +18 -0
  106. package/dist/esm/providers/translation-provider-client.js.map +1 -0
  107. package/dist/esm/providers/translation-provider.js +12 -0
  108. package/dist/esm/providers/translation-provider.js.map +1 -0
  109. package/dist/esm/utils/browser-script.js +43 -8
  110. package/dist/esm/utils/browser-script.js.map +1 -1
  111. package/dist/generated/global-css.d.mts +1 -1
  112. package/dist/generated/global-css.d.ts +1 -1
  113. package/dist/generated/global-css.js +1 -1
  114. package/dist/generated/global-css.js.map +1 -1
  115. package/dist/generated/quetzal-translations.d.mts +4 -0
  116. package/dist/generated/quetzal-translations.d.ts +4 -0
  117. package/dist/generated/quetzal-translations.js +1655 -0
  118. package/dist/generated/quetzal-translations.js.map +1 -0
  119. package/dist/index.d.mts +2 -0
  120. package/dist/index.d.ts +2 -0
  121. package/dist/lib/stack-app.d.mts +4 -1
  122. package/dist/lib/stack-app.d.ts +4 -1
  123. package/dist/lib/stack-app.js +8 -1
  124. package/dist/lib/stack-app.js.map +1 -1
  125. package/dist/lib/translations.d.mts +5 -0
  126. package/dist/lib/translations.d.ts +5 -0
  127. package/dist/lib/translations.js +55 -0
  128. package/dist/lib/translations.js.map +1 -0
  129. package/dist/providers/stack-provider-client.d.mts +3 -3
  130. package/dist/providers/stack-provider-client.d.ts +3 -3
  131. package/dist/providers/stack-provider.d.mts +6 -3
  132. package/dist/providers/stack-provider.d.ts +6 -3
  133. package/dist/providers/stack-provider.js +4 -2
  134. package/dist/providers/stack-provider.js.map +1 -1
  135. package/dist/providers/theme-provider.d.mts +2 -2
  136. package/dist/providers/theme-provider.d.ts +2 -2
  137. package/dist/providers/theme-provider.js.map +1 -1
  138. package/dist/providers/translation-provider-client.d.mts +14 -0
  139. package/dist/providers/translation-provider-client.d.ts +14 -0
  140. package/dist/providers/translation-provider-client.js +43 -0
  141. package/dist/providers/translation-provider-client.js.map +1 -0
  142. package/dist/providers/translation-provider.d.mts +9 -0
  143. package/dist/providers/translation-provider.d.ts +9 -0
  144. package/dist/providers/translation-provider.js +37 -0
  145. package/dist/providers/translation-provider.js.map +1 -0
  146. package/dist/utils/browser-script.js +43 -8
  147. package/dist/utils/browser-script.js.map +1 -1
  148. package/package.json +20 -12
@@ -9,22 +9,24 @@ import { yupObject, yupString } from "@stackframe/stack-shared/dist/schema-field
9
9
  import { generateRandomValues } from "@stackframe/stack-shared/dist/utils/crypto";
10
10
  import { throwErr } from "@stackframe/stack-shared/dist/utils/errors";
11
11
  import { runAsynchronously, runAsynchronouslyWithAlert } from "@stackframe/stack-shared/dist/utils/promises";
12
- import { Button, EditableText, Input, Label, PasswordInput, SimpleTooltip, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Typography } from "@stackframe/stack-ui";
13
- import { CirclePlus, Contact, LogOut, ShieldCheck } from "lucide-react";
12
+ import { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Button, EditableText, Input, Label, PasswordInput, Separator, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Typography } from "@stackframe/stack-ui";
13
+ import { CirclePlus, Contact, Settings, ShieldCheck } from "lucide-react";
14
14
  import { TOTPController, createTOTPKeyURI } from "oslo/otp";
15
15
  import * as QRCode from "qrcode";
16
- import { useEffect, useState } from "react";
16
+ import React, { useEffect, useState } from "react";
17
17
  import { useForm } from "react-hook-form";
18
18
  import * as yup from "yup";
19
19
  import { MessageCard, useStackApp, useUser } from "..";
20
20
  import { FormWarningText } from "../components/elements/form-warning";
21
+ import { MaybeFullPage } from "../components/elements/maybe-full-page";
21
22
  import { SidebarLayout } from "../components/elements/sidebar-layout";
22
23
  import { UserAvatar } from "../components/elements/user-avatar";
23
24
  import { ProfileImageEditor } from "../components/profile-image-editor";
24
25
  import { TeamIcon } from "../components/team-icon";
25
- import { MaybeFullPage } from "../components/elements/maybe-full-page";
26
+ import { useTranslation } from "../lib/translations";
26
27
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
27
28
  function AccountSettings(props) {
29
+ const { t } = useTranslation();
28
30
  const user = useUser({ or: "redirect" });
29
31
  const teams = user.useTeams();
30
32
  const stackApp = useStackApp();
@@ -34,29 +36,25 @@ function AccountSettings(props) {
34
36
  {
35
37
  items: [
36
38
  {
37
- title: "My Profile",
39
+ title: t("My Profile"),
38
40
  type: "item",
39
41
  subpath: "/profile",
40
42
  icon: Contact,
41
- content: /* @__PURE__ */ jsx(ProfileSection, {})
43
+ content: /* @__PURE__ */ jsx(ProfilePage, {})
42
44
  },
43
45
  {
44
- title: "Security",
46
+ title: t("Security"),
45
47
  type: "item",
46
- icon: ShieldCheck,
47
48
  subpath: "/security",
48
- content: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-8", children: [
49
- /* @__PURE__ */ jsx(EmailVerificationSection, {}),
50
- /* @__PURE__ */ jsx(PasswordSection, {}),
51
- /* @__PURE__ */ jsx(MfaSection, {})
52
- ] })
49
+ icon: ShieldCheck,
50
+ content: /* @__PURE__ */ jsx(SecurityPage, {})
53
51
  },
54
52
  {
55
- title: "Sign Out",
56
- subpath: "/sign-out",
53
+ title: t("Settings"),
57
54
  type: "item",
58
- icon: LogOut,
59
- content: /* @__PURE__ */ jsx(SignOutSection, {})
55
+ subpath: "/settings",
56
+ icon: Settings,
57
+ content: /* @__PURE__ */ jsx(SettingsPage, {})
60
58
  },
61
59
  ...props.extraItems?.map((item) => ({
62
60
  title: item.title,
@@ -66,7 +64,7 @@ function AccountSettings(props) {
66
64
  content: item.content
67
65
  })) || [],
68
66
  ...teams.length > 0 || project.config.clientTeamCreationEnabled ? [{
69
- title: "Teams",
67
+ title: t("Teams"),
70
68
  type: "divider"
71
69
  }] : [],
72
70
  ...teams.map((team) => ({
@@ -76,61 +74,108 @@ function AccountSettings(props) {
76
74
  ] }),
77
75
  type: "item",
78
76
  subpath: `/teams/${team.id}`,
79
- content: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-8", children: [
80
- /* @__PURE__ */ jsx(ProfileSettings, { team }),
81
- /* @__PURE__ */ jsx(ManagementSettings, { team }),
82
- /* @__PURE__ */ jsx(MemberInvitation, { team }),
83
- /* @__PURE__ */ jsx(MembersSettings, { team }),
84
- /* @__PURE__ */ jsx(UserSettings, { team })
85
- ] })
77
+ content: /* @__PURE__ */ jsx(TeamPage, { team })
86
78
  })),
87
79
  ...project.config.clientTeamCreationEnabled ? [{
88
- title: "Create a team",
80
+ title: t("Create a team"),
89
81
  icon: CirclePlus,
90
82
  type: "item",
91
83
  subpath: "/team-creation",
92
84
  content: /* @__PURE__ */ jsx(TeamCreation, {})
93
85
  }] : []
94
86
  ].filter((p) => p.type === "divider" || p.content),
95
- title: "Account Settings",
87
+ title: t("Account Settings"),
96
88
  basePath: stackApp.urls.accountSettings
97
89
  }
98
90
  ) }) });
99
91
  }
100
- function ProfileSection() {
92
+ function Section(props) {
93
+ return /* @__PURE__ */ jsxs("div", { className: "flex", children: [
94
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col justify-center", children: [
95
+ /* @__PURE__ */ jsx(Typography, { className: "font-medium", children: props.title }),
96
+ props.description && /* @__PURE__ */ jsx(Typography, { variant: "secondary", type: "footnote", children: props.description })
97
+ ] }),
98
+ /* @__PURE__ */ jsx("div", { className: "flex-1 flex flex-col gap-2", children: props.children })
99
+ ] });
100
+ }
101
+ function PageLayout(props) {
102
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-6", children: [
103
+ /* @__PURE__ */ jsx(Separator, {}),
104
+ React.Children.map(props.children, (child) => child && /* @__PURE__ */ jsxs(Fragment, { children: [
105
+ child,
106
+ /* @__PURE__ */ jsx(Separator, {})
107
+ ] }))
108
+ ] });
109
+ }
110
+ function ProfilePage() {
111
+ const { t } = useTranslation();
101
112
  const user = useUser({ or: "redirect" });
102
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-8", children: [
103
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-start", children: [
104
- /* @__PURE__ */ jsx(Label, { className: "mb-2", children: "Profile image" }),
105
- /* @__PURE__ */ jsx(
106
- ProfileImageEditor,
107
- {
108
- user,
109
- onProfileImageUrlChange: async (profileImageUrl) => {
110
- await user.update({ profileImageUrl });
113
+ return /* @__PURE__ */ jsxs(PageLayout, { children: [
114
+ /* @__PURE__ */ jsx(
115
+ Section,
116
+ {
117
+ title: t("User name"),
118
+ description: t("This is a display name and is not used for authentication"),
119
+ children: /* @__PURE__ */ jsx(
120
+ EditableText,
121
+ {
122
+ value: user.displayName || "",
123
+ onSave: async (newDisplayName) => {
124
+ await user.update({ displayName: newDisplayName });
125
+ }
111
126
  }
112
- }
113
- )
114
- ] }),
115
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
116
- /* @__PURE__ */ jsx(Label, { children: "Display name" }),
117
- /* @__PURE__ */ jsx(EditableText, { value: user.displayName || "", onSave: async (newDisplayName) => {
118
- await user.update({ displayName: newDisplayName });
119
- } })
120
- ] })
127
+ )
128
+ }
129
+ ),
130
+ /* @__PURE__ */ jsx(
131
+ Section,
132
+ {
133
+ title: t("Profile image"),
134
+ description: t("Upload your own image as your avatar"),
135
+ children: /* @__PURE__ */ jsx(
136
+ ProfileImageEditor,
137
+ {
138
+ user,
139
+ onProfileImageUrlChange: async (profileImageUrl) => {
140
+ await user.update({ profileImageUrl });
141
+ }
142
+ }
143
+ )
144
+ }
145
+ )
146
+ ] });
147
+ }
148
+ function SecurityPage() {
149
+ const emailVerificationSection = useEmailVerificationSection();
150
+ const passwordSection = usePasswordSection();
151
+ const mfaSection = useMfaSection();
152
+ return /* @__PURE__ */ jsxs(PageLayout, { children: [
153
+ emailVerificationSection,
154
+ passwordSection,
155
+ mfaSection
156
+ ] });
157
+ }
158
+ function SettingsPage() {
159
+ const deleteAccountSection = useDeleteAccountSection();
160
+ const signOutSection = useSignOutSection();
161
+ return /* @__PURE__ */ jsxs(PageLayout, { children: [
162
+ deleteAccountSection,
163
+ signOutSection
121
164
  ] });
122
165
  }
123
- function EmailVerificationSection() {
166
+ function useEmailVerificationSection() {
167
+ const { t } = useTranslation();
124
168
  const user = useUser({ or: "redirect" });
125
169
  const [emailSent, setEmailSent] = useState(false);
126
170
  if (!user.primaryEmail) {
127
171
  return null;
128
172
  }
129
- return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs("div", { children: [
130
- /* @__PURE__ */ jsx(Label, { children: "Email Verification" }),
131
- user.primaryEmailVerified ? /* @__PURE__ */ jsx(Typography, { variant: "success", children: "Your email has been verified." }) : /* @__PURE__ */ jsxs(Fragment, { children: [
132
- /* @__PURE__ */ jsx(Typography, { variant: "destructive", children: "Your email has not been verified." }),
133
- /* @__PURE__ */ jsx("div", { className: "flex mt-4", children: /* @__PURE__ */ jsx(
173
+ return /* @__PURE__ */ jsx(
174
+ Section,
175
+ {
176
+ title: t("Email Verification"),
177
+ description: t("Verify your email address to secure your account"),
178
+ children: /* @__PURE__ */ jsx("div", { children: user.primaryEmailVerified ? /* @__PURE__ */ jsx(Typography, { variant: "success", children: t("Your email has been verified.") }) : /* @__PURE__ */ jsx("div", { className: "flex", children: /* @__PURE__ */ jsx(
134
179
  Button,
135
180
  {
136
181
  disabled: emailSent,
@@ -138,28 +183,29 @@ function EmailVerificationSection() {
138
183
  await user.sendVerificationEmail();
139
184
  setEmailSent(true);
140
185
  },
141
- children: emailSent ? "Email sent!" : "Send Verification Email"
186
+ children: emailSent ? t("Email sent!") : t("Send Verification Email")
142
187
  }
143
- ) })
144
- ] })
145
- ] }) });
188
+ ) }) })
189
+ }
190
+ );
146
191
  }
147
- var passwordSchema = yupObject({
148
- oldPassword: yupString().required("Please enter your old password"),
149
- newPassword: yupString().required("Please enter your password").test({
150
- name: "is-valid-password",
151
- test: (value, ctx) => {
152
- const error = getPasswordError(value);
153
- if (error) {
154
- return ctx.createError({ message: error.message });
155
- } else {
156
- return true;
192
+ function usePasswordSection() {
193
+ const { t } = useTranslation();
194
+ const passwordSchema = yupObject({
195
+ oldPassword: yupString().required(t("Please enter your old password")),
196
+ newPassword: yupString().required(t("Please enter your password")).test({
197
+ name: "is-valid-password",
198
+ test: (value, ctx) => {
199
+ const error = getPasswordError(value);
200
+ if (error) {
201
+ return ctx.createError({ message: error.message });
202
+ } else {
203
+ return true;
204
+ }
157
205
  }
158
- }
159
- }),
160
- newPasswordRepeat: yupString().nullable().oneOf([yup.ref("newPassword"), "", null], "Passwords do not match").required("Please repeat your password")
161
- });
162
- function PasswordSection() {
206
+ }),
207
+ newPasswordRepeat: yupString().nullable().oneOf([yup.ref("newPassword"), "", null], t("Passwords do not match")).required(t("Please repeat your password"))
208
+ });
163
209
  const user = useUser({ or: "throw" });
164
210
  const [changingPassword, setChangingPassword] = useState(false);
165
211
  const { register, handleSubmit, setError, formState: { errors }, clearErrors, reset } = useForm({
@@ -173,7 +219,7 @@ function PasswordSection() {
173
219
  const { oldPassword, newPassword } = data;
174
220
  const error = await user.updatePassword({ oldPassword, newPassword });
175
221
  if (error) {
176
- setError("oldPassword", { type: "manual", message: "Incorrect password" });
222
+ setError("oldPassword", { type: "manual", message: t("Incorrect password") });
177
223
  } else {
178
224
  reset();
179
225
  setAlreadyReset(true);
@@ -188,15 +234,15 @@ function PasswordSection() {
188
234
  return null;
189
235
  }
190
236
  return /* @__PURE__ */ jsxs("div", { children: [
191
- /* @__PURE__ */ jsx(Label, { children: "Change password" }),
192
- /* @__PURE__ */ jsx("div", { children: alreadyReset ? /* @__PURE__ */ jsx(Typography, { variant: "success", children: "Password changed successfully!" }) : !changingPassword ? /* @__PURE__ */ jsx(
237
+ /* @__PURE__ */ jsx(Label, { children: t("Change password") }),
238
+ /* @__PURE__ */ jsx("div", { children: alreadyReset ? /* @__PURE__ */ jsx(Typography, { variant: "success", children: t("Password changed successfully!") }) : !changingPassword ? /* @__PURE__ */ jsx(
193
239
  Button,
194
240
  {
195
241
  variant: "secondary",
196
242
  onClick: async () => {
197
243
  setChangingPassword(true);
198
244
  },
199
- children: "Change Password"
245
+ children: t("Change Password")
200
246
  }
201
247
  ) : /* @__PURE__ */ jsxs(
202
248
  "form",
@@ -204,7 +250,7 @@ function PasswordSection() {
204
250
  onSubmit: (e) => runAsynchronouslyWithAlert(handleSubmit(onSubmit)(e)),
205
251
  noValidate: true,
206
252
  children: [
207
- /* @__PURE__ */ jsx(Label, { htmlFor: "old-password", className: "mb-1", children: "Old password" }),
253
+ /* @__PURE__ */ jsx(Label, { htmlFor: "old-password", className: "mb-1", children: t("Old password") }),
208
254
  /* @__PURE__ */ jsx(
209
255
  Input,
210
256
  {
@@ -214,7 +260,7 @@ function PasswordSection() {
214
260
  }
215
261
  ),
216
262
  /* @__PURE__ */ jsx(FormWarningText, { text: errors.oldPassword?.message?.toString() }),
217
- /* @__PURE__ */ jsx(Label, { htmlFor: "new-password", className: "mt-4 mb-1", children: "Password" }),
263
+ /* @__PURE__ */ jsx(Label, { htmlFor: "new-password", className: "mt-4 mb-1", children: t("Password") }),
218
264
  /* @__PURE__ */ jsx(
219
265
  PasswordInput,
220
266
  {
@@ -228,7 +274,7 @@ function PasswordSection() {
228
274
  }
229
275
  ),
230
276
  /* @__PURE__ */ jsx(FormWarningText, { text: errors.newPassword?.message?.toString() }),
231
- /* @__PURE__ */ jsx(Label, { htmlFor: "repeat-password", className: "mt-4 mb-1", children: "Repeat password" }),
277
+ /* @__PURE__ */ jsx(Label, { htmlFor: "repeat-password", className: "mt-4 mb-1", children: t("Repeat password") }),
232
278
  /* @__PURE__ */ jsx(
233
279
  PasswordInput,
234
280
  {
@@ -242,13 +288,14 @@ function PasswordSection() {
242
288
  }
243
289
  ),
244
290
  /* @__PURE__ */ jsx(FormWarningText, { text: errors.newPasswordRepeat?.message?.toString() }),
245
- /* @__PURE__ */ jsx(Button, { type: "submit", className: "mt-6", loading, children: "Change Password" })
291
+ /* @__PURE__ */ jsx(Button, { type: "submit", className: "mt-6", loading, children: t("Change Password") })
246
292
  ]
247
293
  }
248
294
  ) })
249
295
  ] });
250
296
  }
251
- function MfaSection() {
297
+ function useMfaSection() {
298
+ const { t } = useTranslation();
252
299
  const project = useStackApp().useProject();
253
300
  const user = useUser({ or: "throw" });
254
301
  const [generatedSecret, setGeneratedSecret] = useState(null);
@@ -273,100 +320,165 @@ function MfaSection() {
273
320
  setIsMaybeWrong(true);
274
321
  });
275
322
  }, [mfaCode, generatedSecret, handleSubmit]);
276
- return /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs("div", { children: [
277
- /* @__PURE__ */ jsx(Label, { children: "Multi-factor Authentication" }),
278
- /* @__PURE__ */ jsxs("div", { children: [
279
- isEnabled ? /* @__PURE__ */ jsx(Typography, { variant: "success", children: "Multi-factor authentication is currently enabled." }) : generatedSecret ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4 items-center", children: [
280
- /* @__PURE__ */ jsx(Typography, { children: "Scan this QR code with your authenticator app:" }),
281
- /* @__PURE__ */ jsx("img", { width: 200, height: 200, src: qrCodeUrl ?? throwErr("TOTP QR code failed to generate"), alt: "TOTP multi-factor authentication QR code" }),
282
- /* @__PURE__ */ jsx(Typography, { children: "Then, enter your six-digit MFA code:" }),
283
- /* @__PURE__ */ jsx(
284
- Input,
323
+ return /* @__PURE__ */ jsx(
324
+ Section,
325
+ {
326
+ title: t("Multi-factor Authentication"),
327
+ description: isEnabled ? t("Multi-factor authentication is currently enabled.") : t("Multi-factor authentication is currently disabled."),
328
+ children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [
329
+ !isEnabled && generatedSecret && /* @__PURE__ */ jsxs(Fragment, { children: [
330
+ /* @__PURE__ */ jsx(Typography, { children: t("Scan this QR code with your authenticator app:") }),
331
+ /* @__PURE__ */ jsx("img", { width: 200, height: 200, src: qrCodeUrl ?? throwErr("TOTP QR code failed to generate"), alt: t("TOTP multi-factor authentication QR code") }),
332
+ /* @__PURE__ */ jsx(Typography, { children: t("Then, enter your six-digit MFA code:") }),
333
+ /* @__PURE__ */ jsx(
334
+ Input,
335
+ {
336
+ value: mfaCode,
337
+ onChange: (e) => {
338
+ setIsMaybeWrong(false);
339
+ setMfaCode(e.target.value);
340
+ },
341
+ placeholder: "123456",
342
+ maxLength: 6,
343
+ disabled: isLoading
344
+ }
345
+ ),
346
+ isMaybeWrong && mfaCode.length === 6 && /* @__PURE__ */ jsx(Typography, { variant: "destructive", children: t("Incorrect code. Please try again.") }),
347
+ /* @__PURE__ */ jsx("div", { className: "flex", children: /* @__PURE__ */ jsx(
348
+ Button,
349
+ {
350
+ variant: "secondary",
351
+ onClick: () => {
352
+ setGeneratedSecret(null);
353
+ setQrCodeUrl(null);
354
+ setMfaCode("");
355
+ },
356
+ children: t("Cancel")
357
+ }
358
+ ) })
359
+ ] }),
360
+ /* @__PURE__ */ jsx("div", { className: "flex gap-2", children: isEnabled ? /* @__PURE__ */ jsx(
361
+ Button,
285
362
  {
286
- value: mfaCode,
287
- onChange: (e) => {
288
- setIsMaybeWrong(false);
289
- setMfaCode(e.target.value);
290
- },
291
- placeholder: "123456",
292
- maxLength: 6,
293
- disabled: isLoading
294
- }
295
- ),
296
- isMaybeWrong && mfaCode.length === 6 && /* @__PURE__ */ jsx(Typography, { variant: "destructive", children: "Incorrect code. Please try again." })
297
- ] }) : /* @__PURE__ */ jsx(Typography, { variant: "destructive", children: "Multi-factor authentication is currently disabled." }),
298
- /* @__PURE__ */ jsx(
299
- Button,
300
- {
301
- className: "mt-4",
302
- variant: isEnabled ? "secondary" : "default",
303
- onClick: async () => {
304
- if (isEnabled) {
363
+ variant: "secondary",
364
+ onClick: async () => {
305
365
  await user.update({
306
366
  totpMultiFactorSecret: null
307
367
  });
308
- } else if (!generatedSecret) {
368
+ },
369
+ children: t("Disable")
370
+ }
371
+ ) : !generatedSecret && /* @__PURE__ */ jsx(
372
+ Button,
373
+ {
374
+ variant: "default",
375
+ onClick: async () => {
309
376
  const secret = generateRandomValues(new Uint8Array(20));
310
377
  setQrCodeUrl(await generateTotpQrCode(project, user, secret));
311
378
  setGeneratedSecret(secret);
312
- } else {
313
- setGeneratedSecret(null);
314
- setQrCodeUrl(null);
315
- setMfaCode("");
316
- }
317
- },
318
- children: isEnabled ? "Disable" : generatedSecret ? "Cancel" : "Enable"
319
- }
320
- )
321
- ] })
322
- ] }) });
379
+ },
380
+ children: t("Enable")
381
+ }
382
+ ) })
383
+ ] })
384
+ }
385
+ );
323
386
  }
324
387
  async function generateTotpQrCode(project, user, secret) {
325
388
  const uri = createTOTPKeyURI(project.displayName, user.primaryEmail ?? user.id, secret);
326
389
  return await QRCode.toDataURL(uri);
327
390
  }
328
- function SignOutSection() {
391
+ function useSignOutSection() {
392
+ const { t } = useTranslation();
329
393
  const user = useUser({ or: "throw" });
330
- return /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
331
- Button,
394
+ return /* @__PURE__ */ jsx(
395
+ Section,
332
396
  {
333
- variant: "secondary",
334
- onClick: () => user.signOut(),
335
- children: "Sign Out"
397
+ title: t("Sign out"),
398
+ description: t("End your current session"),
399
+ children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
400
+ Button,
401
+ {
402
+ variant: "secondary",
403
+ onClick: () => user.signOut(),
404
+ children: t("Sign out")
405
+ }
406
+ ) })
336
407
  }
337
- ) }) });
408
+ );
409
+ }
410
+ function TeamPage(props) {
411
+ const teamUserProfileSection = useTeamUserProfileSection(props);
412
+ const teamProfileImageSection = useTeamProfileImageSection(props);
413
+ const teamDisplayNameSection = useTeamDisplayNameSection(props);
414
+ const leaveTeamSection = useLeaveTeamSection(props);
415
+ const memberInvitationSection = useMemberInvitationSection(props);
416
+ const memberListSection = useMemberListSection(props);
417
+ return /* @__PURE__ */ jsxs(PageLayout, { children: [
418
+ teamUserProfileSection,
419
+ memberInvitationSection,
420
+ memberListSection,
421
+ teamProfileImageSection,
422
+ teamDisplayNameSection,
423
+ leaveTeamSection
424
+ ] });
338
425
  }
339
- function UserSettings(props) {
426
+ function useLeaveTeamSection(props) {
427
+ const { t } = useTranslation();
340
428
  const user = useUser({ or: "redirect" });
341
429
  const [leaving, setLeaving] = useState(false);
342
- return /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children: /* @__PURE__ */ jsx("div", { children: !leaving ? /* @__PURE__ */ jsx(
343
- Button,
430
+ return /* @__PURE__ */ jsx(
431
+ Section,
344
432
  {
345
- variant: "secondary",
346
- onClick: async () => setLeaving(true),
347
- children: "Leave team"
433
+ title: t("Leave Team"),
434
+ description: t("leave this team and remove your team profile"),
435
+ children: !leaving ? /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
436
+ Button,
437
+ {
438
+ variant: "secondary",
439
+ onClick: () => setLeaving(true),
440
+ children: t("Leave team")
441
+ }
442
+ ) }) : /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
443
+ /* @__PURE__ */ jsx(Typography, { variant: "destructive", children: t("Are you sure you want to leave the team?") }),
444
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
445
+ /* @__PURE__ */ jsx(
446
+ Button,
447
+ {
448
+ variant: "destructive",
449
+ onClick: async () => {
450
+ await user.leaveTeam(props.team);
451
+ window.location.reload();
452
+ },
453
+ children: t("Leave")
454
+ }
455
+ ),
456
+ /* @__PURE__ */ jsx(
457
+ Button,
458
+ {
459
+ variant: "secondary",
460
+ onClick: () => setLeaving(false),
461
+ children: t("Cancel")
462
+ }
463
+ )
464
+ ] })
465
+ ] })
348
466
  }
349
- ) : /* @__PURE__ */ jsxs("div", { className: "", children: [
350
- /* @__PURE__ */ jsx(Typography, { variant: "destructive", children: "Are you sure you want to leave the team?" }),
351
- /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
352
- /* @__PURE__ */ jsx(Button, { variant: "destructive", onClick: async () => {
353
- await user.leaveTeam(props.team);
354
- window.location.reload();
355
- }, children: "Leave" }),
356
- /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: () => setLeaving(false), children: "Cancel" })
357
- ] })
358
- ] }) }) });
467
+ );
359
468
  }
360
- function ManagementSettings(props) {
469
+ function useTeamProfileImageSection(props) {
470
+ const { t } = useTranslation();
361
471
  const user = useUser({ or: "redirect" });
362
472
  const updateTeamPermission = user.usePermission(props.team, "$update_team");
363
473
  if (!updateTeamPermission) {
364
474
  return null;
365
475
  }
366
- return /* @__PURE__ */ jsxs(Fragment, { children: [
367
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
368
- /* @__PURE__ */ jsx(Label, { children: "Team display name" }),
369
- /* @__PURE__ */ jsx(
476
+ return /* @__PURE__ */ jsx(
477
+ Section,
478
+ {
479
+ title: t("Team profile image"),
480
+ description: t("Upload an image for your team"),
481
+ children: /* @__PURE__ */ jsx(
370
482
  ProfileImageEditor,
371
483
  {
372
484
  user: props.team,
@@ -375,42 +487,57 @@ function ManagementSettings(props) {
375
487
  }
376
488
  }
377
489
  )
378
- ] }),
379
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
380
- /* @__PURE__ */ jsx(Label, { children: "Team display name" }),
381
- /* @__PURE__ */ jsx(
490
+ }
491
+ );
492
+ }
493
+ function useTeamDisplayNameSection(props) {
494
+ const { t } = useTranslation();
495
+ const user = useUser({ or: "redirect" });
496
+ const updateTeamPermission = user.usePermission(props.team, "$update_team");
497
+ if (!updateTeamPermission) {
498
+ return null;
499
+ }
500
+ return /* @__PURE__ */ jsx(
501
+ Section,
502
+ {
503
+ title: t("Team display name"),
504
+ description: t("Change the display name of your team"),
505
+ children: /* @__PURE__ */ jsx(
382
506
  EditableText,
383
507
  {
384
508
  value: props.team.displayName,
385
509
  onSave: async (newDisplayName) => await props.team.update({ displayName: newDisplayName })
386
510
  }
387
511
  )
388
- ] })
389
- ] });
512
+ }
513
+ );
390
514
  }
391
- function ProfileSettings(props) {
515
+ function useTeamUserProfileSection(props) {
516
+ const { t } = useTranslation();
392
517
  const user = useUser({ or: "redirect" });
393
518
  const profile = user.useTeamProfile(props.team);
394
- return /* @__PURE__ */ jsx("div", { className: "flex flex-col", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
395
- /* @__PURE__ */ jsxs(Label, { className: "flex gap-2", children: [
396
- "User display name ",
397
- /* @__PURE__ */ jsx(SimpleTooltip, { tooltip: "This overwrites your user display name in the account setting", type: "info" })
398
- ] }),
399
- /* @__PURE__ */ jsx(
400
- EditableText,
401
- {
402
- value: profile.displayName || "",
403
- onSave: async (newDisplayName) => {
404
- await profile.update({ displayName: newDisplayName });
519
+ return /* @__PURE__ */ jsx(
520
+ Section,
521
+ {
522
+ title: t("Team user name"),
523
+ description: t("Overwrite your user display name in this team"),
524
+ children: /* @__PURE__ */ jsx(
525
+ EditableText,
526
+ {
527
+ value: profile.displayName || "",
528
+ onSave: async (newDisplayName) => {
529
+ await profile.update({ displayName: newDisplayName });
530
+ }
405
531
  }
406
- }
407
- )
408
- ] }) });
532
+ )
533
+ }
534
+ );
409
535
  }
410
- var invitationSchema = yupObject({
411
- email: yupString().email().required("Please enter an email address")
412
- });
413
- function MemberInvitation(props) {
536
+ function useMemberInvitationSection(props) {
537
+ const { t } = useTranslation();
538
+ const invitationSchema = yupObject({
539
+ email: yupString().email().required(t("Please enter an email address"))
540
+ });
414
541
  const user = useUser({ or: "redirect" });
415
542
  const inviteMemberPermission = user.usePermission(props.team, "$invite_members");
416
543
  if (!inviteMemberPermission) {
@@ -433,35 +560,40 @@ function MemberInvitation(props) {
433
560
  useEffect(() => {
434
561
  setInvitedEmail(null);
435
562
  }, [watch("email")]);
436
- return /* @__PURE__ */ jsxs("div", { children: [
437
- /* @__PURE__ */ jsx(Label, { children: "Invite a user to team" }),
438
- /* @__PURE__ */ jsxs(
439
- "form",
440
- {
441
- onSubmit: (e) => runAsynchronouslyWithAlert(handleSubmit(onSubmit)(e)),
442
- noValidate: true,
443
- children: [
444
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4 md:flex-row", children: [
445
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
446
- Input,
447
- {
448
- placeholder: "Email",
449
- ...register("email")
450
- }
451
- ) }),
452
- /* @__PURE__ */ jsx(Button, { type: "submit", loading, children: "Invite User" })
453
- ] }),
454
- /* @__PURE__ */ jsx(FormWarningText, { text: errors.email?.message?.toString() }),
455
- invitedEmail && /* @__PURE__ */ jsxs(Typography, { type: "label", variant: "secondary", children: [
456
- "Invited ",
457
- invitedEmail
458
- ] })
459
- ]
460
- }
461
- )
462
- ] });
563
+ return /* @__PURE__ */ jsx(
564
+ Section,
565
+ {
566
+ title: t("Invite member"),
567
+ description: t("Invite a user to your team through email"),
568
+ children: /* @__PURE__ */ jsxs(
569
+ "form",
570
+ {
571
+ onSubmit: (e) => runAsynchronouslyWithAlert(handleSubmit(onSubmit)(e)),
572
+ noValidate: true,
573
+ children: [
574
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4 md:flex-row", children: [
575
+ /* @__PURE__ */ jsx(
576
+ Input,
577
+ {
578
+ placeholder: t("Email"),
579
+ ...register("email")
580
+ }
581
+ ),
582
+ /* @__PURE__ */ jsx(Button, { type: "submit", loading, children: t("Invite User") })
583
+ ] }),
584
+ /* @__PURE__ */ jsx(FormWarningText, { text: errors.email?.message?.toString() }),
585
+ invitedEmail && /* @__PURE__ */ jsxs(Typography, { type: "label", variant: "secondary", children: [
586
+ "Invited ",
587
+ invitedEmail
588
+ ] })
589
+ ]
590
+ }
591
+ )
592
+ }
593
+ );
463
594
  }
464
- function MembersSettings(props) {
595
+ function useMemberListSection(props) {
596
+ const { t } = useTranslation();
465
597
  const user = useUser({ or: "redirect" });
466
598
  const readMemberPermission = user.usePermission(props.team, "$read_members");
467
599
  const inviteMemberPermission = user.usePermission(props.team, "$invite_members");
@@ -473,23 +605,24 @@ function MembersSettings(props) {
473
605
  return null;
474
606
  }
475
607
  return /* @__PURE__ */ jsxs("div", { children: [
476
- /* @__PURE__ */ jsx(Label, { children: "Members" }),
477
- /* @__PURE__ */ jsxs(Table, { children: [
608
+ /* @__PURE__ */ jsx(Typography, { className: "font-medium mb-2", children: t("Members") }),
609
+ /* @__PURE__ */ jsx("div", { className: "border rounded-md", children: /* @__PURE__ */ jsxs(Table, { children: [
478
610
  /* @__PURE__ */ jsx(TableHeader, { children: /* @__PURE__ */ jsxs(TableRow, { children: [
479
- /* @__PURE__ */ jsx(TableHead, { className: "w-[100px]", children: "User" }),
480
- /* @__PURE__ */ jsx(TableHead, { className: "w-[200px]", children: "Name" })
611
+ /* @__PURE__ */ jsx(TableHead, { className: "w-[100px]", children: t("User") }),
612
+ /* @__PURE__ */ jsx(TableHead, { className: "w-[200px]", children: t("Name") })
481
613
  ] }) }),
482
614
  /* @__PURE__ */ jsx(TableBody, { children: users.map(({ id, teamProfile }, i) => /* @__PURE__ */ jsxs(TableRow, { children: [
483
615
  /* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsx(UserAvatar, { user: teamProfile }) }),
484
616
  /* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsx(Typography, { children: teamProfile.displayName }) })
485
617
  ] }, id)) })
486
- ] })
618
+ ] }) })
487
619
  ] });
488
620
  }
489
- var teamCreationSchema = yupObject({
490
- displayName: yupString().required("Please enter a team name")
491
- });
492
621
  function TeamCreation() {
622
+ const { t } = useTranslation();
623
+ const teamCreationSchema = yupObject({
624
+ displayName: yupString().required(t("Please enter a team name"))
625
+ });
493
626
  const { register, handleSubmit, formState: { errors } } = useForm({
494
627
  resolver: yupResolver(teamCreationSchema)
495
628
  });
@@ -498,7 +631,7 @@ function TeamCreation() {
498
631
  const user = useUser({ or: "redirect" });
499
632
  const [loading, setLoading] = useState(false);
500
633
  if (!project.config.clientTeamCreationEnabled) {
501
- return /* @__PURE__ */ jsx(MessageCard, { title: "Team creation is not enabled" });
634
+ return /* @__PURE__ */ jsx(MessageCard, { title: t("Team creation is not enabled") });
502
635
  }
503
636
  const onSubmit = async (data) => {
504
637
  setLoading(true);
@@ -508,32 +641,83 @@ function TeamCreation() {
508
641
  setLoading(false);
509
642
  }
510
643
  };
511
- return /* @__PURE__ */ jsx("div", { className: "stack-scope flex flex-col items-stretch", children: /* @__PURE__ */ jsx("div", { className: "mb-6", children: /* @__PURE__ */ jsx(
644
+ return /* @__PURE__ */ jsx(PageLayout, { children: /* @__PURE__ */ jsx(Section, { title: t("Create a Team"), description: t("Enter a display name for your new team"), children: /* @__PURE__ */ jsxs(
512
645
  "form",
513
646
  {
514
- className: "flex flex-col items-stretch stack-scope",
515
647
  onSubmit: (e) => runAsynchronouslyWithAlert(handleSubmit(onSubmit)(e)),
516
648
  noValidate: true,
517
- children: /* @__PURE__ */ jsxs("div", { className: "flex items-end gap-4", children: [
518
- /* @__PURE__ */ jsxs("div", { children: [
519
- /* @__PURE__ */ jsx(Label, { htmlFor: "email", className: "mb-1", children: "Display name" }),
649
+ className: "flex gap-2",
650
+ children: [
651
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col flex-1", children: [
520
652
  /* @__PURE__ */ jsx(
521
653
  Input,
522
654
  {
523
- id: "email",
524
- type: "email",
655
+ id: "displayName",
656
+ type: "text",
525
657
  ...register("displayName")
526
658
  }
527
- )
659
+ ),
660
+ /* @__PURE__ */ jsx(FormWarningText, { text: errors.displayName?.message?.toString() })
528
661
  ] }),
529
- /* @__PURE__ */ jsx(FormWarningText, { text: errors.displayName?.message?.toString() }),
530
- /* @__PURE__ */ jsx(Button, { type: "submit", className: "mt-6", loading, children: "Create" })
531
- ] })
662
+ /* @__PURE__ */ jsx(Button, { type: "submit", loading, children: t("Create") })
663
+ ]
532
664
  }
533
665
  ) }) });
534
666
  }
667
+ function useDeleteAccountSection() {
668
+ const { t } = useTranslation();
669
+ const user = useUser({ or: "redirect" });
670
+ const app = useStackApp();
671
+ const project = app.useProject();
672
+ const [deleting, setDeleting] = useState(false);
673
+ if (!project.config.clientUserDeletionEnabled) {
674
+ return null;
675
+ }
676
+ return /* @__PURE__ */ jsx(
677
+ Section,
678
+ {
679
+ title: t("Delete Account"),
680
+ description: t("Permanently remove your account and all associated data"),
681
+ children: /* @__PURE__ */ jsx("div", { className: "stack-scope flex flex-col items-stretch", children: /* @__PURE__ */ jsx(Accordion, { type: "single", collapsible: true, className: "w-full", children: /* @__PURE__ */ jsxs(AccordionItem, { value: "item-1", children: [
682
+ /* @__PURE__ */ jsx(AccordionTrigger, { children: t("Danger zone") }),
683
+ /* @__PURE__ */ jsx(AccordionContent, { children: !deleting ? /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
684
+ Button,
685
+ {
686
+ variant: "destructive",
687
+ onClick: () => setDeleting(true),
688
+ children: t("Delete account")
689
+ }
690
+ ) }) : /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
691
+ /* @__PURE__ */ jsx(Typography, { variant: "destructive", children: t("Are you sure you want to delete your account? This action is IRREVERSIBLE and will delete ALL associated data.") }),
692
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
693
+ /* @__PURE__ */ jsx(
694
+ Button,
695
+ {
696
+ variant: "destructive",
697
+ onClick: async () => {
698
+ await user.delete();
699
+ await app.redirectToHome();
700
+ },
701
+ children: t("Delete Account")
702
+ }
703
+ ),
704
+ /* @__PURE__ */ jsx(
705
+ Button,
706
+ {
707
+ variant: "secondary",
708
+ onClick: () => setDeleting(false),
709
+ children: t("Cancel")
710
+ }
711
+ )
712
+ ] })
713
+ ] }) })
714
+ ] }) }) })
715
+ }
716
+ );
717
+ }
535
718
  export {
536
719
  AccountSettings,
537
- TeamCreation
720
+ TeamCreation,
721
+ useDeleteAccountSection
538
722
  };
539
723
  //# sourceMappingURL=account-settings.js.map