@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.
- package/CHANGELOG.md +28 -0
- package/dist/components-page/account-settings/active-sessions/active-sessions-page.js +151 -0
- package/dist/components-page/account-settings/active-sessions/active-sessions-page.js.map +1 -0
- package/dist/components-page/account-settings/api-keys/api-keys-page.js +70 -0
- package/dist/components-page/account-settings/api-keys/api-keys-page.js.map +1 -0
- package/dist/components-page/account-settings/editable-text.js +75 -0
- package/dist/components-page/account-settings/editable-text.js.map +1 -0
- package/dist/components-page/account-settings/email-and-auth/email-and-auth-page.js +46 -0
- package/dist/components-page/account-settings/email-and-auth/email-and-auth-page.js.map +1 -0
- package/dist/components-page/account-settings/email-and-auth/emails-section.js +188 -0
- package/dist/components-page/account-settings/email-and-auth/emails-section.js.map +1 -0
- package/dist/components-page/account-settings/email-and-auth/mfa-section.js +146 -0
- package/dist/components-page/account-settings/email-and-auth/mfa-section.js.map +1 -0
- package/dist/components-page/account-settings/email-and-auth/otp-section.js +89 -0
- package/dist/components-page/account-settings/email-and-auth/otp-section.js.map +1 -0
- package/dist/components-page/account-settings/email-and-auth/passkey-section.js +92 -0
- package/dist/components-page/account-settings/email-and-auth/passkey-section.js.map +1 -0
- package/dist/components-page/account-settings/email-and-auth/password-section.js +181 -0
- package/dist/components-page/account-settings/email-and-auth/password-section.js.map +1 -0
- package/dist/components-page/account-settings/page-layout.js +34 -0
- package/dist/components-page/account-settings/page-layout.js.map +1 -0
- package/dist/components-page/account-settings/profile-page/profile-page.js +75 -0
- package/dist/components-page/account-settings/profile-page/profile-page.js.map +1 -0
- package/dist/components-page/account-settings/section.js +44 -0
- package/dist/components-page/account-settings/section.js.map +1 -0
- package/dist/components-page/account-settings/settings/delete-account-section.js +87 -0
- package/dist/components-page/account-settings/settings/delete-account-section.js.map +1 -0
- package/dist/components-page/account-settings/settings/settings-page.js +40 -0
- package/dist/components-page/account-settings/settings/settings-page.js.map +1 -0
- package/dist/components-page/account-settings/settings/sign-out-section.js +54 -0
- package/dist/components-page/account-settings/settings/sign-out-section.js.map +1 -0
- package/dist/components-page/account-settings/teams/leave-team-section.js +79 -0
- package/dist/components-page/account-settings/teams/leave-team-section.js.map +1 -0
- package/dist/components-page/account-settings/teams/team-api-keys-section.js +89 -0
- package/dist/components-page/account-settings/teams/team-api-keys-section.js.map +1 -0
- package/dist/components-page/account-settings/teams/team-creation-page.js +92 -0
- package/dist/components-page/account-settings/teams/team-creation-page.js.map +1 -0
- package/dist/components-page/account-settings/teams/team-display-name-section.js +57 -0
- package/dist/components-page/account-settings/teams/team-display-name-section.js.map +1 -0
- package/dist/components-page/account-settings/teams/team-member-invitation-section.js +131 -0
- package/dist/components-page/account-settings/teams/team-member-invitation-section.js.map +1 -0
- package/dist/components-page/account-settings/teams/team-member-list-section.js +61 -0
- package/dist/components-page/account-settings/teams/team-member-list-section.js.map +1 -0
- package/dist/components-page/account-settings/teams/team-page.js +50 -0
- package/dist/components-page/account-settings/teams/team-page.js.map +1 -0
- package/dist/components-page/account-settings/teams/team-profile-image-section.js +59 -0
- package/dist/components-page/account-settings/teams/team-profile-image-section.js.map +1 -0
- package/dist/components-page/account-settings/teams/team-profile-user-section.js +56 -0
- package/dist/components-page/account-settings/teams/team-profile-user-section.js.map +1 -0
- package/dist/components-page/account-settings.js +16 -1173
- package/dist/components-page/account-settings.js.map +1 -1
- package/dist/components-page/section.js +6 -0
- package/dist/components-page/section.js.map +1 -0
- package/dist/esm/components-page/account-settings/active-sessions/active-sessions-page.js +126 -0
- package/dist/esm/components-page/account-settings/active-sessions/active-sessions-page.js.map +1 -0
- package/dist/esm/components-page/account-settings/api-keys/api-keys-page.js +45 -0
- package/dist/esm/components-page/account-settings/api-keys/api-keys-page.js.map +1 -0
- package/dist/esm/components-page/account-settings/editable-text.js +50 -0
- package/dist/esm/components-page/account-settings/editable-text.js.map +1 -0
- package/dist/esm/components-page/account-settings/email-and-auth/email-and-auth-page.js +21 -0
- package/dist/esm/components-page/account-settings/email-and-auth/email-and-auth-page.js.map +1 -0
- package/dist/esm/components-page/account-settings/email-and-auth/emails-section.js +163 -0
- package/dist/esm/components-page/account-settings/email-and-auth/emails-section.js.map +1 -0
- package/dist/esm/components-page/account-settings/email-and-auth/mfa-section.js +111 -0
- package/dist/esm/components-page/account-settings/email-and-auth/mfa-section.js.map +1 -0
- package/dist/esm/components-page/account-settings/email-and-auth/otp-section.js +64 -0
- package/dist/esm/components-page/account-settings/email-and-auth/otp-section.js.map +1 -0
- package/dist/esm/components-page/account-settings/email-and-auth/passkey-section.js +67 -0
- package/dist/esm/components-page/account-settings/email-and-auth/passkey-section.js.map +1 -0
- package/dist/esm/components-page/account-settings/email-and-auth/password-section.js +146 -0
- package/dist/esm/components-page/account-settings/email-and-auth/password-section.js.map +1 -0
- package/dist/esm/components-page/account-settings/page-layout.js +9 -0
- package/dist/esm/components-page/account-settings/page-layout.js.map +1 -0
- package/dist/esm/components-page/account-settings/profile-page/profile-page.js +50 -0
- package/dist/esm/components-page/account-settings/profile-page/profile-page.js.map +1 -0
- package/dist/esm/components-page/account-settings/section.js +19 -0
- package/dist/esm/components-page/account-settings/section.js.map +1 -0
- package/dist/esm/components-page/account-settings/settings/delete-account-section.js +62 -0
- package/dist/esm/components-page/account-settings/settings/delete-account-section.js.map +1 -0
- package/dist/esm/components-page/account-settings/settings/settings-page.js +15 -0
- package/dist/esm/components-page/account-settings/settings/settings-page.js.map +1 -0
- package/dist/esm/components-page/account-settings/settings/sign-out-section.js +29 -0
- package/dist/esm/components-page/account-settings/settings/sign-out-section.js.map +1 -0
- package/dist/esm/components-page/account-settings/teams/leave-team-section.js +54 -0
- package/dist/esm/components-page/account-settings/teams/leave-team-section.js.map +1 -0
- package/dist/esm/components-page/account-settings/teams/team-api-keys-section.js +64 -0
- package/dist/esm/components-page/account-settings/teams/team-api-keys-section.js.map +1 -0
- package/dist/esm/components-page/account-settings/teams/team-creation-page.js +67 -0
- package/dist/esm/components-page/account-settings/teams/team-creation-page.js.map +1 -0
- package/dist/esm/components-page/account-settings/teams/team-display-name-section.js +32 -0
- package/dist/esm/components-page/account-settings/teams/team-display-name-section.js.map +1 -0
- package/dist/esm/components-page/account-settings/teams/team-member-invitation-section.js +106 -0
- package/dist/esm/components-page/account-settings/teams/team-member-invitation-section.js.map +1 -0
- package/dist/esm/components-page/account-settings/teams/team-member-list-section.js +36 -0
- package/dist/esm/components-page/account-settings/teams/team-member-list-section.js.map +1 -0
- package/dist/esm/components-page/account-settings/teams/team-page.js +25 -0
- package/dist/esm/components-page/account-settings/teams/team-page.js.map +1 -0
- package/dist/esm/components-page/account-settings/teams/team-profile-image-section.js +34 -0
- package/dist/esm/components-page/account-settings/teams/team-profile-image-section.js.map +1 -0
- package/dist/esm/components-page/account-settings/teams/team-profile-user-section.js +31 -0
- package/dist/esm/components-page/account-settings/teams/team-profile-user-section.js.map +1 -0
- package/dist/esm/components-page/account-settings.js +14 -1158
- package/dist/esm/components-page/account-settings.js.map +1 -1
- package/dist/esm/components-page/section.js +4 -0
- package/dist/esm/components-page/section.js.map +1 -0
- package/dist/esm/lib/stack-app/apps/implementations/admin-app-impl.js.map +1 -1
- package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.js +79 -0
- package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.js.map +1 -1
- package/dist/esm/lib/stack-app/apps/implementations/common.js +1 -1
- package/dist/esm/lib/stack-app/apps/implementations/common.js.map +1 -1
- package/dist/esm/lib/stack-app/apps/interfaces/client-app.js.map +1 -1
- package/dist/esm/lib/stack-app/projects/index.js.map +1 -1
- package/dist/esm/lib/translations.js +0 -1
- package/dist/esm/lib/translations.js.map +1 -1
- package/dist/index.d.mts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/lib/stack-app/apps/implementations/admin-app-impl.js.map +1 -1
- package/dist/lib/stack-app/apps/implementations/client-app-impl.js +79 -0
- package/dist/lib/stack-app/apps/implementations/client-app-impl.js.map +1 -1
- package/dist/lib/stack-app/apps/implementations/common.js +1 -1
- package/dist/lib/stack-app/apps/implementations/common.js.map +1 -1
- package/dist/lib/stack-app/apps/interfaces/client-app.js.map +1 -1
- package/dist/lib/stack-app/projects/index.js.map +1 -1
- package/dist/lib/translations.js +0 -1
- package/dist/lib/translations.js.map +1 -1
- 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":"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","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
|