@stackframe/stack 2.5.17 → 2.5.19

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 (108) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/components/credential-sign-in.js +4 -1
  3. package/dist/components/credential-sign-in.js.map +1 -1
  4. package/dist/components/elements/sidebar-layout.d.mts +21 -0
  5. package/dist/components/elements/sidebar-layout.d.ts +21 -0
  6. package/dist/components/elements/sidebar-layout.js +125 -0
  7. package/dist/components/elements/sidebar-layout.js.map +1 -0
  8. package/dist/components/elements/user-avatar.d.mts +5 -11
  9. package/dist/components/elements/user-avatar.d.ts +5 -11
  10. package/dist/components/elements/user-avatar.js.map +1 -1
  11. package/dist/components/message-cards/predefined-message-card.d.mts +1 -1
  12. package/dist/components/message-cards/predefined-message-card.d.ts +1 -1
  13. package/dist/components/message-cards/predefined-message-card.js +8 -0
  14. package/dist/components/message-cards/predefined-message-card.js.map +1 -1
  15. package/dist/components/selected-team-switcher.d.mts +1 -0
  16. package/dist/components/selected-team-switcher.d.ts +1 -0
  17. package/dist/components/selected-team-switcher.js +35 -5
  18. package/dist/components/selected-team-switcher.js.map +1 -1
  19. package/dist/components-page/account-settings.js +123 -31
  20. package/dist/components-page/account-settings.js.map +1 -1
  21. package/dist/components-page/auth-page.d.mts +1 -0
  22. package/dist/components-page/auth-page.d.ts +1 -0
  23. package/dist/components-page/auth-page.js +4 -1
  24. package/dist/components-page/auth-page.js.map +1 -1
  25. package/dist/components-page/forgot-password.d.mts +4 -1
  26. package/dist/components-page/forgot-password.d.ts +4 -1
  27. package/dist/components-page/forgot-password.js +55 -7
  28. package/dist/components-page/forgot-password.js.map +1 -1
  29. package/dist/components-page/password-reset.d.mts +6 -2
  30. package/dist/components-page/password-reset.d.ts +6 -2
  31. package/dist/components-page/password-reset.js +100 -8
  32. package/dist/components-page/password-reset.js.map +1 -1
  33. package/dist/components-page/stack-handler.d.mts +1 -0
  34. package/dist/components-page/stack-handler.d.ts +1 -0
  35. package/dist/components-page/stack-handler.js +32 -6
  36. package/dist/components-page/stack-handler.js.map +1 -1
  37. package/dist/{components/password-reset-form.d.mts → components-page/team-creation.d.mts} +2 -3
  38. package/dist/{components/password-reset-form.d.ts → components-page/team-creation.d.ts} +2 -3
  39. package/dist/components-page/team-creation.js +92 -0
  40. package/dist/components-page/team-creation.js.map +1 -0
  41. package/dist/components-page/team-invitation.d.mts +8 -0
  42. package/dist/components-page/team-invitation.d.ts +8 -0
  43. package/dist/components-page/team-invitation.js +141 -0
  44. package/dist/components-page/team-invitation.js.map +1 -0
  45. package/dist/components-page/team-settings.d.mts +8 -0
  46. package/dist/components-page/team-settings.d.ts +8 -0
  47. package/dist/components-page/team-settings.js +139 -0
  48. package/dist/components-page/team-settings.js.map +1 -0
  49. package/dist/esm/components/credential-sign-in.js +4 -1
  50. package/dist/esm/components/credential-sign-in.js.map +1 -1
  51. package/dist/esm/components/elements/sidebar-layout.js +90 -0
  52. package/dist/esm/components/elements/sidebar-layout.js.map +1 -0
  53. package/dist/esm/components/elements/user-avatar.js.map +1 -1
  54. package/dist/esm/components/message-cards/predefined-message-card.js +8 -0
  55. package/dist/esm/components/message-cards/predefined-message-card.js.map +1 -1
  56. package/dist/esm/components/selected-team-switcher.js +39 -7
  57. package/dist/esm/components/selected-team-switcher.js.map +1 -1
  58. package/dist/esm/components-page/account-settings.js +114 -32
  59. package/dist/esm/components-page/account-settings.js.map +1 -1
  60. package/dist/esm/components-page/auth-page.js +4 -1
  61. package/dist/esm/components-page/auth-page.js.map +1 -1
  62. package/dist/esm/components-page/forgot-password.js +52 -5
  63. package/dist/esm/components-page/forgot-password.js.map +1 -1
  64. package/dist/esm/components-page/password-reset.js +101 -9
  65. package/dist/esm/components-page/password-reset.js.map +1 -1
  66. package/dist/esm/components-page/stack-handler.js +32 -6
  67. package/dist/esm/components-page/stack-handler.js.map +1 -1
  68. package/dist/esm/components-page/team-creation.js +68 -0
  69. package/dist/esm/components-page/team-creation.js.map +1 -0
  70. package/dist/esm/components-page/team-invitation.js +107 -0
  71. package/dist/esm/components-page/team-invitation.js.map +1 -0
  72. package/dist/esm/components-page/team-settings.js +115 -0
  73. package/dist/esm/components-page/team-settings.js.map +1 -0
  74. package/dist/esm/generated/global-css.js +1 -1
  75. package/dist/esm/generated/global-css.js.map +1 -1
  76. package/dist/esm/lib/auth.js +5 -1
  77. package/dist/esm/lib/auth.js.map +1 -1
  78. package/dist/esm/lib/stack-app.js +272 -25
  79. package/dist/esm/lib/stack-app.js.map +1 -1
  80. package/dist/generated/global-css.d.mts +1 -1
  81. package/dist/generated/global-css.d.ts +1 -1
  82. package/dist/generated/global-css.js +1 -1
  83. package/dist/generated/global-css.js.map +1 -1
  84. package/dist/index.d.mts +2 -1
  85. package/dist/index.d.ts +2 -1
  86. package/dist/lib/auth.js +5 -1
  87. package/dist/lib/auth.js.map +1 -1
  88. package/dist/lib/hooks.d.mts +1 -0
  89. package/dist/lib/hooks.d.ts +1 -0
  90. package/dist/lib/stack-app.d.mts +64 -5
  91. package/dist/lib/stack-app.d.ts +64 -5
  92. package/dist/lib/stack-app.js +272 -25
  93. package/dist/lib/stack-app.js.map +1 -1
  94. package/dist/providers/stack-provider-client.d.mts +1 -0
  95. package/dist/providers/stack-provider-client.d.ts +1 -0
  96. package/dist/providers/stack-provider.d.mts +1 -0
  97. package/dist/providers/stack-provider.d.ts +1 -0
  98. package/package.json +10 -6
  99. package/dist/components/forgot-password-form.d.mts +0 -7
  100. package/dist/components/forgot-password-form.d.ts +0 -7
  101. package/dist/components/forgot-password-form.js +0 -83
  102. package/dist/components/forgot-password-form.js.map +0 -1
  103. package/dist/components/password-reset-form.js +0 -135
  104. package/dist/components/password-reset-form.js.map +0 -1
  105. package/dist/esm/components/forgot-password-form.js +0 -59
  106. package/dist/esm/components/forgot-password-form.js.map +0 -1
  107. package/dist/esm/components/password-reset-form.js +0 -105
  108. package/dist/esm/components/password-reset-form.js.map +0 -1
