@stackframe/stack 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 +19 -17
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/components-page/account-settings/teams/team-member-list-section.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Typography } from \"@stackframe/stack-ui\";\nimport { Team } from \"../../..\";\nimport { UserAvatar } from \"../../../components/elements/user-avatar\";\nimport { useUser } from \"../../../lib/hooks\";\nimport { useTranslation } from \"../../../lib/translations\";\n\nexport function TeamMemberListSection(props: { team: Team }) {\n const user = useUser({ or: 'redirect' });\n const readMemberPermission = user.usePermission(props.team, '$read_members');\n const inviteMemberPermission = user.usePermission(props.team, '$invite_members');\n\n if (!readMemberPermission && !inviteMemberPermission) {\n return null;\n }\n\n return <MemberListSectionInner team={props.team} />;\n}\n\nfunction MemberListSectionInner(props: { team: Team }) {\n const { t } = useTranslation();\n const users = props.team.useUsers();\n\n return (\n <div>\n <Typography className='font-medium mb-2'>{t(\"Members\")}</Typography>\n <div className='border rounded-md'>\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead className=\"w-[100px]\">{t(\"User\")}</TableHead>\n <TableHead className=\"w-[200px]\">{t(\"Name\")}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {users.map(({ id, teamProfile }, i) => (\n <TableRow key={id}>\n <TableCell>\n <UserAvatar user={teamProfile} />\n </TableCell>\n <TableCell>\n {teamProfile.displayName && (\n <Typography>{teamProfile.displayName}</Typography>\n )}\n {!teamProfile.displayName && (\n <Typography className=\"text-muted-foreground italic\">{t(\"No display name set\")}</Typography>\n )}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n </div>\n );\n}\n"],"mappings":";AAIA,SAAS,OAAO,WAAW,WAAW,WAAW,aAAa,UAAU,kBAAkB;AAE1F,SAAS,kBAAkB;AAC3B,SAAS,eAAe;AACxB,SAAS,sBAAsB;AAWtB,cAaG,YAbH;AATF,SAAS,sBAAsB,OAAuB;AAC3D,QAAM,OAAO,QAAQ,EAAE,IAAI,WAAW,CAAC;AACvC,QAAM,uBAAuB,KAAK,cAAc,MAAM,MAAM,eAAe;AAC3E,QAAM,yBAAyB,KAAK,cAAc,MAAM,MAAM,iBAAiB;AAE/E,MAAI,CAAC,wBAAwB,CAAC,wBAAwB;AACpD,WAAO;AAAA,EACT;AAEA,SAAO,oBAAC,0BAAuB,MAAM,MAAM,MAAM;AACnD;AAEA,SAAS,uBAAuB,OAAuB;AACrD,QAAM,EAAE,EAAE,IAAI,eAAe;AAC7B,QAAM,QAAQ,MAAM,KAAK,SAAS;AAElC,SACE,qBAAC,SACC;AAAA,wBAAC,cAAW,WAAU,oBAAoB,YAAE,SAAS,GAAE;AAAA,IACvD,oBAAC,SAAI,WAAU,qBACb,+BAAC,SACC;AAAA,0BAAC,eACC,+BAAC,YACC;AAAA,4BAAC,aAAU,WAAU,aAAa,YAAE,MAAM,GAAE;AAAA,QAC5C,oBAAC,aAAU,WAAU,aAAa,YAAE,MAAM,GAAE;AAAA,SAC9C,GACF;AAAA,MACA,oBAAC,aACE,gBAAM,IAAI,CAAC,EAAE,IAAI,YAAY,GAAG,MAC/B,qBAAC,YACC;AAAA,4BAAC,aACC,8BAAC,cAAW,MAAM,aAAa,GACjC;AAAA,QACA,qBAAC,aACE;AAAA,sBAAY,eACX,oBAAC,cAAY,sBAAY,aAAY;AAAA,UAEtC,CAAC,YAAY,eACZ,oBAAC,cAAW,WAAU,gCAAgC,YAAE,qBAAqB,GAAE;AAAA,WAEnF;AAAA,WAXa,EAYf,CACD,GACH;AAAA,OACF,GACF;AAAA,KACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../../../src/components-page/account-settings/teams/team-member-list-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 { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Typography } from \"@stackframe/stack-ui\";\nimport { Team } from \"../../..\";\nimport { UserAvatar } from \"../../../components/elements/user-avatar\";\nimport { useUser } from \"../../../lib/hooks\";\nimport { useTranslation } from \"../../../lib/translations\";\n\nexport function TeamMemberListSection(props: { team: Team }) {\n const user = useUser({ or: 'redirect' });\n const readMemberPermission = user.usePermission(props.team, '$read_members');\n const inviteMemberPermission = user.usePermission(props.team, '$invite_members');\n\n if (!readMemberPermission && !inviteMemberPermission) {\n return null;\n }\n\n return <MemberListSectionInner team={props.team} />;\n}\n\nfunction MemberListSectionInner(props: { team: Team }) {\n const { t } = useTranslation();\n const users = props.team.useUsers();\n\n return (\n <div>\n <Typography className='font-medium mb-2'>{t(\"Members\")}</Typography>\n <div className='border rounded-md'>\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead className=\"w-[100px]\">{t(\"User\")}</TableHead>\n <TableHead className=\"w-[200px]\">{t(\"Name\")}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {users.map(({ id, teamProfile }, i) => (\n <TableRow key={id}>\n <TableCell>\n <UserAvatar user={teamProfile} />\n </TableCell>\n <TableCell>\n {teamProfile.displayName && (\n <Typography>{teamProfile.displayName}</Typography>\n )}\n {!teamProfile.displayName && (\n <Typography className=\"text-muted-foreground italic\">{t(\"No display name set\")}</Typography>\n )}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n </div>\n );\n}\n"],"mappings":";AAIA,SAAS,OAAO,WAAW,WAAW,WAAW,aAAa,UAAU,kBAAkB;AAE1F,SAAS,kBAAkB;AAC3B,SAAS,eAAe;AACxB,SAAS,sBAAsB;AAWtB,cAaG,YAbH;AATF,SAAS,sBAAsB,OAAuB;AAC3D,QAAM,OAAO,QAAQ,EAAE,IAAI,WAAW,CAAC;AACvC,QAAM,uBAAuB,KAAK,cAAc,MAAM,MAAM,eAAe;AAC3E,QAAM,yBAAyB,KAAK,cAAc,MAAM,MAAM,iBAAiB;AAE/E,MAAI,CAAC,wBAAwB,CAAC,wBAAwB;AACpD,WAAO;AAAA,EACT;AAEA,SAAO,oBAAC,0BAAuB,MAAM,MAAM,MAAM;AACnD;AAEA,SAAS,uBAAuB,OAAuB;AACrD,QAAM,EAAE,EAAE,IAAI,eAAe;AAC7B,QAAM,QAAQ,MAAM,KAAK,SAAS;AAElC,SACE,qBAAC,SACC;AAAA,wBAAC,cAAW,WAAU,oBAAoB,YAAE,SAAS,GAAE;AAAA,IACvD,oBAAC,SAAI,WAAU,qBACb,+BAAC,SACC;AAAA,0BAAC,eACC,+BAAC,YACC;AAAA,4BAAC,aAAU,WAAU,aAAa,YAAE,MAAM,GAAE;AAAA,QAC5C,oBAAC,aAAU,WAAU,aAAa,YAAE,MAAM,GAAE;AAAA,SAC9C,GACF;AAAA,MACA,oBAAC,aACE,gBAAM,IAAI,CAAC,EAAE,IAAI,YAAY,GAAG,MAC/B,qBAAC,YACC;AAAA,4BAAC,aACC,8BAAC,cAAW,MAAM,aAAa,GACjC;AAAA,QACA,qBAAC,aACE;AAAA,sBAAY,eACX,oBAAC,cAAY,sBAAY,aAAY;AAAA,UAEtC,CAAC,YAAY,eACZ,oBAAC,cAAW,WAAU,gCAAgC,YAAE,qBAAqB,GAAE;AAAA,WAEnF;AAAA,WAXa,EAYf,CACD,GACH;AAAA,OACF,GACF;AAAA,KACF;AAEJ;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/components-page/account-settings/teams/team-page.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\nimport { Team } from \"../../..\";\nimport { PageLayout } from \"../page-layout\";\nimport { LeaveTeamSection } from \"./leave-team-section\";\nimport { TeamApiKeysSection } from \"./team-api-keys-section\";\nimport { TeamDisplayNameSection } from \"./team-display-name-section\";\nimport { TeamMemberInvitationSection } from \"./team-member-invitation-section\";\nimport { TeamMemberListSection } from \"./team-member-list-section\";\nimport { TeamProfileImageSection } from \"./team-profile-image-section\";\nimport { TeamUserProfileSection } from \"./team-profile-user-section\";\n\n\nexport function TeamPage(props: { team: Team }) {\n return (\n <PageLayout>\n <TeamUserProfileSection key={`user-profile-${props.team.id}`} team={props.team} />\n <TeamProfileImageSection key={`profile-image-${props.team.id}`} team={props.team} />\n <TeamDisplayNameSection key={`display-name-${props.team.id}`} team={props.team} />\n <TeamMemberListSection key={`member-list-${props.team.id}`} team={props.team} />\n <TeamMemberInvitationSection key={`member-invitation-${props.team.id}`} team={props.team} />\n <TeamApiKeysSection key={`api-keys-${props.team.id}`} team={props.team} />\n <LeaveTeamSection key={`leave-team-${props.team.id}`} team={props.team} />\n </PageLayout>\n );\n}\n"],"mappings":";AAKA,SAAS,kBAAkB;AAC3B,SAAS,wBAAwB;AACjC,SAAS,0BAA0B;AACnC,SAAS,8BAA8B;AACvC,SAAS,mCAAmC;AAC5C,SAAS,6BAA6B;AACtC,SAAS,+BAA+B;AACxC,SAAS,8BAA8B;AAKnC,SACE,KADF;AAFG,SAAS,SAAS,OAAuB;AAC9C,SACE,qBAAC,cACC;AAAA,wBAAC,0BAA6D,MAAM,MAAM,QAA7C,gBAAgB,MAAM,KAAK,EAAE,EAAsB;AAAA,IAChF,oBAAC,2BAA+D,MAAM,MAAM,QAA9C,iBAAiB,MAAM,KAAK,EAAE,EAAsB;AAAA,IAClF,oBAAC,0BAA6D,MAAM,MAAM,QAA7C,gBAAgB,MAAM,KAAK,EAAE,EAAsB;AAAA,IAChF,oBAAC,yBAA2D,MAAM,MAAM,QAA5C,eAAe,MAAM,KAAK,EAAE,EAAsB;AAAA,IAC9E,oBAAC,+BAAuE,MAAM,MAAM,QAAlD,qBAAqB,MAAM,KAAK,EAAE,EAAsB;AAAA,IAC1F,oBAAC,sBAAqD,MAAM,MAAM,QAAzC,YAAY,MAAM,KAAK,EAAE,EAAsB;AAAA,IACxE,oBAAC,oBAAqD,MAAM,MAAM,QAA3C,cAAc,MAAM,KAAK,EAAE,EAAsB;AAAA,KAC1E;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../../../src/components-page/account-settings/teams/team-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 { Team } from \"../../..\";\nimport { PageLayout } from \"../page-layout\";\nimport { LeaveTeamSection } from \"./leave-team-section\";\nimport { TeamApiKeysSection } from \"./team-api-keys-section\";\nimport { TeamDisplayNameSection } from \"./team-display-name-section\";\nimport { TeamMemberInvitationSection } from \"./team-member-invitation-section\";\nimport { TeamMemberListSection } from \"./team-member-list-section\";\nimport { TeamProfileImageSection } from \"./team-profile-image-section\";\nimport { TeamUserProfileSection } from \"./team-profile-user-section\";\n\n\nexport function TeamPage(props: { team: Team }) {\n return (\n <PageLayout>\n <TeamUserProfileSection key={`user-profile-${props.team.id}`} team={props.team} />\n <TeamProfileImageSection key={`profile-image-${props.team.id}`} team={props.team} />\n <TeamDisplayNameSection key={`display-name-${props.team.id}`} team={props.team} />\n <TeamMemberListSection key={`member-list-${props.team.id}`} team={props.team} />\n <TeamMemberInvitationSection key={`member-invitation-${props.team.id}`} team={props.team} />\n <TeamApiKeysSection key={`api-keys-${props.team.id}`} team={props.team} />\n <LeaveTeamSection key={`leave-team-${props.team.id}`} team={props.team} />\n </PageLayout>\n );\n}\n"],"mappings":";AAKA,SAAS,kBAAkB;AAC3B,SAAS,wBAAwB;AACjC,SAAS,0BAA0B;AACnC,SAAS,8BAA8B;AACvC,SAAS,mCAAmC;AAC5C,SAAS,6BAA6B;AACtC,SAAS,+BAA+B;AACxC,SAAS,8BAA8B;AAKnC,SACE,KADF;AAFG,SAAS,SAAS,OAAuB;AAC9C,SACE,qBAAC,cACC;AAAA,wBAAC,0BAA6D,MAAM,MAAM,QAA7C,gBAAgB,MAAM,KAAK,EAAE,EAAsB;AAAA,IAChF,oBAAC,2BAA+D,MAAM,MAAM,QAA9C,iBAAiB,MAAM,KAAK,EAAE,EAAsB;AAAA,IAClF,oBAAC,0BAA6D,MAAM,MAAM,QAA7C,gBAAgB,MAAM,KAAK,EAAE,EAAsB;AAAA,IAChF,oBAAC,yBAA2D,MAAM,MAAM,QAA5C,eAAe,MAAM,KAAK,EAAE,EAAsB;AAAA,IAC9E,oBAAC,+BAAuE,MAAM,MAAM,QAAlD,qBAAqB,MAAM,KAAK,EAAE,EAAsB;AAAA,IAC1F,oBAAC,sBAAqD,MAAM,MAAM,QAAzC,YAAY,MAAM,KAAK,EAAE,EAAsB;AAAA,IACxE,oBAAC,oBAAqD,MAAM,MAAM,QAA3C,cAAc,MAAM,KAAK,EAAE,EAAsB;AAAA,KAC1E;AAEJ;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/components-page/account-settings/teams/team-profile-image-section.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\nimport { Team } from \"../../..\";\nimport { ProfileImageEditor } from \"../../../components/profile-image-editor\";\nimport { useUser } from \"../../../lib/hooks\";\nimport { useTranslation } from \"../../../lib/translations\";\nimport { Section } from \"../section\";\n\nexport function TeamProfileImageSection(props: { team: Team }) {\n const { t } = useTranslation();\n const user = useUser({ or: 'redirect' });\n const updateTeamPermission = user.usePermission(props.team, '$update_team');\n\n if (!updateTeamPermission) {\n return null;\n }\n\n return (\n <Section\n title={t(\"Team profile image\")}\n description={t(\"Upload an image for your team\")}\n >\n <ProfileImageEditor\n user={props.team}\n onProfileImageUrlChange={async (profileImageUrl) => {\n await props.team.update({ profileImageUrl });\n }}\n />\n </Section>\n );\n}\n"],"mappings":";AAKA,SAAS,0BAA0B;AACnC,SAAS,eAAe;AACxB,SAAS,sBAAsB;AAC/B,SAAS,eAAe;AAgBlB;AAdC,SAAS,wBAAwB,OAAuB;AAC7D,QAAM,EAAE,EAAE,IAAI,eAAe;AAC7B,QAAM,OAAO,QAAQ,EAAE,IAAI,WAAW,CAAC;AACvC,QAAM,uBAAuB,KAAK,cAAc,MAAM,MAAM,cAAc;AAE1E,MAAI,CAAC,sBAAsB;AACzB,WAAO;AAAA,EACT;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,EAAE,oBAAoB;AAAA,MAC7B,aAAa,EAAE,+BAA+B;AAAA,MAE9C;AAAA,QAAC;AAAA;AAAA,UACC,MAAM,MAAM;AAAA,UACZ,yBAAyB,OAAO,oBAAoB;AAClD,kBAAM,MAAM,KAAK,OAAO,EAAE,gBAAgB,CAAC;AAAA,UAC7C;AAAA;AAAA,MACF;AAAA;AAAA,EACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../../../src/components-page/account-settings/teams/team-profile-image-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 { Team } from \"../../..\";\nimport { ProfileImageEditor } from \"../../../components/profile-image-editor\";\nimport { useUser } from \"../../../lib/hooks\";\nimport { useTranslation } from \"../../../lib/translations\";\nimport { Section } from \"../section\";\n\nexport function TeamProfileImageSection(props: { team: Team }) {\n const { t } = useTranslation();\n const user = useUser({ or: 'redirect' });\n const updateTeamPermission = user.usePermission(props.team, '$update_team');\n\n if (!updateTeamPermission) {\n return null;\n }\n\n return (\n <Section\n title={t(\"Team profile image\")}\n description={t(\"Upload an image for your team\")}\n >\n <ProfileImageEditor\n user={props.team}\n onProfileImageUrlChange={async (profileImageUrl) => {\n await props.team.update({ profileImageUrl });\n }}\n />\n </Section>\n );\n}\n"],"mappings":";AAKA,SAAS,0BAA0B;AACnC,SAAS,eAAe;AACxB,SAAS,sBAAsB;AAC/B,SAAS,eAAe;AAgBlB;AAdC,SAAS,wBAAwB,OAAuB;AAC7D,QAAM,EAAE,EAAE,IAAI,eAAe;AAC7B,QAAM,OAAO,QAAQ,EAAE,IAAI,WAAW,CAAC;AACvC,QAAM,uBAAuB,KAAK,cAAc,MAAM,MAAM,cAAc;AAE1E,MAAI,CAAC,sBAAsB;AACzB,WAAO;AAAA,EACT;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,EAAE,oBAAoB;AAAA,MAC7B,aAAa,EAAE,+BAA+B;AAAA,MAE9C;AAAA,QAAC;AAAA;AAAA,UACC,MAAM,MAAM;AAAA,UACZ,yBAAyB,OAAO,oBAAoB;AAClD,kBAAM,MAAM,KAAK,OAAO,EAAE,gBAAgB,CAAC;AAAA,UAC7C;AAAA;AAAA,MACF;AAAA;AAAA,EACF;AAEJ;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/components-page/account-settings/teams/team-profile-user-section.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\nimport { Team } from \"../../..\";\nimport { useUser } from \"../../../lib/hooks\";\nimport { useTranslation } from \"../../../lib/translations\";\nimport { EditableText } from \"../editable-text\";\nimport { Section } from \"../section\";\n\nexport function TeamUserProfileSection(props: { team: Team }) {\n const { t } = useTranslation();\n const user = useUser({ or: 'redirect' });\n const profile = user.useTeamProfile(props.team);\n\n return (\n <Section\n title={t(\"Team user name\")}\n description={t(\"Overwrite your user display name in this team\")}\n >\n <EditableText\n value={profile.displayName || ''}\n onSave={async (newDisplayName) => {\n await profile.update({ displayName: newDisplayName });\n }}\n />\n </Section>\n );\n}\n"],"mappings":";AAKA,SAAS,eAAe;AACxB,SAAS,sBAAsB;AAC/B,SAAS,oBAAoB;AAC7B,SAAS,eAAe;AAYlB;AAVC,SAAS,uBAAuB,OAAuB;AAC5D,QAAM,EAAE,EAAE,IAAI,eAAe;AAC7B,QAAM,OAAO,QAAQ,EAAE,IAAI,WAAW,CAAC;AACvC,QAAM,UAAU,KAAK,eAAe,MAAM,IAAI;AAE9C,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,EAAE,gBAAgB;AAAA,MACzB,aAAa,EAAE,+CAA+C;AAAA,MAE9D;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,QAAQ,eAAe;AAAA,UAC9B,QAAQ,OAAO,mBAAmB;AAChC,kBAAM,QAAQ,OAAO,EAAE,aAAa,eAAe,CAAC;AAAA,UACtD;AAAA;AAAA,MACF;AAAA;AAAA,EACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../../../src/components-page/account-settings/teams/team-profile-user-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 { Team } from \"../../..\";\nimport { useUser } from \"../../../lib/hooks\";\nimport { useTranslation } from \"../../../lib/translations\";\nimport { EditableText } from \"../editable-text\";\nimport { Section } from \"../section\";\n\nexport function TeamUserProfileSection(props: { team: Team }) {\n const { t } = useTranslation();\n const user = useUser({ or: 'redirect' });\n const profile = user.useTeamProfile(props.team);\n\n return (\n <Section\n title={t(\"Team user name\")}\n description={t(\"Overwrite your user display name in this team\")}\n >\n <EditableText\n value={profile.displayName || ''}\n onSave={async (newDisplayName) => {\n await profile.update({ displayName: newDisplayName });\n }}\n />\n </Section>\n );\n}\n"],"mappings":";AAKA,SAAS,eAAe;AACxB,SAAS,sBAAsB;AAC/B,SAAS,oBAAoB;AAC7B,SAAS,eAAe;AAYlB;AAVC,SAAS,uBAAuB,OAAuB;AAC5D,QAAM,EAAE,EAAE,IAAI,eAAe;AAC7B,QAAM,OAAO,QAAQ,EAAE,IAAI,WAAW,CAAC;AACvC,QAAM,UAAU,KAAK,eAAe,MAAM,IAAI;AAE9C,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,EAAE,gBAAgB;AAAA,MACzB,aAAa,EAAE,+CAA+C;AAAA,MAE9D;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,QAAQ,eAAe;AAAA,UAC9B,QAAQ,OAAO,mBAAmB;AAChC,kBAAM,QAAQ,OAAO,EAAE,aAAa,eAAe,CAAC;AAAA,UACtD;AAAA;AAAA,MACF;AAAA;AAAA,EACF;AAEJ;","names":[]}
@@ -3,7 +3,7 @@
3
3
 
