@stackframe/stack 2.8.3 → 2.8.6

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 (126) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/components-page/account-settings/active-sessions/active-sessions-page.js +151 -0
  3. package/dist/components-page/account-settings/active-sessions/active-sessions-page.js.map +1 -0
  4. package/dist/components-page/account-settings/api-keys/api-keys-page.js +70 -0
  5. package/dist/components-page/account-settings/api-keys/api-keys-page.js.map +1 -0
  6. package/dist/components-page/account-settings/editable-text.js +75 -0
  7. package/dist/components-page/account-settings/editable-text.js.map +1 -0
  8. package/dist/components-page/account-settings/email-and-auth/email-and-auth-page.js +46 -0
  9. package/dist/components-page/account-settings/email-and-auth/email-and-auth-page.js.map +1 -0
  10. package/dist/components-page/account-settings/email-and-auth/emails-section.js +188 -0
  11. package/dist/components-page/account-settings/email-and-auth/emails-section.js.map +1 -0
  12. package/dist/components-page/account-settings/email-and-auth/mfa-section.js +146 -0
  13. package/dist/components-page/account-settings/email-and-auth/mfa-section.js.map +1 -0
  14. package/dist/components-page/account-settings/email-and-auth/otp-section.js +89 -0
  15. package/dist/components-page/account-settings/email-and-auth/otp-section.js.map +1 -0
  16. package/dist/components-page/account-settings/email-and-auth/passkey-section.js +92 -0
  17. package/dist/components-page/account-settings/email-and-auth/passkey-section.js.map +1 -0
  18. package/dist/components-page/account-settings/email-and-auth/password-section.js +181 -0
  19. package/dist/components-page/account-settings/email-and-auth/password-section.js.map +1 -0
  20. package/dist/components-page/account-settings/page-layout.js +34 -0
  21. package/dist/components-page/account-settings/page-layout.js.map +1 -0
  22. package/dist/components-page/account-settings/profile-page/profile-page.js +75 -0
  23. package/dist/components-page/account-settings/profile-page/profile-page.js.map +1 -0
  24. package/dist/components-page/account-settings/section.js +44 -0
  25. package/dist/components-page/account-settings/section.js.map +1 -0
  26. package/dist/components-page/account-settings/settings/delete-account-section.js +87 -0
  27. package/dist/components-page/account-settings/settings/delete-account-section.js.map +1 -0
  28. package/dist/components-page/account-settings/settings/settings-page.js +40 -0
  29. package/dist/components-page/account-settings/settings/settings-page.js.map +1 -0
  30. package/dist/components-page/account-settings/settings/sign-out-section.js +54 -0
  31. package/dist/components-page/account-settings/settings/sign-out-section.js.map +1 -0
  32. package/dist/components-page/account-settings/teams/leave-team-section.js +79 -0
  33. package/dist/components-page/account-settings/teams/leave-team-section.js.map +1 -0
  34. package/dist/components-page/account-settings/teams/team-api-keys-section.js +89 -0
  35. package/dist/components-page/account-settings/teams/team-api-keys-section.js.map +1 -0
  36. package/dist/components-page/account-settings/teams/team-creation-page.js +92 -0
  37. package/dist/components-page/account-settings/teams/team-creation-page.js.map +1 -0
  38. package/dist/components-page/account-settings/teams/team-display-name-section.js +57 -0
  39. package/dist/components-page/account-settings/teams/team-display-name-section.js.map +1 -0
  40. package/dist/components-page/account-settings/teams/team-member-invitation-section.js +131 -0
  41. package/dist/components-page/account-settings/teams/team-member-invitation-section.js.map +1 -0
  42. package/dist/components-page/account-settings/teams/team-member-list-section.js +61 -0
  43. package/dist/components-page/account-settings/teams/team-member-list-section.js.map +1 -0
  44. package/dist/components-page/account-settings/teams/team-page.js +50 -0
  45. package/dist/components-page/account-settings/teams/team-page.js.map +1 -0
  46. package/dist/components-page/account-settings/teams/team-profile-image-section.js +59 -0
  47. package/dist/components-page/account-settings/teams/team-profile-image-section.js.map +1 -0
  48. package/dist/components-page/account-settings/teams/team-profile-user-section.js +56 -0
  49. package/dist/components-page/account-settings/teams/team-profile-user-section.js.map +1 -0
  50. package/dist/components-page/account-settings.js +16 -1173
  51. package/dist/components-page/account-settings.js.map +1 -1
  52. package/dist/components-page/section.js +6 -0
  53. package/dist/components-page/section.js.map +1 -0
  54. package/dist/esm/components-page/account-settings/active-sessions/active-sessions-page.js +126 -0
  55. package/dist/esm/components-page/account-settings/active-sessions/active-sessions-page.js.map +1 -0
  56. package/dist/esm/components-page/account-settings/api-keys/api-keys-page.js +45 -0
  57. package/dist/esm/components-page/account-settings/api-keys/api-keys-page.js.map +1 -0
  58. package/dist/esm/components-page/account-settings/editable-text.js +50 -0
  59. package/dist/esm/components-page/account-settings/editable-text.js.map +1 -0
  60. package/dist/esm/components-page/account-settings/email-and-auth/email-and-auth-page.js +21 -0
  61. package/dist/esm/components-page/account-settings/email-and-auth/email-and-auth-page.js.map +1 -0
  62. package/dist/esm/components-page/account-settings/email-and-auth/emails-section.js +163 -0
  63. package/dist/esm/components-page/account-settings/email-and-auth/emails-section.js.map +1 -0
  64. package/dist/esm/components-page/account-settings/email-and-auth/mfa-section.js +111 -0
  65. package/dist/esm/components-page/account-settings/email-and-auth/mfa-section.js.map +1 -0
  66. package/dist/esm/components-page/account-settings/email-and-auth/otp-section.js +64 -0
  67. package/dist/esm/components-page/account-settings/email-and-auth/otp-section.js.map +1 -0
  68. package/dist/esm/components-page/account-settings/email-and-auth/passkey-section.js +67 -0
  69. package/dist/esm/components-page/account-settings/email-and-auth/passkey-section.js.map +1 -0
  70. package/dist/esm/components-page/account-settings/email-and-auth/password-section.js +146 -0
  71. package/dist/esm/components-page/account-settings/email-and-auth/password-section.js.map +1 -0
  72. package/dist/esm/components-page/account-settings/page-layout.js +9 -0
  73. package/dist/esm/components-page/account-settings/page-layout.js.map +1 -0
  74. package/dist/esm/components-page/account-settings/profile-page/profile-page.js +50 -0
  75. package/dist/esm/components-page/account-settings/profile-page/profile-page.js.map +1 -0
  76. package/dist/esm/components-page/account-settings/section.js +19 -0
  77. package/dist/esm/components-page/account-settings/section.js.map +1 -0
  78. package/dist/esm/components-page/account-settings/settings/delete-account-section.js +62 -0
  79. package/dist/esm/components-page/account-settings/settings/delete-account-section.js.map +1 -0
  80. package/dist/esm/components-page/account-settings/settings/settings-page.js +15 -0
  81. package/dist/esm/components-page/account-settings/settings/settings-page.js.map +1 -0
  82. package/dist/esm/components-page/account-settings/settings/sign-out-section.js +29 -0
  83. package/dist/esm/components-page/account-settings/settings/sign-out-section.js.map +1 -0
  84. package/dist/esm/components-page/account-settings/teams/leave-team-section.js +54 -0
  85. package/dist/esm/components-page/account-settings/teams/leave-team-section.js.map +1 -0
  86. package/dist/esm/components-page/account-settings/teams/team-api-keys-section.js +64 -0
  87. package/dist/esm/components-page/account-settings/teams/team-api-keys-section.js.map +1 -0
  88. package/dist/esm/components-page/account-settings/teams/team-creation-page.js +67 -0
  89. package/dist/esm/components-page/account-settings/teams/team-creation-page.js.map +1 -0
  90. package/dist/esm/components-page/account-settings/teams/team-display-name-section.js +32 -0
  91. package/dist/esm/components-page/account-settings/teams/team-display-name-section.js.map +1 -0
  92. package/dist/esm/components-page/account-settings/teams/team-member-invitation-section.js +106 -0
  93. package/dist/esm/components-page/account-settings/teams/team-member-invitation-section.js.map +1 -0
  94. package/dist/esm/components-page/account-settings/teams/team-member-list-section.js +36 -0
  95. package/dist/esm/components-page/account-settings/teams/team-member-list-section.js.map +1 -0
  96. package/dist/esm/components-page/account-settings/teams/team-page.js +25 -0
  97. package/dist/esm/components-page/account-settings/teams/team-page.js.map +1 -0
  98. package/dist/esm/components-page/account-settings/teams/team-profile-image-section.js +34 -0
  99. package/dist/esm/components-page/account-settings/teams/team-profile-image-section.js.map +1 -0
  100. package/dist/esm/components-page/account-settings/teams/team-profile-user-section.js +31 -0
  101. package/dist/esm/components-page/account-settings/teams/team-profile-user-section.js.map +1 -0
  102. package/dist/esm/components-page/account-settings.js +14 -1158
  103. package/dist/esm/components-page/account-settings.js.map +1 -1
  104. package/dist/esm/components-page/section.js +4 -0
  105. package/dist/esm/components-page/section.js.map +1 -0
  106. package/dist/esm/lib/stack-app/apps/implementations/admin-app-impl.js.map +1 -1
  107. package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.js +79 -0
  108. package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.js.map +1 -1
  109. package/dist/esm/lib/stack-app/apps/implementations/common.js +1 -1
  110. package/dist/esm/lib/stack-app/apps/implementations/common.js.map +1 -1
  111. package/dist/esm/lib/stack-app/apps/interfaces/client-app.js.map +1 -1
  112. package/dist/esm/lib/stack-app/projects/index.js.map +1 -1
  113. package/dist/esm/lib/translations.js +0 -1
  114. package/dist/esm/lib/translations.js.map +1 -1
  115. package/dist/index.d.mts +5 -1
  116. package/dist/index.d.ts +5 -1
  117. package/dist/lib/stack-app/apps/implementations/admin-app-impl.js.map +1 -1
  118. package/dist/lib/stack-app/apps/implementations/client-app-impl.js +79 -0
  119. package/dist/lib/stack-app/apps/implementations/client-app-impl.js.map +1 -1
  120. package/dist/lib/stack-app/apps/implementations/common.js +1 -1
  121. package/dist/lib/stack-app/apps/implementations/common.js.map +1 -1
  122. package/dist/lib/stack-app/apps/interfaces/client-app.js.map +1 -1
  123. package/dist/lib/stack-app/projects/index.js.map +1 -1
  124. package/dist/lib/translations.js +0 -1
  125. package/dist/lib/translations.js.map +1 -1
  126. package/package.json +4 -4
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../src/components-page/account-settings/email-and-auth/password-section.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\nimport { yupResolver } from \"@hookform/resolvers/yup\";\nimport { getPasswordError } from '@stackframe/stack-shared/dist/helpers/password';\nimport { passwordSchema as schemaFieldsPasswordSchema, yupObject, yupString } from \"@stackframe/stack-shared/dist/schema-fields\";\nimport { runAsynchronously, runAsynchronouslyWithAlert } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { Button, Input, Label, PasswordInput, Typography } from \"@stackframe/stack-ui\";\nimport { useState } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport * as yup from \"yup\";\nimport { useStackApp } from '../../..';\nimport { FormWarningText } from \"../../../components/elements/form-warning\";\nimport { useUser } from \"../../../lib/hooks\";\nimport { useTranslation } from \"../../../lib/translations\";\nimport { Section } from \"../section\";\n\n\nexport function PasswordSection() {\n const { t } = useTranslation();\n const user = useUser({ or: \"throw\" });\n const contactChannels = user.useContactChannels();\n const [changingPassword, setChangingPassword] = useState(false);\n const [loading, setLoading] = useState(false);\n const project = useStackApp().useProject();\n\n const passwordSchema = yupObject({\n oldPassword: user.hasPassword ? schemaFieldsPasswordSchema.defined().nonEmpty(t('Please enter your old password')) : yupString(),\n newPassword: schemaFieldsPasswordSchema.defined().nonEmpty(t('Please enter your password')).test({\n name: 'is-valid-password',\n test: (value, ctx) => {\n const error = getPasswordError(value);\n if (error) {\n return ctx.createError({ message: error.message });\n } else {\n return true;\n }\n }\n }),\n newPasswordRepeat: yupString().nullable().oneOf([yup.ref('newPassword'), \"\", null], t('Passwords do not match')).defined().nonEmpty(t('Please repeat your password'))\n });\n\n const { register, handleSubmit, setError, formState: { errors }, clearErrors, reset } = useForm({\n resolver: yupResolver(passwordSchema)\n });\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n const hasValidEmail = contactChannels.filter(x => x.type === 'email' && x.usedForAuth).length > 0;\n\n const onSubmit = async (data: yup.InferType<typeof passwordSchema>) => {\n setLoading(true);\n try {\n const { oldPassword, newPassword } = data;\n const error = user.hasPassword\n ? await user.updatePassword({ oldPassword: oldPassword!, newPassword })\n : await user.setPassword({ password: newPassword! });\n if (error) {\n setError('oldPassword', { type: 'manual', message: t('Incorrect password') });\n } else {\n reset();\n setChangingPassword(false);\n }\n } finally {\n setLoading(false);\n }\n };\n\n const registerPassword = register('newPassword');\n const registerPasswordRepeat = register('newPasswordRepeat');\n\n if (!project.config.credentialEnabled) {\n return null;\n }\n\n return (\n <Section\n title={t(\"Password\")}\n description={user.hasPassword ? t(\"Update your password\") : t(\"Set a password for your account\")}\n >\n <div className='flex flex-col gap-4'>\n {!changingPassword ? (\n hasValidEmail ? (\n <Button\n variant='secondary'\n onClick={() => setChangingPassword(true)}\n >\n {user.hasPassword ? t(\"Update password\") : t(\"Set password\")}\n </Button>\n ) : (\n <Typography variant='secondary' type='label'>{t(\"To set a password, please add a sign-in email.\")}</Typography>\n )\n ) : (\n <form\n onSubmit={e => runAsynchronouslyWithAlert(handleSubmit(onSubmit)(e))}\n noValidate\n >\n {user.hasPassword && (\n <>\n <Label htmlFor=\"old-password\" className=\"mb-1\">{t(\"Old password\")}</Label>\n <Input\n id=\"old-password\"\n type=\"password\"\n autoComplete=\"current-password\"\n {...register(\"oldPassword\")}\n />\n <FormWarningText text={errors.oldPassword?.message?.toString()} />\n </>\n )}\n\n <Label htmlFor=\"new-password\" className=\"mt-4 mb-1\">{t(\"New password\")}</Label>\n <PasswordInput\n id=\"new-password\"\n autoComplete=\"new-password\"\n {...registerPassword}\n onChange={(e) => {\n clearErrors('newPassword');\n clearErrors('newPasswordRepeat');\n runAsynchronously(registerPassword.onChange(e));\n }}\n />\n <FormWarningText text={errors.newPassword?.message?.toString()} />\n\n <Label htmlFor=\"repeat-password\" className=\"mt-4 mb-1\">{t(\"Repeat new password\")}</Label>\n <PasswordInput\n id=\"repeat-password\"\n autoComplete=\"new-password\"\n {...registerPasswordRepeat}\n onChange={(e) => {\n clearErrors('newPassword');\n clearErrors('newPasswordRepeat');\n runAsynchronously(registerPasswordRepeat.onChange(e));\n }}\n />\n <FormWarningText text={errors.newPasswordRepeat?.message?.toString()} />\n\n <div className=\"mt-6 flex gap-4\">\n <Button type=\"submit\" loading={loading}>\n {user.hasPassword ? t(\"Update Password\") : t(\"Set Password\")}\n </Button>\n <Button\n variant=\"secondary\"\n onClick={() => {\n setChangingPassword(false);\n reset();\n }}\n >\n {t(\"Cancel\")}\n </Button>\n </div>\n </form>\n )}\n </div>\n </Section>\n );\n}\n"],"mappings":";AAIA,SAAS,mBAAmB;AAC5B,SAAS,wBAAwB;AACjC,SAAS,kBAAkB,4BAA4B,WAAW,iBAAiB;AACnF,SAAS,mBAAmB,kCAAkC;AAC9D,SAAS,QAAQ,OAAO,OAAO,eAAe,kBAAkB;AAChE,SAAS,gBAAgB;AACzB,SAAS,eAAe;AACxB,YAAY,SAAS;AACrB,SAAS,mBAAmB;AAC5B,SAAS,uBAAuB;AAChC,SAAS,eAAe;AACxB,SAAS,sBAAsB;AAC/B,SAAS,eAAe;AAmEZ,SAeE,UAfF,KAeE,YAfF;AAhEL,SAAS,kBAAkB;AAChC,QAAM,EAAE,EAAE,IAAI,eAAe;AAC7B,QAAM,OAAO,QAAQ,EAAE,IAAI,QAAQ,CAAC;AACpC,QAAM,kBAAkB,KAAK,mBAAmB;AAChD,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,SAAS,KAAK;AAC9D,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,KAAK;AAC5C,QAAM,UAAU,YAAY,EAAE,WAAW;AAEzC,QAAM,iBAAiB,UAAU;AAAA,IAC/B,aAAa,KAAK,cAAc,2BAA2B,QAAQ,EAAE,SAAS,EAAE,gCAAgC,CAAC,IAAI,UAAU;AAAA,IAC/H,aAAa,2BAA2B,QAAQ,EAAE,SAAS,EAAE,4BAA4B,CAAC,EAAE,KAAK;AAAA,MAC/F,MAAM;AAAA,MACN,MAAM,CAAC,OAAO,QAAQ;AACpB,cAAM,QAAQ,iBAAiB,KAAK;AACpC,YAAI,OAAO;AACT,iBAAO,IAAI,YAAY,EAAE,SAAS,MAAM,QAAQ,CAAC;AAAA,QACnD,OAAO;AACL,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF,CAAC;AAAA,IACD,mBAAmB,UAAU,EAAE,SAAS,EAAE,MAAM,CAAK,QAAI,aAAa,GAAG,IAAI,IAAI,GAAG,EAAE,wBAAwB,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,6BAA6B,CAAC;AAAA,EACtK,CAAC;AAED,QAAM,EAAE,UAAU,cAAc,UAAU,WAAW,EAAE,OAAO,GAAG,aAAa,MAAM,IAAI,QAAQ;AAAA,IAC9F,UAAU,YAAY,cAAc;AAAA,EACtC,CAAC;AAGD,QAAM,gBAAgB,gBAAgB,OAAO,OAAK,EAAE,SAAS,WAAW,EAAE,WAAW,EAAE,SAAS;AAEhG,QAAM,WAAW,OAAO,SAA+C;AACrE,eAAW,IAAI;AACf,QAAI;AACF,YAAM,EAAE,aAAa,YAAY,IAAI;AACrC,YAAM,QAAQ,KAAK,cACf,MAAM,KAAK,eAAe,EAAE,aAA2B,YAAY,CAAC,IACpE,MAAM,KAAK,YAAY,EAAE,UAAU,YAAa,CAAC;AACrD,UAAI,OAAO;AACT,iBAAS,eAAe,EAAE,MAAM,UAAU,SAAS,EAAE,oBAAoB,EAAE,CAAC;AAAA,MAC9E,OAAO;AACL,cAAM;AACN,4BAAoB,KAAK;AAAA,MAC3B;AAAA,IACF,UAAE;AACA,iBAAW,KAAK;AAAA,IAClB;AAAA,EACF;AAEA,QAAM,mBAAmB,SAAS,aAAa;AAC/C,QAAM,yBAAyB,SAAS,mBAAmB;AAE3D,MAAI,CAAC,QAAQ,OAAO,mBAAmB;AACrC,WAAO;AAAA,EACT;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,EAAE,UAAU;AAAA,MACnB,aAAa,KAAK,cAAc,EAAE,sBAAsB,IAAI,EAAE,iCAAiC;AAAA,MAE/F,8BAAC,SAAI,WAAU,uBACZ,WAAC,mBACA,gBACE;AAAA,QAAC;AAAA;AAAA,UACC,SAAQ;AAAA,UACR,SAAS,MAAM,oBAAoB,IAAI;AAAA,UAEtC,eAAK,cAAc,EAAE,iBAAiB,IAAI,EAAE,cAAc;AAAA;AAAA,MAC7D,IAEA,oBAAC,cAAW,SAAQ,aAAY,MAAK,SAAS,YAAE,gDAAgD,GAAE,IAGpG;AAAA,QAAC;AAAA;AAAA,UACC,UAAU,OAAK,2BAA2B,aAAa,QAAQ,EAAE,CAAC,CAAC;AAAA,UACnE,YAAU;AAAA,UAET;AAAA,iBAAK,eACJ,iCACE;AAAA,kCAAC,SAAM,SAAQ,gBAAe,WAAU,QAAQ,YAAE,cAAc,GAAE;AAAA,cAClE;AAAA,gBAAC;AAAA;AAAA,kBACC,IAAG;AAAA,kBACH,MAAK;AAAA,kBACL,cAAa;AAAA,kBACZ,GAAG,SAAS,aAAa;AAAA;AAAA,cAC5B;AAAA,cACA,oBAAC,mBAAgB,MAAM,OAAO,aAAa,SAAS,SAAS,GAAG;AAAA,eAClE;AAAA,YAGF,oBAAC,SAAM,SAAQ,gBAAe,WAAU,aAAa,YAAE,cAAc,GAAE;AAAA,YACvE;AAAA,cAAC;AAAA;AAAA,gBACC,IAAG;AAAA,gBACH,cAAa;AAAA,gBACZ,GAAG;AAAA,gBACJ,UAAU,CAAC,MAAM;AACf,8BAAY,aAAa;AACzB,8BAAY,mBAAmB;AAC/B,oCAAkB,iBAAiB,SAAS,CAAC,CAAC;AAAA,gBAChD;AAAA;AAAA,YACF;AAAA,YACA,oBAAC,mBAAgB,MAAM,OAAO,aAAa,SAAS,SAAS,GAAG;AAAA,YAEhE,oBAAC,SAAM,SAAQ,mBAAkB,WAAU,aAAa,YAAE,qBAAqB,GAAE;AAAA,YACjF;AAAA,cAAC;AAAA;AAAA,gBACC,IAAG;AAAA,gBACH,cAAa;AAAA,gBACZ,GAAG;AAAA,gBACJ,UAAU,CAAC,MAAM;AACf,8BAAY,aAAa;AACzB,8BAAY,mBAAmB;AAC/B,oCAAkB,uBAAuB,SAAS,CAAC,CAAC;AAAA,gBACtD;AAAA;AAAA,YACF;AAAA,YACA,oBAAC,mBAAgB,MAAM,OAAO,mBAAmB,SAAS,SAAS,GAAG;AAAA,YAEtE,qBAAC,SAAI,WAAU,mBACb;AAAA,kCAAC,UAAO,MAAK,UAAS,SACnB,eAAK,cAAc,EAAE,iBAAiB,IAAI,EAAE,cAAc,GAC7D;AAAA,cACA;AAAA,gBAAC;AAAA;AAAA,kBACC,SAAQ;AAAA,kBACR,SAAS,MAAM;AACb,wCAAoB,KAAK;AACzB,0BAAM;AAAA,kBACR;AAAA,kBAEC,YAAE,QAAQ;AAAA;AAAA,cACb;AAAA,eACF;AAAA;AAAA;AAAA,MACF,GAEJ;AAAA;AAAA,EACF;AAEJ;","names":[]}
@@ -0,0 +1,9 @@
1
+ // src/components-page/account-settings/page-layout.tsx
2
+ import { jsx } from "react/jsx-runtime";
3
+ function PageLayout(props) {
4
+ return /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-6", children: props.children });
5
+ }
6
+ export {
7
+ PageLayout
8
+ };
9
+ //# sourceMappingURL=page-layout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/components-page/account-settings/page-layout.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\nexport function PageLayout(props: { children: React.ReactNode }) {\n return (\n <div className='flex flex-col gap-6'>\n {props.children}\n </div>\n );\n}\n"],"mappings":";AAMI;AAFG,SAAS,WAAW,OAAsC;AAC/D,SACE,oBAAC,SAAI,WAAU,uBACZ,gBAAM,UACT;AAEJ;","names":[]}
@@ -0,0 +1,50 @@
1
+ // src/components-page/account-settings/profile-page/profile-page.tsx
2
+ import { ProfileImageEditor } from "../../../components/profile-image-editor";
3
+ import { useUser } from "../../../lib/hooks";
4
+ import { useTranslation } from "../../../lib/translations";
5
+ import { EditableText } from "../editable-text";
6
+ import { PageLayout } from "../page-layout";
7
+ import { Section } from "../section";
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
+ function ProfilePage() {
10
+ const { t } = useTranslation();
11
+ const user = useUser({ or: "redirect" });
12
+ return /* @__PURE__ */ jsxs(PageLayout, { children: [
13
+ /* @__PURE__ */ jsx(
14
+ Section,
15
+ {
16
+ title: t("User name"),
17
+ description: t("This is a display name and is not used for authentication"),
18
+ children: /* @__PURE__ */ jsx(
19
+ EditableText,
20
+ {
21
+ value: user.displayName || "",
22
+ onSave: async (newDisplayName) => {
23
+ await user.update({ displayName: newDisplayName });
24
+ }
25
+ }
26
+ )
27
+ }
28
+ ),
29
+ /* @__PURE__ */ jsx(
30
+ Section,
31
+ {
32
+ title: t("Profile image"),
33
+ description: t("Upload your own image as your avatar"),
34
+ children: /* @__PURE__ */ jsx(
35
+ ProfileImageEditor,
36
+ {
37
+ user,
38
+ onProfileImageUrlChange: async (profileImageUrl) => {
39
+ await user.update({ profileImageUrl });
40
+ }
41
+ }
42
+ )
43
+ }
44
+ )
45
+ ] });
46
+ }
47
+ export {
48
+ ProfilePage
49
+ };
50
+ //# sourceMappingURL=profile-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../src/components-page/account-settings/profile-page/profile-page.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\nimport { ProfileImageEditor } from \"../../../components/profile-image-editor\";\nimport { useUser } from \"../../../lib/hooks\";\nimport { useTranslation } from \"../../../lib/translations\";\nimport { EditableText } from \"../editable-text\";\nimport { PageLayout } from \"../page-layout\";\nimport { Section } from \"../section\";\n\nexport function ProfilePage() {\n const { t } = useTranslation();\n const user = useUser({ or: 'redirect' });\n\n return (\n <PageLayout>\n <Section\n title={t(\"User name\")}\n description={t(\"This is a display name and is not used for authentication\")}\n >\n <EditableText\n value={user.displayName || ''}\n onSave={async (newDisplayName) => {\n await user.update({ displayName: newDisplayName });\n }}/>\n </Section>\n\n <Section\n title={t(\"Profile image\")}\n description={t(\"Upload your own image as your avatar\")}\n >\n <ProfileImageEditor\n user={user}\n onProfileImageUrlChange={async (profileImageUrl) => {\n await user.update({ profileImageUrl });\n }}\n />\n </Section>\n </PageLayout>\n );\n}\n"],"mappings":";AAIA,SAAS,0BAA0B;AACnC,SAAS,eAAe;AACxB,SAAS,sBAAsB;AAC/B,SAAS,oBAAoB;AAC7B,SAAS,kBAAkB;AAC3B,SAAS,eAAe;AAOpB,SAKI,KALJ;AALG,SAAS,cAAc;AAC5B,QAAM,EAAE,EAAE,IAAI,eAAe;AAC7B,QAAM,OAAO,QAAQ,EAAE,IAAI,WAAW,CAAC;AAEvC,SACE,qBAAC,cACC;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,EAAE,WAAW;AAAA,QACpB,aAAa,EAAE,2DAA2D;AAAA,QAE1E;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,KAAK,eAAe;AAAA,YAC3B,QAAQ,OAAO,mBAAmB;AAChC,oBAAM,KAAK,OAAO,EAAE,aAAa,eAAe,CAAC;AAAA,YACnD;AAAA;AAAA,QAAE;AAAA;AAAA,IACN;AAAA,IAEA;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,EAAE,eAAe;AAAA,QACxB,aAAa,EAAE,sCAAsC;AAAA,QAErD;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA,yBAAyB,OAAO,oBAAoB;AAClD,oBAAM,KAAK,OAAO,EAAE,gBAAgB,CAAC;AAAA,YACvC;AAAA;AAAA,QACF;AAAA;AAAA,IACF;AAAA,KACF;AAEJ;","names":[]}
@@ -0,0 +1,19 @@
1
+ // src/components-page/account-settings/section.tsx
2
+ import { Separator, Typography } from "@stackframe/stack-ui";
3
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
+ function Section(props) {
5
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
6
+ /* @__PURE__ */ jsx(Separator, {}),
7
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col sm:flex-row gap-2", children: [
8
+ /* @__PURE__ */ jsxs("div", { className: "sm:flex-1 flex flex-col justify-center", children: [
9
+ /* @__PURE__ */ jsx(Typography, { className: "font-medium", children: props.title }),
10
+ props.description && /* @__PURE__ */ jsx(Typography, { variant: "secondary", type: "footnote", children: props.description })
11
+ ] }),
12
+ /* @__PURE__ */ jsx("div", { className: "sm:flex-1 sm:items-end flex flex-col gap-2 ", children: props.children })
13
+ ] })
14
+ ] });
15
+ }
16
+ export {
17
+ Section
18
+ };
19
+ //# sourceMappingURL=section.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/components-page/account-settings/section.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\nimport { Separator, Typography } from \"@stackframe/stack-ui\";\n\nexport function Section(props: { title: string, description?: string, children: React.ReactNode }) {\n return (\n <>\n <Separator />\n <div className='flex flex-col sm:flex-row gap-2'>\n <div className='sm:flex-1 flex flex-col justify-center'>\n <Typography className='font-medium'>\n {props.title}\n </Typography>\n {props.description && <Typography variant='secondary' type='footnote'>\n {props.description}\n </Typography>}\n </div>\n <div className='sm:flex-1 sm:items-end flex flex-col gap-2 '>\n {props.children}\n </div>\n </div>\n </>\n );\n}\n"],"mappings":";AAIA,SAAS,WAAW,kBAAkB;AAIlC,mBACE,KAEE,YAHJ;AAFG,SAAS,QAAQ,OAA2E;AACjG,SACE,iCACE;AAAA,wBAAC,aAAU;AAAA,IACX,qBAAC,SAAI,WAAU,mCACb;AAAA,2BAAC,SAAI,WAAU,0CACb;AAAA,4BAAC,cAAW,WAAU,eACnB,gBAAM,OACT;AAAA,QACC,MAAM,eAAe,oBAAC,cAAW,SAAQ,aAAY,MAAK,YACxD,gBAAM,aACT;AAAA,SACF;AAAA,MACA,oBAAC,SAAI,WAAU,+CACZ,gBAAM,UACT;AAAA,OACF;AAAA,KACF;AAEJ;","names":[]}
@@ -0,0 +1,62 @@
1
+ // src/components-page/account-settings/settings/delete-account-section.tsx
2
+ import { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Button, Typography } from "@stackframe/stack-ui";
3
+ import { useState } from "react";
4
+ import { useStackApp, useUser } from "../../../lib/hooks";
5
+ import { useTranslation } from "../../../lib/translations";
6
+ import { Section } from "../section";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ function DeleteAccountSection() {
9
+ const { t } = useTranslation();
10
+ const user = useUser({ or: "redirect" });
11
+ const app = useStackApp();
12
+ const project = app.useProject();
13
+ const [deleting, setDeleting] = useState(false);
14
+ if (!project.config.clientUserDeletionEnabled) {
15
+ return null;
16
+ }
17
+ return /* @__PURE__ */ jsx(
18
+ Section,
19
+ {
20
+ title: t("Delete Account"),
21
+ description: t("Permanently remove your account and all associated data"),
22
+ children: /* @__PURE__ */ jsx("div", { className: "stack-scope flex flex-col items-stretch", children: /* @__PURE__ */ jsx(Accordion, { type: "single", collapsible: true, className: "w-full", children: /* @__PURE__ */ jsxs(AccordionItem, { value: "item-1", children: [
23
+ /* @__PURE__ */ jsx(AccordionTrigger, { children: t("Danger zone") }),
24
+ /* @__PURE__ */ jsx(AccordionContent, { children: !deleting ? /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
25
+ Button,
26
+ {
27
+ variant: "destructive",
28
+ onClick: () => setDeleting(true),
29
+ children: t("Delete account")
30
+ }
31
+ ) }) : /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
32
+ /* @__PURE__ */ jsx(Typography, { variant: "destructive", children: t("Are you sure you want to delete your account? This action is IRREVERSIBLE and will delete ALL associated data.") }),
33
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
34
+ /* @__PURE__ */ jsx(
35
+ Button,
36
+ {
37
+ variant: "destructive",
38
+ onClick: async () => {
39
+ await user.delete();
40
+ await app.redirectToHome();
41
+ },
42
+ children: t("Delete Account")
43
+ }
44
+ ),
45
+ /* @__PURE__ */ jsx(
46
+ Button,
47
+ {
48
+ variant: "secondary",
49
+ onClick: () => setDeleting(false),
50
+ children: t("Cancel")
51
+ }
52
+ )
53
+ ] })
54
+ ] }) })
55
+ ] }) }) })
56
+ }
57
+ );
58
+ }
59
+ export {
60
+ DeleteAccountSection
61
+ };
62
+ //# sourceMappingURL=delete-account-section.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../src/components-page/account-settings/settings/delete-account-section.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\nimport { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Button, Typography } from \"@stackframe/stack-ui\";\nimport { useState } from \"react\";\nimport { useStackApp, useUser } from \"../../../lib/hooks\";\nimport { useTranslation } from \"../../../lib/translations\";\nimport { Section } from \"../section\";\n\nexport function DeleteAccountSection() {\n const { t } = useTranslation();\n const user = useUser({ or: 'redirect' });\n const app = useStackApp();\n const project = app.useProject();\n const [deleting, setDeleting] = useState(false);\n if (!project.config.clientUserDeletionEnabled) {\n return null;\n }\n\n return (\n <Section\n title={t(\"Delete Account\")}\n description={t(\"Permanently remove your account and all associated data\")}\n >\n <div className='stack-scope flex flex-col items-stretch'>\n <Accordion type=\"single\" collapsible className=\"w-full\">\n <AccordionItem value=\"item-1\">\n <AccordionTrigger>{t(\"Danger zone\")}</AccordionTrigger>\n <AccordionContent>\n {!deleting ? (\n <div>\n <Button\n variant='destructive'\n onClick={() => setDeleting(true)}\n >\n {t(\"Delete account\")}\n </Button>\n </div>\n ) : (\n <div className='flex flex-col gap-2'>\n <Typography variant='destructive'>\n {t(\"Are you sure you want to delete your account? This action is IRREVERSIBLE and will delete ALL associated data.\")}\n </Typography>\n <div className='flex gap-2'>\n <Button\n variant='destructive'\n onClick={async () => {\n await user.delete();\n await app.redirectToHome();\n }}\n >\n {t(\"Delete Account\")}\n </Button>\n <Button\n variant='secondary'\n onClick={() => setDeleting(false)}\n >\n {t(\"Cancel\")}\n </Button>\n </div>\n </div>\n )}\n </AccordionContent>\n </AccordionItem>\n </Accordion>\n </div>\n </Section>\n );\n}\n"],"mappings":";AAIA,SAAS,WAAW,kBAAkB,eAAe,kBAAkB,QAAQ,kBAAkB;AACjG,SAAS,gBAAgB;AACzB,SAAS,aAAa,eAAe;AACrC,SAAS,sBAAsB;AAC/B,SAAS,eAAe;AAoBZ,cAgBM,YAhBN;AAlBL,SAAS,uBAAuB;AACrC,QAAM,EAAE,EAAE,IAAI,eAAe;AAC7B,QAAM,OAAO,QAAQ,EAAE,IAAI,WAAW,CAAC;AACvC,QAAM,MAAM,YAAY;AACxB,QAAM,UAAU,IAAI,WAAW;AAC/B,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAC9C,MAAI,CAAC,QAAQ,OAAO,2BAA2B;AAC7C,WAAO;AAAA,EACT;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,EAAE,gBAAgB;AAAA,MACzB,aAAa,EAAE,yDAAyD;AAAA,MAExE,8BAAC,SAAI,WAAU,2CACb,8BAAC,aAAU,MAAK,UAAS,aAAW,MAAC,WAAU,UAC7C,+BAAC,iBAAc,OAAM,UACnB;AAAA,4BAAC,oBAAkB,YAAE,aAAa,GAAE;AAAA,QACpC,oBAAC,oBACE,WAAC,WACA,oBAAC,SACC;AAAA,UAAC;AAAA;AAAA,YACC,SAAQ;AAAA,YACR,SAAS,MAAM,YAAY,IAAI;AAAA,YAE9B,YAAE,gBAAgB;AAAA;AAAA,QACrB,GACF,IAEA,qBAAC,SAAI,WAAU,uBACb;AAAA,8BAAC,cAAW,SAAQ,eACjB,YAAE,gHAAgH,GACrH;AAAA,UACA,qBAAC,SAAI,WAAU,cACb;AAAA;AAAA,cAAC;AAAA;AAAA,gBACC,SAAQ;AAAA,gBACR,SAAS,YAAY;AACnB,wBAAM,KAAK,OAAO;AAClB,wBAAM,IAAI,eAAe;AAAA,gBAC3B;AAAA,gBAEC,YAAE,gBAAgB;AAAA;AAAA,YACrB;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACC,SAAQ;AAAA,gBACR,SAAS,MAAM,YAAY,KAAK;AAAA,gBAE/B,YAAE,QAAQ;AAAA;AAAA,YACb;AAAA,aACF;AAAA,WACF,GAEJ;AAAA,SACF,GACF,GACF;AAAA;AAAA,EACF;AAEJ;","names":[]}
@@ -0,0 +1,15 @@
1
+ // src/components-page/account-settings/settings/settings-page.tsx
2
+ import { PageLayout } from "../page-layout";
3
+ import { DeleteAccountSection } from "./delete-account-section";
4
+ import { SignOutSection } from "./sign-out-section";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ function SettingsPage() {
7
+ return /* @__PURE__ */ jsxs(PageLayout, { children: [
8
+ /* @__PURE__ */ jsx(DeleteAccountSection, {}),
9
+ /* @__PURE__ */ jsx(SignOutSection, {})
10
+ ] });
11
+ }
12
+ export {
13
+ SettingsPage
14
+ };
15
+ //# sourceMappingURL=settings-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../src/components-page/account-settings/settings/settings-page.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\nimport { PageLayout } from \"../page-layout\";\nimport { DeleteAccountSection } from \"./delete-account-section\";\nimport { SignOutSection } from \"./sign-out-section\";\n\n\nexport function SettingsPage() {\n return (\n <PageLayout>\n <DeleteAccountSection />\n <SignOutSection />\n </PageLayout>\n );\n}\n"],"mappings":";AAIA,SAAS,kBAAkB;AAC3B,SAAS,4BAA4B;AACrC,SAAS,sBAAsB;AAK3B,SACE,KADF;AAFG,SAAS,eAAe;AAC7B,SACE,qBAAC,cACC;AAAA,wBAAC,wBAAqB;AAAA,IACtB,oBAAC,kBAAe;AAAA,KAClB;AAEJ;","names":[]}
@@ -0,0 +1,29 @@
1
+ // src/components-page/account-settings/settings/sign-out-section.tsx
2
+ import { Button } from "@stackframe/stack-ui";
3
+ import { useUser } from "../../../lib/hooks";
4
+ import { useTranslation } from "../../../lib/translations";
5
+ import { Section } from "../section";
6
+ import { jsx } from "react/jsx-runtime";
7
+ function SignOutSection() {
8
+ const { t } = useTranslation();
9
+ const user = useUser({ or: "throw" });
10
+ return /* @__PURE__ */ jsx(
11
+ Section,
12
+ {
13
+ title: t("Sign out"),
14
+ description: t("End your current session"),
15
+ children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
16
+ Button,
17
+ {
18
+ variant: "secondary",
19
+ onClick: () => user.signOut(),
20
+ children: t("Sign out")
21
+ }
22
+ ) })
23
+ }
24
+ );
25
+ }
26
+ export {
27
+ SignOutSection
28
+ };
29
+ //# sourceMappingURL=sign-out-section.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../src/components-page/account-settings/settings/sign-out-section.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\nimport { Button } from \"@stackframe/stack-ui\";\nimport { useUser } from \"../../../lib/hooks\";\nimport { useTranslation } from \"../../../lib/translations\";\nimport { Section } from \"../section\";\n\nexport function SignOutSection() {\n const { t } = useTranslation();\n const user = useUser({ or: \"throw\" });\n\n return (\n <Section\n title={t(\"Sign out\")}\n description={t(\"End your current session\")}\n >\n <div>\n <Button\n variant='secondary'\n onClick={() => user.signOut()}\n >\n {t(\"Sign out\")}\n </Button>\n </div>\n </Section>\n );\n}\n"],"mappings":";AAIA,SAAS,cAAc;AACvB,SAAS,eAAe;AACxB,SAAS,sBAAsB;AAC/B,SAAS,eAAe;AAYhB;AAVD,SAAS,iBAAiB;AAC/B,QAAM,EAAE,EAAE,IAAI,eAAe;AAC7B,QAAM,OAAO,QAAQ,EAAE,IAAI,QAAQ,CAAC;AAEpC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,EAAE,UAAU;AAAA,MACnB,aAAa,EAAE,0BAA0B;AAAA,MAEzC,8BAAC,SACC;AAAA,QAAC;AAAA;AAAA,UACC,SAAQ;AAAA,UACR,SAAS,MAAM,KAAK,QAAQ;AAAA,UAE3B,YAAE,UAAU;AAAA;AAAA,MACf,GACF;AAAA;AAAA,EACF;AAEJ;","names":[]}
@@ -0,0 +1,54 @@
1
+ // src/components-page/account-settings/teams/leave-team-section.tsx
2
+ import { Button, Typography } from "@stackframe/stack-ui";
3
+ import { useState } from "react";
4
+ import { useUser } from "../../../lib/hooks";
5
+ import { useTranslation } from "../../../lib/translations";
6
+ import { Section } from "../section";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ function LeaveTeamSection(props) {
9
+ const { t } = useTranslation();
10
+ const user = useUser({ or: "redirect" });
11
+ const [leaving, setLeaving] = useState(false);
12
+ return /* @__PURE__ */ jsx(
13
+ Section,
14
+ {
15
+ title: t("Leave Team"),
16
+ description: t("leave this team and remove your team profile"),
17
+ children: !leaving ? /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
18
+ Button,
19
+ {
20
+ variant: "secondary",
21
+ onClick: () => setLeaving(true),
22
+ children: t("Leave team")
23
+ }
24
+ ) }) : /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
25
+ /* @__PURE__ */ jsx(Typography, { variant: "destructive", children: t("Are you sure you want to leave the team?") }),
26
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
27
+ /* @__PURE__ */ jsx(
28
+ Button,
29
+ {
30
+ variant: "destructive",
31
+ onClick: async () => {
32
+ await user.leaveTeam(props.team);
33
+ window.location.reload();
34
+ },
35
+ children: t("Leave")
36
+ }
37
+ ),
38
+ /* @__PURE__ */ jsx(
39
+ Button,
40
+ {
41
+ variant: "secondary",
42
+ onClick: () => setLeaving(false),
43
+ children: t("Cancel")
44
+ }
45
+ )
46
+ ] })
47
+ ] })
48
+ }
49
+ );
50
+ }
51
+ export {
52
+ LeaveTeamSection
53
+ };
54
+ //# sourceMappingURL=leave-team-section.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../src/components-page/account-settings/teams/leave-team-section.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\nimport { Button, Typography } from \"@stackframe/stack-ui\";\nimport { useState } from \"react\";\nimport { Team } from \"../../..\";\nimport { useUser } from \"../../../lib/hooks\";\nimport { useTranslation } from \"../../../lib/translations\";\nimport { Section } from \"../section\";\n\nexport function LeaveTeamSection(props: { team: Team }) {\n const { t } = useTranslation();\n const user = useUser({ or: 'redirect' });\n const [leaving, setLeaving] = useState(false);\n\n return (\n <Section\n title={t(\"Leave Team\")}\n description={t(\"leave this team and remove your team profile\")}\n >\n {!leaving ? (\n <div>\n <Button\n variant='secondary'\n onClick={() => setLeaving(true)}\n >\n {t(\"Leave team\")}\n </Button>\n </div>\n ) : (\n <div className='flex flex-col gap-2'>\n <Typography variant='destructive'>\n {t(\"Are you sure you want to leave the team?\")}\n </Typography>\n <div className='flex gap-2'>\n <Button\n variant='destructive'\n onClick={async () => {\n await user.leaveTeam(props.team);\n window.location.reload();\n }}\n >\n {t(\"Leave\")}\n </Button>\n <Button\n variant='secondary'\n onClick={() => setLeaving(false)}\n >\n {t(\"Cancel\")}\n </Button>\n </div>\n </div>\n )}\n </Section>\n );\n}\n"],"mappings":";AAIA,SAAS,QAAQ,kBAAkB;AACnC,SAAS,gBAAgB;AAEzB,SAAS,eAAe;AACxB,SAAS,sBAAsB;AAC/B,SAAS,eAAe;AAcd,cAYA,YAZA;AAZH,SAAS,iBAAiB,OAAuB;AACtD,QAAM,EAAE,EAAE,IAAI,eAAe;AAC7B,QAAM,OAAO,QAAQ,EAAE,IAAI,WAAW,CAAC;AACvC,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,KAAK;AAE5C,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,EAAE,YAAY;AAAA,MACrB,aAAa,EAAE,8CAA8C;AAAA,MAE5D,WAAC,UACA,oBAAC,SACC;AAAA,QAAC;AAAA;AAAA,UACC,SAAQ;AAAA,UACR,SAAS,MAAM,WAAW,IAAI;AAAA,UAE7B,YAAE,YAAY;AAAA;AAAA,MACjB,GACF,IAEA,qBAAC,SAAI,WAAU,uBACb;AAAA,4BAAC,cAAW,SAAQ,eACjB,YAAE,0CAA0C,GAC/C;AAAA,QACA,qBAAC,SAAI,WAAU,cACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,SAAQ;AAAA,cACR,SAAS,YAAY;AACnB,sBAAM,KAAK,UAAU,MAAM,IAAI;AAC/B,uBAAO,SAAS,OAAO;AAAA,cACzB;AAAA,cAEC,YAAE,OAAO;AAAA;AAAA,UACZ;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,SAAQ;AAAA,cACR,SAAS,MAAM,WAAW,KAAK;AAAA,cAE9B,YAAE,QAAQ;AAAA;AAAA,UACb;AAAA,WACF;AAAA,SACF;AAAA;AAAA,EAEJ;AAEJ;","names":[]}
@@ -0,0 +1,64 @@
1
+ // src/components-page/account-settings/teams/team-api-keys-section.tsx
2
+ import { StackAssertionError } from "@stackframe/stack-shared/dist/utils/errors";
3
+ import { Button } from "@stackframe/stack-ui";
4
+ import { useState } from "react";
5
+ import { CreateApiKeyDialog, ShowApiKeyDialog } from "../../../components/api-key-dialogs";
6
+ import { ApiKeyTable } from "../../../components/api-key-table";
7
+ import { useUser } from "../../../lib/hooks";
8
+ import { useTranslation } from "../../../lib/translations";
9
+ import { Section } from "../section";
10
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
11
+ function TeamApiKeysSection(props) {
12
+ const user = useUser({ or: "redirect" });
13
+ const team = user.useTeam(props.team.id);
14
+ if (!team) {
15
+ throw new StackAssertionError("Team not found");
16
+ }
17
+ const manageApiKeysPermission = user.usePermission(props.team, "$manage_api_keys");
18
+ if (!manageApiKeysPermission) {
19
+ return null;
20
+ }
21
+ return /* @__PURE__ */ jsx(TeamApiKeysSectionInner, { team: props.team });
22
+ }
23
+ function TeamApiKeysSectionInner(props) {
24
+ const { t } = useTranslation();
25
+ const [isNewApiKeyDialogOpen, setIsNewApiKeyDialogOpen] = useState(false);
26
+ const [returnedApiKey, setReturnedApiKey] = useState(null);
27
+ const apiKeys = props.team.useApiKeys();
28
+ const CreateDialog = CreateApiKeyDialog;
29
+ const ShowDialog = ShowApiKeyDialog;
30
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
31
+ /* @__PURE__ */ jsx(
32
+ Section,
33
+ {
34
+ title: t("API Keys"),
35
+ description: t("API keys grant programmatic access to your team."),
36
+ children: /* @__PURE__ */ jsx(Button, { onClick: () => setIsNewApiKeyDialogOpen(true), children: t("Create API Key") })
37
+ }
38
+ ),
39
+ /* @__PURE__ */ jsx(ApiKeyTable, { apiKeys }),
40
+ /* @__PURE__ */ jsx(
41
+ CreateDialog,
42
+ {
43
+ open: isNewApiKeyDialogOpen,
44
+ onOpenChange: setIsNewApiKeyDialogOpen,
45
+ onKeyCreated: setReturnedApiKey,
46
+ createApiKey: async (data) => {
47
+ const apiKey = await props.team.createApiKey(data);
48
+ return apiKey;
49
+ }
50
+ }
51
+ ),
52
+ /* @__PURE__ */ jsx(
53
+ ShowDialog,
54
+ {
55
+ apiKey: returnedApiKey,
56
+ onClose: () => setReturnedApiKey(null)
57
+ }
58
+ )
59
+ ] });
60
+ }
61
+ export {
62
+ TeamApiKeysSection
63
+ };
64
+ //# sourceMappingURL=team-api-keys-section.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../src/components-page/account-settings/teams/team-api-keys-section.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\nimport { StackAssertionError } from \"@stackframe/stack-shared/dist/utils/errors\";\nimport { Button } from \"@stackframe/stack-ui\";\nimport { useState } from \"react\";\nimport { CreateApiKeyDialog, ShowApiKeyDialog } from \"../../../components/api-key-dialogs\";\nimport { ApiKeyTable } from \"../../../components/api-key-table\";\nimport { useUser } from \"../../../lib/hooks\";\nimport { TeamApiKeyFirstView } from \"../../../lib/stack-app/api-keys\";\nimport { Team } from \"../../../lib/stack-app/teams\";\nimport { useTranslation } from \"../../../lib/translations\";\nimport { Section } from \"../section\";\n\n\nexport function TeamApiKeysSection(props: { team: Team }) {\n const user = useUser({ or: 'redirect' });\n const team = user.useTeam(props.team.id);\n\n if (!team) {\n throw new StackAssertionError(\"Team not found\");\n }\n\n const manageApiKeysPermission = user.usePermission(props.team, '$manage_api_keys');\n if (!manageApiKeysPermission) {\n return null;\n }\n\n return <TeamApiKeysSectionInner team={props.team} />;\n}\n\nfunction TeamApiKeysSectionInner(props: { team: Team }) {\n const { t } = useTranslation();\n\n const [isNewApiKeyDialogOpen, setIsNewApiKeyDialogOpen] = useState(false);\n const [returnedApiKey, setReturnedApiKey] = useState<TeamApiKeyFirstView | null>(null);\n\n const apiKeys = props.team.useApiKeys();\n\n const CreateDialog = CreateApiKeyDialog<\"team\">;\n const ShowDialog = ShowApiKeyDialog<\"team\">;\n\n return (\n <>\n <Section\n title={t(\"API Keys\")}\n description={t(\"API keys grant programmatic access to your team.\")}\n >\n <Button onClick={() => setIsNewApiKeyDialogOpen(true)}>\n {t(\"Create API Key\")}\n </Button>\n </Section>\n <ApiKeyTable apiKeys={apiKeys} />\n\n <CreateDialog\n open={isNewApiKeyDialogOpen}\n onOpenChange={setIsNewApiKeyDialogOpen}\n onKeyCreated={setReturnedApiKey}\n createApiKey={async (data) => {\n const apiKey = await props.team.createApiKey(data);\n return apiKey;\n }}\n />\n <ShowDialog\n apiKey={returnedApiKey}\n onClose={() => setReturnedApiKey(null)}\n />\n </>\n );\n}\n"],"mappings":";AAIA,SAAS,2BAA2B;AACpC,SAAS,cAAc;AACvB,SAAS,gBAAgB;AACzB,SAAS,oBAAoB,wBAAwB;AACrD,SAAS,mBAAmB;AAC5B,SAAS,eAAe;AAGxB,SAAS,sBAAsB;AAC/B,SAAS,eAAe;AAgBf,SAeL,UAfK,KAeL,YAfK;AAbF,SAAS,mBAAmB,OAAuB;AACxD,QAAM,OAAO,QAAQ,EAAE,IAAI,WAAW,CAAC;AACvC,QAAM,OAAO,KAAK,QAAQ,MAAM,KAAK,EAAE;AAEvC,MAAI,CAAC,MAAM;AACT,UAAM,IAAI,oBAAoB,gBAAgB;AAAA,EAChD;AAEA,QAAM,0BAA0B,KAAK,cAAc,MAAM,MAAM,kBAAkB;AACjF,MAAI,CAAC,yBAAyB;AAC5B,WAAO;AAAA,EACT;AAEA,SAAO,oBAAC,2BAAwB,MAAM,MAAM,MAAM;AACpD;AAEA,SAAS,wBAAwB,OAAuB;AACtD,QAAM,EAAE,EAAE,IAAI,eAAe;AAE7B,QAAM,CAAC,uBAAuB,wBAAwB,IAAI,SAAS,KAAK;AACxE,QAAM,CAAC,gBAAgB,iBAAiB,IAAI,SAAqC,IAAI;AAErF,QAAM,UAAU,MAAM,KAAK,WAAW;AAEtC,QAAM,eAAe;AACrB,QAAM,aAAa;AAEnB,SACE,iCACE;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,EAAE,UAAU;AAAA,QACnB,aAAa,EAAE,kDAAkD;AAAA,QAEjE,8BAAC,UAAO,SAAS,MAAM,yBAAyB,IAAI,GACjD,YAAE,gBAAgB,GACrB;AAAA;AAAA,IACF;AAAA,IACA,oBAAC,eAAY,SAAkB;AAAA,IAE/B;AAAA,MAAC;AAAA;AAAA,QACC,MAAM;AAAA,QACN,cAAc;AAAA,QACd,cAAc;AAAA,QACd,cAAc,OAAO,SAAS;AAC5B,gBAAM,SAAS,MAAM,MAAM,KAAK,aAAa,IAAI;AACjD,iBAAO;AAAA,QACT;AAAA;AAAA,IACF;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC,QAAQ;AAAA,QACR,SAAS,MAAM,kBAAkB,IAAI;AAAA;AAAA,IACvC;AAAA,KACF;AAEJ;","names":[]}
@@ -0,0 +1,67 @@
1
+ // src/components-page/account-settings/teams/team-creation-page.tsx
2
+ import { yupResolver } from "@hookform/resolvers/yup";
3
+ import { yupObject, yupString } from "@stackframe/stack-shared/dist/schema-fields";
4
+ import { runAsynchronouslyWithAlert } from "@stackframe/stack-shared/dist/utils/promises";
5
+ import { Button, Input } from "@stackframe/stack-ui";
6
+ import { useState } from "react";
7
+ import { useForm } from "react-hook-form";
8
+ import { FormWarningText } from "../../../components/elements/form-warning";
9
+ import { MessageCard } from "../../../components/message-cards/message-card";
10
+ import { useStackApp, useUser } from "../../../lib/hooks";
11
+ import { useTranslation } from "../../../lib/translations";
12
+ import { PageLayout } from "../page-layout";
13
+ import { Section } from "../section";
14
+ import { jsx, jsxs } from "react/jsx-runtime";
15
+ function TeamCreationPage() {
16
+ const { t } = useTranslation();
17
+ const teamCreationSchema = yupObject({
18
+ displayName: yupString().defined().nonEmpty(t("Please enter a team name"))
19
+ });
20
+ const { register, handleSubmit, formState: { errors } } = useForm({
21
+ resolver: yupResolver(teamCreationSchema)
22
+ });
23
+ const app = useStackApp();
24
+ const project = app.useProject();
25
+ const user = useUser({ or: "redirect" });
26
+ const navigate = app.useNavigate();
27
+ const [loading, setLoading] = useState(false);
28
+ if (!project.config.clientTeamCreationEnabled) {
29
+ return /* @__PURE__ */ jsx(MessageCard, { title: t("Team creation is not enabled") });
30
+ }
31
+ const onSubmit = async (data) => {
32
+ setLoading(true);
33
+ let team;
34
+ try {
35
+ team = await user.createTeam({ displayName: data.displayName });
36
+ } finally {
37
+ setLoading(false);
38
+ }
39
+ navigate(`#team-${team.id}`);
40
+ };
41
+ return /* @__PURE__ */ jsx(PageLayout, { children: /* @__PURE__ */ jsx(Section, { title: t("Create a Team"), description: t("Enter a display name for your new team"), children: /* @__PURE__ */ jsxs(
42
+ "form",
43
+ {
44
+ onSubmit: (e) => runAsynchronouslyWithAlert(handleSubmit(onSubmit)(e)),
45
+ noValidate: true,
46
+ className: "flex gap-2 flex-col sm:flex-row",
47
+ children: [
48
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col flex-1", children: [
49
+ /* @__PURE__ */ jsx(
50
+ Input,
51
+ {
52
+ id: "displayName",
53
+ type: "text",
54
+ ...register("displayName")
55
+ }
56
+ ),
57
+ /* @__PURE__ */ jsx(FormWarningText, { text: errors.displayName?.message?.toString() })
58
+ ] }),
59
+ /* @__PURE__ */ jsx(Button, { type: "submit", loading, children: t("Create") })
60
+ ]
61
+ }
62
+ ) }) });
63
+ }
64
+ export {
65
+ TeamCreationPage
66
+ };
67
+ //# sourceMappingURL=team-creation-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../src/components-page/account-settings/teams/team-creation-page.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\nimport { yupResolver } from \"@hookform/resolvers/yup\";\nimport { yupObject, yupString } from \"@stackframe/stack-shared/dist/schema-fields\";\nimport { runAsynchronouslyWithAlert } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { Button, Input } from \"@stackframe/stack-ui\";\nimport { useState } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport * as yup from \"yup\";\nimport { FormWarningText } from \"../../../components/elements/form-warning\";\nimport { MessageCard } from \"../../../components/message-cards/message-card\";\nimport { useStackApp, useUser } from \"../../../lib/hooks\";\nimport { useTranslation } from \"../../../lib/translations\";\nimport { PageLayout } from \"../page-layout\";\nimport { Section } from \"../section\";\n\nexport function TeamCreationPage() {\n const { t } = useTranslation();\n\n const teamCreationSchema = yupObject({\n displayName: yupString().defined().nonEmpty(t(\"Please enter a team name\")),\n });\n\n const { register, handleSubmit, formState: { errors } } = useForm({\n resolver: yupResolver(teamCreationSchema)\n });\n const app = useStackApp();\n const project = app.useProject();\n const user = useUser({ or: 'redirect' });\n const navigate = app.useNavigate();\n const [loading, setLoading] = useState(false);\n\n if (!project.config.clientTeamCreationEnabled) {\n return <MessageCard title={t(\"Team creation is not enabled\")} />;\n }\n\n const onSubmit = async (data: yup.InferType<typeof teamCreationSchema>) => {\n setLoading(true);\n\n let team;\n try {\n team = await user.createTeam({ displayName: data.displayName });\n } finally {\n setLoading(false);\n }\n\n navigate(`#team-${team.id}`);\n };\n\n return (\n <PageLayout>\n <Section title={t(\"Create a Team\")} description={t(\"Enter a display name for your new team\")}>\n <form\n onSubmit={e => runAsynchronouslyWithAlert(handleSubmit(onSubmit)(e))}\n noValidate\n className='flex gap-2 flex-col sm:flex-row'\n >\n <div className='flex flex-col flex-1'>\n <Input\n id=\"displayName\"\n type=\"text\"\n {...register(\"displayName\")}\n />\n <FormWarningText text={errors.displayName?.message?.toString()} />\n </div>\n <Button type=\"submit\" loading={loading}>{t(\"Create\")}</Button>\n </form>\n </Section>\n </PageLayout>\n );\n}\n"],"mappings":";AAIA,SAAS,mBAAmB;AAC5B,SAAS,WAAW,iBAAiB;AACrC,SAAS,kCAAkC;AAC3C,SAAS,QAAQ,aAAa;AAC9B,SAAS,gBAAgB;AACzB,SAAS,eAAe;AAExB,SAAS,uBAAuB;AAChC,SAAS,mBAAmB;AAC5B,SAAS,aAAa,eAAe;AACrC,SAAS,sBAAsB;AAC/B,SAAS,kBAAkB;AAC3B,SAAS,eAAe;AAmBb,cAwBD,YAxBC;AAjBJ,SAAS,mBAAmB;AACjC,QAAM,EAAE,EAAE,IAAI,eAAe;AAE7B,QAAM,qBAAqB,UAAU;AAAA,IACnC,aAAa,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,0BAA0B,CAAC;AAAA,EAC3E,CAAC;AAED,QAAM,EAAE,UAAU,cAAc,WAAW,EAAE,OAAO,EAAE,IAAI,QAAQ;AAAA,IAChE,UAAU,YAAY,kBAAkB;AAAA,EAC1C,CAAC;AACD,QAAM,MAAM,YAAY;AACxB,QAAM,UAAU,IAAI,WAAW;AAC/B,QAAM,OAAO,QAAQ,EAAE,IAAI,WAAW,CAAC;AACvC,QAAM,WAAW,IAAI,YAAY;AACjC,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,KAAK;AAE5C,MAAI,CAAC,QAAQ,OAAO,2BAA2B;AAC7C,WAAO,oBAAC,eAAY,OAAO,EAAE,8BAA8B,GAAG;AAAA,EAChE;AAEA,QAAM,WAAW,OAAO,SAAmD;AACzE,eAAW,IAAI;AAEf,QAAI;AACJ,QAAI;AACF,aAAO,MAAM,KAAK,WAAW,EAAE,aAAa,KAAK,YAAY,CAAC;AAAA,IAChE,UAAE;AACA,iBAAW,KAAK;AAAA,IAClB;AAEA,aAAS,SAAS,KAAK,EAAE,EAAE;AAAA,EAC7B;AAEA,SACE,oBAAC,cACC,8BAAC,WAAQ,OAAO,EAAE,eAAe,GAAG,aAAa,EAAE,wCAAwC,GACzF;AAAA,IAAC;AAAA;AAAA,MACC,UAAU,OAAK,2BAA2B,aAAa,QAAQ,EAAE,CAAC,CAAC;AAAA,MACnE,YAAU;AAAA,MACV,WAAU;AAAA,MAEV;AAAA,6BAAC,SAAI,WAAU,wBACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,IAAG;AAAA,cACH,MAAK;AAAA,cACJ,GAAG,SAAS,aAAa;AAAA;AAAA,UAC5B;AAAA,UACA,oBAAC,mBAAgB,MAAM,OAAO,aAAa,SAAS,SAAS,GAAG;AAAA,WAClE;AAAA,QACA,oBAAC,UAAO,MAAK,UAAS,SAAmB,YAAE,QAAQ,GAAE;AAAA;AAAA;AAAA,EACvD,GACF,GACF;AAEJ;","names":[]}
@@ -0,0 +1,32 @@
1
+ // src/components-page/account-settings/teams/team-display-name-section.tsx
2
+ import { useUser } from "../../../lib/hooks";
3
+ import { useTranslation } from "../../../lib/translations";
4
+ import { EditableText } from "../editable-text";
5
+ import { Section } from "../section";
6
+ import { jsx } from "react/jsx-runtime";
7
+ function TeamDisplayNameSection(props) {
8
+ const { t } = useTranslation();
9
+ const user = useUser({ or: "redirect" });
10
+ const updateTeamPermission = user.usePermission(props.team, "$update_team");
11
+ if (!updateTeamPermission) {
12
+ return null;
13
+ }
14
+ return /* @__PURE__ */ jsx(
15
+ Section,
16
+ {
17
+ title: t("Team display name"),
18
+ description: t("Change the display name of your team"),
19
+ children: /* @__PURE__ */ jsx(
20
+ EditableText,
21
+ {
22
+ value: props.team.displayName,
23
+ onSave: async (newDisplayName) => await props.team.update({ displayName: newDisplayName })
24
+ }
25
+ )
26
+ }
27
+ );
28
+ }
29
+ export {
30
+ TeamDisplayNameSection
31
+ };
32
+ //# sourceMappingURL=team-display-name-section.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../src/components-page/account-settings/teams/team-display-name-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 TeamDisplayNameSection(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 display name\")}\n description={t(\"Change the display name of your team\")}\n >\n <EditableText\n value={props.team.displayName}\n onSave={async (newDisplayName) => await props.team.update({ displayName: newDisplayName })}\n />\n </Section>\n );\n}\n"],"mappings":";AAKA,SAAS,eAAe;AACxB,SAAS,sBAAsB;AAC/B,SAAS,oBAAoB;AAC7B,SAAS,eAAe;AAgBlB;AAdC,SAAS,uBAAuB,OAAuB;AAC5D,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,mBAAmB;AAAA,MAC5B,aAAa,EAAE,sCAAsC;AAAA,MAErD;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,MAAM,KAAK;AAAA,UAClB,QAAQ,OAAO,mBAAmB,MAAM,MAAM,KAAK,OAAO,EAAE,aAAa,eAAe,CAAC;AAAA;AAAA,MAC3F;AAAA;AAAA,EACF;AAEJ;","names":[]}
@@ -0,0 +1,106 @@
1
+ // src/components-page/account-settings/teams/team-member-invitation-section.tsx
2
+ import { yupResolver } from "@hookform/resolvers/yup";
3
+ import { strictEmailSchema, yupObject } from "@stackframe/stack-shared/dist/schema-fields";
4
+ import { runAsynchronouslyWithAlert } from "@stackframe/stack-shared/dist/utils/promises";
5
+ import { Button, Input, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Typography } from "@stackframe/stack-ui";
6
+ import { Trash } from "lucide-react";
7
+ import { useEffect, useState } from "react";
8
+ import { useForm } from "react-hook-form";
9
+ import { FormWarningText } from "../../../components/elements/form-warning";
10
+ import { useUser } from "../../../lib/hooks";
11
+ import { useTranslation } from "../../../lib/translations";
12
+ import { Section } from "../section";
13
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
14
+ function TeamMemberInvitationSection(props) {
15
+ const user = useUser({ or: "redirect" });
16
+ const inviteMemberPermission = user.usePermission(props.team, "$invite_members");
17
+ if (!inviteMemberPermission) {
18
+ return null;
19
+ }
20
+ return /* @__PURE__ */ jsx(MemberInvitationSectionInner, { team: props.team });
21
+ }
22
+ function MemberInvitationsSectionInvitationsList(props) {
23
+ const user = useUser({ or: "redirect" });
24
+ const { t } = useTranslation();
25
+ const invitationsToShow = props.team.useInvitations();
26
+ const removeMemberPermission = user.usePermission(props.team, "$remove_members");
27
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(Table, { className: "mt-6", children: [
28
+ /* @__PURE__ */ jsx(TableHeader, { children: /* @__PURE__ */ jsxs(TableRow, { children: [
29
+ /* @__PURE__ */ jsx(TableHead, { className: "w-[200px]", children: t("Outstanding invitations") }),
30
+ /* @__PURE__ */ jsx(TableHead, { className: "w-[60px]", children: t("Expires") }),
31
+ /* @__PURE__ */ jsx(TableHead, { className: "w-[36px] max-w-[36px]" })
32
+ ] }) }),
33
+ /* @__PURE__ */ jsxs(TableBody, { children: [
34
+ invitationsToShow.map((invitation, i) => /* @__PURE__ */ jsxs(TableRow, { children: [
35
+ /* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsx(Typography, { children: invitation.recipientEmail }) }),
36
+ /* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsx(Typography, { variant: "secondary", children: invitation.expiresAt.toLocaleString() }) }),
37
+ /* @__PURE__ */ jsx(TableCell, { align: "right", className: "max-w-[36px]", children: removeMemberPermission && /* @__PURE__ */ jsx(Button, { onClick: async () => await invitation.revoke(), size: "icon", variant: "ghost", children: /* @__PURE__ */ jsx(Trash, { className: "w-4 h-4" }) }) })
38
+ ] }, invitation.id)),
39
+ invitationsToShow.length === 0 && /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(TableCell, { colSpan: 3, children: /* @__PURE__ */ jsx(Typography, { variant: "secondary", children: t("No outstanding invitations") }) }) })
40
+ ] })
41
+ ] }) });
42
+ }
43
+ function MemberInvitationSectionInner(props) {
44
+ const user = useUser({ or: "redirect" });
45
+ const { t } = useTranslation();
46
+ const readMemberPermission = user.usePermission(props.team, "$read_members");
47
+ const invitationSchema = yupObject({
48
+ email: strictEmailSchema(t("Please enter a valid email address")).defined().nonEmpty(t("Please enter an email address"))
49
+ });
50
+ const { register, handleSubmit, formState: { errors }, watch } = useForm({
51
+ resolver: yupResolver(invitationSchema)
52
+ });
53
+ const [loading, setLoading] = useState(false);
54
+ const [invitedEmail, setInvitedEmail] = useState(null);
55
+ const onSubmit = async (data) => {
56
+ setLoading(true);
57
+ try {
58
+ await props.team.inviteUser({ email: data.email });
59
+ setInvitedEmail(data.email);
60
+ } finally {
61
+ setLoading(false);
62
+ }
63
+ };
64
+ useEffect(() => {
65
+ setInvitedEmail(null);
66
+ }, [watch("email")]);
67
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
68
+ /* @__PURE__ */ jsx(
69
+ Section,
70
+ {
71
+ title: t("Invite member"),
72
+ description: t("Invite a user to your team through email"),
73
+ children: /* @__PURE__ */ jsxs(
74
+ "form",
75
+ {
76
+ onSubmit: (e) => runAsynchronouslyWithAlert(handleSubmit(onSubmit)(e)),
77
+ noValidate: true,
78
+ className: "w-full",
79
+ children: [
80
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4 sm:flex-row w-full", children: [
81
+ /* @__PURE__ */ jsx(
82
+ Input,
83
+ {
84
+ placeholder: t("Email"),
85
+ ...register("email")
86
+ }
87
+ ),
88
+ /* @__PURE__ */ jsx(Button, { type: "submit", loading, children: t("Invite User") })
89
+ ] }),
90
+ /* @__PURE__ */ jsx(FormWarningText, { text: errors.email?.message?.toString() }),
91
+ invitedEmail && /* @__PURE__ */ jsxs(Typography, { type: "label", variant: "secondary", children: [
92
+ "Invited ",
93
+ invitedEmail
94
+ ] })
95
+ ]
96
+ }
97
+ )
98
+ }
99
+ ),
100
+ readMemberPermission && /* @__PURE__ */ jsx(MemberInvitationsSectionInvitationsList, { team: props.team })
101
+ ] });
102
+ }
103
+ export {
104
+ TeamMemberInvitationSection
105
+ };
106
+ //# sourceMappingURL=team-member-invitation-section.js.map