@@ -1,16 +1,19 @@
1
1
  // src/components-page/stack-handler.tsx
2
+ import { getRelativePart } from "@stackframe/stack-shared/dist/utils/urls";
2
3
  import { RedirectType, notFound, redirect } from "next/navigation";
3
- import { EmailVerification } from "./email-verification";
4
4
  import { AuthPage } from "..";
5
5
  import { MessageCard } from "../components/message-cards/message-card";
6
- import { SignOut } from "./sign-out";
7
- import { ForgotPassword } from "./forgot-password";
8
- import { OAuthCallback } from "./oauth-callback";
9
6
  import { AccountSettings } from "./account-settings";
10
- import { MagicLinkCallback } from "./magic-link-callback";
7
+ import { EmailVerification } from "./email-verification";
11
8
  import { ErrorPage } from "./error-page";
9
+ import { ForgotPassword } from "./forgot-password";
10
+ import { MagicLinkCallback } from "./magic-link-callback";
11
+ import { OAuthCallback } from "./oauth-callback";
12
12
  import { PasswordReset } from "./password-reset";
13
- import { getRelativePart } from "@stackframe/stack-shared/dist/utils/urls";
13
+ import { SignOut } from "./sign-out";
14
+ import { TeamInvitation } from "./team-invitation";
15
+ import { TeamSettings } from "./team-settings";
16
+ import { TeamCreation } from "./team-creation";
14
17
  import { jsx } from "react/jsx-runtime";