4
4
  // src/components-page/account-settings.tsx
5
5
  import { Skeleton, Typography } from "@stackframe/stack-ui";
6
- import { Contact, ShieldCheck, Bell, Monitor, Key, Settings, CirclePlus } from "lucide-react";
6
+ import { Contact, ShieldCheck, Bell, Monitor, Key, Settings, CirclePlus, CreditCard } from "lucide-react";
7
7
  import { Suspense } from "react";
8
8
  import { useStackApp, useUser } from "../index.js";
9
9
  import { MaybeFullPage } from "../components/elements/maybe-full-page.js";
@@ -15,6 +15,7 @@ import { ApiKeysPage } from "./account-settings/api-keys/api-keys-page.js";
15
15
  import { EmailsAndAuthPage } from "./account-settings/email-and-auth/email-and-auth-page.js";
16
16
  import { NotificationsPage } from "./account-settings/notifications/notifications-page.js";
17
17
  import { ProfilePage } from "./account-settings/profile-page/profile-page.js";
18
+ import { PaymentsPage } from "./account-settings/payments/payments-page.js";
18
19
  import { SettingsPage } from "./account-settings/settings/settings-page.js";
19
20
  import { TeamCreationPage } from "./account-settings/teams/team-creation-page.js";
20
21
  import { TeamPage } from "./account-settings/teams/team-page.js";
@@ -26,7 +27,8 @@ var iconMap = {
26
27
  Monitor,
27
28
  Key,
28
29
  Settings,
29
- CirclePlus
30
+ CirclePlus,
31
+ CreditCard
30
32
  };
31
33
  var Icon = ({ name }) => {
32
34
  const LucideIcon = iconMap[name];
@@ -38,11 +40,14 @@ function AccountSettings(props) {
38
40
  const stackApp = useStackApp();
39
41
  const projectFromHook = stackApp.useProject();
40
42
  const user = props.mockUser ? {
41
- useTeams: () => []
43
+ useTeams: () => [],
42
44
  // Mock empty teams for now
45
+ useBilling: () => ({ hasCustomer: false })
46
+ // Mock empty billing for now
43
47
  } : userFromHook;
44
48
  const project = props.mockProject || projectFromHook;
45
49
  const teams = user?.useTeams() || [];
50
+ const billing = user?.useBilling() || null;
46
51
  if (!props.mockUser && !userFromHook) {
47
52
  return null;
48
53
  }
@@ -85,6 +90,13 @@ function AccountSettings(props) {
85
90
  icon: /* @__PURE__ */ jsx(Icon, { name: "Key" }),
86
91
  content: /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(ApiKeysPageSkeleton, {}), children: /* @__PURE__ */ jsx(ApiKeysPage, { mockApiKeys: props.mockApiKeys, mockMode: !!props.mockUser }) })
87
92
  }] : [],
93
+ {
94
+ title: t("Payments"),
95
+ type: "item",
96
+ id: "payments",
97
+ icon: /* @__PURE__ */ jsx(Icon, { name: "CreditCard" }),
98
+ content: /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(PaymentsPageSkeleton, {}), children: /* @__PURE__ */ jsx(PaymentsPage, { mockMode: !!props.mockUser }) })
99
+ },
88
100
  {
89
101
  title: t("Settings"),
90
102
  type: "item",
@@ -156,6 +168,14 @@ function ApiKeysPageSkeleton() {
156
168
  /* @__PURE__ */ jsx(Skeleton, { className: "h-[200px] w-full mt-1 rounded-md" })
157
169
  ] });
158
170
  }
