@stackframe/react 2.8.58 → 2.8.59

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 (233) hide show
  1. package/dist/components/api-key-dialogs.js.map +1 -1
  2. package/dist/components/api-key-table.js.map +1 -1
  3. package/dist/components/credential-sign-in.js.map +1 -1
  4. package/dist/components/credential-sign-up.js.map +1 -1
  5. package/dist/components/elements/form-warning.js.map +1 -1
  6. package/dist/components/elements/maybe-full-page.js.map +1 -1
  7. package/dist/components/elements/separator-with-text.js.map +1 -1
  8. package/dist/components/elements/sidebar-layout.js.map +1 -1
  9. package/dist/components/elements/ssr-layout-effect.js.map +1 -1
  10. package/dist/components/elements/user-avatar.js.map +1 -1
  11. package/dist/components/link.js.map +1 -1
  12. package/dist/components/magic-link-sign-in.js.map +1 -1
  13. package/dist/components/message-cards/known-error-message-card.js.map +1 -1
  14. package/dist/components/message-cards/message-card.js.map +1 -1
  15. package/dist/components/message-cards/predefined-message-card.js.map +1 -1
  16. package/dist/components/oauth-button-group.js.map +1 -1
  17. package/dist/components/oauth-button.js.map +1 -1
  18. package/dist/components/passkey-button.js.map +1 -1
  19. package/dist/components/profile-image-editor.js.map +1 -1
  20. package/dist/components/selected-team-switcher.js.map +1 -1
  21. package/dist/components/team-icon.js.map +1 -1
  22. package/dist/components/team-switcher.js.map +1 -1
  23. package/dist/components/use-in-iframe.js.map +1 -1
  24. package/dist/components/user-button.js.map +1 -1
  25. package/dist/components-page/account-settings/active-sessions/active-sessions-page.js.map +1 -1
  26. package/dist/components-page/account-settings/api-keys/api-keys-page.js.map +1 -1
  27. package/dist/components-page/account-settings/editable-text.js.map +1 -1
  28. package/dist/components-page/account-settings/email-and-auth/email-and-auth-page.js.map +1 -1
  29. package/dist/components-page/account-settings/email-and-auth/emails-section.js.map +1 -1
  30. package/dist/components-page/account-settings/email-and-auth/mfa-section.js.map +1 -1
  31. package/dist/components-page/account-settings/email-and-auth/otp-section.js.map +1 -1
  32. package/dist/components-page/account-settings/email-and-auth/passkey-section.js.map +1 -1
  33. package/dist/components-page/account-settings/email-and-auth/password-section.js.map +1 -1
  34. package/dist/components-page/account-settings/notifications/notifications-page.js.map +1 -1
  35. package/dist/components-page/account-settings/page-layout.js.map +1 -1
  36. package/dist/components-page/account-settings/payments/payments-page.js +79 -0
  37. package/dist/components-page/account-settings/payments/payments-page.js.map +1 -0
  38. package/dist/components-page/account-settings/payments/payments-panel.js +374 -0
  39. package/dist/components-page/account-settings/payments/payments-panel.js.map +1 -0
  40. package/dist/components-page/account-settings/profile-page/profile-page.js.map +1 -1
  41. package/dist/components-page/account-settings/section.js.map +1 -1
  42. package/dist/components-page/account-settings/settings/delete-account-section.js.map +1 -1
  43. package/dist/components-page/account-settings/settings/settings-page.js.map +1 -1
  44. package/dist/components-page/account-settings/settings/sign-out-section.js.map +1 -1
  45. package/dist/components-page/account-settings/teams/leave-team-section.js.map +1 -1
  46. package/dist/components-page/account-settings/teams/team-api-keys-section.js.map +1 -1
  47. package/dist/components-page/account-settings/teams/team-creation-page.js.map +1 -1
  48. package/dist/components-page/account-settings/teams/team-display-name-section.js.map +1 -1
  49. package/dist/components-page/account-settings/teams/team-member-invitation-section.js.map +1 -1
  50. package/dist/components-page/account-settings/teams/team-member-list-section.js.map +1 -1
  51. package/dist/components-page/account-settings/teams/team-page.js.map +1 -1
  52. package/dist/components-page/account-settings/teams/team-profile-image-section.js.map +1 -1
  53. package/dist/components-page/account-settings/teams/team-profile-user-section.js.map +1 -1
  54. package/dist/components-page/account-settings.js +22 -2
  55. package/dist/components-page/account-settings.js.map +1 -1
  56. package/dist/components-page/auth-page.js.map +1 -1
  57. package/dist/components-page/cli-auth-confirm.js.map +1 -1
  58. package/dist/components-page/email-verification.js.map +1 -1
  59. package/dist/components-page/error-page.js.map +1 -1
  60. package/dist/components-page/forgot-password.js.map +1 -1
  61. package/dist/components-page/magic-link-callback.js.map +1 -1
  62. package/dist/components-page/mfa.js.map +1 -1
  63. package/dist/components-page/oauth-callback.js.map +1 -1
  64. package/dist/components-page/onboarding.js.map +1 -1
  65. package/dist/components-page/password-reset.js.map +1 -1
  66. package/dist/components-page/section.js.map +1 -1
  67. package/dist/components-page/sign-in.js.map +1 -1
  68. package/dist/components-page/sign-out.js.map +1 -1
  69. package/dist/components-page/sign-up.js.map +1 -1
  70. package/dist/components-page/stack-handler-client.js.map +1 -1
  71. package/dist/components-page/stack-handler.js.map +1 -1
  72. package/dist/components-page/team-creation.js.map +1 -1
  73. package/dist/components-page/team-invitation.js.map +1 -1
  74. package/dist/esm/components/api-key-dialogs.js.map +1 -1
  75. package/dist/esm/components/api-key-table.js.map +1 -1
  76. package/dist/esm/components/credential-sign-in.js.map +1 -1
  77. package/dist/esm/components/credential-sign-up.js.map +1 -1
  78. package/dist/esm/components/elements/form-warning.js.map +1 -1
  79. package/dist/esm/components/elements/maybe-full-page.js.map +1 -1
  80. package/dist/esm/components/elements/separator-with-text.js.map +1 -1
  81. package/dist/esm/components/elements/sidebar-layout.js.map +1 -1
  82. package/dist/esm/components/elements/ssr-layout-effect.js.map +1 -1
  83. package/dist/esm/components/elements/user-avatar.js.map +1 -1
  84. package/dist/esm/components/link.js.map +1 -1
  85. package/dist/esm/components/magic-link-sign-in.js.map +1 -1
  86. package/dist/esm/components/message-cards/known-error-message-card.js.map +1 -1
  87. package/dist/esm/components/message-cards/message-card.js.map +1 -1
  88. package/dist/esm/components/message-cards/predefined-message-card.js.map +1 -1
  89. package/dist/esm/components/oauth-button-group.js.map +1 -1
  90. package/dist/esm/components/oauth-button.js.map +1 -1
  91. package/dist/esm/components/passkey-button.js.map +1 -1
  92. package/dist/esm/components/profile-image-editor.js.map +1 -1
  93. package/dist/esm/components/selected-team-switcher.js.map +1 -1
  94. package/dist/esm/components/team-icon.js.map +1 -1
  95. package/dist/esm/components/team-switcher.js.map +1 -1
  96. package/dist/esm/components/use-in-iframe.js.map +1 -1
  97. package/dist/esm/components/user-button.js.map +1 -1
  98. package/dist/esm/components-page/account-settings/active-sessions/active-sessions-page.js.map +1 -1
  99. package/dist/esm/components-page/account-settings/api-keys/api-keys-page.js.map +1 -1
  100. package/dist/esm/components-page/account-settings/editable-text.js.map +1 -1
  101. package/dist/esm/components-page/account-settings/email-and-auth/email-and-auth-page.js.map +1 -1
  102. package/dist/esm/components-page/account-settings/email-and-auth/emails-section.js.map +1 -1
  103. package/dist/esm/components-page/account-settings/email-and-auth/mfa-section.js.map +1 -1
  104. package/dist/esm/components-page/account-settings/email-and-auth/otp-section.js.map +1 -1
  105. package/dist/esm/components-page/account-settings/email-and-auth/passkey-section.js.map +1 -1
  106. package/dist/esm/components-page/account-settings/email-and-auth/password-section.js.map +1 -1
  107. package/dist/esm/components-page/account-settings/notifications/notifications-page.js.map +1 -1
  108. package/dist/esm/components-page/account-settings/page-layout.js.map +1 -1
  109. package/dist/esm/components-page/account-settings/payments/payments-page.js +55 -0
  110. package/dist/esm/components-page/account-settings/payments/payments-page.js.map +1 -0
  111. package/dist/esm/components-page/account-settings/payments/payments-panel.js +350 -0
  112. package/dist/esm/components-page/account-settings/payments/payments-panel.js.map +1 -0
  113. package/dist/esm/components-page/account-settings/profile-page/profile-page.js.map +1 -1
  114. package/dist/esm/components-page/account-settings/section.js.map +1 -1
  115. package/dist/esm/components-page/account-settings/settings/delete-account-section.js.map +1 -1
  116. package/dist/esm/components-page/account-settings/settings/settings-page.js.map +1 -1
  117. package/dist/esm/components-page/account-settings/settings/sign-out-section.js.map +1 -1
  118. package/dist/esm/components-page/account-settings/teams/leave-team-section.js.map +1 -1
  119. package/dist/esm/components-page/account-settings/teams/team-api-keys-section.js.map +1 -1
  120. package/dist/esm/components-page/account-settings/teams/team-creation-page.js.map +1 -1
  121. package/dist/esm/components-page/account-settings/teams/team-display-name-section.js.map +1 -1
  122. package/dist/esm/components-page/account-settings/teams/team-member-invitation-section.js.map +1 -1
  123. package/dist/esm/components-page/account-settings/teams/team-member-list-section.js.map +1 -1
  124. package/dist/esm/components-page/account-settings/teams/team-page.js.map +1 -1
  125. package/dist/esm/components-page/account-settings/teams/team-profile-image-section.js.map +1 -1
  126. package/dist/esm/components-page/account-settings/teams/team-profile-user-section.js.map +1 -1
  127. package/dist/esm/components-page/account-settings.js +23 -3
  128. package/dist/esm/components-page/account-settings.js.map +1 -1
  129. package/dist/esm/components-page/auth-page.js.map +1 -1
  130. package/dist/esm/components-page/cli-auth-confirm.js.map +1 -1
  131. package/dist/esm/components-page/email-verification.js.map +1 -1
  132. package/dist/esm/components-page/error-page.js.map +1 -1
  133. package/dist/esm/components-page/forgot-password.js.map +1 -1
  134. package/dist/esm/components-page/magic-link-callback.js.map +1 -1
  135. package/dist/esm/components-page/mfa.js.map +1 -1
  136. package/dist/esm/components-page/oauth-callback.js.map +1 -1
  137. package/dist/esm/components-page/onboarding.js.map +1 -1
  138. package/dist/esm/components-page/password-reset.js.map +1 -1
  139. package/dist/esm/components-page/section.js.map +1 -1
  140. package/dist/esm/components-page/sign-in.js.map +1 -1
  141. package/dist/esm/components-page/sign-out.js.map +1 -1
  142. package/dist/esm/components-page/sign-up.js.map +1 -1
  143. package/dist/esm/components-page/stack-handler-client.js.map +1 -1
  144. package/dist/esm/components-page/stack-handler.js.map +1 -1
  145. package/dist/esm/components-page/team-creation.js.map +1 -1
  146. package/dist/esm/components-page/team-invitation.js.map +1 -1
  147. package/dist/esm/generated/global-css.js +1 -1
  148. package/dist/esm/generated/global-css.js.map +1 -1
  149. package/dist/esm/generated/quetzal-translations.js.map +1 -1
  150. package/dist/esm/index.js.map +1 -1
  151. package/dist/esm/integrations/convex/component/convex.config.js.map +1 -1
  152. package/dist/esm/integrations/convex.js.map +1 -1
  153. package/dist/esm/lib/auth.js.map +1 -1
  154. package/dist/esm/lib/cookie.js.map +1 -1
  155. package/dist/esm/lib/hooks.js.map +1 -1
  156. package/dist/esm/lib/stack-app/api-keys/index.js.map +1 -1
  157. package/dist/esm/lib/stack-app/apps/implementations/admin-app-impl.js.map +1 -1
  158. package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.js +63 -4
  159. package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.js.map +1 -1
  160. package/dist/esm/lib/stack-app/apps/implementations/common.js +1 -1
  161. package/dist/esm/lib/stack-app/apps/implementations/common.js.map +1 -1
  162. package/dist/esm/lib/stack-app/apps/implementations/index.js.map +1 -1
  163. package/dist/esm/lib/stack-app/apps/implementations/server-app-impl.js.map +1 -1
  164. package/dist/esm/lib/stack-app/apps/index.js.map +1 -1
  165. package/dist/esm/lib/stack-app/apps/interfaces/admin-app.js.map +1 -1
  166. package/dist/esm/lib/stack-app/apps/interfaces/client-app.js.map +1 -1
  167. package/dist/esm/lib/stack-app/apps/interfaces/server-app.js.map +1 -1
  168. package/dist/esm/lib/stack-app/common.js.map +1 -1
  169. package/dist/esm/lib/stack-app/contact-channels/index.js.map +1 -1
  170. package/dist/esm/lib/stack-app/email-templates/index.js.map +1 -1
  171. package/dist/esm/lib/stack-app/index.js.map +1 -1
  172. package/dist/esm/lib/stack-app/internal-api-keys/index.js.map +1 -1
  173. package/dist/esm/lib/stack-app/permissions/index.js.map +1 -1
  174. package/dist/esm/lib/stack-app/projects/index.js.map +1 -1
  175. package/dist/esm/lib/stack-app/teams/index.js.map +1 -1
  176. package/dist/esm/lib/stack-app/users/index.js.map +1 -1
  177. package/dist/esm/lib/translations.js.map +1 -1
  178. package/dist/esm/providers/stack-provider-client.js.map +1 -1
  179. package/dist/esm/providers/stack-provider.js.map +1 -1
  180. package/dist/esm/providers/theme-provider.js.map +1 -1
  181. package/dist/esm/providers/translation-provider-client.js.map +1 -1
  182. package/dist/esm/providers/translation-provider.js.map +1 -1
  183. package/dist/esm/utils/browser-script.js.map +1 -1
  184. package/dist/esm/utils/constants.js.map +1 -1
  185. package/dist/esm/utils/url.js.map +1 -1
  186. package/dist/generated/global-css.js +1 -1
  187. package/dist/generated/global-css.js.map +1 -1
  188. package/dist/generated/quetzal-translations.js.map +1 -1
  189. package/dist/index.d.mts +37 -1
  190. package/dist/index.d.ts +37 -1
  191. package/dist/index.js.map +1 -1
  192. package/dist/integrations/convex/component/convex.config.js.map +1 -1
  193. package/dist/integrations/convex.js.map +1 -1
  194. package/dist/lib/auth.js.map +1 -1
  195. package/dist/lib/cookie.js.map +1 -1
  196. package/dist/lib/hooks.js.map +1 -1
  197. package/dist/lib/stack-app/api-keys/index.js.map +1 -1
  198. package/dist/lib/stack-app/apps/implementations/admin-app-impl.js.map +1 -1
  199. package/dist/lib/stack-app/apps/implementations/client-app-impl.js +63 -4
  200. package/dist/lib/stack-app/apps/implementations/client-app-impl.js.map +1 -1
  201. package/dist/lib/stack-app/apps/implementations/common.js +1 -1
  202. package/dist/lib/stack-app/apps/implementations/common.js.map +1 -1
  203. package/dist/lib/stack-app/apps/implementations/index.js.map +1 -1
  204. package/dist/lib/stack-app/apps/implementations/server-app-impl.js.map +1 -1
  205. package/dist/lib/stack-app/apps/index.js.map +1 -1
  206. package/dist/lib/stack-app/apps/interfaces/admin-app.js.map +1 -1
  207. package/dist/lib/stack-app/apps/interfaces/client-app.js.map +1 -1
  208. package/dist/lib/stack-app/apps/interfaces/server-app.js.map +1 -1
  209. package/dist/lib/stack-app/common.js.map +1 -1
  210. package/dist/lib/stack-app/connected-accounts/index.js.map +1 -1
  211. package/dist/lib/stack-app/contact-channels/index.js.map +1 -1
  212. package/dist/lib/stack-app/customers/index.js.map +1 -1
  213. package/dist/lib/stack-app/data-vault/index.js.map +1 -1
  214. package/dist/lib/stack-app/email/index.js.map +1 -1
  215. package/dist/lib/stack-app/email-templates/index.js.map +1 -1
  216. package/dist/lib/stack-app/index.js.map +1 -1
  217. package/dist/lib/stack-app/internal-api-keys/index.js.map +1 -1
  218. package/dist/lib/stack-app/notification-categories/index.js.map +1 -1
  219. package/dist/lib/stack-app/permissions/index.js.map +1 -1
  220. package/dist/lib/stack-app/project-configs/index.js.map +1 -1
  221. package/dist/lib/stack-app/projects/index.js.map +1 -1
  222. package/dist/lib/stack-app/teams/index.js.map +1 -1
  223. package/dist/lib/stack-app/users/index.js.map +1 -1
  224. package/dist/lib/translations.js.map +1 -1
  225. package/dist/providers/stack-provider-client.js.map +1 -1
  226. package/dist/providers/stack-provider.js.map +1 -1
  227. package/dist/providers/theme-provider.js.map +1 -1
  228. package/dist/providers/translation-provider-client.js.map +1 -1
  229. package/dist/providers/translation-provider.js.map +1 -1
  230. package/dist/utils/browser-script.js.map +1 -1
  231. package/dist/utils/constants.js.map +1 -1
  232. package/dist/utils/url.js.map +1 -1
  233. package/package.json +18 -16