15
18
  async function StackHandler({
16
19
  app,
@@ -44,9 +47,20 @@ async function StackHandler({
44
47
  oauthCallback: "oauth-callback",
45
48
  accountSettings: "account-settings",
46
49
  magicLinkCallback: "magic-link-callback",
50
+ teamInvitation: "team-invitation",
51
+ teamCreation: "team-creation",
47
52
  error: "error"
48
53
  };
49
54
  const path = stack.join("/");
55
+ if (/team-settings\/[a-zA-Z0-9-]+/.test(path)) {
56
+ const teamId = path.split("/")[1];
57
+ const user = await app.getUser();
58
+ const team = await user?.getTeam(teamId);
59
+ if (!team) {
60
+ return notFound();
61
+ }
62
+ return /* @__PURE__ */ jsx(TeamSettings, { fullPage, teamId });
63
+ }
50
64
  switch (path) {
51
65
  case availablePaths.signIn: {
52
66
  redirectIfNotHandler("signIn");
@@ -84,6 +98,18 @@ async function StackHandler({
84
98
  redirectIfNotHandler("magicLinkCallback");
85
99
  return /* @__PURE__ */ jsx(MagicLinkCallback, { searchParams, fullPage });
86
100
  }
101
+ case availablePaths.teamInvitation: {
102
+ redirectIfNotHandler("teamInvitation");
103
+ return /* @__PURE__ */ jsx(TeamInvitation, { searchParams, fullPage });
104
+ }
105
+ case availablePaths.teamCreation: {
106
+ const project = await app.getProject();
107
+ if (!project.config.clientTeamCreationEnabled) {
108
+ return notFound();
109
+ }
110
+ redirectIfNotHandler("teamCreation");
111
+ return /* @__PURE__ */ jsx(TeamCreation, { fullPage });
112
+ }
87
113
  case availablePaths.error: {
88
114
  return /* @__PURE__ */ jsx(ErrorPage, { searchParams, fullPage });
89
115
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components-page/stack-handler.tsx"],"sourcesContent":["import { SignUp } from \"./sign-up\";\nimport { SignIn } from \"./sign-in\";\nimport { RedirectType, notFound, redirect } from 'next/navigation';\nimport { EmailVerification } from \"./email-verification\";\nimport { AuthPage, StackServerApp } from \"..\";\nimport { MessageCard } from \"../components/message-cards/message-card\";\nimport { HandlerUrls } from \"../lib/stack-app\";\nimport { SignOut } from \"./sign-out\";\nimport { ForgotPassword } from \"./forgot-password\";\nimport { OAuthCallback } from \"./oauth-callback\";\nimport { AccountSettings } from \"./account-settings\";\nimport { MagicLinkCallback } from \"./magic-link-callback\";\nimport { ErrorPage } from \"./error-page\";\nimport { PasswordReset } from \"./password-reset\";\nimport { getRelativePart } from \"@stackframe/stack-shared/dist/utils/urls\";\n\nexport default async function StackHandler<HasTokenStore extends boolean>({\n app,\n params: { stack } = {},\n searchParams = {},\n fullPage = false,\n}: {\n app: StackServerApp<HasTokenStore>,\n params?: { stack?: string[] },\n searchParams?: Record<string, string>,\n fullPage?: boolean,\n}) {\n if (!stack) {\n return (\n <MessageCard title=\"Invalid Stack Handler Setup\" fullPage={fullPage}>\n <p>Can't use Stack handler at this location. Make sure that the file is in a folder called [...stack].</p>\n </MessageCard>\n );\n }\n\n function redirectIfNotHandler(name: keyof HandlerUrls) {\n const url = app.urls[name];\n const handlerUrl = app.urls.handler;\n\n if (url !== handlerUrl && url.startsWith(handlerUrl + \"/\")) {\n // don't redirect if the url is a handler url\n return;\n }\n\n const urlObj = new URL(url, \"http://example.com\");\n for (const [key, value] of Object.entries(searchParams)) {\n urlObj.searchParams.set(key, value);\n }\n\n redirect(getRelativePart(urlObj), RedirectType.replace);\n };\n\n const availablePaths = {\n signIn: 'sign-in',\n signUp: 'sign-up',\n emailVerification: 'email-verification',\n passwordReset: 'password-reset',\n forgotPassword: 'forgot-password',\n signOut: 'sign-out',\n oauthCallback: 'oauth-callback',\n accountSettings: 'account-settings',\n magicLinkCallback: 'magic-link-callback',\n error: 'error',\n };\n\n const path = stack.join('/');\n switch (path) {\n case availablePaths.signIn: {\n redirectIfNotHandler('signIn');\n return <AuthPage fullPage={fullPage} type='sign-in' automaticRedirect />;\n }\n case availablePaths.signUp: {\n redirectIfNotHandler('signUp');\n return <AuthPage fullPage={fullPage} type='sign-up' automaticRedirect />;\n }\n case availablePaths.emailVerification: {\n redirectIfNotHandler('emailVerification');\n return <EmailVerification searchParams={searchParams} fullPage={fullPage} />;\n }\n case availablePaths.passwordReset: {\n redirectIfNotHandler('passwordReset');\n return <PasswordReset searchParams={searchParams} fullPage={fullPage} />;\n }\n case availablePaths.forgotPassword: {\n redirectIfNotHandler('forgotPassword');\n return <ForgotPassword fullPage={fullPage} />;\n }\n case availablePaths.signOut: {\n redirectIfNotHandler('signOut');\n return <SignOut fullPage={fullPage} />;\n }\n case availablePaths.oauthCallback: {\n redirectIfNotHandler('oauthCallback');\n return <OAuthCallback fullPage={fullPage} />;\n }\n case availablePaths.accountSettings: {\n redirectIfNotHandler('accountSettings');\n return <AccountSettings fullPage={fullPage} />;\n }\n case availablePaths.magicLinkCallback: {\n redirectIfNotHandler('magicLinkCallback');\n return <MagicLinkCallback searchParams={searchParams} fullPage={fullPage} />;\n }\n case availablePaths.error: {\n return <ErrorPage searchParams={searchParams} fullPage={fullPage} />;\n }\n default: {\n for (const [key, value] of Object.entries(availablePaths)) {\n if (path === value.replaceAll('-', '')) {\n redirect(`${app.urls.handler}/${value}`, RedirectType.replace);\n }\n }\n return notFound();\n }\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/components-page/stack-handler.tsx"],"sourcesContent":["import { getRelativePart } from \"@stackframe/stack-shared/dist/utils/urls\";\nimport { RedirectType, notFound, redirect } from 'next/navigation';\nimport { AuthPage, StackServerApp } from \"..\";\nimport { MessageCard } from \"../components/message-cards/message-card\";\nimport { HandlerUrls } from \"../lib/stack-app\";\nimport { AccountSettings } from \"./account-settings\";\nimport { EmailVerification } from \"./email-verification\";\nimport { ErrorPage } from \"./error-page\";\nimport { ForgotPassword } from \"./forgot-password\";\nimport { MagicLinkCallback } from \"./magic-link-callback\";\nimport { OAuthCallback } from \"./oauth-callback\";\nimport { PasswordReset } from \"./password-reset\";\nimport { SignOut } from \"./sign-out\";\nimport { TeamInvitation } from \"./team-invitation\";\nimport { TeamSettings } from \"./team-settings\";\nimport { TeamCreation } from \"./team-creation\";\n\nexport default async function StackHandler<HasTokenStore extends boolean>({\n app,\n params: { stack } = {},\n searchParams = {},\n fullPage = false,\n}: {\n app: StackServerApp<HasTokenStore>,\n params?: { stack?: string[] },\n searchParams?: Record<string, string>,\n fullPage?: boolean,\n}) {\n if (!stack) {\n return (\n <MessageCard title=\"Invalid Stack Handler Setup\" fullPage={fullPage}>\n <p>Can't use Stack handler at this location. Make sure that the file is in a folder called [...stack].</p>\n </MessageCard>\n );\n }\n\n function redirectIfNotHandler(name: keyof HandlerUrls) {\n const url = app.urls[name];\n const handlerUrl = app.urls.handler;\n\n if (url !== handlerUrl && url.startsWith(handlerUrl + \"/\")) {\n // don't redirect if the url is a handler url\n return;\n }\n\n const urlObj = new URL(url, \"http://example.com\");\n for (const [key, value] of Object.entries(searchParams)) {\n urlObj.searchParams.set(key, value);\n }\n\n redirect(getRelativePart(urlObj), RedirectType.replace);\n };\n\n const availablePaths = {\n signIn: 'sign-in',\n signUp: 'sign-up',\n emailVerification: 'email-verification',\n passwordReset: 'password-reset',\n forgotPassword: 'forgot-password',\n signOut: 'sign-out',\n oauthCallback: 'oauth-callback',\n accountSettings: 'account-settings',\n magicLinkCallback: 'magic-link-callback',\n teamInvitation: 'team-invitation',\n teamCreation: 'team-creation',\n error: 'error',\n };\n\n const path = stack.join('/');\n\n if (/team-settings\\/[a-zA-Z0-9-]+/.test(path)) {\n const teamId = path.split('/')[1];\n const user = await app.getUser();\n const team = await user?.getTeam(teamId);\n\n if (!team) {\n return notFound();\n }\n\n return <TeamSettings fullPage={fullPage} teamId={teamId} />;\n }\n\n\n switch (path) {\n case availablePaths.signIn: {\n redirectIfNotHandler('signIn');\n return <AuthPage fullPage={fullPage} type='sign-in' automaticRedirect />;\n }\n case availablePaths.signUp: {\n redirectIfNotHandler('signUp');\n return <AuthPage fullPage={fullPage} type='sign-up' automaticRedirect />;\n }\n case availablePaths.emailVerification: {\n redirectIfNotHandler('emailVerification');\n return <EmailVerification searchParams={searchParams} fullPage={fullPage} />;\n }\n case availablePaths.passwordReset: {\n redirectIfNotHandler('passwordReset');\n return <PasswordReset searchParams={searchParams} fullPage={fullPage} />;\n }\n case availablePaths.forgotPassword: {\n redirectIfNotHandler('forgotPassword');\n return <ForgotPassword fullPage={fullPage} />;\n }\n case availablePaths.signOut: {\n redirectIfNotHandler('signOut');\n return <SignOut fullPage={fullPage} />;\n }\n case availablePaths.oauthCallback: {\n redirectIfNotHandler('oauthCallback');\n return <OAuthCallback fullPage={fullPage} />;\n }\n case availablePaths.accountSettings: {\n redirectIfNotHandler('accountSettings');\n return <AccountSettings fullPage={fullPage} />;\n }\n case availablePaths.magicLinkCallback: {\n redirectIfNotHandler('magicLinkCallback');\n return <MagicLinkCallback searchParams={searchParams} fullPage={fullPage} />;\n }\n case availablePaths.teamInvitation: {\n redirectIfNotHandler('teamInvitation');\n return <TeamInvitation searchParams={searchParams} fullPage={fullPage} />;\n }\n case availablePaths.teamCreation: {\n const project = await app.getProject();\n if (!project.config.clientTeamCreationEnabled) {\n return notFound();\n }\n\n redirectIfNotHandler('teamCreation');\n return <TeamCreation fullPage={fullPage} />;\n }\n case availablePaths.error: {\n return <ErrorPage searchParams={searchParams} fullPage={fullPage} />;\n }\n default: {\n for (const [key, value] of Object.entries(availablePaths)) {\n if (path === value.replaceAll('-', '')) {\n redirect(`${app.urls.handler}/${value}`, RedirectType.replace);\n }\n }\n return notFound();\n }\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,68 @@
1
+ "use client";
2
+ "use client";
3
+
4
+ // src/components-page/team-creation.tsx
5
+ import { yupResolver } from "@hookform/resolvers/yup";
6
+ import { yupObject, yupString } from "@stackframe/stack-shared/dist/schema-fields";
7
+ import { runAsynchronously } from "@stackframe/stack-shared/dist/utils/promises";
8
+ import { Button, Input, Label, Typography } from "@stackframe/stack-ui";
9
+ import { useState } from "react";
10
+ import { useForm } from "react-hook-form";
11
+ import { MessageCard, useStackApp, useUser } from "..";
12
+ import { FormWarningText } from "../components/elements/form-warning";
13
+ import { MaybeFullPage } from "../components/elements/maybe-full-page";
14
+ import { useRouter } from "next/navigation";
15
+ import { jsx, jsxs } from "react/jsx-runtime";
16
+ var schema = yupObject({
17
+ displayName: yupString().required("Please enter a team name")
18
+ });
19
+ function TeamCreation(props) {
20
+ const { register, handleSubmit, formState: { errors } } = useForm({
21
+ resolver: yupResolver(schema)
22
+ });
23
+ const app = useStackApp();
24
+ const project = app.useProject();
25
+ const user = useUser({ or: "redirect" });
26
+ const [loading, setLoading] = useState(false);
27
+ const router = useRouter();
28
+ if (!project.config.clientTeamCreationEnabled) {
29
+ return /* @__PURE__ */ jsx(MessageCard, { title: "Team creation is not enabled" });
30
+ }
31
+ const onSubmit = async (data) => {
32
+ setLoading(true);
33
+ try {
34
+ const team = await user.createTeam({ displayName: data.displayName });
35
+ router.push(`${app.urls.handler}/team-settings/${team.id}`);
36
+ } finally {
37
+ setLoading(false);
38
+ }
39
+ };
40
+ return /* @__PURE__ */ jsx(MaybeFullPage, { fullPage: props.fullPage, children: /* @__PURE__ */ jsxs("div", { className: "stack-scope flex flex-col items-stretch", children: [
41
+ /* @__PURE__ */ jsx("div", { className: "text-center mb-6", children: /* @__PURE__ */ jsx(Typography, { type: "h2", children: "Create a Team" }) }),
42
+ /* @__PURE__ */ jsxs(
43
+ "form",
44
+ {
45
+ className: "flex flex-col items-stretch stack-scope",
46
+ onSubmit: (e) => runAsynchronously(handleSubmit(onSubmit)(e)),
47
+ noValidate: true,
48
+ children: [
49
+ /* @__PURE__ */ jsx(Label, { htmlFor: "email", className: "mb-1", children: "Display name" }),
50
+ /* @__PURE__ */ jsx(
51
+ Input,
52
+ {
53
+ id: "email",
54
+ type: "email",
55
+ ...register("displayName")
56
+ }
57
+ ),
58
+ /* @__PURE__ */ jsx(FormWarningText, { text: errors.displayName?.message?.toString() }),
59
+ /* @__PURE__ */ jsx(Button, { type: "submit", className: "mt-6", loading, children: "Create" })
60
+ ]
61
+ }
62
+ )
63
+ ] }) });
64
+ }
65
+ export {
66
+ TeamCreation
67
+ };
68
+ //# sourceMappingURL=team-creation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components-page/team-creation.tsx"],"sourcesContent":["'use client';\n\nimport { yupResolver } from \"@hookform/resolvers/yup\";\nimport { yupObject, yupString } from \"@stackframe/stack-shared/dist/schema-fields\";\nimport { runAsynchronously } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { Button, Input, Label, Typography } from \"@stackframe/stack-ui\";\nimport { useState } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport * as yup from \"yup\";\nimport { MessageCard, useStackApp, useUser } from \"..\";\nimport { FormWarningText } from \"../components/elements/form-warning\";\nimport { MaybeFullPage } from \"../components/elements/maybe-full-page\";\nimport { useRouter } from \"next/navigation\";\n\nconst schema = yupObject({\n displayName: yupString().required('Please enter a team name'),\n});\n\nexport function TeamCreation(props: { fullPage?: boolean }) {\n const { register, handleSubmit, formState: { errors } } = useForm({\n resolver: yupResolver(schema)\n });\n const app = useStackApp();\n const project = app.useProject();\n const user = useUser({ or: 'redirect' });\n const [loading, setLoading] = useState(false);\n const router = useRouter();\n\n if (!project.config.clientTeamCreationEnabled) {\n return <MessageCard title='Team creation is not enabled' />;\n }\n\n const onSubmit = async (data: yup.InferType<typeof schema>) => {\n setLoading(true);\n\n try {\n const team = await user.createTeam({ displayName: data.displayName });\n router.push(`${app.urls.handler}/team-settings/${team.id}`);\n } finally {\n setLoading(false);\n }\n };\n\n return (\n <MaybeFullPage fullPage={props.fullPage}>\n <div className='stack-scope flex flex-col items-stretch'>\n <div className=\"text-center mb-6\">\n <Typography type='h2'>\n Create a Team\n </Typography>\n </div>\n <form\n className=\"flex flex-col items-stretch stack-scope\"\n onSubmit={e => runAsynchronously(handleSubmit(onSubmit)(e))}\n noValidate\n >\n <Label htmlFor=\"email\" className=\"mb-1\">Display name</Label>\n <Input\n id=\"email\"\n type=\"email\"\n {...register('displayName')}\n />\n <FormWarningText text={errors.displayName?.message?.toString()} />\n\n <Button type=\"submit\" className=\"mt-6\" loading={loading}>\n Create\n </Button>\n </form>\n </div>\n </MaybeFullPage>\n );\n}"],"mappings":";;;AAEA,SAAS,mBAAmB;AAC5B,SAAS,WAAW,iBAAiB;AACrC,SAAS,yBAAyB;AAClC,SAAS,QAAQ,OAAO,OAAO,kBAAkB;AACjD,SAAS,gBAAgB;AACzB,SAAS,eAAe;AAExB,SAAS,aAAa,aAAa,eAAe;AAClD,SAAS,uBAAuB;AAChC,SAAS,qBAAqB;AAC9B,SAAS,iBAAiB;AAiBf,cAsBH,YAtBG;AAfX,IAAM,SAAS,UAAU;AAAA,EACvB,aAAa,UAAU,EAAE,SAAS,0BAA0B;AAC9D,CAAC;AAEM,SAAS,aAAa,OAA+B;AAC1D,QAAM,EAAE,UAAU,cAAc,WAAW,EAAE,OAAO,EAAE,IAAI,QAAQ;AAAA,IAChE,UAAU,YAAY,MAAM;AAAA,EAC9B,CAAC;AACD,QAAM,MAAM,YAAY;AACxB,QAAM,UAAU,IAAI,WAAW;AAC/B,QAAM,OAAO,QAAQ,EAAE,IAAI,WAAW,CAAC;AACvC,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,KAAK;AAC5C,QAAM,SAAS,UAAU;AAEzB,MAAI,CAAC,QAAQ,OAAO,2BAA2B;AAC7C,WAAO,oBAAC,eAAY,OAAM,gCAA+B;AAAA,EAC3D;AAEA,QAAM,WAAW,OAAO,SAAuC;AAC7D,eAAW,IAAI;AAEf,QAAI;AACF,YAAM,OAAO,MAAM,KAAK,WAAW,EAAE,aAAa,KAAK,YAAY,CAAC;AACpE,aAAO,KAAK,GAAG,IAAI,KAAK,OAAO,kBAAkB,KAAK,EAAE,EAAE;AAAA,IAC5D,UAAE;AACA,iBAAW,KAAK;AAAA,IAClB;AAAA,EACF;AAEA,SACE,oBAAC,iBAAc,UAAU,MAAM,UAC7B,+BAAC,SAAI,WAAU,2CACb;AAAA,wBAAC,SAAI,WAAU,oBACb,8BAAC,cAAW,MAAK,MAAK,2BAEtB,GACF;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QACV,UAAU,OAAK,kBAAkB,aAAa,QAAQ,EAAE,CAAC,CAAC;AAAA,QAC1D,YAAU;AAAA,QAEV;AAAA,8BAAC,SAAM,SAAQ,SAAQ,WAAU,QAAO,0BAAY;AAAA,UACpD;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,UAEhE,oBAAC,UAAO,MAAK,UAAS,WAAU,QAAO,SAAkB,oBAEzD;AAAA;AAAA;AAAA,IACF;AAAA,KACF,GACF;AAEJ;","names":[]}
@@ -0,0 +1,107 @@
1
+ "use client";
2
+ "use client";
3
+
4
+ // src/components-page/team-invitation.tsx
5
+ import { KnownErrors } from "@stackframe/stack-shared";
6
+ import { cacheFunction } from "@stackframe/stack-shared/dist/utils/caches";
7
+ import { runAsynchronouslyWithAlert } from "@stackframe/stack-shared/dist/utils/promises";
8
+ import { Typography } from "@stackframe/stack-ui";
9
+ import React from "react";
10
+ import { MessageCard, useStackApp, useUser } from "..";
11
+ import { PredefinedMessageCard } from "../components/message-cards/predefined-message-card";
12
+ import { jsx, jsxs } from "react/jsx-runtime";
13
+ var cachedVerifyInvitation = cacheFunction(async (stackApp, code) => {
14
+ return await stackApp.verifyTeamInvitationCode(code);
15
+ });
16
+ var cachedGetInvitationDetails = cacheFunction(async (stackApp, code) => {
17
+ return await stackApp.getTeamInvitationDetails(code);
18
+ });
19
+ function TeamInvitationInner(props) {
20
+ const stackApp = useStackApp();
21
+ const [success, setSuccess] = React.useState(false);
22
+ const [errorMessage, setErrorMessage] = React.useState(null);
23
+ const details = React.use(cachedGetInvitationDetails(stackApp, props.searchParams.code || ""));
24
+ if (errorMessage || details.status === "error") {
25
+ return /* @__PURE__ */ jsx(PredefinedMessageCard, { type: "unknownError", fullPage: props.fullPage });
26
+ }
27
+ if (success) {
28
+ return /* @__PURE__ */ jsx(
29
+ MessageCard,
30
+ {
31
+ title: "Team invitation",
32
+ fullPage: props.fullPage,
33
+ primaryButtonText: "Go to home",
34
+ primaryAction: () => stackApp.redirectToHome(),
35
+ children: /* @__PURE__ */ jsxs(Typography, { children: [
36
+ "You have successfully joined ",
37
+ details.data.teamDisplayName
38
+ ] })
39
+ }
40
+ );
41
+ }
42
+ return /* @__PURE__ */ jsx(
43
+ MessageCard,
44
+ {
45
+ title: "Team invitation",
46
+ fullPage: props.fullPage,
47
+ primaryButtonText: "Join",
48
+ primaryAction: () => runAsynchronouslyWithAlert(async () => {
49
+ const result = await stackApp.acceptTeamInvitation(props.searchParams.code || "");
50
+ if (result.status === "error") {
51
+ setErrorMessage(result.error.message);
52
+ } else {
53
+ setSuccess(true);
54
+ }
55
+ }),
56
+ secondaryButtonText: "Ignore",
57
+ secondaryAction: () => stackApp.redirectToHome(),
58
+ children: /* @__PURE__ */ jsxs(Typography, { children: [
59
+ "You are invited to join ",
60
+ details.data.teamDisplayName
61
+ ] })
62
+ }
63
+ );
64
+ }
65
+ function TeamInvitation({ fullPage = false, searchParams }) {
66
+ const user = useUser();
67
+ const stackApp = useStackApp();
68
+ const invalidJsx = /* @__PURE__ */ jsx(MessageCard, { title: "Invalid Team Invitation Link", fullPage, children: /* @__PURE__ */ jsx(Typography, { children: "Please double check if you have the correct team invitation link." }) });
69
+ const expiredJsx = /* @__PURE__ */ jsx(MessageCard, { title: "Expired Team Invitation Link", fullPage, children: /* @__PURE__ */ jsx(Typography, { children: "Your team invitation link has expired. Please request a new team invitation link " }) });
70
+ const usedJsx = /* @__PURE__ */ jsx(MessageCard, { title: "Used Team Invitation Link", fullPage, children: /* @__PURE__ */ jsx(Typography, { children: "This team invitation link has already been used." }) });
71
+ const code = searchParams.code;
72
+ if (!code) {
73
+ return invalidJsx;
74
+ }
75
+ if (!user) {
76
+ return /* @__PURE__ */ jsx(
77
+ MessageCard,
78
+ {
79
+ title: "Team invitation",
80
+ fullPage,
81
+ primaryButtonText: "Go to sign in",
82
+ primaryAction: () => stackApp.redirectToSignIn(),
83
+ secondaryButtonText: "Cancel",
84
+ secondaryAction: () => stackApp.redirectToHome(),
85
+ children: /* @__PURE__ */ jsx(Typography, { children: "Sign in or create an account to join the team." })
86
+ }
87
+ );
88
+ }
89
+ const verificationResult = React.use(cachedVerifyInvitation(stackApp, searchParams.code || ""));
90
+ if (verificationResult.status === "error") {
91
+ const error = verificationResult.error;
92
+ if (error instanceof KnownErrors.VerificationCodeNotFound) {
93
+ return invalidJsx;
94
+ } else if (error instanceof KnownErrors.VerificationCodeExpired) {
95
+ return expiredJsx;
96
+ } else if (error instanceof KnownErrors.VerificationCodeAlreadyUsed) {
97
+ return usedJsx;
98
+ } else {
99
+ throw error;
100
+ }
101
+ }
102
+ return /* @__PURE__ */ jsx(TeamInvitationInner, { fullPage, searchParams });
103
+ }
104
+ export {
105
+ TeamInvitation
106
+ };
107
+ //# sourceMappingURL=team-invitation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components-page/team-invitation.tsx"],"sourcesContent":["'use client';\n\nimport { KnownErrors } from \"@stackframe/stack-shared\";\nimport { cacheFunction } from \"@stackframe/stack-shared/dist/utils/caches\";\nimport { runAsynchronouslyWithAlert } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { Typography } from \"@stackframe/stack-ui\";\nimport React from \"react\";\nimport { MessageCard, StackClientApp, useStackApp, useUser } from \"..\";\nimport { PredefinedMessageCard } from \"../components/message-cards/predefined-message-card\";\n\nconst cachedVerifyInvitation = cacheFunction(async (stackApp: StackClientApp<true>, code: string) => {\n return await stackApp.verifyTeamInvitationCode(code);\n});\n\nconst cachedGetInvitationDetails = cacheFunction(async (stackApp: StackClientApp<true>, code: string) => {\n return await stackApp.getTeamInvitationDetails(code);\n});\n\nfunction TeamInvitationInner(props: { fullPage?: boolean, searchParams: Record<string, string> }) {\n const stackApp = useStackApp();\n const [success, setSuccess] = React.useState(false);\n const [errorMessage, setErrorMessage] = React.useState<string | null>(null);\n const details = React.use(cachedGetInvitationDetails(stackApp, props.searchParams.code || ''));\n\n if (errorMessage || details.status === 'error') {\n return (\n <PredefinedMessageCard type=\"unknownError\" fullPage={props.fullPage} />\n );\n }\n\n if (success) {\n return (\n <MessageCard\n title=\"Team invitation\"\n fullPage={props.fullPage}\n primaryButtonText=\"Go to home\"\n primaryAction={() => stackApp.redirectToHome()}\n >\n <Typography>You have successfully joined {details.data.teamDisplayName}</Typography>\n </MessageCard>\n );\n }\n\n\n return (\n <MessageCard\n title=\"Team invitation\"\n fullPage={props.fullPage}\n primaryButtonText=\"Join\"\n primaryAction={() => runAsynchronouslyWithAlert(async () => {\n const result = await stackApp.acceptTeamInvitation(props.searchParams.code || '');\n if (result.status === 'error') {\n setErrorMessage(result.error.message);\n } else {\n setSuccess(true);\n }\n })}\n secondaryButtonText=\"Ignore\"\n secondaryAction={() => stackApp.redirectToHome()}\n >\n <Typography>You are invited to join {details.data.teamDisplayName}</Typography>\n </MessageCard>\n );\n}\n\nexport function TeamInvitation({ fullPage=false, searchParams }: { fullPage?: boolean, searchParams: Record<string, string> }) {\n const user = useUser();\n const stackApp = useStackApp();\n\n const invalidJsx = (\n <MessageCard title=\"Invalid Team Invitation Link\" fullPage={fullPage}>\n <Typography>Please double check if you have the correct team invitation link.</Typography>\n </MessageCard>\n );\n\n const expiredJsx = (\n <MessageCard title=\"Expired Team Invitation Link\" fullPage={fullPage}>\n <Typography>Your team invitation link has expired. Please request a new team invitation link </Typography>\n </MessageCard>\n );\n\n const usedJsx = (\n <MessageCard title=\"Used Team Invitation Link\" fullPage={fullPage}>\n <Typography>This team invitation link has already been used.</Typography>\n </MessageCard>\n );\n\n const code = searchParams.code;\n if (!code) {\n return invalidJsx;\n }\n\n if (!user) {\n return (\n <MessageCard\n title=\"Team invitation\"\n fullPage={fullPage}\n primaryButtonText=\"Go to sign in\"\n primaryAction={() => stackApp.redirectToSignIn()}\n secondaryButtonText=\"Cancel\"\n secondaryAction={() => stackApp.redirectToHome()}\n >\n <Typography>Sign in or create an account to join the team.</Typography>\n </MessageCard>\n );\n }\n\n const verificationResult = React.use(cachedVerifyInvitation(stackApp, searchParams.code || ''));\n\n if (verificationResult.status === 'error') {\n const error = verificationResult.error;\n if (error instanceof KnownErrors.VerificationCodeNotFound) {\n return invalidJsx;\n } else if (error instanceof KnownErrors.VerificationCodeExpired) {\n return expiredJsx;\n } else if (error instanceof KnownErrors.VerificationCodeAlreadyUsed) {\n return usedJsx;\n } else {\n throw error;\n }\n }\n\n return <TeamInvitationInner fullPage={fullPage} searchParams={searchParams} />;\n};\n"],"mappings":"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","names":[]}
@@ -0,0 +1,115 @@
1
+ "use client";
2
+ "use client";
3
+
4
+ // src/components-page/team-settings.tsx
5
+ import { ActionDialog, Button, Container, EditableText, Input, Label, SimpleTooltip, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Typography } from "@stackframe/stack-ui";
6
+ import { Contact, Info, Users } from "lucide-react";
7
+ import { useEffect, useState } from "react";
8
+ import { MessageCard, useStackApp, useUser } from "..";
9
+ import { SidebarLayout } from "../components/elements/sidebar-layout";
10
+ import { UserAvatar } from "../components/elements/user-avatar";
11
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
12
+ function TeamSettings(props) {
13
+ const user = useUser({ or: "redirect" });
14
+ const team = user.useTeam(props.teamId);
15
+ if (!team) {
16
+ return /* @__PURE__ */ jsx(MessageCard, { title: "Team not found" });
17
+ }
18
+ const inner = /* @__PURE__ */ jsx(
19
+ SidebarLayout,
20
+ {
21
+ items: [
22
+ { title: "My Profile", content: profileSettings({ team }), icon: Contact, description: `Your profile in the team "${team.displayName}"` },
23
+ { title: "Members", content: membersSettings({ team }), icon: Users },
24
+ { title: "Team Info", content: managementSettings({ team }), icon: Info }
25
+ // { title: 'Settings', content: userSettings({ team }), icon: Settings },
26
+ ].filter(({ content }) => content),
27
+ title: "Team Settings"
28
+ }
29
+ );
30
+ if (props.fullPage) {
31
+ return /* @__PURE__ */ jsx(Container, { size: 800, className: "stack-scope", children: inner });
32
+ } else {
33
+ return inner;
34
+ }
35
+ }
36
+ function managementSettings(props) {
37
+ const user = useUser({ or: "redirect" });
38
+ const updateTeamPermission = user.usePermission(props.team, "$update_team");
39
+ if (!updateTeamPermission) {
40
+ return null;
41
+ }
42
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs("div", { children: [
43
+ /* @__PURE__ */ jsx(Label, { children: "Team display name" }),
44
+ /* @__PURE__ */ jsx(EditableText, { value: props.team.displayName, onSave: () => {
45
+ } })
46
+ ] }) });
47
+ }
48
+ function profileSettings(props) {
49
+ const user = useUser({ or: "redirect" });
50
+ const profile = user.useTeamProfile(props.team);
51
+ return /* @__PURE__ */ jsx("div", { className: "flex flex-col", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
52
+ /* @__PURE__ */ jsxs(Label, { className: "flex gap-2", children: [
53
+ "Display name ",
54
+ /* @__PURE__ */ jsx(SimpleTooltip, { tooltip: "This overwrites your user display name in the account setting", type: "info" })
55
+ ] }),
56
+ /* @__PURE__ */ jsx(
57
+ EditableText,
58
+ {
59
+ value: profile.displayName || "",
60
+ onSave: async (newDisplayName) => {
61
+ await profile.update({ displayName: newDisplayName });
62
+ }
63
+ }
64
+ )
65
+ ] }) });
66
+ }
67
+ function membersSettings(props) {
68
+ const [removeModalOpen, setRemoveModalOpen] = useState(false);
69
+ const user = useUser({ or: "redirect" });
70
+ const removeMemberPermission = user.usePermission(props.team, "$remove_members");
71
+ const readMemberPermission = user.usePermission(props.team, "$read_members");
72
+ const inviteMemberPermission = user.usePermission(props.team, "$invite_members");
73
+ const [email, setEmail] = useState("");
74
+ const [invited, setInvited] = useState(false);
75
+ if (!readMemberPermission && !inviteMemberPermission) {
76
+ return null;
77
+ }
78
+ const users = props.team.useUsers();
79
+ useEffect(() => {
80
+ if (invited && email) {
81
+ setInvited(false);
82
+ }
83
+ }, [email]);
84
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-8", children: [
85
+ inviteMemberPermission && /* @__PURE__ */ jsxs("div", { children: [
86
+ /* @__PURE__ */ jsx(Label, { children: "Invite a user to team" }),
87
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 md:flex-row", children: [
88
+ /* @__PURE__ */ jsx(Input, { placeholder: "Email", value: email, onChange: (e) => setEmail(e.target.value) }),
89
+ /* @__PURE__ */ jsx(Button, { onClick: async () => {
90
+ await props.team.inviteUser({ email });
91
+ setEmail("");
92
+ setInvited(true);
93
+ }, children: "Invite" })
94
+ ] }),
95
+ invited && /* @__PURE__ */ jsx(Typography, { type: "label", variant: "secondary", children: "User invited." })
96
+ ] }),
97
+ readMemberPermission && /* @__PURE__ */ jsxs("div", { children: [
98
+ /* @__PURE__ */ jsx(Label, { children: "Members" }),
99
+ /* @__PURE__ */ jsxs(Table, { children: [
100
+ /* @__PURE__ */ jsx(TableHeader, { children: /* @__PURE__ */ jsxs(TableRow, { children: [
101
+ /* @__PURE__ */ jsx(TableHead, { className: "w-[100px]", children: "User" }),
102
+ /* @__PURE__ */ jsx(TableHead, { className: "w-[200px]", children: "Name" })
103
+ ] }) }),
104
+ /* @__PURE__ */ jsx(TableBody, { children: users.map(({ id, teamProfile }, i) => /* @__PURE__ */ jsxs(TableRow, { children: [
105
+ /* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsx(UserAvatar, { user: teamProfile }) }),
106
+ /* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsx(Typography, { children: teamProfile.displayName }) })
107
+ ] }, id)) })
108
+ ] })
109
+ ] })
110
+ ] }) });
111
+ }
112
+ export {
113
+ TeamSettings
114
+ };
115
+ //# sourceMappingURL=team-settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components-page/team-settings.tsx"],"sourcesContent":["'use client';\n\nimport { ActionCell, ActionDialog, Button, Container, EditableText, Input, Label, SimpleTooltip, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Typography } from \"@stackframe/stack-ui\";\nimport { Contact, Info, Settings, Users } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\nimport { MessageCard, Team, useStackApp, useUser } from \"..\";\nimport { SidebarLayout } from \"../components/elements/sidebar-layout\";\nimport { UserAvatar } from \"../components/elements/user-avatar\";\n\nexport function TeamSettings(props: { fullPage?: boolean, teamId: string }) {\n const user = useUser({ or: 'redirect' });\n const team = user.useTeam(props.teamId);\n\n if (!team) {\n return <MessageCard title='Team not found' />;\n }\n\n\n const inner = <SidebarLayout\n items={[\n { title: 'My Profile', content: profileSettings({ team }), icon: Contact, description: `Your profile in the team \"${team.displayName}\"` },\n { title: 'Members', content: membersSettings({ team }), icon: Users },\n { title: 'Team Info', content: managementSettings({ team }), icon: Info },\n // { title: 'Settings', content: userSettings({ team }), icon: Settings },\n ].filter(({ content }) => content as any)}\n title='Team Settings'\n />;\n\n if (props.fullPage) {\n return (\n <Container size={800} className='stack-scope'>\n {inner}\n </Container>\n );\n } else {\n return inner;\n }\n}\n\nfunction managementSettings(props: { team: Team }) {\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 <>\n <div>\n <Label>Team display name</Label>\n <EditableText value={props.team.displayName} onSave={() => {}}/>\n </div>\n </>\n );\n}\n\nfunction profileSettings(props: { team: Team }) {\n const user = useUser({ or: 'redirect' });\n const profile = user.useTeamProfile(props.team);\n\n return (\n <div className=\"flex flex-col\">\n <div className=\"flex flex-col\">\n <Label className=\"flex gap-2\">Display name <SimpleTooltip tooltip=\"This overwrites your user display name in the account setting\" type='info'/></Label>\n <EditableText\n value={profile.displayName || ''}\n onSave={async (newDisplayName) => {\n await profile.update({ displayName: newDisplayName });\n }}/>\n </div>\n </div>\n );\n}\n\nfunction userSettings(props: { team: Team }) {\n const app = useStackApp();\n const user = useUser({ or: 'redirect' });\n\n return (\n <div>\n <div>\n <Button\n variant='secondary'\n onClick={async () => {\n await user.leaveTeam(props.team);\n await app.redirectToHome();\n }}\n >\n Leave team\n </Button>\n </div>\n </div>\n );\n}\n\nfunction RemoveMemberDialog(props: {\n open?: boolean,\n onOpenChange?: (open: boolean) => void,\n}) {\n return (\n <ActionDialog\n open={props.open}\n onOpenChange={props.onOpenChange}\n title=\"Delete domain\"\n danger\n okButton={{\n label: \"Delete\",\n onClick: async () => {\n }\n }}\n cancelButton\n >\n <Typography>\n Do you really want to remove from the team?\n </Typography>\n </ActionDialog>\n );\n}\n\nfunction membersSettings(props: { team: Team }) {\n const [removeModalOpen, setRemoveModalOpen] = useState(false);\n const user = useUser({ or: 'redirect' });\n const removeMemberPermission = user.usePermission(props.team, '$remove_members');\n const readMemberPermission = user.usePermission(props.team, '$read_members');\n const inviteMemberPermission = user.usePermission(props.team, '$invite_members');\n const [email, setEmail] = useState('');\n const [invited, setInvited] = useState(false);\n\n if (!readMemberPermission && !inviteMemberPermission) {\n return null;\n }\n\n const users = props.team.useUsers();\n\n useEffect(() => {\n if (invited && email) {\n setInvited(false);\n }\n }, [email]);\n\n return (\n <>\n <div className=\"flex flex-col gap-8\">\n {inviteMemberPermission &&\n <div>\n <Label>Invite a user to team</Label>\n <div className=\"flex flex-col gap-2 md:flex-row\">\n <Input placeholder=\"Email\" value={email} onChange={e => setEmail(e.target.value)}/>\n <Button onClick={async () => {\n await props.team.inviteUser({ email });\n setEmail('');\n setInvited(true);\n }}>Invite</Button>\n </div>\n {invited && <Typography type='label' variant='secondary'>User invited.</Typography>}\n </div>}\n {readMemberPermission &&\n <div>\n <Label>Members</Label>\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead className=\"w-[100px]\">User</TableHead>\n <TableHead className=\"w-[200px]\">Name</TableHead>\n {/* {removeMemberPermission && <TableHead className=\"w-[100px]\">Actions</TableHead>} */}\n </TableRow>\n </TableHeader>\n <TableBody>\n {users.map(({ id, teamProfile }, i) => (\n <TableRow key={id}>\n <TableCell>\n <UserAvatar user={teamProfile}/>\n </TableCell>\n <TableCell>\n <Typography>{teamProfile.displayName}</Typography>\n </TableCell>\n {/* {removeMemberPermission && <TableCell>\n <ActionCell items={[\n { item: 'Remove', onClick: () => setRemoveModalOpen(true), danger: true },\n ]}/>\n <RemoveMemberDialog open={removeModalOpen} onOpenChange={setRemoveModalOpen} />\n </TableCell>} */}\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>}\n </div>\n </>\n );\n}"],"mappings":"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","names":[]}