171
+ function PaymentsPageSkeleton() {
172
+ return /* @__PURE__ */ jsxs(PageLayout, { children: [
173
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-6 w-48 mb-2" }),
174
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-9 w-full mt-1" }),
175
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-9 w-full mt-1" }),
176
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-[200px] w-full mt-1 rounded-md" })
177
+ ] });
178
+ }
159
179
  function TeamPageSkeleton() {
160
180
  return /* @__PURE__ */ jsxs(PageLayout, { children: [
161
181
  /* @__PURE__ */ jsx(Skeleton, { className: "h-9 w-full mt-1" }),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components-page/account-settings.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\n\nimport { Skeleton, Typography } from '@stackframe/stack-ui';\nimport { Contact, ShieldCheck, Bell, Monitor, Key, Settings, CirclePlus } from 'lucide-react';\nimport React, { Suspense } from \"react\";\nimport { useStackApp, useUser } from '..';\nimport { MaybeFullPage } from \"../components/elements/maybe-full-page\";\nimport { SidebarLayout } from '../components/elements/sidebar-layout';\nimport { TeamIcon } from '../components/team-icon';\nimport { useTranslation } from \"../lib/translations\";\nimport { ActiveSessionsPage } from \"./account-settings/active-sessions/active-sessions-page\";\nimport { ApiKeysPage } from \"./account-settings/api-keys/api-keys-page\";\nimport { EmailsAndAuthPage } from './account-settings/email-and-auth/email-and-auth-page';\nimport { NotificationsPage } from './account-settings/notifications/notifications-page';\nimport { ProfilePage } from \"./account-settings/profile-page/profile-page\";\nimport { SettingsPage } from './account-settings/settings/settings-page';\nimport { TeamCreationPage } from './account-settings/teams/team-creation-page';\nimport { TeamPage } from './account-settings/teams/team-page';\n\nconst iconMap = {\n Contact,\n ShieldCheck,\n Bell,\n Monitor,\n Key,\n Settings,\n CirclePlus\n} as const;\n\nconst Icon = ({ name }: { name: keyof typeof iconMap }) => {\n const LucideIcon = iconMap[name];\n return <LucideIcon className=\"mr-2 h-4 w-4\"/>;\n};\n\nexport function AccountSettings(props: {\n fullPage?: boolean,\n extraItems?: ({\n title: string,\n content: React.ReactNode,\n id: string,\n } & ({\n icon?: React.ReactNode,\n } | {\n iconName?: keyof typeof iconMap,\n }))[],\n mockUser?: {\n displayName?: string,\n profileImageUrl?: string,\n },\n mockApiKeys?: Array<{\n id: string,\n description: string,\n createdAt: string,\n expiresAt?: string,\n manuallyRevokedAt?: string,\n }>,\n mockProject?: {\n config: {\n allowUserApiKeys: boolean,\n clientTeamCreationEnabled: boolean,\n },\n },\n mockSessions?: Array<{\n id: string,\n isCurrentSession: boolean,\n isImpersonation?: boolean,\n createdAt: string,\n lastUsedAt?: string,\n geoInfo?: {\n ip?: string,\n cityName?: string,\n },\n }>,\n}) {\n const { t } = useTranslation();\n const userFromHook = useUser({ or: props.mockUser ? 'return-null' : 'redirect' });\n const stackApp = useStackApp();\n const projectFromHook = stackApp.useProject();\n\n // Use mock data if provided, otherwise use real data\n const user = props.mockUser ? {\n useTeams: () => [], // Mock empty teams for now\n } : userFromHook;\n\n const project = props.mockProject || projectFromHook;\n const teams = user?.useTeams() || [];\n\n // If we're not in mock mode and don't have a user, the useUser hook will handle redirect\n if (!props.mockUser && !userFromHook) {\n return null;\n }\n\n return (\n <MaybeFullPage fullPage={!!props.fullPage}>\n <div className=\"self-stretch flex-grow w-full\">\n <SidebarLayout\n items={([\n {\n title: t('My Profile'),\n type: 'item',\n id: 'profile',\n icon: <Icon name=\"Contact\"/>,\n content: <ProfilePage mockUser={props.mockUser}/>,\n },\n {\n title: t('Emails & Auth'),\n type: 'item',\n id: 'auth',\n icon: <Icon name=\"ShieldCheck\"/>,\n content: <Suspense fallback={<EmailsAndAuthPageSkeleton/>}>\n <EmailsAndAuthPage mockMode={!!props.mockUser}/>\n </Suspense>,\n },\n {\n title: t('Notifications'),\n type: 'item',\n id: 'notifications',\n icon: <Icon name=\"Bell\"/>,\n content: <Suspense fallback={<NotificationsPageSkeleton/>}>\n <NotificationsPage/>\n </Suspense>,\n },\n {\n title: t('Active Sessions'),\n type: 'item',\n id: 'sessions',\n icon: <Icon name=\"Monitor\"/>,\n content: <Suspense fallback={<ActiveSessionsPageSkeleton/>}>\n <ActiveSessionsPage mockSessions={props.mockSessions} mockMode={!!props.mockUser}/>\n </Suspense>,\n },\n ...(project.config.allowUserApiKeys ? [{\n title: t('API Keys'),\n type: 'item',\n id: 'api-keys',\n icon: <Icon name=\"Key\" />,\n content: <Suspense fallback={<ApiKeysPageSkeleton/>}>\n <ApiKeysPage mockApiKeys={props.mockApiKeys} mockMode={!!props.mockUser} />\n </Suspense>,\n }] as const : []),\n {\n title: t('Settings'),\n type: 'item',\n id: 'settings',\n icon: <Icon name=\"Settings\"/>,\n content: <SettingsPage mockMode={!!props.mockUser}/>,\n },\n ...(props.extraItems?.map(item => ({\n title: item.title,\n type: 'item',\n id: item.id,\n icon: (() => {\n const iconName = (item as any).iconName as keyof typeof iconMap | undefined;\n if (iconName) {\n return <Icon name={iconName}/>;\n } else if ((item as any).icon) {\n return (item as any).icon;\n }\n return null;\n })(),\n content: item.content,\n } as const)) || []),\n ...(teams.length > 0 || project.config.clientTeamCreationEnabled) ? [{\n title: t('Teams'),\n type: 'divider',\n }] as const : [],\n ...teams.map(team => ({\n title: <div className='flex gap-2 items-center w-full'>\n <TeamIcon team={team}/>\n <Typography className=\"max-w-[320px] md:w-[90%] truncate\">{team.displayName}</Typography>\n </div>,\n type: 'item',\n id: `team-${team.id}`,\n content: <Suspense fallback={<TeamPageSkeleton/>}>\n <TeamPage team={team}/>\n </Suspense>,\n } as const)),\n ...project.config.clientTeamCreationEnabled ? [{\n title: t('Create a team'),\n icon: <Icon name=\"CirclePlus\"/>,\n type: 'item',\n id: 'team-creation',\n content: <Suspense fallback={<TeamCreationSkeleton/>}>\n <TeamCreationPage mockMode={!!props.mockUser} />\n </Suspense>,\n }] as const : [],\n ] as const).filter((p) => p.type === 'divider' || (p as any).content )}\n title={t(\"Account Settings\")}\n />\n </div>\n </MaybeFullPage>\n );\n}\n\nfunction PageLayout(props: { children: React.ReactNode }) {\n return (\n <div className='flex flex-col gap-6'>\n {props.children}\n </div>\n );\n}\n\nfunction EmailsAndAuthPageSkeleton() {\n return <PageLayout>\n <Skeleton className=\"h-9 w-full mt-1\"/>\n <Skeleton className=\"h-9 w-full mt-1\"/>\n <Skeleton className=\"h-9 w-full mt-1\"/>\n <Skeleton className=\"h-9 w-full mt-1\"/>\n </PageLayout>;\n}\n\nfunction ActiveSessionsPageSkeleton() {\n return <PageLayout>\n <Skeleton className=\"h-6 w-48 mb-2\"/>\n <Skeleton className=\"h-4 w-full mb-4\"/>\n <Skeleton className=\"h-[200px] w-full mt-1 rounded-md\"/>\n </PageLayout>;\n}\n\nfunction ApiKeysPageSkeleton() {\n return <PageLayout>\n <Skeleton className=\"h-9 w-full mt-1\"/>\n <Skeleton className=\"h-[200px] w-full mt-1 rounded-md\"/>\n </PageLayout>;\n}\n\nfunction TeamPageSkeleton() {\n return <PageLayout>\n <Skeleton className=\"h-9 w-full mt-1\"/>\n <Skeleton className=\"h-9 w-full mt-1\"/>\n <Skeleton className=\"h-9 w-full mt-1\"/>\n <Skeleton className=\"h-[200px] w-full mt-1 rounded-md\"/>\n </PageLayout>;\n}\n\nfunction TeamCreationSkeleton() {\n return <PageLayout>\n <Skeleton className=\"h-9 w-full mt-1\"/>\n <Skeleton className=\"h-9 w-full mt-1\"/>\n </PageLayout>;\n}\n\nfunction NotificationsPageSkeleton() {\n return <PageLayout>\n <Skeleton className=\"h-9 w-full mt-1\"/>\n <Skeleton className=\"h-9 w-full mt-1\"/>\n </PageLayout>;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/components-page/account-settings.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 { Skeleton, Typography } from '@stackframe/stack-ui';\nimport { Contact, ShieldCheck, Bell, Monitor, Key, Settings, CirclePlus, CreditCard } from 'lucide-react';\nimport React, { Suspense } from \"react\";\nimport { useStackApp, useUser } from '..';\nimport { MaybeFullPage } from \"../components/elements/maybe-full-page\";\nimport { SidebarLayout } from '../components/elements/sidebar-layout';\nimport { TeamIcon } from '../components/team-icon';\nimport { useTranslation } from \"../lib/translations\";\nimport { ActiveSessionsPage } from \"./account-settings/active-sessions/active-sessions-page\";\nimport { ApiKeysPage } from \"./account-settings/api-keys/api-keys-page\";\nimport { EmailsAndAuthPage } from './account-settings/email-and-auth/email-and-auth-page';\nimport { NotificationsPage } from './account-settings/notifications/notifications-page';\nimport { ProfilePage } from \"./account-settings/profile-page/profile-page\";\nimport { PaymentsPage } from \"./account-settings/payments/payments-page\";\nimport { SettingsPage } from './account-settings/settings/settings-page';\nimport { TeamCreationPage } from './account-settings/teams/team-creation-page';\nimport { TeamPage } from './account-settings/teams/team-page';\n\nconst iconMap = {\n Contact,\n ShieldCheck,\n Bell,\n Monitor,\n Key,\n Settings,\n CirclePlus,\n CreditCard,\n} as const;\n\nconst Icon = ({ name }: { name: keyof typeof iconMap }) => {\n const LucideIcon = iconMap[name];\n return <LucideIcon className=\"mr-2 h-4 w-4\"/>;\n};\n\nexport function AccountSettings(props: {\n fullPage?: boolean,\n extraItems?: ({\n title: string,\n content: React.ReactNode,\n id: string,\n } & ({\n icon?: React.ReactNode,\n } | {\n iconName?: keyof typeof iconMap,\n }))[],\n mockUser?: {\n displayName?: string,\n profileImageUrl?: string,\n },\n mockApiKeys?: Array<{\n id: string,\n description: string,\n createdAt: string,\n expiresAt?: string,\n manuallyRevokedAt?: string,\n }>,\n mockProject?: {\n config: {\n allowUserApiKeys: boolean,\n clientTeamCreationEnabled: boolean,\n },\n },\n mockSessions?: Array<{\n id: string,\n isCurrentSession: boolean,\n isImpersonation?: boolean,\n createdAt: string,\n lastUsedAt?: string,\n geoInfo?: {\n ip?: string,\n cityName?: string,\n },\n }>,\n}) {\n const { t } = useTranslation();\n const userFromHook = useUser({ or: props.mockUser ? 'return-null' : 'redirect' });\n const stackApp = useStackApp();\n const projectFromHook = stackApp.useProject();\n\n // Use mock data if provided, otherwise use real data\n const user = props.mockUser ? {\n useTeams: () => [], // Mock empty teams for now\n useBilling: () => ({ hasCustomer: false }), // Mock empty billing for now\n } : userFromHook;\n\n const project = props.mockProject || projectFromHook;\n const teams = user?.useTeams() || [];\n const billing = user?.useBilling() || null;\n\n // If we're not in mock mode and don't have a user, the useUser hook will handle redirect\n if (!props.mockUser && !userFromHook) {\n return null;\n }\n\n return (\n <MaybeFullPage fullPage={!!props.fullPage}>\n <div className=\"self-stretch flex-grow w-full\">\n <SidebarLayout\n items={([\n {\n title: t('My Profile'),\n type: 'item',\n id: 'profile',\n icon: <Icon name=\"Contact\"/>,\n content: <ProfilePage mockUser={props.mockUser}/>,\n },\n {\n title: t('Emails & Auth'),\n type: 'item',\n id: 'auth',\n icon: <Icon name=\"ShieldCheck\"/>,\n content: <Suspense fallback={<EmailsAndAuthPageSkeleton/>}>\n <EmailsAndAuthPage mockMode={!!props.mockUser}/>\n </Suspense>,\n },\n {\n title: t('Notifications'),\n type: 'item',\n id: 'notifications',\n icon: <Icon name=\"Bell\"/>,\n content: <Suspense fallback={<NotificationsPageSkeleton/>}>\n <NotificationsPage/>\n </Suspense>,\n },\n {\n title: t('Active Sessions'),\n type: 'item',\n id: 'sessions',\n icon: <Icon name=\"Monitor\"/>,\n content: <Suspense fallback={<ActiveSessionsPageSkeleton/>}>\n <ActiveSessionsPage mockSessions={props.mockSessions} mockMode={!!props.mockUser}/>\n </Suspense>,\n },\n ...(project.config.allowUserApiKeys ? [{\n title: t('API Keys'),\n type: 'item',\n id: 'api-keys',\n icon: <Icon name=\"Key\" />,\n content: <Suspense fallback={<ApiKeysPageSkeleton/>}>\n <ApiKeysPage mockApiKeys={props.mockApiKeys} mockMode={!!props.mockUser} />\n </Suspense>,\n }] as const : []),\n {\n title: t('Payments'),\n type: 'item',\n id: 'payments',\n icon: <Icon name=\"CreditCard\" />,\n content: <Suspense fallback={<PaymentsPageSkeleton/>}>\n <PaymentsPage mockMode={!!props.mockUser} />\n </Suspense>,\n },\n {\n title: t('Settings'),\n type: 'item',\n id: 'settings',\n icon: <Icon name=\"Settings\"/>,\n content: <SettingsPage mockMode={!!props.mockUser}/>,\n },\n ...(props.extraItems?.map(item => ({\n title: item.title,\n type: 'item',\n id: item.id,\n icon: (() => {\n const iconName = (item as any).iconName as keyof typeof iconMap | undefined;\n if (iconName) {\n return <Icon name={iconName}/>;\n } else if ((item as any).icon) {\n return (item as any).icon;\n }\n return null;\n })(),\n content: item.content,\n } as const)) || []),\n ...(teams.length > 0 || project.config.clientTeamCreationEnabled) ? [{\n title: t('Teams'),\n type: 'divider',\n }] as const : [],\n ...teams.map(team => ({\n title: <div className='flex gap-2 items-center w-full'>\n <TeamIcon team={team}/>\n <Typography className=\"max-w-[320px] md:w-[90%] truncate\">{team.displayName}</Typography>\n </div>,\n type: 'item',\n id: `team-${team.id}`,\n content: <Suspense fallback={<TeamPageSkeleton/>}>\n <TeamPage team={team}/>\n </Suspense>,\n } as const)),\n ...project.config.clientTeamCreationEnabled ? [{\n title: t('Create a team'),\n icon: <Icon name=\"CirclePlus\"/>,\n type: 'item',\n id: 'team-creation',\n content: <Suspense fallback={<TeamCreationSkeleton/>}>\n <TeamCreationPage mockMode={!!props.mockUser} />\n </Suspense>,\n }] as const : [],\n ] as const).filter((p) => p.type === 'divider' || (p as any).content )}\n title={t(\"Account Settings\")}\n />\n </div>\n </MaybeFullPage>\n );\n}\n\nfunction PageLayout(props: { children: React.ReactNode }) {\n return (\n <div className='flex flex-col gap-6'>\n {props.children}\n </div>\n );\n}\n\nfunction EmailsAndAuthPageSkeleton() {\n return <PageLayout>\n <Skeleton className=\"h-9 w-full mt-1\"/>\n <Skeleton className=\"h-9 w-full mt-1\"/>\n <Skeleton className=\"h-9 w-full mt-1\"/>\n <Skeleton className=\"h-9 w-full mt-1\"/>\n </PageLayout>;\n}\n\nfunction ActiveSessionsPageSkeleton() {\n return <PageLayout>\n <Skeleton className=\"h-6 w-48 mb-2\"/>\n <Skeleton className=\"h-4 w-full mb-4\"/>\n <Skeleton className=\"h-[200px] w-full mt-1 rounded-md\"/>\n </PageLayout>;\n}\n\nfunction ApiKeysPageSkeleton() {\n return <PageLayout>\n <Skeleton className=\"h-9 w-full mt-1\"/>\n <Skeleton className=\"h-[200px] w-full mt-1 rounded-md\"/>\n </PageLayout>;\n}\n\nfunction PaymentsPageSkeleton() {\n return <PageLayout>\n <Skeleton className=\"h-6 w-48 mb-2\"/>\n <Skeleton className=\"h-9 w-full mt-1\"/>\n <Skeleton className=\"h-9 w-full mt-1\"/>\n <Skeleton className=\"h-[200px] w-full mt-1 rounded-md\"/>\n </PageLayout>;\n}\n\nfunction TeamPageSkeleton() {\n return <PageLayout>\n <Skeleton className=\"h-9 w-full mt-1\"/>\n <Skeleton className=\"h-9 w-full mt-1\"/>\n <Skeleton className=\"h-9 w-full mt-1\"/>\n <Skeleton className=\"h-[200px] w-full mt-1 rounded-md\"/>\n </PageLayout>;\n}\n\nfunction TeamCreationSkeleton() {\n return <PageLayout>\n <Skeleton className=\"h-9 w-full mt-1\"/>\n <Skeleton className=\"h-9 w-full mt-1\"/>\n </PageLayout>;\n}\n\nfunction NotificationsPageSkeleton() {\n return <PageLayout>\n <Skeleton className=\"h-9 w-full mt-1\"/>\n <Skeleton className=\"h-9 w-full mt-1\"/>\n </PageLayout>;\n}\n"],"mappings":"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","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components-page/auth-page.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\n\nimport { runAsynchronously } from '@stackframe/stack-shared/dist/utils/promises';\nimport { Skeleton, Tabs, TabsContent, TabsList, TabsTrigger, Typography, cn } from '@stackframe/stack-ui';\nimport { Suspense, useEffect } from 'react';\nimport { useStackApp, useUser } from '..';\nimport { CredentialSignIn } from '../components/credential-sign-in';\nimport { CredentialSignUp } from '../components/credential-sign-up';\nimport { MaybeFullPage } from '../components/elements/maybe-full-page';\nimport { SeparatorWithText } from '../components/elements/separator-with-text';\nimport { StyledLink } from '../components/link';\nimport { MagicLinkSignIn } from '../components/magic-link-sign-in';\nimport { PredefinedMessageCard } from '../components/message-cards/predefined-message-card';\nimport { OAuthButtonGroup } from '../components/oauth-button-group';\nimport { PasskeyButton } from '../components/passkey-button';\nimport { useTranslation } from '../lib/translations';\n\ntype Props = {\n noPasswordRepeat?: boolean,\n firstTab?: 'magic-link' | 'password',\n fullPage?: boolean,\n type: 'sign-in' | 'sign-up',\n automaticRedirect?: boolean,\n extraInfo?: React.ReactNode,\n mockProject?: {\n config: {\n signUpEnabled: boolean,\n credentialEnabled: boolean,\n passkeyEnabled: boolean,\n magicLinkEnabled: boolean,\n oauthProviders: {\n id: string,\n }[],\n },\n },\n}\n\nexport function AuthPage(props: Props) {\n return <Suspense fallback={<Fallback {...props} />}>\n <Inner {...props} />\n </Suspense>;\n}\n\nfunction Fallback(props: Props) {\n return (\n <MaybeFullPage fullPage={!!props.fullPage}>\n <div className='stack-scope flex flex-col items-stretch' style={{ maxWidth: '380px', flexBasis: '380px', padding: props.fullPage ? '1rem' : 0 }}>\n <div className=\"text-center mb-6 flex flex-col\">\n <Skeleton className='h-9 w-2/3 self-center' />\n\n <Skeleton className='h-3 w-16 mt-8' />\n <Skeleton className='h-9 w-full mt-1' />\n\n <Skeleton className='h-3 w-24 mt-2' />\n <Skeleton className='h-9 w-full mt-1' />\n\n <Skeleton className='h-9 w-full mt-6' />\n </div>\n </div>\n </MaybeFullPage>\n );\n}\n\nfunction Inner(props: Props) {\n const stackApp = useStackApp();\n const user = useUser();\n const projectFromHook = stackApp.useProject();\n const project = props.mockProject || projectFromHook;\n const { t } = useTranslation();\n\n useEffect(() => {\n if (props.automaticRedirect && user && !props.mockProject) {\n runAsynchronously(props.type === 'sign-in'\n ? stackApp.redirectToAfterSignIn({ replace: true })\n : stackApp.redirectToAfterSignUp({ replace: true })\n );\n }\n }, [user, props.mockProject, stackApp, props.automaticRedirect]);\n\n if (user && !props.mockProject && !props.automaticRedirect) {\n return <PredefinedMessageCard type='signedIn' fullPage={props.fullPage} />;\n }\n\n if (props.type === 'sign-up' && !project.config.signUpEnabled) {\n return <PredefinedMessageCard type='signUpDisabled' fullPage={props.fullPage} />;\n }\n\n const hasOAuthProviders = project.config.oauthProviders.length > 0;\n const hasPasskey = (project.config.passkeyEnabled === true && props.type === \"sign-in\");\n const enableSeparator = (project.config.credentialEnabled || project.config.magicLinkEnabled) && (hasOAuthProviders || hasPasskey);\n\n return (\n <MaybeFullPage fullPage={!!props.fullPage}>\n <div className='stack-scope flex flex-col items-stretch' style={{ maxWidth: '380px', flexBasis: '380px', padding: props.fullPage ? '1rem' : 0 }}>\n <div className=\"text-center mb-6\">\n <Typography type='h2'>\n {props.type === 'sign-in' ? t(\"Sign in to your account\") : t(\"Create a new account\")}\n </Typography>\n {props.type === 'sign-in' ? (\n project.config.signUpEnabled && (\n <Typography>\n {t(\"Don't have an account?\")}{\" \"}\n <StyledLink href={stackApp.urls.signUp} onClick={(e) => {\n runAsynchronously(stackApp.redirectToSignUp());\n e.preventDefault();\n }}>{t(\"Sign up\")}</StyledLink>\n </Typography>\n )\n ) : (\n <Typography>\n {t(\"Already have an account?\")}{\" \"}\n <StyledLink href={stackApp.urls.signIn} onClick={(e) => {\n runAsynchronously(stackApp.redirectToSignIn());\n e.preventDefault();\n }}>{t(\"Sign in\")}</StyledLink>\n </Typography>\n )}\n </div>\n {(hasOAuthProviders || hasPasskey) && (\n <div className='gap-4 flex flex-col items-stretch stack-scope'>\n {hasOAuthProviders && <OAuthButtonGroup type={props.type} mockProject={props.mockProject} />}\n {hasPasskey && <PasskeyButton type={props.type} />}\n </div>\n )}\n\n {enableSeparator && <SeparatorWithText text={t('Or continue with')} />}\n {project.config.credentialEnabled && project.config.magicLinkEnabled ? (\n <Tabs defaultValue={props.firstTab || 'magic-link'}>\n <TabsList className={cn('w-full mb-2', {\n 'flex-row-reverse': props.firstTab === 'password'\n })}>\n <TabsTrigger value='magic-link' className='flex-1'>{t(\"Email\")}</TabsTrigger>\n <TabsTrigger value='password' className='flex-1'>{t(\"Email & Password\")}</TabsTrigger>\n </TabsList>\n <TabsContent value='magic-link'>\n <MagicLinkSignIn />\n </TabsContent>\n <TabsContent value='password'>\n {props.type === 'sign-up' ? <CredentialSignUp noPasswordRepeat={props.noPasswordRepeat} /> : <CredentialSignIn />}\n </TabsContent>\n </Tabs>\n ) : project.config.credentialEnabled ? (\n props.type === 'sign-up' ? <CredentialSignUp noPasswordRepeat={props.noPasswordRepeat} /> : <CredentialSignIn />\n ) : project.config.magicLinkEnabled ? (\n <MagicLinkSignIn />\n ) : !(hasOAuthProviders || hasPasskey) ? <Typography variant={\"destructive\"} className=\"text-center\">{t(\"No authentication method enabled.\")}</Typography> : null}\n {props.extraInfo && (\n <div className={cn('flex flex-col items-center text-center text-sm text-gray-500', {\n 'mt-2': project.config.credentialEnabled || project.config.magicLinkEnabled,\n 'mt-6': !(project.config.credentialEnabled || project.config.magicLinkEnabled),\n })}>\n <div>{props.extraInfo}</div>\n </div>\n )}\n </div>\n </MaybeFullPage>\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/components-page/auth-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 { runAsynchronously } from '@stackframe/stack-shared/dist/utils/promises';\nimport { Skeleton, Tabs, TabsContent, TabsList, TabsTrigger, Typography, cn } from '@stackframe/stack-ui';\nimport { Suspense, useEffect } from 'react';\nimport { useStackApp, useUser } from '..';\nimport { CredentialSignIn } from '../components/credential-sign-in';\nimport { CredentialSignUp } from '../components/credential-sign-up';\nimport { MaybeFullPage } from '../components/elements/maybe-full-page';\nimport { SeparatorWithText } from '../components/elements/separator-with-text';\nimport { StyledLink } from '../components/link';\nimport { MagicLinkSignIn } from '../components/magic-link-sign-in';\nimport { PredefinedMessageCard } from '../components/message-cards/predefined-message-card';\nimport { OAuthButtonGroup } from '../components/oauth-button-group';\nimport { PasskeyButton } from '../components/passkey-button';\nimport { useTranslation } from '../lib/translations';\n\ntype Props = {\n noPasswordRepeat?: boolean,\n firstTab?: 'magic-link' | 'password',\n fullPage?: boolean,\n type: 'sign-in' | 'sign-up',\n automaticRedirect?: boolean,\n extraInfo?: React.ReactNode,\n mockProject?: {\n config: {\n signUpEnabled: boolean,\n credentialEnabled: boolean,\n passkeyEnabled: boolean,\n magicLinkEnabled: boolean,\n oauthProviders: {\n id: string,\n }[],\n },\n },\n}\n\nexport function AuthPage(props: Props) {\n return <Suspense fallback={<Fallback {...props} />}>\n <Inner {...props} />\n </Suspense>;\n}\n\nfunction Fallback(props: Props) {\n return (\n <MaybeFullPage fullPage={!!props.fullPage}>\n <div className='stack-scope flex flex-col items-stretch' style={{ maxWidth: '380px', flexBasis: '380px', padding: props.fullPage ? '1rem' : 0 }}>\n <div className=\"text-center mb-6 flex flex-col\">\n <Skeleton className='h-9 w-2/3 self-center' />\n\n <Skeleton className='h-3 w-16 mt-8' />\n <Skeleton className='h-9 w-full mt-1' />\n\n <Skeleton className='h-3 w-24 mt-2' />\n <Skeleton className='h-9 w-full mt-1' />\n\n <Skeleton className='h-9 w-full mt-6' />\n </div>\n </div>\n </MaybeFullPage>\n );\n}\n\nfunction Inner(props: Props) {\n const stackApp = useStackApp();\n const user = useUser();\n const projectFromHook = stackApp.useProject();\n const project = props.mockProject || projectFromHook;\n const { t } = useTranslation();\n\n useEffect(() => {\n if (props.automaticRedirect && user && !props.mockProject) {\n runAsynchronously(props.type === 'sign-in'\n ? stackApp.redirectToAfterSignIn({ replace: true })\n : stackApp.redirectToAfterSignUp({ replace: true })\n );\n }\n }, [user, props.mockProject, stackApp, props.automaticRedirect]);\n\n if (user && !props.mockProject && !props.automaticRedirect) {\n return <PredefinedMessageCard type='signedIn' fullPage={props.fullPage} />;\n }\n\n if (props.type === 'sign-up' && !project.config.signUpEnabled) {\n return <PredefinedMessageCard type='signUpDisabled' fullPage={props.fullPage} />;\n }\n\n const hasOAuthProviders = project.config.oauthProviders.length > 0;\n const hasPasskey = (project.config.passkeyEnabled === true && props.type === \"sign-in\");\n const enableSeparator = (project.config.credentialEnabled || project.config.magicLinkEnabled) && (hasOAuthProviders || hasPasskey);\n\n return (\n <MaybeFullPage fullPage={!!props.fullPage}>\n <div className='stack-scope flex flex-col items-stretch' style={{ maxWidth: '380px', flexBasis: '380px', padding: props.fullPage ? '1rem' : 0 }}>\n <div className=\"text-center mb-6\">\n <Typography type='h2'>\n {props.type === 'sign-in' ? t(\"Sign in to your account\") : t(\"Create a new account\")}\n </Typography>\n {props.type === 'sign-in' ? (\n project.config.signUpEnabled && (\n <Typography>\n {t(\"Don't have an account?\")}{\" \"}\n <StyledLink href={stackApp.urls.signUp} onClick={(e) => {\n runAsynchronously(stackApp.redirectToSignUp());\n e.preventDefault();\n }}>{t(\"Sign up\")}</StyledLink>\n </Typography>\n )\n ) : (\n <Typography>\n {t(\"Already have an account?\")}{\" \"}\n <StyledLink href={stackApp.urls.signIn} onClick={(e) => {\n runAsynchronously(stackApp.redirectToSignIn());\n e.preventDefault();\n }}>{t(\"Sign in\")}</StyledLink>\n </Typography>\n )}\n </div>\n {(hasOAuthProviders || hasPasskey) && (\n <div className='gap-4 flex flex-col items-stretch stack-scope'>\n {hasOAuthProviders && <OAuthButtonGroup type={props.type} mockProject={props.mockProject} />}\n {hasPasskey && <PasskeyButton type={props.type} />}\n </div>\n )}\n\n {enableSeparator && <SeparatorWithText text={t('Or continue with')} />}\n {project.config.credentialEnabled && project.config.magicLinkEnabled ? (\n <Tabs defaultValue={props.firstTab || 'magic-link'}>\n <TabsList className={cn('w-full mb-2', {\n 'flex-row-reverse': props.firstTab === 'password'\n })}>\n <TabsTrigger value='magic-link' className='flex-1'>{t(\"Email\")}</TabsTrigger>\n <TabsTrigger value='password' className='flex-1'>{t(\"Email & Password\")}</TabsTrigger>\n </TabsList>\n <TabsContent value='magic-link'>\n <MagicLinkSignIn />\n </TabsContent>\n <TabsContent value='password'>\n {props.type === 'sign-up' ? <CredentialSignUp noPasswordRepeat={props.noPasswordRepeat} /> : <CredentialSignIn />}\n </TabsContent>\n </Tabs>\n ) : project.config.credentialEnabled ? (\n props.type === 'sign-up' ? <CredentialSignUp noPasswordRepeat={props.noPasswordRepeat} /> : <CredentialSignIn />\n ) : project.config.magicLinkEnabled ? (\n <MagicLinkSignIn />\n ) : !(hasOAuthProviders || hasPasskey) ? <Typography variant={\"destructive\"} className=\"text-center\">{t(\"No authentication method enabled.\")}</Typography> : null}\n {props.extraInfo && (\n <div className={cn('flex flex-col items-center text-center text-sm text-gray-500', {\n 'mt-2': project.config.credentialEnabled || project.config.magicLinkEnabled,\n 'mt-6': !(project.config.credentialEnabled || project.config.magicLinkEnabled),\n })}>\n <div>{props.extraInfo}</div>\n </div>\n )}\n </div>\n </MaybeFullPage>\n );\n}\n"],"mappings":"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","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components-page/cli-auth-confirm.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\n\nimport { Typography } from \"@stackframe/stack-ui\";\nimport { useState } from \"react\";\nimport { stackAppInternalsSymbol, useStackApp } from \"..\";\nimport { MessageCard } from \"../components/message-cards/message-card\";\nimport { useTranslation } from \"../lib/translations\";\n\nexport function CliAuthConfirmation({ fullPage = true }: { fullPage?: boolean }) {\n const { t } = useTranslation();\n const app = useStackApp();\n const [authorizing, setAuthorizing] = useState(false);\n const [success, setSuccess] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const user = app.useUser({ or: \"redirect\" });\n\n const handleAuthorize = async () => {\n if (authorizing) return;\n\n setAuthorizing(true);\n try {\n // Get login code from URL query parameters\n const urlParams = new URLSearchParams(window.location.search);\n const loginCode = urlParams.get(\"login_code\");\n\n if (!loginCode) {\n throw new Error(\"Missing login code in URL parameters\");\n }\n const refreshToken = (await user.currentSession.getTokens()).refreshToken;\n if (!refreshToken) {\n throw new Error(\"You must be logged in to authorize CLI access\");\n }\n\n // Use the internal API to send the CLI login request\n const result = await (app as any)[stackAppInternalsSymbol].sendRequest(\"/auth/cli/complete\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\"\n },\n body: JSON.stringify({\n login_code: loginCode,\n refresh_token: (await user.currentSession.getTokens()).refreshToken\n })\n });\n\n if (!result.ok) {\n throw new Error(`Authorization failed: ${result.status} ${await result.text()}`);\n }\n\n setSuccess(true);\n } catch (err) {\n setError(err as Error);\n } finally {\n setAuthorizing(false);\n }\n };\n\n if (success) {\n return (\n <MessageCard\n title={t(\"CLI Authorization Successful\")}\n fullPage={fullPage}\n primaryButtonText={t(\"Close\")}\n primaryAction={() => window.close()}\n >\n <Typography>\n {t(\"The CLI application has been authorized successfully. You can now close this window and return to the command line.\")}\n </Typography>\n </MessageCard>\n );\n }\n\n if (error) {\n return (\n <MessageCard\n title={t(\"Authorization Failed\")}\n fullPage={fullPage}\n primaryButtonText={t(\"Try Again\")}\n primaryAction={() => setError(null)}\n secondaryButtonText={t(\"Cancel\")}\n secondaryAction={() => window.close()}\n >\n <Typography className=\"text-red-600\">\n {t(\"Failed to authorize the CLI application:\")}\n </Typography>\n <Typography className=\"text-red-600\">\n {error.message}\n </Typography>\n </MessageCard>\n );\n }\n\n return (\n <MessageCard\n title={t(\"Authorize CLI Application\")}\n fullPage={fullPage}\n primaryButtonText={authorizing ? t(\"Authorizing...\") : t(\"Authorize\")}\n primaryAction={handleAuthorize}\n secondaryButtonText={t(\"Cancel\")}\n secondaryAction={() => window.close()}\n >\n <Typography>\n {t(\"A command line application is requesting access to your account. Click the button below to authorize it.\")}\n </Typography>\n <Typography variant=\"destructive\">\n {t(\"WARNING: Make sure you trust the command line application, as it will gain access to your account. If you did not initiate this request, you can close this page and ignore it. We will never send you this link via email or any other means.\")}\n </Typography>\n </MessageCard>\n );\n}\n"],"mappings":";;;AAOA,SAAS,kBAAkB;AAC3B,SAAS,gBAAgB;AACzB,SAAS,yBAAyB,mBAAmB;AACrD,SAAS,mBAAmB;AAC5B,SAAS,sBAAsB;AA4DvB,cASF,YATE;AA1DD,SAAS,oBAAoB,EAAE,WAAW,KAAK,GAA2B;AAC/E,QAAM,EAAE,EAAE,IAAI,eAAe;AAC7B,QAAM,MAAM,YAAY;AACxB,QAAM,CAAC,aAAa,cAAc,IAAI,SAAS,KAAK;AACpD,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,KAAK;AAC5C,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAuB,IAAI;AAErD,QAAM,OAAO,IAAI,QAAQ,EAAE,IAAI,WAAW,CAAC;AAE3C,QAAM,kBAAkB,YAAY;AAClC,QAAI,YAAa;AAEjB,mBAAe,IAAI;AACnB,QAAI;AAEF,YAAM,YAAY,IAAI,gBAAgB,OAAO,SAAS,MAAM;AAC5D,YAAM,YAAY,UAAU,IAAI,YAAY;AAE5C,UAAI,CAAC,WAAW;AACd,cAAM,IAAI,MAAM,sCAAsC;AAAA,MACxD;AACA,YAAM,gBAAgB,MAAM,KAAK,eAAe,UAAU,GAAG;AAC7D,UAAI,CAAC,cAAc;AACjB,cAAM,IAAI,MAAM,+CAA+C;AAAA,MACjE;AAGA,YAAM,SAAS,MAAO,IAAY,uBAAuB,EAAE,YAAY,sBAAsB;AAAA,QAC3F,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,KAAK,UAAU;AAAA,UACnB,YAAY;AAAA,UACZ,gBAAgB,MAAM,KAAK,eAAe,UAAU,GAAG;AAAA,QACzD,CAAC;AAAA,MACH,CAAC;AAED,UAAI,CAAC,OAAO,IAAI;AACd,cAAM,IAAI,MAAM,yBAAyB,OAAO,MAAM,IAAI,MAAM,OAAO,KAAK,CAAC,EAAE;AAAA,MACjF;AAEA,iBAAW,IAAI;AAAA,IACjB,SAAS,KAAK;AACZ,eAAS,GAAY;AAAA,IACvB,UAAE;AACA,qBAAe,KAAK;AAAA,IACtB;AAAA,EACF;AAEA,MAAI,SAAS;AACX,WACE;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,EAAE,8BAA8B;AAAA,QACvC;AAAA,QACA,mBAAmB,EAAE,OAAO;AAAA,QAC5B,eAAe,MAAM,OAAO,MAAM;AAAA,QAElC,8BAAC,cACE,YAAE,qHAAqH,GAC1H;AAAA;AAAA,IACF;AAAA,EAEJ;AAEA,MAAI,OAAO;AACT,WACE;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,EAAE,sBAAsB;AAAA,QAC/B;AAAA,QACA,mBAAmB,EAAE,WAAW;AAAA,QAChC,eAAe,MAAM,SAAS,IAAI;AAAA,QAClC,qBAAqB,EAAE,QAAQ;AAAA,QAC/B,iBAAiB,MAAM,OAAO,MAAM;AAAA,QAEpC;AAAA,8BAAC,cAAW,WAAU,gBACnB,YAAE,0CAA0C,GAC/C;AAAA,UACA,oBAAC,cAAW,WAAU,gBACnB,gBAAM,SACT;AAAA;AAAA;AAAA,IACF;AAAA,EAEJ;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,EAAE,2BAA2B;AAAA,MACpC;AAAA,MACA,mBAAmB,cAAc,EAAE,gBAAgB,IAAI,EAAE,WAAW;AAAA,MACpE,eAAe;AAAA,MACf,qBAAqB,EAAE,QAAQ;AAAA,MAC/B,iBAAiB,MAAM,OAAO,MAAM;AAAA,MAEpC;AAAA,4BAAC,cACE,YAAE,0GAA0G,GAC/G;AAAA,QACA,oBAAC,cAAW,SAAQ,eACjB,YAAE,gPAAgP,GACrP;AAAA;AAAA;AAAA,EACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/components-page/cli-auth-confirm.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 { Typography } from \"@stackframe/stack-ui\";\nimport { useState } from \"react\";\nimport { stackAppInternalsSymbol, useStackApp } from \"..\";\nimport { MessageCard } from \"../components/message-cards/message-card\";\nimport { useTranslation } from \"../lib/translations\";\n\nexport function CliAuthConfirmation({ fullPage = true }: { fullPage?: boolean }) {\n const { t } = useTranslation();\n const app = useStackApp();\n const [authorizing, setAuthorizing] = useState(false);\n const [success, setSuccess] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const user = app.useUser({ or: \"redirect\" });\n\n const handleAuthorize = async () => {\n if (authorizing) return;\n\n setAuthorizing(true);\n try {\n // Get login code from URL query parameters\n const urlParams = new URLSearchParams(window.location.search);\n const loginCode = urlParams.get(\"login_code\");\n\n if (!loginCode) {\n throw new Error(\"Missing login code in URL parameters\");\n }\n const refreshToken = (await user.currentSession.getTokens()).refreshToken;\n if (!refreshToken) {\n throw new Error(\"You must be logged in to authorize CLI access\");\n }\n\n // Use the internal API to send the CLI login request\n const result = await (app as any)[stackAppInternalsSymbol].sendRequest(\"/auth/cli/complete\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\"\n },\n body: JSON.stringify({\n login_code: loginCode,\n refresh_token: (await user.currentSession.getTokens()).refreshToken\n })\n });\n\n if (!result.ok) {\n throw new Error(`Authorization failed: ${result.status} ${await result.text()}`);\n }\n\n setSuccess(true);\n } catch (err) {\n setError(err as Error);\n } finally {\n setAuthorizing(false);\n }\n };\n\n if (success) {\n return (\n <MessageCard\n title={t(\"CLI Authorization Successful\")}\n fullPage={fullPage}\n primaryButtonText={t(\"Close\")}\n primaryAction={() => window.close()}\n >\n <Typography>\n {t(\"The CLI application has been authorized successfully. You can now close this window and return to the command line.\")}\n </Typography>\n </MessageCard>\n );\n }\n\n if (error) {\n return (\n <MessageCard\n title={t(\"Authorization Failed\")}\n fullPage={fullPage}\n primaryButtonText={t(\"Try Again\")}\n primaryAction={() => setError(null)}\n secondaryButtonText={t(\"Cancel\")}\n secondaryAction={() => window.close()}\n >\n <Typography className=\"text-red-600\">\n {t(\"Failed to authorize the CLI application:\")}\n </Typography>\n <Typography className=\"text-red-600\">\n {error.message}\n </Typography>\n </MessageCard>\n );\n }\n\n return (\n <MessageCard\n title={t(\"Authorize CLI Application\")}\n fullPage={fullPage}\n primaryButtonText={authorizing ? t(\"Authorizing...\") : t(\"Authorize\")}\n primaryAction={handleAuthorize}\n secondaryButtonText={t(\"Cancel\")}\n secondaryAction={() => window.close()}\n >\n <Typography>\n {t(\"A command line application is requesting access to your account. Click the button below to authorize it.\")}\n </Typography>\n <Typography variant=\"destructive\">\n {t(\"WARNING: Make sure you trust the command line application, as it will gain access to your account. If you did not initiate this request, you can close this page and ignore it. We will never send you this link via email or any other means.\")}\n </Typography>\n </MessageCard>\n );\n}\n"],"mappings":";;;AAOA,SAAS,kBAAkB;AAC3B,SAAS,gBAAgB;AACzB,SAAS,yBAAyB,mBAAmB;AACrD,SAAS,mBAAmB;AAC5B,SAAS,sBAAsB;AA4DvB,cASF,YATE;AA1DD,SAAS,oBAAoB,EAAE,WAAW,KAAK,GAA2B;AAC/E,QAAM,EAAE,EAAE,IAAI,eAAe;AAC7B,QAAM,MAAM,YAAY;AACxB,QAAM,CAAC,aAAa,cAAc,IAAI,SAAS,KAAK;AACpD,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,KAAK;AAC5C,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAuB,IAAI;AAErD,QAAM,OAAO,IAAI,QAAQ,EAAE,IAAI,WAAW,CAAC;AAE3C,QAAM,kBAAkB,YAAY;AAClC,QAAI,YAAa;AAEjB,mBAAe,IAAI;AACnB,QAAI;AAEF,YAAM,YAAY,IAAI,gBAAgB,OAAO,SAAS,MAAM;AAC5D,YAAM,YAAY,UAAU,IAAI,YAAY;AAE5C,UAAI,CAAC,WAAW;AACd,cAAM,IAAI,MAAM,sCAAsC;AAAA,MACxD;AACA,YAAM,gBAAgB,MAAM,KAAK,eAAe,UAAU,GAAG;AAC7D,UAAI,CAAC,cAAc;AACjB,cAAM,IAAI,MAAM,+CAA+C;AAAA,MACjE;AAGA,YAAM,SAAS,MAAO,IAAY,uBAAuB,EAAE,YAAY,sBAAsB;AAAA,QAC3F,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,KAAK,UAAU;AAAA,UACnB,YAAY;AAAA,UACZ,gBAAgB,MAAM,KAAK,eAAe,UAAU,GAAG;AAAA,QACzD,CAAC;AAAA,MACH,CAAC;AAED,UAAI,CAAC,OAAO,IAAI;AACd,cAAM,IAAI,MAAM,yBAAyB,OAAO,MAAM,IAAI,MAAM,OAAO,KAAK,CAAC,EAAE;AAAA,MACjF;AAEA,iBAAW,IAAI;AAAA,IACjB,SAAS,KAAK;AACZ,eAAS,GAAY;AAAA,IACvB,UAAE;AACA,qBAAe,KAAK;AAAA,IACtB;AAAA,EACF;AAEA,MAAI,SAAS;AACX,WACE;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,EAAE,8BAA8B;AAAA,QACvC;AAAA,QACA,mBAAmB,EAAE,OAAO;AAAA,QAC5B,eAAe,MAAM,OAAO,MAAM;AAAA,QAElC,8BAAC,cACE,YAAE,qHAAqH,GAC1H;AAAA;AAAA,IACF;AAAA,EAEJ;AAEA,MAAI,OAAO;AACT,WACE;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,EAAE,sBAAsB;AAAA,QAC/B;AAAA,QACA,mBAAmB,EAAE,WAAW;AAAA,QAChC,eAAe,MAAM,SAAS,IAAI;AAAA,QAClC,qBAAqB,EAAE,QAAQ;AAAA,QAC/B,iBAAiB,MAAM,OAAO,MAAM;AAAA,QAEpC;AAAA,8BAAC,cAAW,WAAU,gBACnB,YAAE,0CAA0C,GAC/C;AAAA,UACA,oBAAC,cAAW,WAAU,gBACnB,gBAAM,SACT;AAAA;AAAA;AAAA,IACF;AAAA,EAEJ;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,EAAE,2BAA2B;AAAA,MACpC;AAAA,MACA,mBAAmB,cAAc,EAAE,gBAAgB,IAAI,EAAE,WAAW;AAAA,MACpE,eAAe;AAAA,MACf,qBAAqB,EAAE,QAAQ;AAAA,MAC/B,iBAAiB,MAAM,OAAO,MAAM;AAAA,MAEpC;AAAA,4BAAC,cACE,YAAE,0GAA0G,GAC/G;AAAA,QACA,oBAAC,cAAW,SAAQ,eACjB,YAAE,gPAAgP,GACrP;AAAA;AAAA;AAAA,EACF;AAEJ;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components-page/email-verification.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\n\nimport { KnownErrors } from \"@stackframe/stack-shared\";\nimport { throwErr } from \"@stackframe/stack-shared/dist/utils/errors\";\nimport React from \"react\";\nimport { useStackApp, useUser } from \"..\";\nimport { MessageCard } from \"../components/message-cards/message-card\";\nimport { useTranslation } from \"../lib/translations\";\n\nexport function EmailVerification(props: {\n searchParams?: Record<string, string>,\n fullPage?: boolean,\n}) {\n const { t } = useTranslation();\n const stackApp = useStackApp();\n const user = useUser();\n const [result, setResult] = React.useState<Awaited<ReturnType<typeof stackApp.verifyEmail>> | null>(null);\n\n const invalidJsx = (\n <MessageCard title={t(\"Invalid Verification Link\")} fullPage={!!props.fullPage}>\n <p>{t(\"Please check if you have the correct link. If you continue to have issues, please contact support.\")}</p>\n </MessageCard>\n );\n\n const expiredJsx = (\n <MessageCard title={t(\"Expired Verification Link\")} fullPage={!!props.fullPage}>\n <p>{t(\"Your email verification link has expired. Please request a new verification link from your account settings.\")}</p>\n </MessageCard>\n );\n\n if (!props.searchParams?.code) {\n return invalidJsx;\n }\n\n if (!result) {\n return <MessageCard\n title={t(\"Do you want to verify your email?\")}\n fullPage={!!props.fullPage}\n primaryButtonText={t(\"Verify\")}\n primaryAction={async () => {\n const result = await stackApp.verifyEmail(props.searchParams?.code || throwErr(\"No verification code provided\"));\n setResult(result);\n }}\n secondaryButtonText={t(\"Cancel\")}\n secondaryAction={async () => {\n await stackApp.redirectToHome();\n }}\n />;\n } else {\n if (result.status === 'error') {\n if (KnownErrors.VerificationCodeNotFound.isInstance(result.error)) {\n return invalidJsx;\n } else if (KnownErrors.VerificationCodeExpired.isInstance(result.error)) {\n return expiredJsx;\n } else if (KnownErrors.VerificationCodeAlreadyUsed.isInstance(result.error)) {\n // everything fine, continue\n } else {\n throw result.error;\n }\n }\n\n return <MessageCard\n title={t(\"You email has been verified!\")}\n fullPage={!!props.fullPage}\n primaryButtonText={t(\"Go home\")}\n primaryAction={async () => {\n await stackApp.redirectToHome();\n }}\n />;\n }\n}\n"],"mappings":";;;AAOA,SAAS,mBAAmB;AAC5B,SAAS,gBAAgB;AACzB,OAAO,WAAW;AAClB,SAAS,aAAa,eAAe;AACrC,SAAS,mBAAmB;AAC5B,SAAS,sBAAsB;AAazB;AAXC,SAAS,kBAAkB,OAG/B;AACD,QAAM,EAAE,EAAE,IAAI,eAAe;AAC7B,QAAM,WAAW,YAAY;AAC7B,QAAM,OAAO,QAAQ;AACrB,QAAM,CAAC,QAAQ,SAAS,IAAI,MAAM,SAAkE,IAAI;AAExG,QAAM,aACJ,oBAAC,eAAY,OAAO,EAAE,2BAA2B,GAAG,UAAU,CAAC,CAAC,MAAM,UACpE,8BAAC,OAAG,YAAE,oGAAoG,GAAE,GAC9G;AAGF,QAAM,aACJ,oBAAC,eAAY,OAAO,EAAE,2BAA2B,GAAG,UAAU,CAAC,CAAC,MAAM,UACpE,8BAAC,OAAG,YAAE,8GAA8G,GAAE,GACxH;AAGF,MAAI,CAAC,MAAM,cAAc,MAAM;AAC7B,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,MAAC;AAAA;AAAA,QACN,OAAO,EAAE,mCAAmC;AAAA,QAC5C,UAAU,CAAC,CAAC,MAAM;AAAA,QAClB,mBAAmB,EAAE,QAAQ;AAAA,QAC7B,eAAe,YAAY;AACzB,gBAAMA,UAAS,MAAM,SAAS,YAAY,MAAM,cAAc,QAAQ,SAAS,+BAA+B,CAAC;AAC/G,oBAAUA,OAAM;AAAA,QAClB;AAAA,QACA,qBAAqB,EAAE,QAAQ;AAAA,QAC/B,iBAAiB,YAAY;AAC3B,gBAAM,SAAS,eAAe;AAAA,QAChC;AAAA;AAAA,IACF;AAAA,EACF,OAAO;AACL,QAAI,OAAO,WAAW,SAAS;AAC7B,UAAI,YAAY,yBAAyB,WAAW,OAAO,KAAK,GAAG;AACjE,eAAO;AAAA,MACT,WAAW,YAAY,wBAAwB,WAAW,OAAO,KAAK,GAAG;AACvE,eAAO;AAAA,MACT,WAAW,YAAY,4BAA4B,WAAW,OAAO,KAAK,GAAG;AAAA,MAE7E,OAAO;AACL,cAAM,OAAO;AAAA,MACf;AAAA,IACF;AAEA,WAAO;AAAA,MAAC;AAAA;AAAA,QACN,OAAO,EAAE,8BAA8B;AAAA,QACvC,UAAU,CAAC,CAAC,MAAM;AAAA,QAClB,mBAAmB,EAAE,SAAS;AAAA,QAC9B,eAAe,YAAY;AACzB,gBAAM,SAAS,eAAe;AAAA,QAChC;AAAA;AAAA,IACF;AAAA,EACF;AACF;","names":["result"]}