@@ -0,0 +1,79 @@
1
+ "use client";
2
+ "use strict";
3
+ "use client";
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
21
+
22
+ // src/components-page/account-settings/payments/payments-page.tsx
23
+ var payments_page_exports = {};
24
+ __export(payments_page_exports, {
25
+ PaymentsPage: () => PaymentsPage
26
+ });
27
+ module.exports = __toCommonJS(payments_page_exports);
28
+ var import_react = require("react");
29
+ var import__ = require("../../../index.js");
30
+ var import_hooks = require("../../../lib/hooks.js");
31
+ var import_translations = require("../../../lib/translations.js");
32
+ var import_page_layout = require("../page-layout.js");
33
+ var import_payments_panel = require("./payments-panel.js");
34
+ var import_jsx_runtime = require("react/jsx-runtime");
35
+ function PaymentsPage(props) {
36
+ const { t } = (0, import_translations.useTranslation)();
37
+ const user = (0, import_hooks.useUser)({ or: props.mockMode ? "return-null" : "redirect" });
38
+ const teams = user?.useTeams() ?? [];
39
+ const hasTeams = teams.length > 0;
40
+ const [selectedTeam, setSelectedTeam] = (0, import_react.useState)(null);
41
+ const customer = selectedTeam ?? user;
42
+ const customerType = selectedTeam ? "team" : "user";
43
+ if (props.mockMode) {
44
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_page_layout.PageLayout, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
45
+ import_payments_panel.PaymentsPanel,
46
+ {
47
+ mockMode: true
48
+ }
49
+ ) });
50
+ }
51
+ if (!customer) {
52
+ return null;
53
+ }
54
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_page_layout.PageLayout, { children: [
55
+ hasTeams ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
56
+ import__.TeamSwitcher,
57
+ {
58
+ team: selectedTeam ?? void 0,
59
+ allowNull: true,
60
+ nullLabel: t("Personal"),
61
+ onChange: async (team) => {
62
+ setSelectedTeam(team);
63
+ }
64
+ }
65
+ ) : null,
66
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
67
+ import_payments_panel.PaymentsPanel,
68
+ {
69
+ customer,
70
+ customerType
71
+ }
72
+ )
73
+ ] });
74
+ }
75
+ // Annotate the CommonJS export names for ESM import in node:
76
+ 0 && (module.exports = {
77
+ PaymentsPage
78
+ });
79
+ //# sourceMappingURL=payments-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/components-page/account-settings/payments/payments-page.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { useState } from \"react\";\nimport { Team, TeamSwitcher } from \"../../..\";\nimport { useUser } from \"../../../lib/hooks\";\nimport { useTranslation } from \"../../../lib/translations\";\nimport { PageLayout } from \"../page-layout\";\nimport { PaymentsPanel } from \"./payments-panel\";\n\nexport function PaymentsPage(props: { mockMode?: boolean }) {\n const { t } = useTranslation();\n const user = useUser({ or: props.mockMode ? \"return-null\" : \"redirect\" });\n const teams = user?.useTeams() ?? [];\n const hasTeams = teams.length > 0;\n const [selectedTeam, setSelectedTeam] = useState<Team | null>(null);\n const customer = selectedTeam ?? user;\n const customerType = selectedTeam ? \"team\" : \"user\";\n\n if (props.mockMode) {\n return (\n <PageLayout>\n <PaymentsPanel\n mockMode\n />\n </PageLayout>\n );\n }\n\n if (!customer) {\n return null;\n }\n\n\n return (\n <PageLayout>\n {hasTeams ? (\n <TeamSwitcher\n team={selectedTeam ?? undefined}\n allowNull\n nullLabel={t(\"Personal\")}\n onChange={async (team) => {\n setSelectedTeam(team);\n }}\n />\n ) : null}\n <PaymentsPanel\n customer={customer}\n customerType={customerType}\n />\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,mBAAyB;AACzB,eAAmC;AACnC,mBAAwB;AACxB,0BAA+B;AAC/B,yBAA2B;AAC3B,4BAA8B;AActB;AAZD,SAAS,aAAa,OAA+B;AAC1D,QAAM,EAAE,EAAE,QAAI,oCAAe;AAC7B,QAAM,WAAO,sBAAQ,EAAE,IAAI,MAAM,WAAW,gBAAgB,WAAW,CAAC;AACxE,QAAM,QAAQ,MAAM,SAAS,KAAK,CAAC;AACnC,QAAM,WAAW,MAAM,SAAS;AAChC,QAAM,CAAC,cAAc,eAAe,QAAI,uBAAsB,IAAI;AAClE,QAAM,WAAW,gBAAgB;AACjC,QAAM,eAAe,eAAe,SAAS;AAE7C,MAAI,MAAM,UAAU;AAClB,WACE,4CAAC,iCACC;AAAA,MAAC;AAAA;AAAA,QACC,UAAQ;AAAA;AAAA,IACV,GACF;AAAA,EAEJ;AAEA,MAAI,CAAC,UAAU;AACb,WAAO;AAAA,EACT;AAGA,SACE,6CAAC,iCACE;AAAA,eACC;AAAA,MAAC;AAAA;AAAA,QACC,MAAM,gBAAgB;AAAA,QACtB,WAAS;AAAA,QACT,WAAW,EAAE,UAAU;AAAA,QACvB,UAAU,OAAO,SAAS;AACxB,0BAAgB,IAAI;AAAA,QACtB;AAAA;AAAA,IACF,IACE;AAAA,IACJ;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA;AAAA,IACF;AAAA,KACF;AAEJ;","names":[]}
@@ -0,0 +1,374 @@
1
+ "use client";
2
+ "use strict";
3
+ "use client";
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
21
+
22
+ // src/components-page/account-settings/payments/payments-panel.tsx
23
+ var payments_panel_exports = {};
24
+ __export(payments_panel_exports, {
25
+ PaymentsPanel: () => PaymentsPanel
26
+ });
27
+ module.exports = __toCommonJS(payments_panel_exports);
28
+ var import_stack_shared = require("@stackframe/stack-shared");
29
+ var import_promises = require("@stackframe/stack-shared/dist/utils/promises");
30
+ var import_results = require("@stackframe/stack-shared/dist/utils/results");
31
+ var import_stack_ui = require("@stackframe/stack-ui");
32
+ var import_react_stripe_js = require("@stripe/react-stripe-js");
33
+ var import_stripe_js = require("@stripe/stripe-js");
34
+ var import_react = require("react");
35
+ var import__ = require("../../../index.js");
36
+ var import_translations = require("../../../lib/translations.js");
37
+ var import_section = require("../section.js");
38
+ var import_jsx_runtime = require("react/jsx-runtime");
39
+ function formatPaymentMethod(pm) {
40
+ const details = [
41
+ pm.brand ? pm.brand.toUpperCase() : null,
42
+ pm.last4 ? `\u2022\u2022\u2022\u2022 ${pm.last4}` : null,
43
+ pm.exp_month && pm.exp_year ? `exp ${pm.exp_month}/${pm.exp_year}` : null
44
+ ].filter(Boolean);
45
+ return details.join(" \xB7 ");
46
+ }
47
+ function SetDefaultPaymentMethodForm(props) {
48
+ const stripe = (0, import_react_stripe_js.useStripe)();
49
+ const elements = (0, import_react_stripe_js.useElements)();
50
+ const [errorMessage, setErrorMessage] = (0, import_react.useState)(null);
51
+ const darkMode = "color-scheme" in document.documentElement.style && document.documentElement.style["color-scheme"] === "dark";
52
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-4", children: [
53
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-2", children: [
54
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { className: "font-medium", children: "Card details" }),
55
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "rounded-md border border-input p-3", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_stripe_js.CardElement, { options: { hidePostalCode: true, style: { base: { color: darkMode ? "white" : "black" } } } }) })
56
+ ] }),
57
+ errorMessage && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "secondary", type: "footnote", children: errorMessage }),
58
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
59
+ import_stack_ui.Button,
60
+ {
61
+ onClick: async () => {
62
+ if (!stripe || !elements) {
63
+ setErrorMessage("Stripe is still loading. Please try again.");
64
+ return;
65
+ }
66
+ const card = elements.getElement(import_react_stripe_js.CardElement);
67
+ if (!card) {
68
+ setErrorMessage("Card element not found.");
69
+ return;
70
+ }
71
+ const result = await stripe.confirmCardSetup(props.clientSecret, {
72
+ payment_method: { card }
73
+ });
74
+ if (result.error) {
75
+ setErrorMessage(result.error.message ?? "Failed to save payment method.");
76
+ return;
77
+ }
78
+ if (!result.setupIntent.id) {
79
+ setErrorMessage("No setup intent returned from Stripe.");
80
+ return;
81
+ }
82
+ await props.onSetupIntentSucceeded(result.setupIntent.id);
83
+ },
84
+ children: "Save payment method"
85
+ }
86
+ )
87
+ ] });
88
+ }
89
+ function PaymentsPanel(props) {
90
+ if (props.mockMode) {
91
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MockPaymentsPanel, { title: props.title });
92
+ }
93
+ if (!props.customer) {
94
+ return null;
95
+ }
96
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RealPaymentsPanel, { title: props.title, customer: props.customer, customerType: props.customerType ?? "user" });
97
+ }
98
+ function MockPaymentsPanel(props) {
99
+ const { t } = (0, import_translations.useTranslation)();
100
+ const defaultPaymentMethod = {
101
+ id: "pm_mock",
102
+ brand: "visa",
103
+ last4: "4242",
104
+ exp_month: 12,
105
+ exp_year: 2030
106
+ };
107
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-4", children: [
108
+ props.title && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { className: "font-medium", children: props.title }),
109
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
110
+ import_section.Section,
111
+ {
112
+ title: t("Payment method"),
113
+ description: t("Manage the default payment method used for subscriptions and invoices."),
114
+ children: [
115
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { children: formatPaymentMethod(defaultPaymentMethod) }),
116
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Button, { disabled: true, children: t("Update payment method") })
117
+ ]
118
+ }
119
+ ),
120
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
121
+ import_section.Section,
122
+ {
123
+ title: t("Active plans"),
124
+ description: t("View your active plans and purchases."),
125
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-3", children: [
126
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-start justify-between gap-4", children: [
127
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "min-w-0", children: [
128
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { className: "truncate", children: t("Pro") }),
129
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_stack_ui.Typography, { variant: "secondary", type: "footnote", children: [
130
+ t("Renews on"),
131
+ " Jan 1, 2030"
132
+ ] })
133
+ ] }),
134
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Button, { disabled: true, variant: "secondary", color: "neutral", children: t("Cancel subscription") })
135
+ ] }),
136
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex items-start justify-between gap-4", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "min-w-0", children: [
137
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { className: "truncate", children: t("Credits pack") }),
138
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "secondary", type: "footnote", children: t("One-time purchase") })
139
+ ] }) })
140
+ ] })
141
+ }
142
+ )
143
+ ] });
144
+ }
145
+ function RealPaymentsPanel(props) {
146
+ const { t } = (0, import_translations.useTranslation)();
147
+ const stackApp = (0, import__.useStackApp)();
148
+ const billing = props.customer.useBilling();
149
+ const defaultPaymentMethod = billing.defaultPaymentMethod;
150
+ const products = props.customer.useProducts();
151
+ const productsForCustomerType = products.filter((product) => product.customerType === props.customerType);
152
+ const [paymentDialogOpen, setPaymentDialogOpen] = (0, import_react.useState)(false);
153
+ const [setupIntentClientSecret, setSetupIntentClientSecret] = (0, import_react.useState)(null);
154
+ const [setupIntentStripeAccountId, setSetupIntentStripeAccountId] = (0, import_react.useState)(null);
155
+ const [cancelProductId, setCancelProductId] = (0, import_react.useState)(null);
156
+ const [switchFromProductId, setSwitchFromProductId] = (0, import_react.useState)(null);
157
+ const [switchToProductId, setSwitchToProductId] = (0, import_react.useState)(null);
158
+ const stripePromise = (0, import_react.useMemo)(() => {
159
+ if (!setupIntentStripeAccountId) return null;
160
+ const publishableKey = process.env.NEXT_PUBLIC_STACK_STRIPE_PUBLISHABLE_KEY;
161
+ if (!publishableKey) return null;
162
+ return (0, import_stripe_js.loadStripe)(publishableKey, { stripeAccount: setupIntentStripeAccountId });
163
+ }, [setupIntentStripeAccountId]);
164
+ const handleAsyncError = (error) => {
165
+ if (error instanceof import_stack_shared.KnownErrors.DefaultPaymentMethodRequired) {
166
+ (0, import_stack_ui.toast)({
167
+ title: t("No default payment method"),
168
+ description: t("Add a payment method before switching plans."),
169
+ variant: "destructive"
170
+ });
171
+ return;
172
+ }
173
+ alert(`An unhandled error occurred. Please ${process.env.NODE_ENV === "development" ? "check the browser console for the full error." : "report this to the developer."}
174
+
175
+ ${error}`);
176
+ };
177
+ const openPaymentDialog = () => {
178
+ (0, import_promises.runAsynchronously)(async () => {
179
+ setPaymentDialogOpen(true);
180
+ const res = await props.customer.createPaymentMethodSetupIntent();
181
+ setSetupIntentClientSecret(res.clientSecret);
182
+ setSetupIntentStripeAccountId(res.stripeAccountId);
183
+ }, { onError: handleAsyncError });
184
+ };
185
+ const closePaymentDialog = () => {
186
+ setPaymentDialogOpen(false);
187
+ setSetupIntentClientSecret(null);
188
+ setSetupIntentStripeAccountId(null);
189
+ };
190
+ const openSwitchDialog = (productId, firstOptionId) => {
191
+ setSwitchFromProductId(productId);
192
+ setSwitchToProductId(firstOptionId);
193
+ };
194
+ const closeSwitchDialog = () => {
195
+ setSwitchFromProductId(null);
196
+ setSwitchToProductId(null);
197
+ };
198
+ const switchSourceProduct = switchFromProductId ? productsForCustomerType.find((product) => product.id === switchFromProductId) ?? null : null;
199
+ const switchOptions = switchSourceProduct?.switchOptions ?? [];
200
+ const selectedSwitchOption = switchOptions.find((option) => option.productId === switchToProductId) ?? null;
201
+ const selectedPriceId = selectedSwitchOption ? Object.keys(selectedSwitchOption.prices)[0] ?? null : null;
202
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-4", children: [
203
+ props.title && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { className: "font-medium", children: props.title }),
204
+ defaultPaymentMethod && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
205
+ import_section.Section,
206
+ {
207
+ title: t("Payment method"),
208
+ description: t("Manage the default payment method used for subscriptions and invoices."),
209
+ children: [
210
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { children: formatPaymentMethod(defaultPaymentMethod) }),
211
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Button, { onClick: openPaymentDialog, children: t("Update payment method") }),
212
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
213
+ import_stack_ui.ActionDialog,
214
+ {
215
+ open: paymentDialogOpen,
216
+ onOpenChange: (open) => {
217
+ if (!open) {
218
+ closePaymentDialog();
219
+ } else {
220
+ setPaymentDialogOpen(true);
221
+ }
222
+ },
223
+ title: t("Update payment method"),
224
+ children: !setupIntentClientSecret || !setupIntentStripeAccountId || !stripePromise ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Skeleton, { className: "h-10 w-full" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
225
+ import_react_stripe_js.Elements,
226
+ {
227
+ stripe: stripePromise,
228
+ options: {
229
+ clientSecret: setupIntentClientSecret
230
+ },
231
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
232
+ SetDefaultPaymentMethodForm,
233
+ {
234
+ clientSecret: setupIntentClientSecret,
235
+ onSetupIntentSucceeded: async (setupIntentId) => {
236
+ await props.customer.setDefaultPaymentMethodFromSetupIntent(setupIntentId);
237
+ closePaymentDialog();
238
+ }
239
+ }
240
+ )
241
+ }
242
+ )
243
+ }
244
+ )
245
+ ]
246
+ }
247
+ ),
248
+ productsForCustomerType.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
249
+ import_section.Section,
250
+ {
251
+ title: t("Active plans"),
252
+ description: t("View your active plans and purchases."),
253
+ children: [
254
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "space-y-3", children: productsForCustomerType.map((product, index) => {
255
+ const quantitySuffix = product.quantity !== 1 ? ` \xD7${product.quantity}` : "";
256
+ const isSubscription = product.type === "subscription";
257
+ const isCancelable = isSubscription && !!product.id && !!product.subscription?.isCancelable;
258
+ const canSwitchPlans = isSubscription && defaultPaymentMethod && !!product.id && (product.switchOptions?.length ?? 0) > 0;
259
+ const renewsAt = isSubscription ? product.subscription?.currentPeriodEnd ?? null : null;
260
+ const subtitle = product.type === "one_time" ? t("One-time purchase") : renewsAt ? `${t("Renews on")} ${new Intl.DateTimeFormat(void 0, { year: "numeric", month: "short", day: "numeric" }).format(renewsAt)}` : t("Subscription");
261
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-start justify-between gap-4", children: [
262
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "min-w-0", children: [
263
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_stack_ui.Typography, { className: "truncate", children: [
264
+ product.displayName,
265
+ quantitySuffix
266
+ ] }),
267
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "secondary", type: "footnote", children: subtitle })
268
+ ] }),
269
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col items-end gap-2", children: [
270
+ canSwitchPlans && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
271
+ import_stack_ui.Button,
272
+ {
273
+ variant: "secondary",
274
+ color: "neutral",
275
+ onClick: () => openSwitchDialog(product.id, product.switchOptions?.[0]?.productId ?? null),
276
+ children: t("Change plan")
277
+ }
278
+ ),
279
+ isCancelable && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
280
+ import_stack_ui.Button,
281
+ {
282
+ variant: "secondary",
283
+ color: "neutral",
284
+ onClick: () => setCancelProductId(product.id),
285
+ children: t("Cancel subscription")
286
+ }
287
+ )
288
+ ] })
289
+ ] }, product.id ?? `${product.displayName}-${index}`);
290
+ }) }),
291
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
292
+ import_stack_ui.ActionDialog,
293
+ {
294
+ open: cancelProductId !== null,
295
+ onOpenChange: (open) => {
296
+ if (!open) setCancelProductId(null);
297
+ },
298
+ title: t("Cancel subscription"),
299
+ description: t("Canceling will stop future renewals for this subscription."),
300
+ danger: true,
301
+ cancelButton: true,
302
+ okButton: {
303
+ label: t("Cancel subscription"),
304
+ onClick: async () => {
305
+ const productId = cancelProductId;
306
+ if (!productId) return;
307
+ if (props.customerType === "team") {
308
+ await stackApp.cancelSubscription({ teamId: props.customer.id, productId });
309
+ } else {
310
+ await stackApp.cancelSubscription({ productId });
311
+ }
312
+ setCancelProductId(null);
313
+ }
314
+ }
315
+ }
316
+ ),
317
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
318
+ import_stack_ui.ActionDialog,
319
+ {
320
+ open: switchFromProductId !== null,
321
+ onOpenChange: (open) => {
322
+ if (!open) closeSwitchDialog();
323
+ },
324
+ title: t("Change plan"),
325
+ description: t("Select a new plan from the same product line."),
326
+ cancelButton: true,
327
+ okButton: {
328
+ label: t("Switch plan"),
329
+ onClick: async () => {
330
+ const fromProductId = switchFromProductId;
331
+ const toProductId = switchToProductId;
332
+ if (!fromProductId || !toProductId) return;
333
+ if (!selectedPriceId) return;
334
+ const result = await import_results.Result.fromThrowingAsync(() => props.customer.switchSubscription({
335
+ fromProductId,
336
+ toProductId,
337
+ priceId: selectedPriceId
338
+ }));
339
+ if (result.status === "error") {
340
+ handleAsyncError(result.error);
341
+ return "prevent-close";
342
+ }
343
+ closeSwitchDialog();
344
+ },
345
+ props: {
346
+ disabled: !switchFromProductId || !switchToProductId || !selectedPriceId
347
+ }
348
+ },
349
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "space-y-2", children: switchOptions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "secondary", type: "footnote", children: t("No other plans available for this subscription.") }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
350
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { type: "footnote", children: t("Choose a plan") }),
351
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
352
+ import_stack_ui.Select,
353
+ {
354
+ value: switchToProductId ?? void 0,
355
+ onValueChange: (value) => setSwitchToProductId(value || null),
356
+ children: [
357
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.SelectTrigger, { className: "w-full", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.SelectValue, { placeholder: t("Choose a plan") }) }),
358
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.SelectContent, { children: switchOptions.map((option) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.SelectItem, { value: option.productId, children: option.displayName }, option.productId)) })
359
+ ]
360
+ }
361
+ )
362
+ ] }) })
363
+ }
364
+ )
365
+ ]
366
+ }
367
+ )
368
+ ] });
369
+ }
370
+ // Annotate the CommonJS export names for ESM import in node:
371
+ 0 && (module.exports = {
372
+ PaymentsPanel
373
+ });
374
+ //# sourceMappingURL=payments-panel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/components-page/account-settings/payments/payments-panel.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { KnownErrors } from \"@stackframe/stack-shared\";\nimport { runAsynchronously } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { Result } from \"@stackframe/stack-shared/dist/utils/results\";\nimport { ActionDialog, Button, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Skeleton, toast, Typography } from \"@stackframe/stack-ui\";\nimport { CardElement, Elements, useElements, useStripe } from \"@stripe/react-stripe-js\";\nimport { loadStripe } from \"@stripe/stripe-js\";\nimport { useMemo, useState } from \"react\";\nimport { useStackApp } from \"../../..\";\nimport { useTranslation } from \"../../../lib/translations\";\nimport { Section } from \"../section\";\n\ntype PaymentMethodSummary = {\n id: string,\n brand: string | null,\n last4: string | null,\n exp_month: number | null,\n exp_year: number | null,\n} | null;\n\nfunction formatPaymentMethod(pm: NonNullable<PaymentMethodSummary>) {\n const details = [\n pm.brand ? pm.brand.toUpperCase() : null,\n pm.last4 ? `•••• ${pm.last4}` : null,\n pm.exp_month && pm.exp_year ? `exp ${pm.exp_month}/${pm.exp_year}` : null,\n ].filter(Boolean);\n return details.join(\" · \");\n}\n\ntype CustomerBilling = {\n hasCustomer: boolean,\n defaultPaymentMethod: PaymentMethodSummary,\n};\n\ntype CustomerPaymentMethodSetupIntent = {\n clientSecret: string,\n stripeAccountId: string,\n};\n\ntype CustomerLike = {\n id: string,\n useBilling: () => CustomerBilling,\n useProducts: () => Array<{\n id: string | null,\n quantity: number,\n displayName: string,\n customerType: \"user\" | \"team\" | \"custom\",\n type: \"one_time\" | \"subscription\",\n switchOptions?: Array<{\n productId: string,\n displayName: string,\n prices: Record<string, { interval?: [number, \"day\" | \"week\" | \"month\" | \"year\"] }>,\n }>,\n subscription: null | {\n currentPeriodEnd: Date | null,\n cancelAtPeriodEnd: boolean,\n isCancelable: boolean,\n },\n }>,\n createPaymentMethodSetupIntent: () => Promise<CustomerPaymentMethodSetupIntent>,\n setDefaultPaymentMethodFromSetupIntent: (setupIntentId: string) => Promise<PaymentMethodSummary>,\n switchSubscription: (options: { fromProductId: string, toProductId: string, priceId?: string, quantity?: number }) => Promise<void>,\n};\n\nfunction SetDefaultPaymentMethodForm(props: {\n clientSecret: string,\n onSetupIntentSucceeded: (setupIntentId: string) => Promise<void>,\n}) {\n const stripe = useStripe();\n const elements = useElements();\n const [errorMessage, setErrorMessage] = useState<string | null>(null);\n const darkMode = \"color-scheme\" in document.documentElement.style && document.documentElement.style[\"color-scheme\"] === \"dark\";\n\n return (\n <div className=\"space-y-4\">\n <div className=\"space-y-2\">\n <Typography className=\"font-medium\">Card details</Typography>\n <div className=\"rounded-md border border-input p-3\">\n <CardElement options={{ hidePostalCode: true, style: { base: { color: darkMode ? \"white\" : \"black\" } } }} />\n </div>\n </div>\n {errorMessage && (\n <Typography variant=\"secondary\" type=\"footnote\">\n {errorMessage}\n </Typography>\n )}\n <Button\n onClick={async () => {\n if (!stripe || !elements) {\n setErrorMessage(\"Stripe is still loading. Please try again.\");\n return;\n }\n const card = elements.getElement(CardElement);\n if (!card) {\n setErrorMessage(\"Card element not found.\");\n return;\n }\n\n const result = await stripe.confirmCardSetup(props.clientSecret, {\n payment_method: { card },\n });\n if (result.error) {\n setErrorMessage(result.error.message ?? \"Failed to save payment method.\");\n return;\n }\n if (!result.setupIntent.id) {\n setErrorMessage(\"No setup intent returned from Stripe.\");\n return;\n }\n await props.onSetupIntentSucceeded(result.setupIntent.id);\n }}\n >\n Save payment method\n </Button>\n </div>\n );\n}\n\nexport function PaymentsPanel(props: {\n title?: string,\n customer?: CustomerLike,\n customerType?: \"user\" | \"team\",\n mockMode?: boolean,\n}) {\n if (props.mockMode) {\n return <MockPaymentsPanel title={props.title} />;\n }\n if (!props.customer) {\n return null;\n }\n return <RealPaymentsPanel title={props.title} customer={props.customer} customerType={props.customerType ?? \"user\"} />;\n}\n\nfunction MockPaymentsPanel(props: { title?: string }) {\n const { t } = useTranslation();\n const defaultPaymentMethod: PaymentMethodSummary = {\n id: \"pm_mock\",\n brand: \"visa\",\n last4: \"4242\",\n exp_month: 12,\n exp_year: 2030,\n };\n\n return (\n <div className=\"space-y-4\">\n {props.title && <Typography className=\"font-medium\">{props.title}</Typography>}\n <Section\n title={t(\"Payment method\")}\n description={t(\"Manage the default payment method used for subscriptions and invoices.\")}\n >\n <Typography>{formatPaymentMethod(defaultPaymentMethod)}</Typography>\n <Button disabled>\n {t(\"Update payment method\")}\n </Button>\n </Section>\n\n <Section\n title={t(\"Active plans\")}\n description={t(\"View your active plans and purchases.\")}\n >\n <div className=\"space-y-3\">\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"min-w-0\">\n <Typography className=\"truncate\">{t(\"Pro\")}</Typography>\n <Typography variant=\"secondary\" type=\"footnote\">{t(\"Renews on\")} Jan 1, 2030</Typography>\n </div>\n <Button disabled variant=\"secondary\" color=\"neutral\">\n {t(\"Cancel subscription\")}\n </Button>\n </div>\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"min-w-0\">\n <Typography className=\"truncate\">{t(\"Credits pack\")}</Typography>\n <Typography variant=\"secondary\" type=\"footnote\">{t(\"One-time purchase\")}</Typography>\n </div>\n </div>\n </div>\n </Section>\n </div>\n );\n}\n\nfunction RealPaymentsPanel(props: { title?: string, customer: CustomerLike, customerType: \"user\" | \"team\" }) {\n const { t } = useTranslation();\n const stackApp = useStackApp();\n const billing = props.customer.useBilling();\n const defaultPaymentMethod = billing.defaultPaymentMethod;\n const products = props.customer.useProducts();\n const productsForCustomerType = products.filter(product => product.customerType === props.customerType);\n\n const [paymentDialogOpen, setPaymentDialogOpen] = useState(false);\n const [setupIntentClientSecret, setSetupIntentClientSecret] = useState<string | null>(null);\n const [setupIntentStripeAccountId, setSetupIntentStripeAccountId] = useState<string | null>(null);\n const [cancelProductId, setCancelProductId] = useState<string | null>(null);\n const [switchFromProductId, setSwitchFromProductId] = useState<string | null>(null);\n const [switchToProductId, setSwitchToProductId] = useState<string | null>(null);\n\n const stripePromise = useMemo(() => {\n if (!setupIntentStripeAccountId) return null;\n const publishableKey = process.env.NEXT_PUBLIC_STACK_STRIPE_PUBLISHABLE_KEY;\n if (!publishableKey) return null;\n return loadStripe(publishableKey, { stripeAccount: setupIntentStripeAccountId });\n }, [setupIntentStripeAccountId]);\n\n const handleAsyncError = (error: unknown) => {\n if (error instanceof KnownErrors.DefaultPaymentMethodRequired) {\n toast({\n title: t(\"No default payment method\"),\n description: t(\"Add a payment method before switching plans.\"),\n variant: \"destructive\",\n });\n return;\n }\n alert(`An unhandled error occurred. Please ${process.env.NODE_ENV === \"development\" ? \"check the browser console for the full error.\" : \"report this to the developer.\"}\\n\\n${error}`);\n };\n\n const openPaymentDialog = () => {\n runAsynchronously(async () => {\n setPaymentDialogOpen(true);\n const res = await props.customer.createPaymentMethodSetupIntent();\n setSetupIntentClientSecret(res.clientSecret);\n setSetupIntentStripeAccountId(res.stripeAccountId);\n }, { onError: handleAsyncError });\n };\n\n const closePaymentDialog = () => {\n setPaymentDialogOpen(false);\n setSetupIntentClientSecret(null);\n setSetupIntentStripeAccountId(null);\n };\n\n const openSwitchDialog = (productId: string, firstOptionId: string | null) => {\n setSwitchFromProductId(productId);\n setSwitchToProductId(firstOptionId);\n };\n\n const closeSwitchDialog = () => {\n setSwitchFromProductId(null);\n setSwitchToProductId(null);\n };\n\n const switchSourceProduct = switchFromProductId\n ? productsForCustomerType.find((product) => product.id === switchFromProductId) ?? null\n : null;\n const switchOptions = switchSourceProduct?.switchOptions ?? [];\n const selectedSwitchOption = switchOptions.find((option) => option.productId === switchToProductId) ?? null;\n const selectedPriceId = selectedSwitchOption ? (Object.keys(selectedSwitchOption.prices)[0] ?? null) : null;\n\n return (\n <div className=\"space-y-4\">\n {props.title && <Typography className=\"font-medium\">{props.title}</Typography>}\n\n {defaultPaymentMethod && (\n <Section\n title={t(\"Payment method\")}\n description={t(\"Manage the default payment method used for subscriptions and invoices.\")}\n >\n <Typography>{formatPaymentMethod(defaultPaymentMethod)}</Typography>\n\n <Button onClick={openPaymentDialog}>\n {t(\"Update payment method\")}\n </Button>\n\n <ActionDialog\n open={paymentDialogOpen}\n onOpenChange={(open) => {\n if (!open) {\n closePaymentDialog();\n } else {\n setPaymentDialogOpen(true);\n }\n }}\n title={t(\"Update payment method\")}\n >\n {!setupIntentClientSecret || !setupIntentStripeAccountId || !stripePromise ? (\n <Skeleton className=\"h-10 w-full\" />\n ) : (\n <Elements\n stripe={stripePromise}\n options={{\n clientSecret: setupIntentClientSecret,\n }}\n >\n <SetDefaultPaymentMethodForm\n clientSecret={setupIntentClientSecret}\n onSetupIntentSucceeded={async (setupIntentId) => {\n await props.customer.setDefaultPaymentMethodFromSetupIntent(setupIntentId);\n closePaymentDialog();\n }}\n />\n </Elements>\n )}\n </ActionDialog>\n </Section>\n )}\n\n {productsForCustomerType.length > 0 && (\n <Section\n title={t(\"Active plans\")}\n description={t(\"View your active plans and purchases.\")}\n >\n <div className=\"space-y-3\">\n {productsForCustomerType.map((product, index) => {\n const quantitySuffix = product.quantity !== 1 ? ` ×${product.quantity}` : \"\";\n const isSubscription = product.type === \"subscription\";\n const isCancelable = isSubscription && !!product.id && !!product.subscription?.isCancelable;\n const canSwitchPlans = isSubscription && defaultPaymentMethod && !!product.id && (product.switchOptions?.length ?? 0) > 0;\n const renewsAt = isSubscription ? (product.subscription?.currentPeriodEnd ?? null) : null;\n\n const subtitle =\n product.type === \"one_time\"\n ? t(\"One-time purchase\")\n : renewsAt\n ? `${t(\"Renews on\")} ${new Intl.DateTimeFormat(undefined, { year: \"numeric\", month: \"short\", day: \"numeric\" }).format(renewsAt)}`\n : t(\"Subscription\");\n\n return (\n <div key={product.id ?? `${product.displayName}-${index}`} className=\"flex items-start justify-between gap-4\">\n <div className=\"min-w-0\">\n <Typography className=\"truncate\">{product.displayName}{quantitySuffix}</Typography>\n <Typography variant=\"secondary\" type=\"footnote\">{subtitle}</Typography>\n </div>\n\n <div className=\"flex flex-col items-end gap-2\">\n {canSwitchPlans && (\n <Button\n variant=\"secondary\"\n color=\"neutral\"\n onClick={() => openSwitchDialog(product.id!, product.switchOptions?.[0]?.productId ?? null)}\n >\n {t(\"Change plan\")}\n </Button>\n )}\n {isCancelable && (\n <Button\n variant=\"secondary\"\n color=\"neutral\"\n onClick={() => setCancelProductId(product.id)}\n >\n {t(\"Cancel subscription\")}\n </Button>\n )}\n </div>\n </div>\n );\n })}\n </div>\n\n <ActionDialog\n open={cancelProductId !== null}\n onOpenChange={(open) => {\n if (!open) setCancelProductId(null);\n }}\n title={t(\"Cancel subscription\")}\n description={t(\"Canceling will stop future renewals for this subscription.\")}\n danger\n cancelButton\n okButton={{\n label: t(\"Cancel subscription\"),\n onClick: async () => {\n const productId = cancelProductId;\n if (!productId) return;\n if (props.customerType === \"team\") {\n await stackApp.cancelSubscription({ teamId: props.customer.id, productId });\n } else {\n await stackApp.cancelSubscription({ productId });\n }\n setCancelProductId(null);\n },\n }}\n />\n\n <ActionDialog\n open={switchFromProductId !== null}\n onOpenChange={(open) => {\n if (!open) closeSwitchDialog();\n }}\n title={t(\"Change plan\")}\n description={t(\"Select a new plan from the same product line.\")}\n cancelButton\n okButton={{\n label: t(\"Switch plan\"),\n onClick: async () => {\n const fromProductId = switchFromProductId;\n const toProductId = switchToProductId;\n if (!fromProductId || !toProductId) return;\n if (!selectedPriceId) return;\n const result = await Result.fromThrowingAsync(() => props.customer.switchSubscription({\n fromProductId,\n toProductId,\n priceId: selectedPriceId,\n }));\n if (result.status === \"error\") {\n handleAsyncError(result.error);\n return \"prevent-close\";\n }\n closeSwitchDialog();\n },\n props: {\n disabled: !switchFromProductId || !switchToProductId || !selectedPriceId,\n },\n }}\n >\n <div className=\"space-y-2\">\n {switchOptions.length === 0 ? (\n <Typography variant=\"secondary\" type=\"footnote\">\n {t(\"No other plans available for this subscription.\")}\n </Typography>\n ) : (\n <>\n <Typography type=\"footnote\">{t(\"Choose a plan\")}</Typography>\n <Select\n value={switchToProductId ?? undefined}\n onValueChange={(value) => setSwitchToProductId(value || null)}\n >\n <SelectTrigger className=\"w-full\">\n <SelectValue placeholder={t(\"Choose a plan\")} />\n </SelectTrigger>\n <SelectContent>\n {switchOptions.map((option: NonNullable<typeof switchOptions>[number]) => (\n <SelectItem key={option.productId} value={option.productId}>\n {option.displayName}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </>\n )}\n </div>\n </ActionDialog>\n </Section>\n )\n }\n </div >\n );\n}\n"],"mappings":"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","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components-page/account-settings/profile-page/profile-page.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\nimport { ProfileImageEditor } from \"../../../components/profile-image-editor\";\nimport { useUser } from \"../../../lib/hooks\";\nimport { useTranslation } from \"../../../lib/translations\";\nimport { EditableText } from \"../editable-text\";\nimport { PageLayout } from \"../page-layout\";\nimport { Section } from \"../section\";\n\nexport function ProfilePage(props?: {\n mockUser?: {\n displayName?: string,\n profileImageUrl?: string,\n },\n}) {\n const { t } = useTranslation();\n const userFromHook = useUser({ or: props?.mockUser ? 'return-null' : 'redirect' });\n\n // Use mock data if provided, otherwise use real user\n const user = props?.mockUser ? {\n displayName: props.mockUser.displayName || 'John Doe',\n profileImageUrl: props.mockUser.profileImageUrl || null,\n update: async () => {\n // Mock update - do nothing in demo mode\n console.log('Mock update called');\n }\n } : userFromHook;\n\n if (!user) {\n return null; // This shouldn't happen in practice\n }\n\n return (\n <PageLayout>\n <Section\n title={t(\"User name\")}\n description={t(\"This is a display name and is not used for authentication\")}\n >\n <EditableText\n value={user.displayName || ''}\n onSave={async (newDisplayName) => {\n await user.update({ displayName: newDisplayName });\n }}/>\n </Section>\n\n <Section\n title={t(\"Profile image\")}\n description={t(\"Upload your own image as your avatar\")}\n >\n <ProfileImageEditor\n user={user as any}\n onProfileImageUrlChange={async (profileImageUrl: string | null) => {\n await user.update({ profileImageUrl });\n }}\n />\n </Section>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,kCAAmC;AACnC,mBAAwB;AACxB,0BAA+B;AAC/B,2BAA6B;AAC7B,yBAA2B;AAC3B,qBAAwB;AA0BpB;AAxBG,SAAS,YAAY,OAKzB;AACD,QAAM,EAAE,EAAE,QAAI,oCAAe;AAC7B,QAAM,mBAAe,sBAAQ,EAAE,IAAI,OAAO,WAAW,gBAAgB,WAAW,CAAC;AAGjF,QAAM,OAAO,OAAO,WAAW;AAAA,IAC7B,aAAa,MAAM,SAAS,eAAe;AAAA,IAC3C,iBAAiB,MAAM,SAAS,mBAAmB;AAAA,IACnD,QAAQ,YAAY;AAElB,cAAQ,IAAI,oBAAoB;AAAA,IAClC;AAAA,EACF,IAAI;AAEJ,MAAI,CAAC,MAAM;AACT,WAAO;AAAA,EACT;AAEA,SACE,6CAAC,iCACC;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,EAAE,WAAW;AAAA,QACpB,aAAa,EAAE,2DAA2D;AAAA,QAE1E;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,KAAK,eAAe;AAAA,YAC3B,QAAQ,OAAO,mBAAmB;AAChC,oBAAM,KAAK,OAAO,EAAE,aAAa,eAAe,CAAC;AAAA,YACnD;AAAA;AAAA,QAAE;AAAA;AAAA,IACN;AAAA,IAEA;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,EAAE,eAAe;AAAA,QACxB,aAAa,EAAE,sCAAsC;AAAA,QAErD;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA,yBAAyB,OAAO,oBAAmC;AACjE,oBAAM,KAAK,OAAO,EAAE,gBAAgB,CAAC;AAAA,YACvC;AAAA;AAAA,QACF;AAAA;AAAA,IACF;AAAA,KACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../../src/components-page/account-settings/profile-page/profile-page.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { ProfileImageEditor } from \"../../../components/profile-image-editor\";\nimport { useUser } from \"../../../lib/hooks\";\nimport { useTranslation } from \"../../../lib/translations\";\nimport { EditableText } from \"../editable-text\";\nimport { PageLayout } from \"../page-layout\";\nimport { Section } from \"../section\";\n\nexport function ProfilePage(props?: {\n mockUser?: {\n displayName?: string,\n profileImageUrl?: string,\n },\n}) {\n const { t } = useTranslation();\n const userFromHook = useUser({ or: props?.mockUser ? 'return-null' : 'redirect' });\n\n // Use mock data if provided, otherwise use real user\n const user = props?.mockUser ? {\n displayName: props.mockUser.displayName || 'John Doe',\n profileImageUrl: props.mockUser.profileImageUrl || null,\n update: async () => {\n // Mock update - do nothing in demo mode\n console.log('Mock update called');\n }\n } : userFromHook;\n\n if (!user) {\n return null; // This shouldn't happen in practice\n }\n\n return (\n <PageLayout>\n <Section\n title={t(\"User name\")}\n description={t(\"This is a display name and is not used for authentication\")}\n >\n <EditableText\n value={user.displayName || ''}\n onSave={async (newDisplayName) => {\n await user.update({ displayName: newDisplayName });\n }}/>\n </Section>\n\n <Section\n title={t(\"Profile image\")}\n description={t(\"Upload your own image as your avatar\")}\n >\n <ProfileImageEditor\n user={user as any}\n onProfileImageUrlChange={async (profileImageUrl: string | null) => {\n await user.update({ profileImageUrl });\n }}\n />\n </Section>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,kCAAmC;AACnC,mBAAwB;AACxB,0BAA+B;AAC/B,2BAA6B;AAC7B,yBAA2B;AAC3B,qBAAwB;AA0BpB;AAxBG,SAAS,YAAY,OAKzB;AACD,QAAM,EAAE,EAAE,QAAI,oCAAe;AAC7B,QAAM,mBAAe,sBAAQ,EAAE,IAAI,OAAO,WAAW,gBAAgB,WAAW,CAAC;AAGjF,QAAM,OAAO,OAAO,WAAW;AAAA,IAC7B,aAAa,MAAM,SAAS,eAAe;AAAA,IAC3C,iBAAiB,MAAM,SAAS,mBAAmB;AAAA,IACnD,QAAQ,YAAY;AAElB,cAAQ,IAAI,oBAAoB;AAAA,IAClC;AAAA,EACF,IAAI;AAEJ,MAAI,CAAC,MAAM;AACT,WAAO;AAAA,EACT;AAEA,SACE,6CAAC,iCACC;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,EAAE,WAAW;AAAA,QACpB,aAAa,EAAE,2DAA2D;AAAA,QAE1E;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,KAAK,eAAe;AAAA,YAC3B,QAAQ,OAAO,mBAAmB;AAChC,oBAAM,KAAK,OAAO,EAAE,aAAa,eAAe,CAAC;AAAA,YACnD;AAAA;AAAA,QAAE;AAAA;AAAA,IACN;AAAA,IAEA;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,EAAE,eAAe;AAAA,QACxB,aAAa,EAAE,sCAAsC;AAAA,QAErD;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA,yBAAyB,OAAO,oBAAmC;AACjE,oBAAM,KAAK,OAAO,EAAE,gBAAgB,CAAC;AAAA,YACvC;AAAA;AAAA,QACF;AAAA;AAAA,IACF;AAAA,KACF;AAEJ;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components-page/account-settings/section.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\nimport { Separator, Typography } from \"@stackframe/stack-ui\";\n\nexport function Section(props: { title: string, description?: string, children: React.ReactNode }) {\n return (\n <>\n <Separator />\n <div className='flex flex-col sm:flex-row gap-2'>\n <div className='sm:flex-1 flex flex-col justify-center'>\n <Typography className='font-medium'>\n {props.title}\n </Typography>\n {props.description && <Typography variant='secondary' type='footnote'>\n {props.description}\n </Typography>}\n </div>\n <div className='sm:flex-1 sm:items-end flex flex-col gap-2 '>\n {props.children}\n </div>\n </div>\n </>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,sBAAsC;AAIlC;AAFG,SAAS,QAAQ,OAA2E;AACjG,SACE,4EACE;AAAA,gDAAC,6BAAU;AAAA,IACX,6CAAC,SAAI,WAAU,mCACb;AAAA,mDAAC,SAAI,WAAU,0CACb;AAAA,oDAAC,8BAAW,WAAU,eACnB,gBAAM,OACT;AAAA,QACC,MAAM,eAAe,4CAAC,8BAAW,SAAQ,aAAY,MAAK,YACxD,gBAAM,aACT;AAAA,SACF;AAAA,MACA,4CAAC,SAAI,WAAU,+CACZ,gBAAM,UACT;AAAA,OACF;AAAA,KACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/components-page/account-settings/section.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { Separator, Typography } from \"@stackframe/stack-ui\";\n\nexport function Section(props: { title: string, description?: string, children: React.ReactNode }) {\n return (\n <>\n <Separator />\n <div className='flex flex-col sm:flex-row gap-2'>\n <div className='sm:flex-1 flex flex-col justify-center'>\n <Typography className='font-medium'>\n {props.title}\n </Typography>\n {props.description && <Typography variant='secondary' type='footnote'>\n {props.description}\n </Typography>}\n </div>\n <div className='sm:flex-1 sm:items-end flex flex-col gap-2 '>\n {props.children}\n </div>\n </div>\n </>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,sBAAsC;AAIlC;AAFG,SAAS,QAAQ,OAA2E;AACjG,SACE,4EACE;AAAA,gDAAC,6BAAU;AAAA,IACX,6CAAC,SAAI,WAAU,mCACb;AAAA,mDAAC,SAAI,WAAU,0CACb;AAAA,oDAAC,8BAAW,WAAU,eACnB,gBAAM,OACT;AAAA,QACC,MAAM,eAAe,4CAAC,8BAAW,SAAQ,aAAY,MAAK,YACxD,gBAAM,aACT;AAAA,SACF;AAAA,MACA,4CAAC,SAAI,WAAU,+CACZ,gBAAM,UACT;AAAA,OACF;AAAA,KACF;AAEJ;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components-page/account-settings/settings/delete-account-section.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\nimport { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Button, Typography } from \"@stackframe/stack-ui\";\nimport { useState } from \"react\";\nimport { useStackApp, useUser } from \"../../../lib/hooks\";\nimport { useTranslation } from \"../../../lib/translations\";\nimport { Section } from \"../section\";\n\nexport function DeleteAccountSection(props?: { mockMode?: boolean }) {\n const { t } = useTranslation();\n const user = useUser({ or: props?.mockMode ? 'return-null' : 'redirect' });\n const app = useStackApp();\n const project = app.useProject();\n const [deleting, setDeleting] = useState(false);\n\n // In mock mode, always show the delete section\n const showDeleteSection = props?.mockMode || project.config.clientUserDeletionEnabled;\n\n if (!showDeleteSection) {\n return null;\n }\n\n const handleDeleteAccount = async () => {\n if (props?.mockMode) {\n // Mock mode - just show an alert\n alert(\"Mock mode: Account deletion clicked\");\n setDeleting(false);\n return;\n }\n\n if (user) {\n await user.delete();\n await app.redirectToHome();\n }\n };\n\n return (\n <Section\n title={t(\"Delete Account\")}\n description={t(\"Permanently remove your account and all associated data\")}\n >\n <div className='stack-scope flex flex-col items-stretch'>\n <Accordion type=\"single\" collapsible className=\"w-full\">\n <AccordionItem value=\"item-1\">\n <AccordionTrigger>{t(\"Danger zone\")}</AccordionTrigger>\n <AccordionContent>\n {!deleting ? (\n <div>\n <Button\n variant='destructive'\n onClick={() => setDeleting(true)}\n >\n {t(\"Delete account\")}\n </Button>\n </div>\n ) : (\n <div className='flex flex-col gap-2'>\n <Typography variant='destructive'>\n {t(\"Are you sure you want to delete your account? This action is IRREVERSIBLE and will delete ALL associated data.\")}\n </Typography>\n <div className='flex gap-2'>\n <Button\n variant='destructive'\n onClick={handleDeleteAccount}\n >\n {t(\"Delete Account\")}\n </Button>\n <Button\n variant='secondary'\n onClick={() => setDeleting(false)}\n >\n {t(\"Cancel\")}\n </Button>\n </div>\n </div>\n )}\n </AccordionContent>\n </AccordionItem>\n </Accordion>\n </div>\n </Section>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,sBAAiG;AACjG,mBAAyB;AACzB,mBAAqC;AACrC,0BAA+B;AAC/B,qBAAwB;AAsCZ;AApCL,SAAS,qBAAqB,OAAgC;AACnE,QAAM,EAAE,EAAE,QAAI,oCAAe;AAC7B,QAAM,WAAO,sBAAQ,EAAE,IAAI,OAAO,WAAW,gBAAgB,WAAW,CAAC;AACzE,QAAM,UAAM,0BAAY;AACxB,QAAM,UAAU,IAAI,WAAW;AAC/B,QAAM,CAAC,UAAU,WAAW,QAAI,uBAAS,KAAK;AAG9C,QAAM,oBAAoB,OAAO,YAAY,QAAQ,OAAO;AAE5D,MAAI,CAAC,mBAAmB;AACtB,WAAO;AAAA,EACT;AAEA,QAAM,sBAAsB,YAAY;AACtC,QAAI,OAAO,UAAU;AAEnB,YAAM,qCAAqC;AAC3C,kBAAY,KAAK;AACjB;AAAA,IACF;AAEA,QAAI,MAAM;AACR,YAAM,KAAK,OAAO;AAClB,YAAM,IAAI,eAAe;AAAA,IAC3B;AAAA,EACF;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,EAAE,gBAAgB;AAAA,MACzB,aAAa,EAAE,yDAAyD;AAAA,MAExE,sDAAC,SAAI,WAAU,2CACb,sDAAC,6BAAU,MAAK,UAAS,aAAW,MAAC,WAAU,UAC7C,uDAAC,iCAAc,OAAM,UACnB;AAAA,oDAAC,oCAAkB,YAAE,aAAa,GAAE;AAAA,QACpC,4CAAC,oCACE,WAAC,WACA,4CAAC,SACC;AAAA,UAAC;AAAA;AAAA,YACC,SAAQ;AAAA,YACR,SAAS,MAAM,YAAY,IAAI;AAAA,YAE9B,YAAE,gBAAgB;AAAA;AAAA,QACrB,GACF,IAEA,6CAAC,SAAI,WAAU,uBACb;AAAA,sDAAC,8BAAW,SAAQ,eACjB,YAAE,gHAAgH,GACrH;AAAA,UACA,6CAAC,SAAI,WAAU,cACb;AAAA;AAAA,cAAC;AAAA;AAAA,gBACC,SAAQ;AAAA,gBACR,SAAS;AAAA,gBAER,YAAE,gBAAgB;AAAA;AAAA,YACrB;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACC,SAAQ;AAAA,gBACR,SAAS,MAAM,YAAY,KAAK;AAAA,gBAE/B,YAAE,QAAQ;AAAA;AAAA,YACb;AAAA,aACF;AAAA,WACF,GAEJ;AAAA,SACF,GACF,GACF;AAAA;AAAA,EACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../../src/components-page/account-settings/settings/delete-account-section.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Button, Typography } from \"@stackframe/stack-ui\";\nimport { useState } from \"react\";\nimport { useStackApp, useUser } from \"../../../lib/hooks\";\nimport { useTranslation } from \"../../../lib/translations\";\nimport { Section } from \"../section\";\n\nexport function DeleteAccountSection(props?: { mockMode?: boolean }) {\n const { t } = useTranslation();\n const user = useUser({ or: props?.mockMode ? 'return-null' : 'redirect' });\n const app = useStackApp();\n const project = app.useProject();\n const [deleting, setDeleting] = useState(false);\n\n // In mock mode, always show the delete section\n const showDeleteSection = props?.mockMode || project.config.clientUserDeletionEnabled;\n\n if (!showDeleteSection) {\n return null;\n }\n\n const handleDeleteAccount = async () => {\n if (props?.mockMode) {\n // Mock mode - just show an alert\n alert(\"Mock mode: Account deletion clicked\");\n setDeleting(false);\n return;\n }\n\n if (user) {\n await user.delete();\n await app.redirectToHome();\n }\n };\n\n return (\n <Section\n title={t(\"Delete Account\")}\n description={t(\"Permanently remove your account and all associated data\")}\n >\n <div className='stack-scope flex flex-col items-stretch'>\n <Accordion type=\"single\" collapsible className=\"w-full\">\n <AccordionItem value=\"item-1\">\n <AccordionTrigger>{t(\"Danger zone\")}</AccordionTrigger>\n <AccordionContent>\n {!deleting ? (\n <div>\n <Button\n variant='destructive'\n onClick={() => setDeleting(true)}\n >\n {t(\"Delete account\")}\n </Button>\n </div>\n ) : (\n <div className='flex flex-col gap-2'>\n <Typography variant='destructive'>\n {t(\"Are you sure you want to delete your account? This action is IRREVERSIBLE and will delete ALL associated data.\")}\n </Typography>\n <div className='flex gap-2'>\n <Button\n variant='destructive'\n onClick={handleDeleteAccount}\n >\n {t(\"Delete Account\")}\n </Button>\n <Button\n variant='secondary'\n onClick={() => setDeleting(false)}\n >\n {t(\"Cancel\")}\n </Button>\n </div>\n </div>\n )}\n </AccordionContent>\n </AccordionItem>\n </Accordion>\n </div>\n </Section>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,sBAAiG;AACjG,mBAAyB;AACzB,mBAAqC;AACrC,0BAA+B;AAC/B,qBAAwB;AAsCZ;AApCL,SAAS,qBAAqB,OAAgC;AACnE,QAAM,EAAE,EAAE,QAAI,oCAAe;AAC7B,QAAM,WAAO,sBAAQ,EAAE,IAAI,OAAO,WAAW,gBAAgB,WAAW,CAAC;AACzE,QAAM,UAAM,0BAAY;AACxB,QAAM,UAAU,IAAI,WAAW;AAC/B,QAAM,CAAC,UAAU,WAAW,QAAI,uBAAS,KAAK;AAG9C,QAAM,oBAAoB,OAAO,YAAY,QAAQ,OAAO;AAE5D,MAAI,CAAC,mBAAmB;AACtB,WAAO;AAAA,EACT;AAEA,QAAM,sBAAsB,YAAY;AACtC,QAAI,OAAO,UAAU;AAEnB,YAAM,qCAAqC;AAC3C,kBAAY,KAAK;AACjB;AAAA,IACF;AAEA,QAAI,MAAM;AACR,YAAM,KAAK,OAAO;AAClB,YAAM,IAAI,eAAe;AAAA,IAC3B;AAAA,EACF;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,EAAE,gBAAgB;AAAA,MACzB,aAAa,EAAE,yDAAyD;AAAA,MAExE,sDAAC,SAAI,WAAU,2CACb,sDAAC,6BAAU,MAAK,UAAS,aAAW,MAAC,WAAU,UAC7C,uDAAC,iCAAc,OAAM,UACnB;AAAA,oDAAC,oCAAkB,YAAE,aAAa,GAAE;AAAA,QACpC,4CAAC,oCACE,WAAC,WACA,4CAAC,SACC;AAAA,UAAC;AAAA;AAAA,YACC,SAAQ;AAAA,YACR,SAAS,MAAM,YAAY,IAAI;AAAA,YAE9B,YAAE,gBAAgB;AAAA;AAAA,QACrB,GACF,IAEA,6CAAC,SAAI,WAAU,uBACb;AAAA,sDAAC,8BAAW,SAAQ,eACjB,YAAE,gHAAgH,GACrH;AAAA,UACA,6CAAC,SAAI,WAAU,cACb;AAAA;AAAA,cAAC;AAAA;AAAA,gBACC,SAAQ;AAAA,gBACR,SAAS;AAAA,gBAER,YAAE,gBAAgB;AAAA;AAAA,YACrB;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACC,SAAQ;AAAA,gBACR,SAAS,MAAM,YAAY,KAAK;AAAA,gBAE/B,YAAE,QAAQ;AAAA;AAAA,YACb;AAAA,aACF;AAAA,WACF,GAEJ;AAAA,SACF,GACF,GACF;AAAA;AAAA,EACF;AAEJ;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components-page/account-settings/settings/settings-page.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\nimport { PageLayout } from \"../page-layout\";\nimport { DeleteAccountSection } from \"./delete-account-section\";\nimport { SignOutSection } from \"./sign-out-section\";\n\n\nexport function SettingsPage(props?: {\n mockMode?: boolean,\n}) {\n return (\n <PageLayout>\n <DeleteAccountSection mockMode={props?.mockMode} />\n <SignOutSection mockMode={props?.mockMode} />\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,yBAA2B;AAC3B,oCAAqC;AACrC,8BAA+B;AAO3B;AAJG,SAAS,aAAa,OAE1B;AACD,SACE,6CAAC,iCACC;AAAA,gDAAC,sDAAqB,UAAU,OAAO,UAAU;AAAA,IACjD,4CAAC,0CAAe,UAAU,OAAO,UAAU;AAAA,KAC7C;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../../src/components-page/account-settings/settings/settings-page.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { PageLayout } from \"../page-layout\";\nimport { DeleteAccountSection } from \"./delete-account-section\";\nimport { SignOutSection } from \"./sign-out-section\";\n\n\nexport function SettingsPage(props?: {\n mockMode?: boolean,\n}) {\n return (\n <PageLayout>\n <DeleteAccountSection mockMode={props?.mockMode} />\n <SignOutSection mockMode={props?.mockMode} />\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,yBAA2B;AAC3B,oCAAqC;AACrC,8BAA+B;AAO3B;AAJG,SAAS,aAAa,OAE1B;AACD,SACE,6CAAC,iCACC;AAAA,gDAAC,sDAAqB,UAAU,OAAO,UAAU;AAAA,IACjD,4CAAC,0CAAe,UAAU,OAAO,UAAU;AAAA,KAC7C;AAEJ;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components-page/account-settings/settings/sign-out-section.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\nimport { Button } from \"@stackframe/stack-ui\";\nimport { useUser } from \"../../../lib/hooks\";\nimport { useTranslation } from \"../../../lib/translations\";\nimport { Section } from \"../section\";\n\nexport function SignOutSection(props?: { mockMode?: boolean }) {\n const { t } = useTranslation();\n const user = useUser({ or: props?.mockMode ? \"return-null\" : \"throw\" });\n\n const handleSignOut = async () => {\n if (props?.mockMode) {\n // Mock mode - just show an alert or do nothing\n alert(\"Mock mode: Sign out clicked\");\n return;\n }\n if (user) {\n await user.signOut();\n }\n };\n\n return (\n <Section\n title={t(\"Sign out\")}\n description={t(\"End your current session\")}\n >\n <div>\n <Button\n variant='secondary'\n onClick={handleSignOut}\n >\n {t(\"Sign out\")}\n </Button>\n </div>\n </Section>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,sBAAuB;AACvB,mBAAwB;AACxB,0BAA+B;AAC/B,qBAAwB;AAuBhB;AArBD,SAAS,eAAe,OAAgC;AAC7D,QAAM,EAAE,EAAE,QAAI,oCAAe;AAC7B,QAAM,WAAO,sBAAQ,EAAE,IAAI,OAAO,WAAW,gBAAgB,QAAQ,CAAC;AAEtE,QAAM,gBAAgB,YAAY;AAChC,QAAI,OAAO,UAAU;AAEnB,YAAM,6BAA6B;AACnC;AAAA,IACF;AACA,QAAI,MAAM;AACR,YAAM,KAAK,QAAQ;AAAA,IACrB;AAAA,EACF;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,EAAE,UAAU;AAAA,MACnB,aAAa,EAAE,0BAA0B;AAAA,MAEzC,sDAAC,SACC;AAAA,QAAC;AAAA;AAAA,UACC,SAAQ;AAAA,UACR,SAAS;AAAA,UAER,YAAE,UAAU;AAAA;AAAA,MACf,GACF;AAAA;AAAA,EACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../../src/components-page/account-settings/settings/sign-out-section.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { Button } from \"@stackframe/stack-ui\";\nimport { useUser } from \"../../../lib/hooks\";\nimport { useTranslation } from \"../../../lib/translations\";\nimport { Section } from \"../section\";\n\nexport function SignOutSection(props?: { mockMode?: boolean }) {\n const { t } = useTranslation();\n const user = useUser({ or: props?.mockMode ? \"return-null\" : \"throw\" });\n\n const handleSignOut = async () => {\n if (props?.mockMode) {\n // Mock mode - just show an alert or do nothing\n alert(\"Mock mode: Sign out clicked\");\n return;\n }\n if (user) {\n await user.signOut();\n }\n };\n\n return (\n <Section\n title={t(\"Sign out\")}\n description={t(\"End your current session\")}\n >\n <div>\n <Button\n variant='secondary'\n onClick={handleSignOut}\n >\n {t(\"Sign out\")}\n </Button>\n </div>\n </Section>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,sBAAuB;AACvB,mBAAwB;AACxB,0BAA+B;AAC/B,qBAAwB;AAuBhB;AArBD,SAAS,eAAe,OAAgC;AAC7D,QAAM,EAAE,EAAE,QAAI,oCAAe;AAC7B,QAAM,WAAO,sBAAQ,EAAE,IAAI,OAAO,WAAW,gBAAgB,QAAQ,CAAC;AAEtE,QAAM,gBAAgB,YAAY;AAChC,QAAI,OAAO,UAAU;AAEnB,YAAM,6BAA6B;AACnC;AAAA,IACF;AACA,QAAI,MAAM;AACR,YAAM,KAAK,QAAQ;AAAA,IACrB;AAAA,EACF;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,EAAE,UAAU;AAAA,MACnB,aAAa,EAAE,0BAA0B;AAAA,MAEzC,sDAAC,SACC;AAAA,QAAC;AAAA;AAAA,UACC,SAAQ;AAAA,UACR,SAAS;AAAA,UAER,YAAE,UAAU;AAAA;AAAA,MACf,GACF;AAAA;AAAA,EACF;AAEJ;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components-page/account-settings/teams/leave-team-section.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\nimport { Button, Typography } from \"@stackframe/stack-ui\";\nimport { useState } from \"react\";\nimport { Team } from \"../../..\";\nimport { useUser } from \"../../../lib/hooks\";\nimport { useTranslation } from \"../../../lib/translations\";\nimport { Section } from \"../section\";\n\nexport function LeaveTeamSection(props: { team: Team }) {\n const { t } = useTranslation();\n const user = useUser({ or: 'redirect' });\n const [leaving, setLeaving] = useState(false);\n\n return (\n <Section\n title={t(\"Leave Team\")}\n description={t(\"leave this team and remove your team profile\")}\n >\n {!leaving ? (\n <div>\n <Button\n variant='secondary'\n onClick={() => setLeaving(true)}\n >\n {t(\"Leave team\")}\n </Button>\n </div>\n ) : (\n <div className='flex flex-col gap-2'>\n <Typography variant='destructive'>\n {t(\"Are you sure you want to leave the team?\")}\n </Typography>\n <div className='flex gap-2'>\n <Button\n variant='destructive'\n onClick={async () => {\n await user.leaveTeam(props.team);\n window.location.reload();\n }}\n >\n {t(\"Leave\")}\n </Button>\n <Button\n variant='secondary'\n onClick={() => setLeaving(false)}\n >\n {t(\"Cancel\")}\n </Button>\n </div>\n </div>\n )}\n </Section>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,sBAAmC;AACnC,mBAAyB;AAEzB,mBAAwB;AACxB,0BAA+B;AAC/B,qBAAwB;AAcd;AAZH,SAAS,iBAAiB,OAAuB;AACtD,QAAM,EAAE,EAAE,QAAI,oCAAe;AAC7B,QAAM,WAAO,sBAAQ,EAAE,IAAI,WAAW,CAAC;AACvC,QAAM,CAAC,SAAS,UAAU,QAAI,uBAAS,KAAK;AAE5C,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,EAAE,YAAY;AAAA,MACrB,aAAa,EAAE,8CAA8C;AAAA,MAE5D,WAAC,UACA,4CAAC,SACC;AAAA,QAAC;AAAA;AAAA,UACC,SAAQ;AAAA,UACR,SAAS,MAAM,WAAW,IAAI;AAAA,UAE7B,YAAE,YAAY;AAAA;AAAA,MACjB,GACF,IAEA,6CAAC,SAAI,WAAU,uBACb;AAAA,oDAAC,8BAAW,SAAQ,eACjB,YAAE,0CAA0C,GAC/C;AAAA,QACA,6CAAC,SAAI,WAAU,cACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,SAAQ;AAAA,cACR,SAAS,YAAY;AACnB,sBAAM,KAAK,UAAU,MAAM,IAAI;AAC/B,uBAAO,SAAS,OAAO;AAAA,cACzB;AAAA,cAEC,YAAE,OAAO;AAAA;AAAA,UACZ;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,SAAQ;AAAA,cACR,SAAS,MAAM,WAAW,KAAK;AAAA,cAE9B,YAAE,QAAQ;AAAA;AAAA,UACb;AAAA,WACF;AAAA,SACF;AAAA;AAAA,EAEJ;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../../src/components-page/account-settings/teams/leave-team-section.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { Button, Typography } from \"@stackframe/stack-ui\";\nimport { useState } from \"react\";\nimport { Team } from \"../../..\";\nimport { useUser } from \"../../../lib/hooks\";\nimport { useTranslation } from \"../../../lib/translations\";\nimport { Section } from \"../section\";\n\nexport function LeaveTeamSection(props: { team: Team }) {\n const { t } = useTranslation();\n const user = useUser({ or: 'redirect' });\n const [leaving, setLeaving] = useState(false);\n\n return (\n <Section\n title={t(\"Leave Team\")}\n description={t(\"leave this team and remove your team profile\")}\n >\n {!leaving ? (\n <div>\n <Button\n variant='secondary'\n onClick={() => setLeaving(true)}\n >\n {t(\"Leave team\")}\n </Button>\n </div>\n ) : (\n <div className='flex flex-col gap-2'>\n <Typography variant='destructive'>\n {t(\"Are you sure you want to leave the team?\")}\n </Typography>\n <div className='flex gap-2'>\n <Button\n variant='destructive'\n onClick={async () => {\n await user.leaveTeam(props.team);\n window.location.reload();\n }}\n >\n {t(\"Leave\")}\n </Button>\n <Button\n variant='secondary'\n onClick={() => setLeaving(false)}\n >\n {t(\"Cancel\")}\n </Button>\n </div>\n </div>\n )}\n </Section>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,sBAAmC;AACnC,mBAAyB;AAEzB,mBAAwB;AACxB,0BAA+B;AAC/B,qBAAwB;AAcd;AAZH,SAAS,iBAAiB,OAAuB;AACtD,QAAM,EAAE,EAAE,QAAI,oCAAe;AAC7B,QAAM,WAAO,sBAAQ,EAAE,IAAI,WAAW,CAAC;AACvC,QAAM,CAAC,SAAS,UAAU,QAAI,uBAAS,KAAK;AAE5C,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,EAAE,YAAY;AAAA,MACrB,aAAa,EAAE,8CAA8C;AAAA,MAE5D,WAAC,UACA,4CAAC,SACC;AAAA,QAAC;AAAA;AAAA,UACC,SAAQ;AAAA,UACR,SAAS,MAAM,WAAW,IAAI;AAAA,UAE7B,YAAE,YAAY;AAAA;AAAA,MACjB,GACF,IAEA,6CAAC,SAAI,WAAU,uBACb;AAAA,oDAAC,8BAAW,SAAQ,eACjB,YAAE,0CAA0C,GAC/C;AAAA,QACA,6CAAC,SAAI,WAAU,cACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,SAAQ;AAAA,cACR,SAAS,YAAY;AACnB,sBAAM,KAAK,UAAU,MAAM,IAAI;AAC/B,uBAAO,SAAS,OAAO;AAAA,cACzB;AAAA,cAEC,YAAE,OAAO;AAAA;AAAA,UACZ;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,SAAQ;AAAA,cACR,SAAS,MAAM,WAAW,KAAK;AAAA,cAE9B,YAAE,QAAQ;AAAA;AAAA,UACb;AAAA,WACF;AAAA,SACF;AAAA;AAAA,EAEJ;AAEJ;","names":[]}