1
+ {"version":3,"sources":["../../../src/components-page/email-verification.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 { throwErr } from \"@stackframe/stack-shared/dist/utils/errors\";\nimport React from \"react\";\nimport { useStackApp, useUser } from \"..\";\nimport { MessageCard } from \"../components/message-cards/message-card\";\nimport { useTranslation } from \"../lib/translations\";\n\nexport function EmailVerification(props: {\n searchParams?: Record<string, string>,\n fullPage?: boolean,\n}) {\n const { t } = useTranslation();\n const stackApp = useStackApp();\n const user = useUser();\n const [result, setResult] = React.useState<Awaited<ReturnType<typeof stackApp.verifyEmail>> | null>(null);\n\n const invalidJsx = (\n <MessageCard title={t(\"Invalid Verification Link\")} fullPage={!!props.fullPage}>\n <p>{t(\"Please check if you have the correct link. If you continue to have issues, please contact support.\")}</p>\n </MessageCard>\n );\n\n const expiredJsx = (\n <MessageCard title={t(\"Expired Verification Link\")} fullPage={!!props.fullPage}>\n <p>{t(\"Your email verification link has expired. Please request a new verification link from your account settings.\")}</p>\n </MessageCard>\n );\n\n if (!props.searchParams?.code) {\n return invalidJsx;\n }\n\n if (!result) {\n return <MessageCard\n title={t(\"Do you want to verify your email?\")}\n fullPage={!!props.fullPage}\n primaryButtonText={t(\"Verify\")}\n primaryAction={async () => {\n const result = await stackApp.verifyEmail(props.searchParams?.code || throwErr(\"No verification code provided\"));\n setResult(result);\n }}\n secondaryButtonText={t(\"Cancel\")}\n secondaryAction={async () => {\n await stackApp.redirectToHome();\n }}\n />;\n } else {\n if (result.status === 'error') {\n if (KnownErrors.VerificationCodeNotFound.isInstance(result.error)) {\n return invalidJsx;\n } else if (KnownErrors.VerificationCodeExpired.isInstance(result.error)) {\n return expiredJsx;\n } else if (KnownErrors.VerificationCodeAlreadyUsed.isInstance(result.error)) {\n // everything fine, continue\n } else {\n throw result.error;\n }\n }\n\n return <MessageCard\n title={t(\"You email has been verified!\")}\n fullPage={!!props.fullPage}\n primaryButtonText={t(\"Go home\")}\n primaryAction={async () => {\n await stackApp.redirectToHome();\n }}\n />;\n }\n}\n"],"mappings":";;;AAOA,SAAS,mBAAmB;AAC5B,SAAS,gBAAgB;AACzB,OAAO,WAAW;AAClB,SAAS,aAAa,eAAe;AACrC,SAAS,mBAAmB;AAC5B,SAAS,sBAAsB;AAazB;AAXC,SAAS,kBAAkB,OAG/B;AACD,QAAM,EAAE,EAAE,IAAI,eAAe;AAC7B,QAAM,WAAW,YAAY;AAC7B,QAAM,OAAO,QAAQ;AACrB,QAAM,CAAC,QAAQ,SAAS,IAAI,MAAM,SAAkE,IAAI;AAExG,QAAM,aACJ,oBAAC,eAAY,OAAO,EAAE,2BAA2B,GAAG,UAAU,CAAC,CAAC,MAAM,UACpE,8BAAC,OAAG,YAAE,oGAAoG,GAAE,GAC9G;AAGF,QAAM,aACJ,oBAAC,eAAY,OAAO,EAAE,2BAA2B,GAAG,UAAU,CAAC,CAAC,MAAM,UACpE,8BAAC,OAAG,YAAE,8GAA8G,GAAE,GACxH;AAGF,MAAI,CAAC,MAAM,cAAc,MAAM;AAC7B,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,MAAC;AAAA;AAAA,QACN,OAAO,EAAE,mCAAmC;AAAA,QAC5C,UAAU,CAAC,CAAC,MAAM;AAAA,QAClB,mBAAmB,EAAE,QAAQ;AAAA,QAC7B,eAAe,YAAY;AACzB,gBAAMA,UAAS,MAAM,SAAS,YAAY,MAAM,cAAc,QAAQ,SAAS,+BAA+B,CAAC;AAC/G,oBAAUA,OAAM;AAAA,QAClB;AAAA,QACA,qBAAqB,EAAE,QAAQ;AAAA,QAC/B,iBAAiB,YAAY;AAC3B,gBAAM,SAAS,eAAe;AAAA,QAChC;AAAA;AAAA,IACF;AAAA,EACF,OAAO;AACL,QAAI,OAAO,WAAW,SAAS;AAC7B,UAAI,YAAY,yBAAyB,WAAW,OAAO,KAAK,GAAG;AACjE,eAAO;AAAA,MACT,WAAW,YAAY,wBAAwB,WAAW,OAAO,KAAK,GAAG;AACvE,eAAO;AAAA,MACT,WAAW,YAAY,4BAA4B,WAAW,OAAO,KAAK,GAAG;AAAA,MAE7E,OAAO;AACL,cAAM,OAAO;AAAA,MACf;AAAA,IACF;AAEA,WAAO;AAAA,MAAC;AAAA;AAAA,QACN,OAAO,EAAE,8BAA8B;AAAA,QACvC,UAAU,CAAC,CAAC,MAAM;AAAA,QAClB,mBAAmB,EAAE,SAAS;AAAA,QAC9B,eAAe,YAAY;AACzB,gBAAM,SAAS,eAAe;AAAA,QAChC;AAAA;AAAA,IACF;AAAA,EACF;AACF;","names":["result"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components-page/error-page.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\n\nimport { KnownError, KnownErrors } from \"@stackframe/stack-shared\";\nimport { Typography } from \"@stackframe/stack-ui\";\nimport { useStackApp } from \"..\";\nimport { KnownErrorMessageCard } from \"../components/message-cards/known-error-message-card\";\nimport { MessageCard } from \"../components/message-cards/message-card\";\nimport { PredefinedMessageCard } from \"../components/message-cards/predefined-message-card\";\nimport { useTranslation } from \"../lib/translations\";\n\n\nexport function ErrorPage(props: { fullPage?: boolean, searchParams: Record<string, string> }) {\n const { t } = useTranslation();\n const stackApp = useStackApp();\n const errorCode = props.searchParams.errorCode;\n const message = props.searchParams.message;\n const details = props.searchParams.details;\n\n const unknownErrorCard = <PredefinedMessageCard type='unknownError' fullPage={!!props.fullPage} />;\n\n if (!errorCode || !message) {\n return unknownErrorCard;\n }\n\n let error;\n try {\n const detailJson = details ? JSON.parse(details) : {};\n error = KnownError.fromJson({ code: errorCode, message, details: detailJson });\n } catch (e) {\n return unknownErrorCard;\n }\n\n if (KnownErrors.OAuthConnectionAlreadyConnectedToAnotherUser.isInstance(error)) {\n // TODO: add \"Connect a different account\" button\n return (\n <MessageCard\n title={t(\"Failed to connect account\")}\n fullPage={!!props.fullPage}\n primaryButtonText={t(\"Go Home\")}\n primaryAction={() => stackApp.redirectToHome()}\n >\n <Typography>\n {t(\"This account is already connected to another user. Please connect a different account.\")}\n </Typography>\n </MessageCard>\n );\n }\n\n if (KnownErrors.UserAlreadyConnectedToAnotherOAuthConnection.isInstance(error)) {\n // TODO: add \"Connect again\" button\n return (\n <MessageCard\n title={t(\"Failed to connect account\")}\n fullPage={!!props.fullPage}\n primaryButtonText={t(\"Go Home\")}\n primaryAction={() => stackApp.redirectToHome()}\n >\n <Typography>\n {t(\"The user is already connected to another OAuth account. Did you maybe selected the wrong account on the OAuth provider page?\")}\n </Typography>\n </MessageCard>\n );\n }\n\n if (KnownErrors.OAuthProviderAccessDenied.isInstance(error)) {\n return (\n <MessageCard\n title={t(\"OAuth provider access denied\")}\n fullPage={!!props.fullPage}\n primaryButtonText={t(\"Sign in again\")}\n primaryAction={() => stackApp.redirectToSignIn()}\n secondaryButtonText={t(\"Go Home\")}\n secondaryAction={() => stackApp.redirectToHome()}\n >\n <Typography>\n {t(\"The sign-in operation has been cancelled or denied. Please try again.\")}\n </Typography>\n </MessageCard>\n );\n }\n\n return <KnownErrorMessageCard error={error} fullPage={!!props.fullPage} />;\n}\n"],"mappings":";;;AAOA,SAAS,YAAY,mBAAmB;AACxC,SAAS,kBAAkB;AAC3B,SAAS,mBAAmB;AAC5B,SAAS,6BAA6B;AACtC,SAAS,mBAAmB;AAC5B,SAAS,6BAA6B;AACtC,SAAS,sBAAsB;AAUJ;AAPpB,SAAS,UAAU,OAAqE;AAC7F,QAAM,EAAE,EAAE,IAAI,eAAe;AAC7B,QAAM,WAAW,YAAY;AAC7B,QAAM,YAAY,MAAM,aAAa;AACrC,QAAM,UAAU,MAAM,aAAa;AACnC,QAAM,UAAU,MAAM,aAAa;AAEnC,QAAM,mBAAmB,oBAAC,yBAAsB,MAAK,gBAAe,UAAU,CAAC,CAAC,MAAM,UAAU;AAEhG,MAAI,CAAC,aAAa,CAAC,SAAS;AAC1B,WAAO;AAAA,EACT;AAEA,MAAI;AACJ,MAAI;AACF,UAAM,aAAa,UAAU,KAAK,MAAM,OAAO,IAAI,CAAC;AACpD,YAAQ,WAAW,SAAS,EAAE,MAAM,WAAW,SAAS,SAAS,WAAW,CAAC;AAAA,EAC/E,SAAS,GAAG;AACV,WAAO;AAAA,EACT;AAEA,MAAI,YAAY,6CAA6C,WAAW,KAAK,GAAG;AAE9E,WACE;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,EAAE,2BAA2B;AAAA,QACpC,UAAU,CAAC,CAAC,MAAM;AAAA,QAClB,mBAAmB,EAAE,SAAS;AAAA,QAC9B,eAAe,MAAM,SAAS,eAAe;AAAA,QAE7C,8BAAC,cACE,YAAE,wFAAwF,GAC7F;AAAA;AAAA,IACF;AAAA,EAEJ;AAEA,MAAI,YAAY,6CAA6C,WAAW,KAAK,GAAG;AAE9E,WACE;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,EAAE,2BAA2B;AAAA,QACpC,UAAU,CAAC,CAAC,MAAM;AAAA,QAClB,mBAAmB,EAAE,SAAS;AAAA,QAC9B,eAAe,MAAM,SAAS,eAAe;AAAA,QAE7C,8BAAC,cACE,YAAE,8HAA8H,GACnI;AAAA;AAAA,IACF;AAAA,EAEJ;AAEA,MAAI,YAAY,0BAA0B,WAAW,KAAK,GAAG;AAC3D,WACE;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,EAAE,8BAA8B;AAAA,QACvC,UAAU,CAAC,CAAC,MAAM;AAAA,QAClB,mBAAmB,EAAE,eAAe;AAAA,QACpC,eAAe,MAAM,SAAS,iBAAiB;AAAA,QAC/C,qBAAqB,EAAE,SAAS;AAAA,QAChC,iBAAiB,MAAM,SAAS,eAAe;AAAA,QAE/C,8BAAC,cACE,YAAE,uEAAuE,GAC5E;AAAA;AAAA,IACF;AAAA,EAEJ;AAEA,SAAO,oBAAC,yBAAsB,OAAc,UAAU,CAAC,CAAC,MAAM,UAAU;AAC1E;","names":[]}
1
+ {"version":3,"sources":["../../../src/components-page/error-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 { KnownError, KnownErrors } from \"@stackframe/stack-shared\";\nimport { Typography } from \"@stackframe/stack-ui\";\nimport { useStackApp } from \"..\";\nimport { KnownErrorMessageCard } from \"../components/message-cards/known-error-message-card\";\nimport { MessageCard } from \"../components/message-cards/message-card\";\nimport { PredefinedMessageCard } from \"../components/message-cards/predefined-message-card\";\nimport { useTranslation } from \"../lib/translations\";\n\n\nexport function ErrorPage(props: { fullPage?: boolean, searchParams: Record<string, string> }) {\n const { t } = useTranslation();\n const stackApp = useStackApp();\n const errorCode = props.searchParams.errorCode;\n const message = props.searchParams.message;\n const details = props.searchParams.details;\n\n const unknownErrorCard = <PredefinedMessageCard type='unknownError' fullPage={!!props.fullPage} />;\n\n if (!errorCode || !message) {\n return unknownErrorCard;\n }\n\n let error;\n try {\n const detailJson = details ? JSON.parse(details) : {};\n error = KnownError.fromJson({ code: errorCode, message, details: detailJson });\n } catch (e) {\n return unknownErrorCard;\n }\n\n if (KnownErrors.OAuthConnectionAlreadyConnectedToAnotherUser.isInstance(error)) {\n // TODO: add \"Connect a different account\" button\n return (\n <MessageCard\n title={t(\"Failed to connect account\")}\n fullPage={!!props.fullPage}\n primaryButtonText={t(\"Go Home\")}\n primaryAction={() => stackApp.redirectToHome()}\n >\n <Typography>\n {t(\"This account is already connected to another user. Please connect a different account.\")}\n </Typography>\n </MessageCard>\n );\n }\n\n if (KnownErrors.UserAlreadyConnectedToAnotherOAuthConnection.isInstance(error)) {\n // TODO: add \"Connect again\" button\n return (\n <MessageCard\n title={t(\"Failed to connect account\")}\n fullPage={!!props.fullPage}\n primaryButtonText={t(\"Go Home\")}\n primaryAction={() => stackApp.redirectToHome()}\n >\n <Typography>\n {t(\"The user is already connected to another OAuth account. Did you maybe selected the wrong account on the OAuth provider page?\")}\n </Typography>\n </MessageCard>\n );\n }\n\n if (KnownErrors.OAuthProviderAccessDenied.isInstance(error)) {\n return (\n <MessageCard\n title={t(\"OAuth provider access denied\")}\n fullPage={!!props.fullPage}\n primaryButtonText={t(\"Sign in again\")}\n primaryAction={() => stackApp.redirectToSignIn()}\n secondaryButtonText={t(\"Go Home\")}\n secondaryAction={() => stackApp.redirectToHome()}\n >\n <Typography>\n {t(\"The sign-in operation has been cancelled or denied. Please try again.\")}\n </Typography>\n </MessageCard>\n );\n }\n\n return <KnownErrorMessageCard error={error} fullPage={!!props.fullPage} />;\n}\n"],"mappings":";;;AAOA,SAAS,YAAY,mBAAmB;AACxC,SAAS,kBAAkB;AAC3B,SAAS,mBAAmB;AAC5B,SAAS,6BAA6B;AACtC,SAAS,mBAAmB;AAC5B,SAAS,6BAA6B;AACtC,SAAS,sBAAsB;AAUJ;AAPpB,SAAS,UAAU,OAAqE;AAC7F,QAAM,EAAE,EAAE,IAAI,eAAe;AAC7B,QAAM,WAAW,YAAY;AAC7B,QAAM,YAAY,MAAM,aAAa;AACrC,QAAM,UAAU,MAAM,aAAa;AACnC,QAAM,UAAU,MAAM,aAAa;AAEnC,QAAM,mBAAmB,oBAAC,yBAAsB,MAAK,gBAAe,UAAU,CAAC,CAAC,MAAM,UAAU;AAEhG,MAAI,CAAC,aAAa,CAAC,SAAS;AAC1B,WAAO;AAAA,EACT;AAEA,MAAI;AACJ,MAAI;AACF,UAAM,aAAa,UAAU,KAAK,MAAM,OAAO,IAAI,CAAC;AACpD,YAAQ,WAAW,SAAS,EAAE,MAAM,WAAW,SAAS,SAAS,WAAW,CAAC;AAAA,EAC/E,SAAS,GAAG;AACV,WAAO;AAAA,EACT;AAEA,MAAI,YAAY,6CAA6C,WAAW,KAAK,GAAG;AAE9E,WACE;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,EAAE,2BAA2B;AAAA,QACpC,UAAU,CAAC,CAAC,MAAM;AAAA,QAClB,mBAAmB,EAAE,SAAS;AAAA,QAC9B,eAAe,MAAM,SAAS,eAAe;AAAA,QAE7C,8BAAC,cACE,YAAE,wFAAwF,GAC7F;AAAA;AAAA,IACF;AAAA,EAEJ;AAEA,MAAI,YAAY,6CAA6C,WAAW,KAAK,GAAG;AAE9E,WACE;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,EAAE,2BAA2B;AAAA,QACpC,UAAU,CAAC,CAAC,MAAM;AAAA,QAClB,mBAAmB,EAAE,SAAS;AAAA,QAC9B,eAAe,MAAM,SAAS,eAAe;AAAA,QAE7C,8BAAC,cACE,YAAE,8HAA8H,GACnI;AAAA;AAAA,IACF;AAAA,EAEJ;AAEA,MAAI,YAAY,0BAA0B,WAAW,KAAK,GAAG;AAC3D,WACE;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,EAAE,8BAA8B;AAAA,QACvC,UAAU,CAAC,CAAC,MAAM;AAAA,QAClB,mBAAmB,EAAE,eAAe;AAAA,QACpC,eAAe,MAAM,SAAS,iBAAiB;AAAA,QAC/C,qBAAqB,EAAE,SAAS;AAAA,QAChC,iBAAiB,MAAM,SAAS,eAAe;AAAA,QAE/C,8BAAC,cACE,YAAE,uEAAuE,GAC5E;AAAA;AAAA,IACF;AAAA,EAEJ;AAEA,SAAO,oBAAC,yBAAsB,OAAc,UAAU,CAAC,CAAC,MAAM,UAAU;AAC1E;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components-page/forgot-password.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\n\nimport { yupResolver } from \"@hookform/resolvers/yup\";\nimport { strictEmailSchema, yupObject } from \"@stackframe/stack-shared/dist/schema-fields\";\nimport { runAsynchronouslyWithAlert } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { Button, Input, Label, Typography, cn } from \"@stackframe/stack-ui\";\nimport { useState } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport * as yup from \"yup\";\nimport { useStackApp, useUser } from \"..\";\nimport { FormWarningText } from \"../components/elements/form-warning\";\nimport { MaybeFullPage } from \"../components/elements/maybe-full-page\";\nimport { StyledLink } from \"../components/link\";\nimport { PredefinedMessageCard } from \"../components/message-cards/predefined-message-card\";\nimport { useTranslation } from \"../lib/translations\";\n\nexport function ForgotPasswordForm({ onSent }: { onSent?: () => void }) {\n const { t } = useTranslation();\n\n const schema = yupObject({\n email: strictEmailSchema(t(\"Please enter a valid email\")).defined().nonEmpty(t(\"Please enter your email\"))\n });\n\n const { register, handleSubmit, formState: { errors }, clearErrors } = useForm({\n resolver: yupResolver(schema)\n });\n const stackApp = useStackApp();\n const [loading, setLoading] = useState(false);\n\n const onSubmit = async (data: yup.InferType<typeof schema>) => {\n setLoading(true);\n try {\n const { email } = data;\n await stackApp.sendForgotPasswordEmail(email);\n onSent?.();\n } finally {\n setLoading(false);\n }\n };\n\n return (\n <form\n className=\"flex flex-col items-stretch stack-scope\"\n onSubmit={e => runAsynchronouslyWithAlert(handleSubmit(onSubmit)(e))}\n noValidate\n >\n <Label htmlFor=\"email\" className=\"mb-1\">{t(\"Your Email\")}</Label>\n <Input\n id=\"email\"\n type=\"email\"\n autoComplete=\"email\"\n {...register('email')}\n onChange={() => clearErrors('email')}\n />\n <FormWarningText text={errors.email?.message?.toString()} />\n\n <Button type=\"submit\" className=\"mt-6\" loading={loading}>\n {t(\"Send Email\")}\n </Button>\n </form>\n );\n}\n\n\nexport function ForgotPassword(props: { fullPage?: boolean }) {\n const { t } = useTranslation();\n const stackApp = useStackApp();\n const user = useUser();\n const [sent, setSent] = useState(false);\n\n if (user) {\n return <PredefinedMessageCard type='signedIn' fullPage={!!props.fullPage} />;\n }\n\n if (sent) {\n return <PredefinedMessageCard type='emailSent' fullPage={!!props.fullPage} />;\n }\n\n return (\n <MaybeFullPage fullPage={!!props.fullPage}>\n <div className={cn(\n \"stack-scope max-w-[380px] flex-basis-[380px]\",\n props.fullPage ? \"p-4\" : \"p-0\"\n )}>\n <div className=\"text-center\">\n <Typography type='h2'>{t(\"Reset Your Password\")}</Typography>\n <Typography>\n {t(\"Don't need to reset?\")}{\" \"}\n <StyledLink href={stackApp.urls['signIn']}>\n {t(\"Sign in\")}\n </StyledLink>\n </Typography>\n </div>\n <div className=\"mt-6\">\n <ForgotPasswordForm onSent={() => setSent(true)} />\n </div>\n </div>\n </MaybeFullPage>\n );\n};\n"],"mappings":";;;AAOA,SAAS,mBAAmB;AAC5B,SAAS,mBAAmB,iBAAiB;AAC7C,SAAS,kCAAkC;AAC3C,SAAS,QAAQ,OAAO,OAAO,YAAY,UAAU;AACrD,SAAS,gBAAgB;AACzB,SAAS,eAAe;AAExB,SAAS,aAAa,eAAe;AACrC,SAAS,uBAAuB;AAChC,SAAS,qBAAqB;AAC9B,SAAS,kBAAkB;AAC3B,SAAS,6BAA6B;AACtC,SAAS,sBAAsB;AA2B3B,SAKE,KALF;AAzBG,SAAS,mBAAmB,EAAE,OAAO,GAA4B;AACtE,QAAM,EAAE,EAAE,IAAI,eAAe;AAE7B,QAAM,SAAS,UAAU;AAAA,IACvB,OAAO,kBAAkB,EAAE,4BAA4B,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,yBAAyB,CAAC;AAAA,EAC3G,CAAC;AAED,QAAM,EAAE,UAAU,cAAc,WAAW,EAAE,OAAO,GAAG,YAAY,IAAI,QAAQ;AAAA,IAC7E,UAAU,YAAY,MAAM;AAAA,EAC9B,CAAC;AACD,QAAM,WAAW,YAAY;AAC7B,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,KAAK;AAE5C,QAAM,WAAW,OAAO,SAAuC;AAC7D,eAAW,IAAI;AACf,QAAI;AACF,YAAM,EAAE,MAAM,IAAI;AAClB,YAAM,SAAS,wBAAwB,KAAK;AAC9C,eAAS;AAAA,IACT,UAAE;AACA,iBAAW,KAAK;AAAA,IAClB;AAAA,EACF;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,UAAU,OAAK,2BAA2B,aAAa,QAAQ,EAAE,CAAC,CAAC;AAAA,MACnE,YAAU;AAAA,MAEV;AAAA,4BAAC,SAAM,SAAQ,SAAQ,WAAU,QAAQ,YAAE,YAAY,GAAE;AAAA,QACzD;AAAA,UAAC;AAAA;AAAA,YACC,IAAG;AAAA,YACH,MAAK;AAAA,YACL,cAAa;AAAA,YACZ,GAAG,SAAS,OAAO;AAAA,YACpB,UAAU,MAAM,YAAY,OAAO;AAAA;AAAA,QACrC;AAAA,QACA,oBAAC,mBAAgB,MAAM,OAAO,OAAO,SAAS,SAAS,GAAG;AAAA,QAE1D,oBAAC,UAAO,MAAK,UAAS,WAAU,QAAO,SACpC,YAAE,YAAY,GACjB;AAAA;AAAA;AAAA,EACF;AAEJ;AAGO,SAAS,eAAe,OAA+B;AAC5D,QAAM,EAAE,EAAE,IAAI,eAAe;AAC7B,QAAM,WAAW,YAAY;AAC7B,QAAM,OAAO,QAAQ;AACrB,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,KAAK;AAEtC,MAAI,MAAM;AACR,WAAO,oBAAC,yBAAsB,MAAK,YAAW,UAAU,CAAC,CAAC,MAAM,UAAU;AAAA,EAC5E;AAEA,MAAI,MAAM;AACR,WAAO,oBAAC,yBAAsB,MAAK,aAAY,UAAU,CAAC,CAAC,MAAM,UAAU;AAAA,EAC7E;AAEA,SACE,oBAAC,iBAAc,UAAU,CAAC,CAAC,MAAM,UAC/B,+BAAC,SAAI,WAAW;AAAA,IACd;AAAA,IACA,MAAM,WAAW,QAAQ;AAAA,EAC3B,GACE;AAAA,yBAAC,SAAI,WAAU,eACb;AAAA,0BAAC,cAAW,MAAK,MAAM,YAAE,qBAAqB,GAAE;AAAA,MAChD,qBAAC,cACE;AAAA,UAAE,sBAAsB;AAAA,QAAG;AAAA,QAC5B,oBAAC,cAAW,MAAM,SAAS,KAAK,QAAQ,GACrC,YAAE,SAAS,GACd;AAAA,SACF;AAAA,OACF;AAAA,IACA,oBAAC,SAAI,WAAU,QACb,8BAAC,sBAAmB,QAAQ,MAAM,QAAQ,IAAI,GAAG,GACnD;AAAA,KACF,GACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/components-page/forgot-password.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 { yupResolver } from \"@hookform/resolvers/yup\";\nimport { strictEmailSchema, yupObject } from \"@stackframe/stack-shared/dist/schema-fields\";\nimport { runAsynchronouslyWithAlert } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { Button, Input, Label, Typography, cn } from \"@stackframe/stack-ui\";\nimport { useState } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport * as yup from \"yup\";\nimport { useStackApp, useUser } from \"..\";\nimport { FormWarningText } from \"../components/elements/form-warning\";\nimport { MaybeFullPage } from \"../components/elements/maybe-full-page\";\nimport { StyledLink } from \"../components/link\";\nimport { PredefinedMessageCard } from \"../components/message-cards/predefined-message-card\";\nimport { useTranslation } from \"../lib/translations\";\n\nexport function ForgotPasswordForm({ onSent }: { onSent?: () => void }) {\n const { t } = useTranslation();\n\n const schema = yupObject({\n email: strictEmailSchema(t(\"Please enter a valid email\")).defined().nonEmpty(t(\"Please enter your email\"))\n });\n\n const { register, handleSubmit, formState: { errors }, clearErrors } = useForm({\n resolver: yupResolver(schema)\n });\n const stackApp = useStackApp();\n const [loading, setLoading] = useState(false);\n\n const onSubmit = async (data: yup.InferType<typeof schema>) => {\n setLoading(true);\n try {\n const { email } = data;\n await stackApp.sendForgotPasswordEmail(email);\n onSent?.();\n } finally {\n setLoading(false);\n }\n };\n\n return (\n <form\n className=\"flex flex-col items-stretch stack-scope\"\n onSubmit={e => runAsynchronouslyWithAlert(handleSubmit(onSubmit)(e))}\n noValidate\n >\n <Label htmlFor=\"email\" className=\"mb-1\">{t(\"Your Email\")}</Label>\n <Input\n id=\"email\"\n type=\"email\"\n autoComplete=\"email\"\n {...register('email')}\n onChange={() => clearErrors('email')}\n />\n <FormWarningText text={errors.email?.message?.toString()} />\n\n <Button type=\"submit\" className=\"mt-6\" loading={loading}>\n {t(\"Send Email\")}\n </Button>\n </form>\n );\n}\n\n\nexport function ForgotPassword(props: { fullPage?: boolean }) {\n const { t } = useTranslation();\n const stackApp = useStackApp();\n const user = useUser();\n const [sent, setSent] = useState(false);\n\n if (user) {\n return <PredefinedMessageCard type='signedIn' fullPage={!!props.fullPage} />;\n }\n\n if (sent) {\n return <PredefinedMessageCard type='emailSent' fullPage={!!props.fullPage} />;\n }\n\n return (\n <MaybeFullPage fullPage={!!props.fullPage}>\n <div className={cn(\n \"stack-scope max-w-[380px] flex-basis-[380px]\",\n props.fullPage ? \"p-4\" : \"p-0\"\n )}>\n <div className=\"text-center\">\n <Typography type='h2'>{t(\"Reset Your Password\")}</Typography>\n <Typography>\n {t(\"Don't need to reset?\")}{\" \"}\n <StyledLink href={stackApp.urls['signIn']}>\n {t(\"Sign in\")}\n </StyledLink>\n </Typography>\n </div>\n <div className=\"mt-6\">\n <ForgotPasswordForm onSent={() => setSent(true)} />\n </div>\n </div>\n </MaybeFullPage>\n );\n};\n"],"mappings":";;;AAOA,SAAS,mBAAmB;AAC5B,SAAS,mBAAmB,iBAAiB;AAC7C,SAAS,kCAAkC;AAC3C,SAAS,QAAQ,OAAO,OAAO,YAAY,UAAU;AACrD,SAAS,gBAAgB;AACzB,SAAS,eAAe;AAExB,SAAS,aAAa,eAAe;AACrC,SAAS,uBAAuB;AAChC,SAAS,qBAAqB;AAC9B,SAAS,kBAAkB;AAC3B,SAAS,6BAA6B;AACtC,SAAS,sBAAsB;AA2B3B,SAKE,KALF;AAzBG,SAAS,mBAAmB,EAAE,OAAO,GAA4B;AACtE,QAAM,EAAE,EAAE,IAAI,eAAe;AAE7B,QAAM,SAAS,UAAU;AAAA,IACvB,OAAO,kBAAkB,EAAE,4BAA4B,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,yBAAyB,CAAC;AAAA,EAC3G,CAAC;AAED,QAAM,EAAE,UAAU,cAAc,WAAW,EAAE,OAAO,GAAG,YAAY,IAAI,QAAQ;AAAA,IAC7E,UAAU,YAAY,MAAM;AAAA,EAC9B,CAAC;AACD,QAAM,WAAW,YAAY;AAC7B,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,KAAK;AAE5C,QAAM,WAAW,OAAO,SAAuC;AAC7D,eAAW,IAAI;AACf,QAAI;AACF,YAAM,EAAE,MAAM,IAAI;AAClB,YAAM,SAAS,wBAAwB,KAAK;AAC9C,eAAS;AAAA,IACT,UAAE;AACA,iBAAW,KAAK;AAAA,IAClB;AAAA,EACF;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,UAAU,OAAK,2BAA2B,aAAa,QAAQ,EAAE,CAAC,CAAC;AAAA,MACnE,YAAU;AAAA,MAEV;AAAA,4BAAC,SAAM,SAAQ,SAAQ,WAAU,QAAQ,YAAE,YAAY,GAAE;AAAA,QACzD;AAAA,UAAC;AAAA;AAAA,YACC,IAAG;AAAA,YACH,MAAK;AAAA,YACL,cAAa;AAAA,YACZ,GAAG,SAAS,OAAO;AAAA,YACpB,UAAU,MAAM,YAAY,OAAO;AAAA;AAAA,QACrC;AAAA,QACA,oBAAC,mBAAgB,MAAM,OAAO,OAAO,SAAS,SAAS,GAAG;AAAA,QAE1D,oBAAC,UAAO,MAAK,UAAS,WAAU,QAAO,SACpC,YAAE,YAAY,GACjB;AAAA;AAAA;AAAA,EACF;AAEJ;AAGO,SAAS,eAAe,OAA+B;AAC5D,QAAM,EAAE,EAAE,IAAI,eAAe;AAC7B,QAAM,WAAW,YAAY;AAC7B,QAAM,OAAO,QAAQ;AACrB,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,KAAK;AAEtC,MAAI,MAAM;AACR,WAAO,oBAAC,yBAAsB,MAAK,YAAW,UAAU,CAAC,CAAC,MAAM,UAAU;AAAA,EAC5E;AAEA,MAAI,MAAM;AACR,WAAO,oBAAC,yBAAsB,MAAK,aAAY,UAAU,CAAC,CAAC,MAAM,UAAU;AAAA,EAC7E;AAEA,SACE,oBAAC,iBAAc,UAAU,CAAC,CAAC,MAAM,UAC/B,+BAAC,SAAI,WAAW;AAAA,IACd;AAAA,IACA,MAAM,WAAW,QAAQ;AAAA,EAC3B,GACE;AAAA,yBAAC,SAAI,WAAU,eACb;AAAA,0BAAC,cAAW,MAAK,MAAM,YAAE,qBAAqB,GAAE;AAAA,MAChD,qBAAC,cACE;AAAA,UAAE,sBAAsB;AAAA,QAAG;AAAA,QAC5B,oBAAC,cAAW,MAAM,SAAS,KAAK,QAAQ,GACrC,YAAE,SAAS,GACd;AAAA,SACF;AAAA,OACF;AAAA,IACA,oBAAC,SAAI,WAAU,QACb,8BAAC,sBAAmB,QAAQ,MAAM,QAAQ,IAAI,GAAG,GACnD;AAAA,KACF,GACF;AAEJ;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components-page/magic-link-callback.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\n\nimport { KnownErrors } from \"@stackframe/stack-shared\";\nimport { cacheFunction } from \"@stackframe/stack-shared/dist/utils/caches\";\nimport { throwErr } from \"@stackframe/stack-shared/dist/utils/errors\";\nimport React from \"react\";\nimport { StackClientApp, useStackApp, useUser } from \"..\";\nimport { MessageCard } from \"../components/message-cards/message-card\";\nimport { PredefinedMessageCard } from \"../components/message-cards/predefined-message-card\";\nimport { useTranslation } from \"../lib/translations\";\n\nconst cacheSignInWithMagicLink = cacheFunction(async (stackApp: StackClientApp<true>, code: string) => {\n return await stackApp.signInWithMagicLink(code);\n});\n\nexport function MagicLinkCallback(props: {\n searchParams?: Record<string, string>,\n fullPage?: boolean,\n}) {\n const { t } = useTranslation();\n const stackApp = useStackApp();\n const user = useUser();\n const [result, setResult] = React.useState<Awaited<ReturnType<typeof stackApp.signInWithMagicLink>> | null>(null);\n\n if (user) {\n return <PredefinedMessageCard type='signedIn' fullPage={!!props.fullPage} />;\n }\n\n const invalidJsx = (\n <MessageCard title={t(\"Invalid Magic Link\")} fullPage={!!props.fullPage}>\n <p>{t(\"Please check if you have the correct link. If you continue to have issues, please contact support.\")}</p>\n </MessageCard>\n );\n\n const expiredJsx = (\n <MessageCard title={t(\"Expired Magic Link\")} fullPage={!!props.fullPage}>\n <p>{t(\"Your magic link has expired. Please request a new magic link if you need to sign-in.\")}</p>\n </MessageCard>\n );\n\n const alreadyUsedJsx = (\n <MessageCard title={t(\"Magic Link Already Used\")} fullPage={!!props.fullPage}>\n <p>{t(\"The magic link has already been used. The link can only be used once. Please request a new magic link if you need to sign-in again.\")}</p>\n </MessageCard>\n );\n\n if (!props.searchParams?.code) {\n return invalidJsx;\n }\n\n if (!result) {\n return <MessageCard\n title={t(\"Do you want to sign in?\")}\n fullPage={!!props.fullPage}\n primaryButtonText={t(\"Sign in\")}\n primaryAction={async () => {\n const result = await stackApp.signInWithMagicLink(props.searchParams?.code || throwErr(\"No magic link provided\"));\n setResult(result);\n }}\n secondaryButtonText={t(\"Cancel\")}\n secondaryAction={async () => {\n await stackApp.redirectToHome();\n }}\n />;\n } else {\n if (result.status === 'error') {\n if (KnownErrors.VerificationCodeNotFound.isInstance(result.error)) {\n return invalidJsx;\n } else if (KnownErrors.VerificationCodeExpired.isInstance(result.error)) {\n return expiredJsx;\n } else if (KnownErrors.VerificationCodeAlreadyUsed.isInstance(result.error)) {\n return alreadyUsedJsx;\n } else {\n throw result.error;\n }\n }\n\n return <MessageCard\n title={t(\"Signed in successfully!\")}\n fullPage={!!props.fullPage}\n primaryButtonText={t(\"Go home\")}\n primaryAction={async () => {\n await stackApp.redirectToHome();\n }}\n />;\n }\n}\n"],"mappings":";;;AAOA,SAAS,mBAAmB;AAC5B,SAAS,qBAAqB;AAC9B,SAAS,gBAAgB;AACzB,OAAO,WAAW;AAClB,SAAyB,aAAa,eAAe;AACrD,SAAS,mBAAmB;AAC5B,SAAS,6BAA6B;AACtC,SAAS,sBAAsB;AAgBpB;AAdX,IAAM,2BAA2B,cAAc,OAAO,UAAgC,SAAiB;AACrG,SAAO,MAAM,SAAS,oBAAoB,IAAI;AAChD,CAAC;AAEM,SAAS,kBAAkB,OAG/B;AACD,QAAM,EAAE,EAAE,IAAI,eAAe;AAC7B,QAAM,WAAW,YAAY;AAC7B,QAAM,OAAO,QAAQ;AACrB,QAAM,CAAC,QAAQ,SAAS,IAAI,MAAM,SAA0E,IAAI;AAEhH,MAAI,MAAM;AACR,WAAO,oBAAC,yBAAsB,MAAK,YAAW,UAAU,CAAC,CAAC,MAAM,UAAU;AAAA,EAC5E;AAEA,QAAM,aACJ,oBAAC,eAAY,OAAO,EAAE,oBAAoB,GAAG,UAAU,CAAC,CAAC,MAAM,UAC7D,8BAAC,OAAG,YAAE,oGAAoG,GAAE,GAC9G;AAGF,QAAM,aACJ,oBAAC,eAAY,OAAO,EAAE,oBAAoB,GAAG,UAAU,CAAC,CAAC,MAAM,UAC7D,8BAAC,OAAG,YAAE,sFAAsF,GAAE,GAChG;AAGF,QAAM,iBACJ,oBAAC,eAAY,OAAO,EAAE,yBAAyB,GAAG,UAAU,CAAC,CAAC,MAAM,UAClE,8BAAC,OAAG,YAAE,qIAAqI,GAAE,GAC/I;AAGF,MAAI,CAAC,MAAM,cAAc,MAAM;AAC7B,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,MAAC;AAAA;AAAA,QACN,OAAO,EAAE,yBAAyB;AAAA,QAClC,UAAU,CAAC,CAAC,MAAM;AAAA,QAClB,mBAAmB,EAAE,SAAS;AAAA,QAC9B,eAAe,YAAY;AACzB,gBAAMA,UAAS,MAAM,SAAS,oBAAoB,MAAM,cAAc,QAAQ,SAAS,wBAAwB,CAAC;AAChH,oBAAUA,OAAM;AAAA,QAClB;AAAA,QACA,qBAAqB,EAAE,QAAQ;AAAA,QAC/B,iBAAiB,YAAY;AAC3B,gBAAM,SAAS,eAAe;AAAA,QAChC;AAAA;AAAA,IACF;AAAA,EACF,OAAO;AACL,QAAI,OAAO,WAAW,SAAS;AAC7B,UAAI,YAAY,yBAAyB,WAAW,OAAO,KAAK,GAAG;AACjE,eAAO;AAAA,MACT,WAAW,YAAY,wBAAwB,WAAW,OAAO,KAAK,GAAG;AACvE,eAAO;AAAA,MACT,WAAW,YAAY,4BAA4B,WAAW,OAAO,KAAK,GAAG;AAC3E,eAAO;AAAA,MACT,OAAO;AACL,cAAM,OAAO;AAAA,MACf;AAAA,IACF;AAEA,WAAO;AAAA,MAAC;AAAA;AAAA,QACN,OAAO,EAAE,yBAAyB;AAAA,QAClC,UAAU,CAAC,CAAC,MAAM;AAAA,QAClB,mBAAmB,EAAE,SAAS;AAAA,QAC9B,eAAe,YAAY;AACzB,gBAAM,SAAS,eAAe;AAAA,QAChC;AAAA;AAAA,IACF;AAAA,EACF;AACF;","names":["result"]}
1
+ {"version":3,"sources":["../../../src/components-page/magic-link-callback.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 { cacheFunction } from \"@stackframe/stack-shared/dist/utils/caches\";\nimport { throwErr } from \"@stackframe/stack-shared/dist/utils/errors\";\nimport React from \"react\";\nimport { StackClientApp, useStackApp, useUser } from \"..\";\nimport { MessageCard } from \"../components/message-cards/message-card\";\nimport { PredefinedMessageCard } from \"../components/message-cards/predefined-message-card\";\nimport { useTranslation } from \"../lib/translations\";\n\nconst cacheSignInWithMagicLink = cacheFunction(async (stackApp: StackClientApp<true>, code: string) => {\n return await stackApp.signInWithMagicLink(code);\n});\n\nexport function MagicLinkCallback(props: {\n searchParams?: Record<string, string>,\n fullPage?: boolean,\n}) {\n const { t } = useTranslation();\n const stackApp = useStackApp();\n const user = useUser();\n const [result, setResult] = React.useState<Awaited<ReturnType<typeof stackApp.signInWithMagicLink>> | null>(null);\n\n if (user) {\n return <PredefinedMessageCard type='signedIn' fullPage={!!props.fullPage} />;\n }\n\n const invalidJsx = (\n <MessageCard title={t(\"Invalid Magic Link\")} fullPage={!!props.fullPage}>\n <p>{t(\"Please check if you have the correct link. If you continue to have issues, please contact support.\")}</p>\n </MessageCard>\n );\n\n const expiredJsx = (\n <MessageCard title={t(\"Expired Magic Link\")} fullPage={!!props.fullPage}>\n <p>{t(\"Your magic link has expired. Please request a new magic link if you need to sign-in.\")}</p>\n </MessageCard>\n );\n\n const alreadyUsedJsx = (\n <MessageCard title={t(\"Magic Link Already Used\")} fullPage={!!props.fullPage}>\n <p>{t(\"The magic link has already been used. The link can only be used once. Please request a new magic link if you need to sign-in again.\")}</p>\n </MessageCard>\n );\n\n if (!props.searchParams?.code) {\n return invalidJsx;\n }\n\n if (!result) {\n return <MessageCard\n title={t(\"Do you want to sign in?\")}\n fullPage={!!props.fullPage}\n primaryButtonText={t(\"Sign in\")}\n primaryAction={async () => {\n const result = await stackApp.signInWithMagicLink(props.searchParams?.code || throwErr(\"No magic link provided\"));\n setResult(result);\n }}\n secondaryButtonText={t(\"Cancel\")}\n secondaryAction={async () => {\n await stackApp.redirectToHome();\n }}\n />;\n } else {\n if (result.status === 'error') {\n if (KnownErrors.VerificationCodeNotFound.isInstance(result.error)) {\n return invalidJsx;\n } else if (KnownErrors.VerificationCodeExpired.isInstance(result.error)) {\n return expiredJsx;\n } else if (KnownErrors.VerificationCodeAlreadyUsed.isInstance(result.error)) {\n return alreadyUsedJsx;\n } else {\n throw result.error;\n }\n }\n\n return <MessageCard\n title={t(\"Signed in successfully!\")}\n fullPage={!!props.fullPage}\n primaryButtonText={t(\"Go home\")}\n primaryAction={async () => {\n await stackApp.redirectToHome();\n }}\n />;\n }\n}\n"],"mappings":";;;AAOA,SAAS,mBAAmB;AAC5B,SAAS,qBAAqB;AAC9B,SAAS,gBAAgB;AACzB,OAAO,WAAW;AAClB,SAAyB,aAAa,eAAe;AACrD,SAAS,mBAAmB;AAC5B,SAAS,6BAA6B;AACtC,SAAS,sBAAsB;AAgBpB;AAdX,IAAM,2BAA2B,cAAc,OAAO,UAAgC,SAAiB;AACrG,SAAO,MAAM,SAAS,oBAAoB,IAAI;AAChD,CAAC;AAEM,SAAS,kBAAkB,OAG/B;AACD,QAAM,EAAE,EAAE,IAAI,eAAe;AAC7B,QAAM,WAAW,YAAY;AAC7B,QAAM,OAAO,QAAQ;AACrB,QAAM,CAAC,QAAQ,SAAS,IAAI,MAAM,SAA0E,IAAI;AAEhH,MAAI,MAAM;AACR,WAAO,oBAAC,yBAAsB,MAAK,YAAW,UAAU,CAAC,CAAC,MAAM,UAAU;AAAA,EAC5E;AAEA,QAAM,aACJ,oBAAC,eAAY,OAAO,EAAE,oBAAoB,GAAG,UAAU,CAAC,CAAC,MAAM,UAC7D,8BAAC,OAAG,YAAE,oGAAoG,GAAE,GAC9G;AAGF,QAAM,aACJ,oBAAC,eAAY,OAAO,EAAE,oBAAoB,GAAG,UAAU,CAAC,CAAC,MAAM,UAC7D,8BAAC,OAAG,YAAE,sFAAsF,GAAE,GAChG;AAGF,QAAM,iBACJ,oBAAC,eAAY,OAAO,EAAE,yBAAyB,GAAG,UAAU,CAAC,CAAC,MAAM,UAClE,8BAAC,OAAG,YAAE,qIAAqI,GAAE,GAC/I;AAGF,MAAI,CAAC,MAAM,cAAc,MAAM;AAC7B,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,MAAC;AAAA;AAAA,QACN,OAAO,EAAE,yBAAyB;AAAA,QAClC,UAAU,CAAC,CAAC,MAAM;AAAA,QAClB,mBAAmB,EAAE,SAAS;AAAA,QAC9B,eAAe,YAAY;AACzB,gBAAMA,UAAS,MAAM,SAAS,oBAAoB,MAAM,cAAc,QAAQ,SAAS,wBAAwB,CAAC;AAChH,oBAAUA,OAAM;AAAA,QAClB;AAAA,QACA,qBAAqB,EAAE,QAAQ;AAAA,QAC/B,iBAAiB,YAAY;AAC3B,gBAAM,SAAS,eAAe;AAAA,QAChC;AAAA;AAAA,IACF;AAAA,EACF,OAAO;AACL,QAAI,OAAO,WAAW,SAAS;AAC7B,UAAI,YAAY,yBAAyB,WAAW,OAAO,KAAK,GAAG;AACjE,eAAO;AAAA,MACT,WAAW,YAAY,wBAAwB,WAAW,OAAO,KAAK,GAAG;AACvE,eAAO;AAAA,MACT,WAAW,YAAY,4BAA4B,WAAW,OAAO,KAAK,GAAG;AAC3E,eAAO;AAAA,MACT,OAAO;AACL,cAAM,OAAO;AAAA,MACf;AAAA,IACF;AAEA,WAAO;AAAA,MAAC;AAAA;AAAA,QACN,OAAO,EAAE,yBAAyB;AAAA,QAClC,UAAU,CAAC,CAAC,MAAM;AAAA,QAClB,mBAAmB,EAAE,SAAS;AAAA,QAC9B,eAAe,YAAY;AACzB,gBAAM,SAAS,eAAe;AAAA,QAChC;AAAA;AAAA,IACF;AAAA,EACF;AACF;","names":["result"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components-page/mfa.tsx"],"sourcesContent":["\"use client\";\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\n\nimport { KnownErrors } from \"@stackframe/stack-shared\";\nimport {\n Button,\n InputOTP,\n InputOTPGroup,\n InputOTPSlot,\n Spinner,\n Typography,\n cn,\n} from \"@stackframe/stack-ui\";\nimport { CheckIcon } from \"lucide-react\";\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport { useStackApp } from \"..\";\nimport { FormWarningText } from \"../components/elements/form-warning\";\nimport { MaybeFullPage } from \"../components/elements/maybe-full-page\";\nimport { useTranslation } from \"../lib/translations\";\n\nfunction MfaForm({ onSuccess, onCancel }: {\n onSuccess?: () => void,\n onCancel?: () => void,\n}) {\n const stackApp = useStackApp();\n const { t } = useTranslation();\n const [otp, setOtp] = useState<string>(\"\");\n const formRef = useRef<HTMLFormElement>(null);\n\n const [submitting, setSubmitting] = useState<boolean>(false);\n const [error, setError] = useState<string | null>(null);\n const [verified, setVerified] = useState<boolean>(false);\n\n const [attemptCode, setAttemptCode] = useState<string | null>(null);\n\n useEffect(() => {\n if (!attemptCode && typeof window !== \"undefined\") {\n const code = window.sessionStorage.getItem(\"stack_mfa_attempt_code\");\n if (code) {\n setAttemptCode(code);\n }\n }\n }, [ attemptCode]);\n\n // Handle OTP verification when code is complete\n useEffect(() => {\n if (otp.length === 6 && !submitting) {\n // Blur any focused inputs\n if (document.activeElement instanceof HTMLElement) {\n document.activeElement.blur();\n }\n if (formRef.current) {\n const inputs = formRef.current.querySelectorAll('input');\n for (const input of inputs) {\n input.blur();\n }\n }\n\n setSubmitting(true);\n setError(null);\n\n if (attemptCode) {\n stackApp\n .signInWithMfa(otp, attemptCode, { noRedirect: true })\n .then(async (result) => {\n if (result.status === \"ok\") {\n setVerified(true);\n\n // Cleanup session storage\n if (typeof window !== \"undefined\") {\n window.sessionStorage.removeItem(\"stack_mfa_attempt_code\");\n }\n\n if (onSuccess) {\n onSuccess();\n } else {\n await stackApp.redirectToAfterSignIn();\n }\n } else {\n throw result.error;\n }\n })\n .catch((e) => {\n if (e instanceof KnownErrors.InvalidTotpCode) {\n setError(t(\"Invalid TOTP code\"));\n } else {\n setError(t(\"Verification failed\"));\n }\n })\n .finally(() => {\n setSubmitting(false);\n if (!verified) {\n setOtp(\"\");\n }\n });\n } else {\n setSubmitting(false);\n setError(t(\"Missing verification information\"));\n }\n }\n\n // Clear error when user is typing\n if (otp.length !== 0 && otp.length !== 6) {\n setError(null);\n }\n }, [otp, submitting, onSuccess, attemptCode, stackApp, t, verified]);\n\n\n const inputStyleClass = useMemo(() => {\n if (verified) {\n return \"opacity-85 transition-all duration-300\";\n }\n\n if (error) {\n return \"ring-red-500 border-red-500\";\n }\n\n return \"focus:ring-primary/50\";\n }, [error, verified]);\n\n return (\n <div className=\"flex flex-col items-stretch stack-scope\">\n <form ref={formRef} className=\"w-full flex flex-col items-center gap-4\">\n <InputOTP\n maxLength={6}\n type=\"text\"\n inputMode=\"numeric\"\n placeholder=\"······\"\n value={otp}\n onChange={(value) => setOtp(value.toUpperCase())}\n disabled={submitting || verified}\n >\n <InputOTPGroup>\n {[0, 1, 2, 3, 4, 5].map((index) => (\n <InputOTPSlot\n key={index}\n index={index}\n size=\"lg\"\n className={cn(\n \"border focus:ring-2 transition-all\",\n inputStyleClass,\n )}\n />\n ))}\n </InputOTPGroup>\n </InputOTP>\n\n {/* Verification Status */}\n <div className=\"h-8 flex flex-col gap-4 items-center justify-center w-full\">\n {verified ? (\n <div className=\"flex items-center gap-2 animate-in fade-in duration-300 slide-in-from-bottom-2\">\n <CheckIcon className=\"w-5 h-5 text-green-600 animate-in zoom-in duration-300\" />\n <Typography className=\"text-sm font-medium\">{t(\"Verified! Redirecting...\")}</Typography>\n </div>\n ) : submitting ? (\n <div className=\"flex items-center gap-2\">\n <Spinner className=\"text-primary h-4 w-4\" />\n <Typography className=\"text-sm\">{t(\"Verifying...\")}</Typography>\n </div>\n ) : null}\n\n {/* Error reporting */}\n {error !== null && !submitting && !verified ? <FormWarningText text={error} /> : null}\n </div>\n </form>\n\n {/* Cancel Button */}\n {onCancel && !verified && (\n <Button\n variant=\"link\"\n onClick={onCancel}\n className=\"underline mt-4 self-center\"\n disabled={submitting || verified}\n >\n {t(\"Cancel\")}\n </Button>\n )}\n </div>\n );\n}\n\nexport function MFA(props: {\n fullPage?: boolean,\n onSuccess?: () => void,\n onCancel?: () => void,\n}) {\n const { t } = useTranslation();\n\n const headerText = t(\"Multi-Factor Authentication\");\n const instructionText = t(\"Enter the six-digit code from your authenticator app\");\n\n if (props.fullPage) {\n return (\n <MaybeFullPage fullPage={true}>\n <div\n className=\"stack-scope flex flex-col items-stretch\"\n style={{ maxWidth: \"380px\", flexBasis: \"380px\", padding: \"1rem\" }}\n >\n <div className=\"text-center mb-6\">\n <Typography type=\"h2\">{headerText}</Typography>\n <Typography className=\"mt-2\">{instructionText}</Typography>\n </div>\n <MfaForm onSuccess={props.onSuccess} onCancel={props.onCancel} />\n </div>\n </MaybeFullPage>\n );\n }\n\n return (\n <div className=\"flex flex-col items-stretch stack-scope\">\n <Typography className=\"mb-4 text-center\">{instructionText}</Typography>\n <MfaForm onSuccess={props.onSuccess} onCancel={props.onCancel} />\n </div>\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/components-page/mfa.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 {\n Button,\n InputOTP,\n InputOTPGroup,\n InputOTPSlot,\n Spinner,\n Typography,\n cn,\n} from \"@stackframe/stack-ui\";\nimport { CheckIcon } from \"lucide-react\";\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport { useStackApp } from \"..\";\nimport { FormWarningText } from \"../components/elements/form-warning\";\nimport { MaybeFullPage } from \"../components/elements/maybe-full-page\";\nimport { useTranslation } from \"../lib/translations\";\n\nfunction MfaForm({ onSuccess, onCancel }: {\n onSuccess?: () => void,\n onCancel?: () => void,\n}) {\n const stackApp = useStackApp();\n const { t } = useTranslation();\n const [otp, setOtp] = useState<string>(\"\");\n const formRef = useRef<HTMLFormElement>(null);\n\n const [submitting, setSubmitting] = useState<boolean>(false);\n const [error, setError] = useState<string | null>(null);\n const [verified, setVerified] = useState<boolean>(false);\n\n const [attemptCode, setAttemptCode] = useState<string | null>(null);\n\n useEffect(() => {\n if (!attemptCode && typeof window !== \"undefined\") {\n const code = window.sessionStorage.getItem(\"stack_mfa_attempt_code\");\n if (code) {\n setAttemptCode(code);\n }\n }\n }, [ attemptCode]);\n\n // Handle OTP verification when code is complete\n useEffect(() => {\n if (otp.length === 6 && !submitting) {\n // Blur any focused inputs\n if (document.activeElement instanceof HTMLElement) {\n document.activeElement.blur();\n }\n if (formRef.current) {\n const inputs = formRef.current.querySelectorAll('input');\n for (const input of inputs) {\n input.blur();\n }\n }\n\n setSubmitting(true);\n setError(null);\n\n if (attemptCode) {\n stackApp\n .signInWithMfa(otp, attemptCode, { noRedirect: true })\n .then(async (result) => {\n if (result.status === \"ok\") {\n setVerified(true);\n\n // Cleanup session storage\n if (typeof window !== \"undefined\") {\n window.sessionStorage.removeItem(\"stack_mfa_attempt_code\");\n }\n\n if (onSuccess) {\n onSuccess();\n } else {\n await stackApp.redirectToAfterSignIn();\n }\n } else {\n throw result.error;\n }\n })\n .catch((e) => {\n if (e instanceof KnownErrors.InvalidTotpCode) {\n setError(t(\"Invalid TOTP code\"));\n } else {\n setError(t(\"Verification failed\"));\n }\n })\n .finally(() => {\n setSubmitting(false);\n if (!verified) {\n setOtp(\"\");\n }\n });\n } else {\n setSubmitting(false);\n setError(t(\"Missing verification information\"));\n }\n }\n\n // Clear error when user is typing\n if (otp.length !== 0 && otp.length !== 6) {\n setError(null);\n }\n }, [otp, submitting, onSuccess, attemptCode, stackApp, t, verified]);\n\n\n const inputStyleClass = useMemo(() => {\n if (verified) {\n return \"opacity-85 transition-all duration-300\";\n }\n\n if (error) {\n return \"ring-red-500 border-red-500\";\n }\n\n return \"focus:ring-primary/50\";\n }, [error, verified]);\n\n return (\n <div className=\"flex flex-col items-stretch stack-scope\">\n <form ref={formRef} className=\"w-full flex flex-col items-center gap-4\">\n <InputOTP\n maxLength={6}\n type=\"text\"\n inputMode=\"numeric\"\n placeholder=\"······\"\n value={otp}\n onChange={(value) => setOtp(value.toUpperCase())}\n disabled={submitting || verified}\n >\n <InputOTPGroup>\n {[0, 1, 2, 3, 4, 5].map((index) => (\n <InputOTPSlot\n key={index}\n index={index}\n size=\"lg\"\n className={cn(\n \"border focus:ring-2 transition-all\",\n inputStyleClass,\n )}\n />\n ))}\n </InputOTPGroup>\n </InputOTP>\n\n {/* Verification Status */}\n <div className=\"h-8 flex flex-col gap-4 items-center justify-center w-full\">\n {verified ? (\n <div className=\"flex items-center gap-2 animate-in fade-in duration-300 slide-in-from-bottom-2\">\n <CheckIcon className=\"w-5 h-5 text-green-600 animate-in zoom-in duration-300\" />\n <Typography className=\"text-sm font-medium\">{t(\"Verified! Redirecting...\")}</Typography>\n </div>\n ) : submitting ? (\n <div className=\"flex items-center gap-2\">\n <Spinner className=\"text-primary h-4 w-4\" />\n <Typography className=\"text-sm\">{t(\"Verifying...\")}</Typography>\n </div>\n ) : null}\n\n {/* Error reporting */}\n {error !== null && !submitting && !verified ? <FormWarningText text={error} /> : null}\n </div>\n </form>\n\n {/* Cancel Button */}\n {onCancel && !verified && (\n <Button\n variant=\"link\"\n onClick={onCancel}\n className=\"underline mt-4 self-center\"\n disabled={submitting || verified}\n >\n {t(\"Cancel\")}\n </Button>\n )}\n </div>\n );\n}\n\nexport function MFA(props: {\n fullPage?: boolean,\n onSuccess?: () => void,\n onCancel?: () => void,\n}) {\n const { t } = useTranslation();\n\n const headerText = t(\"Multi-Factor Authentication\");\n const instructionText = t(\"Enter the six-digit code from your authenticator app\");\n\n if (props.fullPage) {\n return (\n <MaybeFullPage fullPage={true}>\n <div\n className=\"stack-scope flex flex-col items-stretch\"\n style={{ maxWidth: \"380px\", flexBasis: \"380px\", padding: \"1rem\" }}\n >\n <div className=\"text-center mb-6\">\n <Typography type=\"h2\">{headerText}</Typography>\n <Typography className=\"mt-2\">{instructionText}</Typography>\n </div>\n <MfaForm onSuccess={props.onSuccess} onCancel={props.onCancel} />\n </div>\n </MaybeFullPage>\n );\n }\n\n return (\n <div className=\"flex flex-col items-stretch stack-scope\">\n <Typography className=\"mb-4 text-center\">{instructionText}</Typography>\n <MfaForm onSuccess={props.onSuccess} onCancel={props.onCancel} />\n </div>\n );\n}\n"],"mappings":";;;AAOA,SAAS,mBAAmB;AAC5B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,iBAAiB;AAC1B,SAAS,WAAW,SAAS,QAAQ,gBAAgB;AACrD,SAAS,mBAAmB;AAC5B,SAAS,uBAAuB;AAChC,SAAS,qBAAqB;AAC9B,SAAS,sBAAsB;AAoHjB,cAgBF,YAhBE;AAlHd,SAAS,QAAQ,EAAE,WAAW,SAAS,GAGpC;AACD,QAAM,WAAW,YAAY;AAC7B,QAAM,EAAE,EAAE,IAAI,eAAe;AAC7B,QAAM,CAAC,KAAK,MAAM,IAAI,SAAiB,EAAE;AACzC,QAAM,UAAU,OAAwB,IAAI;AAE5C,QAAM,CAAC,YAAY,aAAa,IAAI,SAAkB,KAAK;AAC3D,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAwB,IAAI;AACtD,QAAM,CAAC,UAAU,WAAW,IAAI,SAAkB,KAAK;AAEvD,QAAM,CAAC,aAAa,cAAc,IAAI,SAAwB,IAAI;AAElE,YAAU,MAAM;AACd,QAAI,CAAC,eAAe,OAAO,WAAW,aAAa;AACjD,YAAM,OAAO,OAAO,eAAe,QAAQ,wBAAwB;AACnE,UAAI,MAAM;AACR,uBAAe,IAAI;AAAA,MACrB;AAAA,IACF;AAAA,EACF,GAAG,CAAE,WAAW,CAAC;AAGjB,YAAU,MAAM;AACd,QAAI,IAAI,WAAW,KAAK,CAAC,YAAY;AAEnC,UAAI,SAAS,yBAAyB,aAAa;AACjD,iBAAS,cAAc,KAAK;AAAA,MAC9B;AACA,UAAI,QAAQ,SAAS;AACnB,cAAM,SAAS,QAAQ,QAAQ,iBAAiB,OAAO;AACvD,mBAAW,SAAS,QAAQ;AAC1B,gBAAM,KAAK;AAAA,QACb;AAAA,MACF;AAEA,oBAAc,IAAI;AAClB,eAAS,IAAI;AAEb,UAAI,aAAa;AACf,iBACG,cAAc,KAAK,aAAa,EAAE,YAAY,KAAK,CAAC,EACpD,KAAK,OAAO,WAAW;AACtB,cAAI,OAAO,WAAW,MAAM;AAC1B,wBAAY,IAAI;AAGhB,gBAAI,OAAO,WAAW,aAAa;AACjC,qBAAO,eAAe,WAAW,wBAAwB;AAAA,YAC3D;AAEA,gBAAI,WAAW;AACb,wBAAU;AAAA,YACZ,OAAO;AACL,oBAAM,SAAS,sBAAsB;AAAA,YACvC;AAAA,UACF,OAAO;AACL,kBAAM,OAAO;AAAA,UACf;AAAA,QACF,CAAC,EACA,MAAM,CAAC,MAAM;AACZ,cAAI,aAAa,YAAY,iBAAiB;AAC5C,qBAAS,EAAE,mBAAmB,CAAC;AAAA,UACjC,OAAO;AACL,qBAAS,EAAE,qBAAqB,CAAC;AAAA,UACnC;AAAA,QACF,CAAC,EACA,QAAQ,MAAM;AACb,wBAAc,KAAK;AACnB,cAAI,CAAC,UAAU;AACb,mBAAO,EAAE;AAAA,UACX;AAAA,QACF,CAAC;AAAA,MACL,OAAO;AACL,sBAAc,KAAK;AACnB,iBAAS,EAAE,kCAAkC,CAAC;AAAA,MAChD;AAAA,IACF;AAGA,QAAI,IAAI,WAAW,KAAK,IAAI,WAAW,GAAG;AACxC,eAAS,IAAI;AAAA,IACf;AAAA,EACF,GAAG,CAAC,KAAK,YAAY,WAAW,aAAa,UAAU,GAAG,QAAQ,CAAC;AAGnE,QAAM,kBAAkB,QAAQ,MAAM;AACpC,QAAI,UAAU;AACZ,aAAO;AAAA,IACT;AAEA,QAAI,OAAO;AACT,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT,GAAG,CAAC,OAAO,QAAQ,CAAC;AAEpB,SACE,qBAAC,SAAI,WAAU,2CACb;AAAA,yBAAC,UAAK,KAAK,SAAS,WAAU,2CAC5B;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,WAAW;AAAA,UACX,MAAK;AAAA,UACL,WAAU;AAAA,UACV,aAAY;AAAA,UACZ,OAAO;AAAA,UACP,UAAU,CAAC,UAAU,OAAO,MAAM,YAAY,CAAC;AAAA,UAC/C,UAAU,cAAc;AAAA,UAExB,8BAAC,iBACE,WAAC,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,UACvB;AAAA,YAAC;AAAA;AAAA,cAEC;AAAA,cACA,MAAK;AAAA,cACL,WAAW;AAAA,gBACT;AAAA,gBACA;AAAA,cACF;AAAA;AAAA,YANK;AAAA,UAOP,CACD,GACH;AAAA;AAAA,MACF;AAAA,MAGA,qBAAC,SAAI,WAAU,8DACZ;AAAA,mBACC,qBAAC,SAAI,WAAU,kFACb;AAAA,8BAAC,aAAU,WAAU,0DAAyD;AAAA,UAC9E,oBAAC,cAAW,WAAU,uBAAuB,YAAE,0BAA0B,GAAE;AAAA,WAC7E,IACE,aACF,qBAAC,SAAI,WAAU,2BACb;AAAA,8BAAC,WAAQ,WAAU,wBAAuB;AAAA,UAC1C,oBAAC,cAAW,WAAU,WAAW,YAAE,cAAc,GAAE;AAAA,WACrD,IACE;AAAA,QAGH,UAAU,QAAQ,CAAC,cAAc,CAAC,WAAW,oBAAC,mBAAgB,MAAM,OAAO,IAAK;AAAA,SACnF;AAAA,OACF;AAAA,IAGC,YAAY,CAAC,YACZ;AAAA,MAAC;AAAA;AAAA,QACC,SAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAU;AAAA,QACV,UAAU,cAAc;AAAA,QAEvB,YAAE,QAAQ;AAAA;AAAA,IACb;AAAA,KAEJ;AAEJ;AAEO,SAAS,IAAI,OAIjB;AACD,QAAM,EAAE,EAAE,IAAI,eAAe;AAE7B,QAAM,aAAa,EAAE,6BAA6B;AAClD,QAAM,kBAAkB,EAAE,sDAAsD;AAEhF,MAAI,MAAM,UAAU;AAClB,WACE,oBAAC,iBAAc,UAAU,MACvB;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QACV,OAAO,EAAE,UAAU,SAAS,WAAW,SAAS,SAAS,OAAO;AAAA,QAEhE;AAAA,+BAAC,SAAI,WAAU,oBACb;AAAA,gCAAC,cAAW,MAAK,MAAM,sBAAW;AAAA,YAClC,oBAAC,cAAW,WAAU,QAAQ,2BAAgB;AAAA,aAChD;AAAA,UACA,oBAAC,WAAQ,WAAW,MAAM,WAAW,UAAU,MAAM,UAAU;AAAA;AAAA;AAAA,IACjE,GACF;AAAA,EAEJ;AAEA,SACE,qBAAC,SAAI,WAAU,2CACb;AAAA,wBAAC,cAAW,WAAU,oBAAoB,2BAAgB;AAAA,IAC1D,oBAAC,WAAQ,WAAW,MAAM,WAAW,UAAU,MAAM,UAAU;AAAA,KACjE;AAEJ;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components-page/oauth-callback.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\n\nimport { captureError } from \"@stackframe/stack-shared/dist/utils/errors\";\nimport { runAsynchronously } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { Spinner, cn } from \"@stackframe/stack-ui\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { useStackApp } from \"..\";\nimport { MaybeFullPage } from \"../components/elements/maybe-full-page\";\nimport { StyledLink } from \"../components/link\";\nimport { useTranslation } from \"../lib/translations\";\n\nexport function OAuthCallback({ fullPage }: { fullPage?: boolean }) {\n const { t } = useTranslation();\n const app = useStackApp();\n const called = useRef(false);\n const [error, setError] = useState<unknown>(null);\n const [showRedirectLink, setShowRedirectLink] = useState(false);\n\n useEffect(() => runAsynchronously(async () => {\n if (called.current) return;\n called.current = true;\n let hasRedirected = false;\n try {\n hasRedirected = await app.callOAuthCallback();\n } catch (e) {\n captureError(\"<OAuthCallback />\", e);\n setError(e);\n }\n if (!hasRedirected && (!error || process.env.NODE_ENV === 'production')) {\n await app.redirectToSignIn({ noRedirectBack: true });\n }\n }), []);\n\n useEffect(() => {\n setTimeout(() => setShowRedirectLink(true), 3000);\n }, []);\n\n return (\n <MaybeFullPage\n fullPage={fullPage ?? false}\n containerClassName=\"flex items-center justify-center\"\n >\n <div\n className={cn(\n \"text-center justify-center items-center stack-scope flex flex-col gap-4 max-w-[380px]\",\n fullPage ? \"p-4\" : \"p-0\"\n )}\n >\n <div className=\"flex flex-col justify-center items-center gap-4\">\n <Spinner size={20} />\n </div>\n {showRedirectLink ? <p>{t('If you are not redirected automatically, ')}<StyledLink className=\"whitespace-nowrap\" href={app.urls.home}>{t(\"click here\")}</StyledLink></p> : null}\n {error ? <div>\n <p>{t(\"Something went wrong while processing the OAuth callback:\")}</p>\n <pre>{JSON.stringify(error, null, 2)}</pre>\n <p>{t(\"This is most likely an error in Stack. Please report it.\")}</p>\n </div> : null}\n </div>\n </MaybeFullPage>\n );\n}\n"],"mappings":";;;AAOA,SAAS,oBAAoB;AAC7B,SAAS,yBAAyB;AAClC,SAAS,SAAS,UAAU;AAC5B,SAAS,WAAW,QAAQ,gBAAgB;AAC5C,SAAS,mBAAmB;AAC5B,SAAS,qBAAqB;AAC9B,SAAS,kBAAkB;AAC3B,SAAS,sBAAsB;AAwCrB,cAEkB,YAFlB;AAtCH,SAAS,cAAc,EAAE,SAAS,GAA2B;AAClE,QAAM,EAAE,EAAE,IAAI,eAAe;AAC7B,QAAM,MAAM,YAAY;AACxB,QAAM,SAAS,OAAO,KAAK;AAC3B,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAkB,IAAI;AAChD,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,SAAS,KAAK;AAE9D,YAAU,MAAM,kBAAkB,YAAY;AAC5C,QAAI,OAAO,QAAS;AACpB,WAAO,UAAU;AACjB,QAAI,gBAAgB;AACpB,QAAI;AACF,sBAAgB,MAAM,IAAI,kBAAkB;AAAA,IAC9C,SAAS,GAAG;AACV,mBAAa,qBAAqB,CAAC;AACnC,eAAS,CAAC;AAAA,IACZ;AACA,QAAI,CAAC,kBAAkB,CAAC,SAAS,QAAQ,IAAI,aAAa,eAAe;AACvE,YAAM,IAAI,iBAAiB,EAAE,gBAAgB,KAAK,CAAC;AAAA,IACrD;AAAA,EACF,CAAC,GAAG,CAAC,CAAC;AAEN,YAAU,MAAM;AACd,eAAW,MAAM,oBAAoB,IAAI,GAAG,GAAI;AAAA,EAClD,GAAG,CAAC,CAAC;AAEL,SACE;AAAA,IAAC;AAAA;AAAA,MACC,UAAU,YAAY;AAAA,MACtB,oBAAmB;AAAA,MAEnB;AAAA,QAAC;AAAA;AAAA,UACC,WAAW;AAAA,YACT;AAAA,YACA,WAAW,QAAQ;AAAA,UACrB;AAAA,UAEA;AAAA,gCAAC,SAAI,WAAU,mDACb,8BAAC,WAAQ,MAAM,IAAI,GACrB;AAAA,YACC,mBAAmB,qBAAC,OAAG;AAAA,gBAAE,2CAA2C;AAAA,cAAE,oBAAC,cAAW,WAAU,qBAAoB,MAAM,IAAI,KAAK,MAAO,YAAE,YAAY,GAAE;AAAA,eAAa,IAAO;AAAA,YAC1K,QAAQ,qBAAC,SACR;AAAA,kCAAC,OAAG,YAAE,2DAA2D,GAAE;AAAA,cACnE,oBAAC,SAAK,eAAK,UAAU,OAAO,MAAM,CAAC,GAAE;AAAA,cACrC,oBAAC,OAAG,YAAE,0DAA0D,GAAE;AAAA,eACpE,IAAS;AAAA;AAAA;AAAA,MACX;AAAA;AAAA,EACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/components-page/oauth-callback.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 { captureError } from \"@stackframe/stack-shared/dist/utils/errors\";\nimport { runAsynchronously } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { Spinner, cn } from \"@stackframe/stack-ui\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { useStackApp } from \"..\";\nimport { MaybeFullPage } from \"../components/elements/maybe-full-page\";\nimport { StyledLink } from \"../components/link\";\nimport { useTranslation } from \"../lib/translations\";\n\nexport function OAuthCallback({ fullPage }: { fullPage?: boolean }) {\n const { t } = useTranslation();\n const app = useStackApp();\n const called = useRef(false);\n const [error, setError] = useState<unknown>(null);\n const [showRedirectLink, setShowRedirectLink] = useState(false);\n\n useEffect(() => runAsynchronously(async () => {\n if (called.current) return;\n called.current = true;\n let hasRedirected = false;\n try {\n hasRedirected = await app.callOAuthCallback();\n } catch (e) {\n captureError(\"<OAuthCallback />\", e);\n setError(e);\n }\n if (!hasRedirected && (!error || process.env.NODE_ENV === 'production')) {\n await app.redirectToSignIn({ noRedirectBack: true });\n }\n }), []);\n\n useEffect(() => {\n setTimeout(() => setShowRedirectLink(true), 3000);\n }, []);\n\n return (\n <MaybeFullPage\n fullPage={fullPage ?? false}\n containerClassName=\"flex items-center justify-center\"\n >\n <div\n className={cn(\n \"text-center justify-center items-center stack-scope flex flex-col gap-4 max-w-[380px]\",\n fullPage ? \"p-4\" : \"p-0\"\n )}\n >\n <div className=\"flex flex-col justify-center items-center gap-4\">\n <Spinner size={20} />\n </div>\n {showRedirectLink ? <p>{t('If you are not redirected automatically, ')}<StyledLink className=\"whitespace-nowrap\" href={app.urls.home}>{t(\"click here\")}</StyledLink></p> : null}\n {error ? <div>\n <p>{t(\"Something went wrong while processing the OAuth callback:\")}</p>\n <pre>{JSON.stringify(error, null, 2)}</pre>\n <p>{t(\"This is most likely an error in Stack. Please report it.\")}</p>\n </div> : null}\n </div>\n </MaybeFullPage>\n );\n}\n"],"mappings":";;;AAOA,SAAS,oBAAoB;AAC7B,SAAS,yBAAyB;AAClC,SAAS,SAAS,UAAU;AAC5B,SAAS,WAAW,QAAQ,gBAAgB;AAC5C,SAAS,mBAAmB;AAC5B,SAAS,qBAAqB;AAC9B,SAAS,kBAAkB;AAC3B,SAAS,sBAAsB;AAwCrB,cAEkB,YAFlB;AAtCH,SAAS,cAAc,EAAE,SAAS,GAA2B;AAClE,QAAM,EAAE,EAAE,IAAI,eAAe;AAC7B,QAAM,MAAM,YAAY;AACxB,QAAM,SAAS,OAAO,KAAK;AAC3B,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAkB,IAAI;AAChD,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,SAAS,KAAK;AAE9D,YAAU,MAAM,kBAAkB,YAAY;AAC5C,QAAI,OAAO,QAAS;AACpB,WAAO,UAAU;AACjB,QAAI,gBAAgB;AACpB,QAAI;AACF,sBAAgB,MAAM,IAAI,kBAAkB;AAAA,IAC9C,SAAS,GAAG;AACV,mBAAa,qBAAqB,CAAC;AACnC,eAAS,CAAC;AAAA,IACZ;AACA,QAAI,CAAC,kBAAkB,CAAC,SAAS,QAAQ,IAAI,aAAa,eAAe;AACvE,YAAM,IAAI,iBAAiB,EAAE,gBAAgB,KAAK,CAAC;AAAA,IACrD;AAAA,EACF,CAAC,GAAG,CAAC,CAAC;AAEN,YAAU,MAAM;AACd,eAAW,MAAM,oBAAoB,IAAI,GAAG,GAAI;AAAA,EAClD,GAAG,CAAC,CAAC;AAEL,SACE;AAAA,IAAC;AAAA;AAAA,MACC,UAAU,YAAY;AAAA,MACtB,oBAAmB;AAAA,MAEnB;AAAA,QAAC;AAAA;AAAA,UACC,WAAW;AAAA,YACT;AAAA,YACA,WAAW,QAAQ;AAAA,UACrB;AAAA,UAEA;AAAA,gCAAC,SAAI,WAAU,mDACb,8BAAC,WAAQ,MAAM,IAAI,GACrB;AAAA,YACC,mBAAmB,qBAAC,OAAG;AAAA,gBAAE,2CAA2C;AAAA,cAAE,oBAAC,cAAW,WAAU,qBAAoB,MAAM,IAAI,KAAK,MAAO,YAAE,YAAY,GAAE;AAAA,eAAa,IAAO;AAAA,YAC1K,QAAQ,qBAAC,SACR;AAAA,kCAAC,OAAG,YAAE,2DAA2D,GAAE;AAAA,cACnE,oBAAC,SAAK,eAAK,UAAU,OAAO,MAAM,CAAC,GAAE;AAAA,cACrC,oBAAC,OAAG,YAAE,0DAA0D,GAAE;AAAA,eACpE,IAAS;AAAA;AAAA;AAAA,MACX;AAAA;AAAA,EACF;AAEJ;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components-page/onboarding.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\n\nimport { yupResolver } from \"@hookform/resolvers/yup\";\nimport { strictEmailSchema, yupObject } from \"@stackframe/stack-shared/dist/schema-fields\";\nimport { runAsynchronously, runAsynchronouslyWithAlert } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { Button, Input, Typography } from \"@stackframe/stack-ui\";\nimport { useState } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport * as yup from \"yup\";\nimport { useStackApp, useUser } from \"..\";\nimport { FormWarningText } from \"../components/elements/form-warning\";\nimport { MessageCard } from \"../components/message-cards/message-card\";\nimport { useTranslation } from \"../lib/translations\";\n\nexport function Onboarding(props: {\n fullPage?: boolean,\n}) {\n const { t } = useTranslation();\n const stackApp = useStackApp();\n const user = useUser({ or: \"return-null\", includeRestricted: true });\n\n // If user is not restricted anymore, redirect to the intended destination\n // redirectToAfterSignIn automatically checks for after_auth_return_to in the URL\n if (user && !user.isRestricted) {\n runAsynchronously(stackApp.redirectToAfterSignIn());\n // TODO: This should return a loading indicator, not just null\n return null;\n }\n\n // If user is anonymous or not logged in, redirect to sign-in\n if (!user || user.isAnonymous) {\n runAsynchronously(stackApp.redirectToSignIn());\n // TODO: This should return a loading indicator, not just null\n return null;\n }\n\n // User is restricted - show appropriate onboarding step based on restricted reason\n const restrictedReason = user.restrictedReason;\n\n if (restrictedReason?.type === \"email_not_verified\") {\n // Check if user has a primary email\n const hasPrimaryEmail = !!user.primaryEmail;\n\n if (!hasPrimaryEmail) {\n // User needs to add an email first\n return <AddEmailForm fullPage={props.fullPage} />;\n }\n\n // User has email but it's not verified\n return <VerifyEmailScreen user={user} email={user.primaryEmail} fullPage={props.fullPage} />;\n }\n\n // Unknown restricted reason - show generic message\n return (\n <MessageCard\n title={t(\"Complete your account setup\")}\n fullPage={!!props.fullPage}\n secondaryButtonText={t(\"Sign out\")}\n secondaryAction={async () => {\n await user.signOut();\n }}\n >\n <p>{t(\"Please complete your account setup to continue.\")}</p>\n </MessageCard>\n );\n}\n\nfunction AddEmailForm(props: {\n fullPage?: boolean,\n onEmailAdded?: () => void,\n}) {\n const { t } = useTranslation();\n const user = useUser({ or: \"throw\", includeRestricted: true });\n const stackApp = useStackApp();\n const [loading, setLoading] = useState(false);\n\n const emailSchema = yupObject({\n email: strictEmailSchema(t('Please enter a valid email address'))\n .defined()\n .nonEmpty(t('Email is required')),\n });\n\n const { register, handleSubmit, formState: { errors } } = useForm({\n resolver: yupResolver(emailSchema)\n });\n\n const onSubmit = async (data: yup.InferType<typeof emailSchema>) => {\n setLoading(true);\n try {\n await user.update({ primaryEmail: data.email });\n props.onEmailAdded?.();\n } finally {\n setLoading(false);\n }\n };\n\n return (\n <MessageCard\n title={t(\"Add your email address\")}\n fullPage={!!props.fullPage}\n secondaryButtonText={t(\"Sign out\")}\n secondaryAction={async () => {\n await user.signOut();\n }}\n >\n <Typography className=\"mb-4\">\n {t(\"Please add an email address to complete your account setup. We'll send you a verification email.\")}\n </Typography>\n <form\n onSubmit={e => runAsynchronouslyWithAlert(handleSubmit(onSubmit)(e))}\n noValidate\n className='flex flex-col gap-2'\n >\n <Input\n {...register(\"email\")}\n placeholder={t(\"Enter your email\")}\n type=\"email\"\n />\n {errors.email && <FormWarningText text={errors.email.message} />}\n <Button type=\"submit\" loading={loading} className=\"w-full\">\n {t(\"Continue\")}\n </Button>\n </form>\n </MessageCard>\n );\n}\n\nfunction VerifyEmailScreen(props: {\n user: NonNullable<ReturnType<typeof useUser>>,\n email: string,\n fullPage?: boolean,\n}) {\n const { t } = useTranslation();\n const { user, email } = props;\n const [changingEmail, setChangingEmail] = useState(false);\n\n if (changingEmail) {\n return <AddEmailForm fullPage={props.fullPage} onEmailAdded={() => setChangingEmail(false)} />;\n }\n\n return (\n <MessageCard\n title={t(\"Please check your email inbox\")}\n fullPage={!!props.fullPage}\n primaryButtonText={t(\"Resend verification email\")}\n primaryAction={async () => {\n await user.sendVerificationEmail();\n }}\n secondaryButtonText={t(\"Sign out\")}\n secondaryAction={async () => {\n await user.signOut();\n }}\n >\n <Typography>\n {t(\"Please verify your email address \")}\n <span className=\"font-semibold\">{email}</span>\n {\" (\"}\n <button\n type=\"button\"\n className=\"text-primary hover:underline\"\n onClick={() => setChangingEmail(true)}\n >\n {t(\"change\")}\n </button>\n {\"). \"}\n {t(\"Click the button below to resend the verification link.\")}\n </Typography>\n </MessageCard>\n );\n}\n\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/components-page/onboarding.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 { yupResolver } from \"@hookform/resolvers/yup\";\nimport { strictEmailSchema, yupObject } from \"@stackframe/stack-shared/dist/schema-fields\";\nimport { runAsynchronously, runAsynchronouslyWithAlert } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { Button, Input, Typography } from \"@stackframe/stack-ui\";\nimport { useState } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport * as yup from \"yup\";\nimport { useStackApp, useUser } from \"..\";\nimport { FormWarningText } from \"../components/elements/form-warning\";\nimport { MessageCard } from \"../components/message-cards/message-card\";\nimport { useTranslation } from \"../lib/translations\";\n\nexport function Onboarding(props: {\n fullPage?: boolean,\n}) {\n const { t } = useTranslation();\n const stackApp = useStackApp();\n const user = useUser({ or: \"return-null\", includeRestricted: true });\n\n // If user is not restricted anymore, redirect to the intended destination\n // redirectToAfterSignIn automatically checks for after_auth_return_to in the URL\n if (user && !user.isRestricted) {\n runAsynchronously(stackApp.redirectToAfterSignIn());\n // TODO: This should return a loading indicator, not just null\n return null;\n }\n\n // If user is anonymous or not logged in, redirect to sign-in\n if (!user || user.isAnonymous) {\n runAsynchronously(stackApp.redirectToSignIn());\n // TODO: This should return a loading indicator, not just null\n return null;\n }\n\n // User is restricted - show appropriate onboarding step based on restricted reason\n const restrictedReason = user.restrictedReason;\n\n if (restrictedReason?.type === \"email_not_verified\") {\n // Check if user has a primary email\n const hasPrimaryEmail = !!user.primaryEmail;\n\n if (!hasPrimaryEmail) {\n // User needs to add an email first\n return <AddEmailForm fullPage={props.fullPage} />;\n }\n\n // User has email but it's not verified\n return <VerifyEmailScreen user={user} email={user.primaryEmail} fullPage={props.fullPage} />;\n }\n\n // Unknown restricted reason - show generic message\n return (\n <MessageCard\n title={t(\"Complete your account setup\")}\n fullPage={!!props.fullPage}\n secondaryButtonText={t(\"Sign out\")}\n secondaryAction={async () => {\n await user.signOut();\n }}\n >\n <p>{t(\"Please complete your account setup to continue.\")}</p>\n </MessageCard>\n );\n}\n\nfunction AddEmailForm(props: {\n fullPage?: boolean,\n onEmailAdded?: () => void,\n}) {\n const { t } = useTranslation();\n const user = useUser({ or: \"throw\", includeRestricted: true });\n const stackApp = useStackApp();\n const [loading, setLoading] = useState(false);\n\n const emailSchema = yupObject({\n email: strictEmailSchema(t('Please enter a valid email address'))\n .defined()\n .nonEmpty(t('Email is required')),\n });\n\n const { register, handleSubmit, formState: { errors } } = useForm({\n resolver: yupResolver(emailSchema)\n });\n\n const onSubmit = async (data: yup.InferType<typeof emailSchema>) => {\n setLoading(true);\n try {\n await user.update({ primaryEmail: data.email });\n props.onEmailAdded?.();\n } finally {\n setLoading(false);\n }\n };\n\n return (\n <MessageCard\n title={t(\"Add your email address\")}\n fullPage={!!props.fullPage}\n secondaryButtonText={t(\"Sign out\")}\n secondaryAction={async () => {\n await user.signOut();\n }}\n >\n <Typography className=\"mb-4\">\n {t(\"Please add an email address to complete your account setup. We'll send you a verification email.\")}\n </Typography>\n <form\n onSubmit={e => runAsynchronouslyWithAlert(handleSubmit(onSubmit)(e))}\n noValidate\n className='flex flex-col gap-2'\n >\n <Input\n {...register(\"email\")}\n placeholder={t(\"Enter your email\")}\n type=\"email\"\n />\n {errors.email && <FormWarningText text={errors.email.message} />}\n <Button type=\"submit\" loading={loading} className=\"w-full\">\n {t(\"Continue\")}\n </Button>\n </form>\n </MessageCard>\n );\n}\n\nfunction VerifyEmailScreen(props: {\n user: NonNullable<ReturnType<typeof useUser>>,\n email: string,\n fullPage?: boolean,\n}) {\n const { t } = useTranslation();\n const { user, email } = props;\n const [changingEmail, setChangingEmail] = useState(false);\n\n if (changingEmail) {\n return <AddEmailForm fullPage={props.fullPage} onEmailAdded={() => setChangingEmail(false)} />;\n }\n\n return (\n <MessageCard\n title={t(\"Please check your email inbox\")}\n fullPage={!!props.fullPage}\n primaryButtonText={t(\"Resend verification email\")}\n primaryAction={async () => {\n await user.sendVerificationEmail();\n }}\n secondaryButtonText={t(\"Sign out\")}\n secondaryAction={async () => {\n await user.signOut();\n }}\n >\n <Typography>\n {t(\"Please verify your email address \")}\n <span className=\"font-semibold\">{email}</span>\n {\" (\"}\n <button\n type=\"button\"\n className=\"text-primary hover:underline\"\n onClick={() => setChangingEmail(true)}\n >\n {t(\"change\")}\n </button>\n {\"). \"}\n {t(\"Click the button below to resend the verification link.\")}\n </Typography>\n </MessageCard>\n );\n}\n\n"],"mappings":"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","names":[]}