@stackframe/stack 2.6.10 → 2.6.11

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 CHANGED
@@ -1,5 +1,15 @@
1
1
  # @stackframe/stack
2
2
 
3
+ ## 2.6.11
4
+
5
+ ### Patch Changes
6
+
7
+ - fixed account settings bugs
8
+ - Updated dependencies
9
+ - @stackframe/stack-shared@2.6.11
10
+ - @stackframe/stack-sc@2.6.11
11
+ - @stackframe/stack-ui@2.6.11
12
+
3
13
  ## 2.6.10
4
14
 
5
15
  ### Patch Changes
@@ -25,18 +25,21 @@ __export(sidebar_layout_exports, {
25
25
  SidebarLayout: () => SidebarLayout
26
26
  });
27
27
  module.exports = __toCommonJS(sidebar_layout_exports);
28
+ var import_use_hash = require("@stackframe/stack-shared/dist/hooks/use-hash");
28
29
  var import_stack_ui = require("@stackframe/stack-ui");
29
30
  var import_lucide_react = require("lucide-react");
30
31
  var import_navigation = require("next/navigation");
31
- var import_use_hash = require("@stackframe/stack-shared/dist/hooks/use-hash");
32
+ var import_react = require("react");
32
33
  var import_jsx_runtime = require("react/jsx-runtime");
33
34
  function SidebarLayout(props) {
34
35
  const router = (0, import_navigation.useRouter)();
35
36
  const hash = (0, import_use_hash.useHash)();
36
37
  const selectedIndex = props.items.findIndex((item) => item.id && item.id === hash);
37
- if (selectedIndex === -1) {
38
- router.push("#" + props.items[0].id);
39
- }
38
+ (0, import_react.useEffect)(() => {
39
+ if (selectedIndex === -1) {
40
+ router.push("#" + props.items[0].id);
41
+ }
42
+ }, [hash]);
40
43
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
41
44
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: (0, import_stack_ui.cn)("hidden sm:flex stack-scope h-full", props.className), children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DesktopLayout, { items: props.items, title: props.title, selectedIndex }) }),
42
45
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: (0, import_stack_ui.cn)("sm:hidden stack-scope h-full", props.className), children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MobileLayout, { items: props.items, title: props.title, selectedIndex }) })
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/elements/sidebar-layout.tsx"],"sourcesContent":["'use client';\n\nimport { Button, Typography, cn } from '@stackframe/stack-ui';\nimport { LucideIcon, XIcon } from 'lucide-react';\nimport { usePathname, useRouter } from 'next/navigation';\nimport React, { ReactNode } from 'react';\nimport { useHash } from '@stackframe/stack-shared/dist/hooks/use-hash';\n\nexport type SidebarItem = {\n title: React.ReactNode,\n type: 'item' | 'divider',\n description?: React.ReactNode,\n id?: string,\n icon?: LucideIcon,\n content?: React.ReactNode,\n contentTitle?: React.ReactNode,\n}\n\nexport function SidebarLayout(props: { items: SidebarItem[], title?: ReactNode, className?: string }) {\n const router = useRouter();\n const hash = useHash();\n\n const selectedIndex = props.items.findIndex(item => item.id && (item.id === hash));\n if (selectedIndex === -1) {\n router.push('#' + props.items[0].id);\n }\n\n return (\n <>\n <div className={cn(\"hidden sm:flex stack-scope h-full\", props.className)}>\n <DesktopLayout items={props.items} title={props.title} selectedIndex={selectedIndex} />\n </div>\n <div className={cn(\"sm:hidden stack-scope h-full\", props.className)}>\n <MobileLayout items={props.items} title={props.title} selectedIndex={selectedIndex} />\n </div>\n </>\n );\n}\n\nfunction Items(props: { items: SidebarItem[], selectedIndex: number }) {\n const router = useRouter();\n\n return props.items.map((item, index) => (\n item.type === 'item' ?\n <Button\n key={index}\n variant='ghost'\n size='sm'\n className={cn(\n props.selectedIndex === index && \"bg-muted\",\n \"justify-start text-md text-zinc-800 dark:text-zinc-300 px-2 text-left\",\n )}\n onClick={() => {\n if (item.id) {\n router.push('#' + item.id);\n }\n }}\n >\n {item.icon && <item.icon className=\"mr-2 h-4 w-4\" />}\n {item.title}\n </Button> :\n <Typography key={index}>\n {item.title}\n </Typography>\n ));\n\n}\n\nfunction DesktopLayout(props: { items: SidebarItem[], title?: ReactNode, selectedIndex: number }) {\n const selectedItem = props.items[props.selectedIndex === -1 ? 0 : props.selectedIndex];\n\n return (\n <div className=\"stack-scope flex w-full h-full max-w-full relative\">\n <div className=\"flex max-w-[200px] min-w-[200px] border-r flex-col items-stretch gap-2 p-2 overflow-y-auto\">\n {props.title && <div className='mb-2 ml-2'>\n <Typography type='h2' className=\"text-lg font-semibold text-zinc-800 dark:text-zinc-300\">{props.title}</Typography>\n </div>}\n\n <Items items={props.items} selectedIndex={props.selectedIndex} />\n </div>\n <div className=\"flex-1 w-0 flex justify-center gap-4 py-2 px-4\">\n <div className='flex flex-col max-w-[800px] w-[800px]'>\n <div className='mt-4 mb-6'>\n <Typography type='h4' className='font-semibold'>{selectedItem.title}</Typography>\n {selectedItem.description && <Typography variant='secondary' type='label'>{selectedItem.description}</Typography>}\n </div>\n <div className='flex-1'>\n {selectedItem.content}\n </div>\n </div>\n </div>\n </div>\n );\n}\n\nfunction MobileLayout(props: { items: SidebarItem[], title?: ReactNode, selectedIndex: number }) {\n const selectedItem = props.items[props.selectedIndex];\n const router = useRouter();\n\n if (props.selectedIndex === -1) {\n return (\n <div className=\"flex flex-col gap-2 p-2\">\n {props.title && <div className='mb-2 ml-2'>\n <Typography type='h2' className=\"text-lg font-semibold text-zinc-800 dark:text-zinc-300\">{props.title}</Typography>\n </div>}\n\n <Items items={props.items} selectedIndex={props.selectedIndex} />\n </div>\n );\n } else {\n return (\n <div className=\"flex-1 flex flex-col gap-4 py-2 px-4\">\n <div className='flex flex-col'>\n <div className='flex justify-between'>\n <Typography type='h4' className='font-semibold'>{selectedItem.title}</Typography>\n <Button\n variant='ghost'\n size='icon'\n onClick={() => { router.push('#'); }}\n >\n <XIcon className='h-5 w-5' />\n </Button>\n </div>\n {selectedItem.description && <Typography variant='secondary' type='label'>{selectedItem.description}</Typography>}\n </div>\n <div className='flex-1'>\n {selectedItem.content}\n </div>\n </div>\n );\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/components/elements/sidebar-layout.tsx"],"sourcesContent":["'use client';\n\nimport { useHash } from '@stackframe/stack-shared/dist/hooks/use-hash';\nimport { Button, Typography, cn } from '@stackframe/stack-ui';\nimport { LucideIcon, XIcon } from 'lucide-react';\nimport { useRouter } from 'next/navigation';\nimport React, { ReactNode, useEffect } from 'react';\n\nexport type SidebarItem = {\n title: React.ReactNode,\n type: 'item' | 'divider',\n description?: React.ReactNode,\n id?: string,\n icon?: LucideIcon,\n content?: React.ReactNode,\n contentTitle?: React.ReactNode,\n}\n\nexport function SidebarLayout(props: { items: SidebarItem[], title?: ReactNode, className?: string }) {\n const router = useRouter();\n const hash = useHash();\n const selectedIndex = props.items.findIndex(item => item.id && (item.id === hash));\n\n useEffect(() => {\n if (selectedIndex === -1) {\n router.push('#' + props.items[0].id);\n }\n }, [hash]);\n\n return (\n <>\n <div className={cn(\"hidden sm:flex stack-scope h-full\", props.className)}>\n <DesktopLayout items={props.items} title={props.title} selectedIndex={selectedIndex} />\n </div>\n <div className={cn(\"sm:hidden stack-scope h-full\", props.className)}>\n <MobileLayout items={props.items} title={props.title} selectedIndex={selectedIndex} />\n </div>\n </>\n );\n}\n\nfunction Items(props: { items: SidebarItem[], selectedIndex: number }) {\n const router = useRouter();\n\n return props.items.map((item, index) => (\n item.type === 'item' ?\n <Button\n key={index}\n variant='ghost'\n size='sm'\n className={cn(\n props.selectedIndex === index && \"bg-muted\",\n \"justify-start text-md text-zinc-800 dark:text-zinc-300 px-2 text-left\",\n )}\n onClick={() => {\n if (item.id) {\n router.push('#' + item.id);\n }\n }}\n >\n {item.icon && <item.icon className=\"mr-2 h-4 w-4\" />}\n {item.title}\n </Button> :\n <Typography key={index}>\n {item.title}\n </Typography>\n ));\n\n}\n\nfunction DesktopLayout(props: { items: SidebarItem[], title?: ReactNode, selectedIndex: number }) {\n const selectedItem = props.items[props.selectedIndex === -1 ? 0 : props.selectedIndex];\n\n return (\n <div className=\"stack-scope flex w-full h-full max-w-full relative\">\n <div className=\"flex max-w-[200px] min-w-[200px] border-r flex-col items-stretch gap-2 p-2 overflow-y-auto\">\n {props.title && <div className='mb-2 ml-2'>\n <Typography type='h2' className=\"text-lg font-semibold text-zinc-800 dark:text-zinc-300\">{props.title}</Typography>\n </div>}\n\n <Items items={props.items} selectedIndex={props.selectedIndex} />\n </div>\n <div className=\"flex-1 w-0 flex justify-center gap-4 py-2 px-4\">\n <div className='flex flex-col max-w-[800px] w-[800px]'>\n <div className='mt-4 mb-6'>\n <Typography type='h4' className='font-semibold'>{selectedItem.title}</Typography>\n {selectedItem.description && <Typography variant='secondary' type='label'>{selectedItem.description}</Typography>}\n </div>\n <div className='flex-1'>\n {selectedItem.content}\n </div>\n </div>\n </div>\n </div>\n );\n}\n\nfunction MobileLayout(props: { items: SidebarItem[], title?: ReactNode, selectedIndex: number }) {\n const selectedItem = props.items[props.selectedIndex];\n const router = useRouter();\n\n if (props.selectedIndex === -1) {\n return (\n <div className=\"flex flex-col gap-2 p-2\">\n {props.title && <div className='mb-2 ml-2'>\n <Typography type='h2' className=\"text-lg font-semibold text-zinc-800 dark:text-zinc-300\">{props.title}</Typography>\n </div>}\n\n <Items items={props.items} selectedIndex={props.selectedIndex} />\n </div>\n );\n } else {\n return (\n <div className=\"flex-1 flex flex-col gap-4 py-2 px-4\">\n <div className='flex flex-col'>\n <div className='flex justify-between'>\n <Typography type='h4' className='font-semibold'>{selectedItem.title}</Typography>\n <Button\n variant='ghost'\n size='icon'\n onClick={() => { router.push('#'); }}\n >\n <XIcon className='h-5 w-5' />\n </Button>\n </div>\n {selectedItem.description && <Typography variant='secondary' type='label'>{selectedItem.description}</Typography>}\n </div>\n <div className='flex-1'>\n {selectedItem.content}\n </div>\n </div>\n );\n }\n}\n"],"mappings":"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","names":[]}
@@ -72,7 +72,7 @@ function SelectedTeamSwitcher(props) {
72
72
  user?.selectedTeam ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_stack_ui.SelectGroup, { children: [
73
73
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.SelectLabel, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center justify-between", children: [
74
74
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: t("Current team") }),
75
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Button, { variant: "ghost", size: "icon", className: "h-6 w-6", onClick: () => router.push(`${app.urls.accountSettings}/teams/${user.selectedTeam?.id}`), children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Settings, { className: "h-4 w-4" }) })
75
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Button, { variant: "ghost", size: "icon", className: "h-6 w-6", onClick: () => router.push(`${app.urls.accountSettings}#team-${user.selectedTeam?.id}`), children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Settings, { className: "h-4 w-4" }) })
76
76
  ] }) }),
77
77
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.SelectItem, { value: user.selectedTeam.id, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-2", children: [
78
78
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_team_icon.TeamIcon, { team: user.selectedTeam }),
@@ -91,7 +91,7 @@ function SelectedTeamSwitcher(props) {
91
91
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
92
92
  import_stack_ui.Button,
93
93
  {
94
- onClick: () => router.push(`${app.urls.accountSettings}/team-creation`),
94
+ onClick: () => router.push(`${app.urls.accountSettings}#team-creation`),
95
95
  className: "w-full",
96
96
  variant: "ghost",
97
97
  children: [
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/selected-team-switcher.tsx"],"sourcesContent":["'use client';\nimport { runAsynchronouslyWithAlert } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport {\n Button,\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectSeparator,\n SelectTrigger,\n SelectValue,\n Typography\n} from \"@stackframe/stack-ui\";\nimport { PlusCircle, Settings } from \"lucide-react\";\nimport { useRouter } from \"next/navigation\";\nimport { useEffect, useMemo } from \"react\";\nimport { Team, useStackApp, useUser } from \"..\";\nimport { useTranslation } from \"../lib/translations\";\nimport { TeamIcon } from \"./team-icon\";\n\ntype SelectedTeamSwitcherProps = {\n urlMap?: (team: Team) => string,\n selectedTeam?: Team,\n noUpdateSelectedTeam?: boolean,\n};\n\nexport function SelectedTeamSwitcher(props: SelectedTeamSwitcherProps) {\n const { t } = useTranslation();\n const app = useStackApp();\n const user = useUser();\n const project = app.useProject();\n const router = useRouter();\n const selectedTeam = user?.selectedTeam || props.selectedTeam;\n const rawTeams = user?.useTeams();\n const teams = useMemo(() => rawTeams?.sort((a, b) => b.id === selectedTeam?.id ? 1 : -1), [rawTeams, selectedTeam]);\n\n useEffect(() => {\n if (!props.noUpdateSelectedTeam && props.selectedTeam) {\n runAsynchronouslyWithAlert(user?.setSelectedTeam(props.selectedTeam));\n }\n }, [props.noUpdateSelectedTeam, props.selectedTeam]);\n\n return (\n <Select\n value={selectedTeam?.id}\n onValueChange={(value) => {\n runAsynchronouslyWithAlert(async () => {\n const team = teams?.find(team => team.id === value);\n if (!team) {\n throw new Error('Team not found, this should not happen');\n }\n\n if (!props.noUpdateSelectedTeam) {\n await user?.setSelectedTeam(team);\n }\n if (props.urlMap) {\n router.push(props.urlMap(team));\n }\n });\n }}\n >\n <SelectTrigger className=\"stack-scope max-w-64\">\n <SelectValue placeholder=\"Select team\"/>\n </SelectTrigger>\n <SelectContent className=\"stack-scope\">\n {user?.selectedTeam ? <SelectGroup>\n <SelectLabel>\n <div className=\"flex items-center justify-between\">\n <span>\n {t('Current team')}\n </span>\n <Button variant='ghost' size='icon' className=\"h-6 w-6\" onClick={() => router.push(`${app.urls.accountSettings}/teams/${user.selectedTeam?.id}`)}>\n <Settings className=\"h-4 w-4\"/>\n </Button>\n </div>\n </SelectLabel>\n <SelectItem value={user.selectedTeam.id}>\n <div className=\"flex items-center gap-2\">\n <TeamIcon team={user.selectedTeam} />\n <Typography className=\"max-w-40 truncate\">{user.selectedTeam.displayName}</Typography>\n </div>\n </SelectItem>\n </SelectGroup> : undefined}\n\n {teams?.length ?\n <SelectGroup>\n <SelectLabel>{t('Other teams')}</SelectLabel>\n {teams.filter(team => team.id !== user?.selectedTeam?.id)\n .map(team => (\n <SelectItem value={team.id} key={team.id}>\n <div className=\"flex items-center gap-2\">\n <TeamIcon team={team} />\n <Typography className=\"max-w-64 truncate\">{team.displayName}</Typography>\n </div>\n </SelectItem>\n ))}\n </SelectGroup> :\n <SelectGroup>\n <SelectLabel>{t('No teams yet')}</SelectLabel>\n </SelectGroup>}\n\n {project.config.clientTeamCreationEnabled && <>\n <SelectSeparator/>\n <div>\n <Button\n onClick={() => router.push(`${app.urls.accountSettings}/team-creation`)}\n className=\"w-full\"\n variant='ghost'\n >\n <PlusCircle className=\"mr-2 h-4 w-4\"/> {t('Create a team')}\n </Button>\n </div>\n </>}\n </SelectContent>\n </Select>\n );\n}\n"],"mappings":"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","names":["team"]}
1
+ {"version":3,"sources":["../../src/components/selected-team-switcher.tsx"],"sourcesContent":["'use client';\nimport { runAsynchronouslyWithAlert } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport {\n Button,\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectSeparator,\n SelectTrigger,\n SelectValue,\n Typography\n} from \"@stackframe/stack-ui\";\nimport { PlusCircle, Settings } from \"lucide-react\";\nimport { useRouter } from \"next/navigation\";\nimport { useEffect, useMemo } from \"react\";\nimport { Team, useStackApp, useUser } from \"..\";\nimport { useTranslation } from \"../lib/translations\";\nimport { TeamIcon } from \"./team-icon\";\n\ntype SelectedTeamSwitcherProps = {\n urlMap?: (team: Team) => string,\n selectedTeam?: Team,\n noUpdateSelectedTeam?: boolean,\n};\n\nexport function SelectedTeamSwitcher(props: SelectedTeamSwitcherProps) {\n const { t } = useTranslation();\n const app = useStackApp();\n const user = useUser();\n const project = app.useProject();\n const router = useRouter();\n const selectedTeam = user?.selectedTeam || props.selectedTeam;\n const rawTeams = user?.useTeams();\n const teams = useMemo(() => rawTeams?.sort((a, b) => b.id === selectedTeam?.id ? 1 : -1), [rawTeams, selectedTeam]);\n\n useEffect(() => {\n if (!props.noUpdateSelectedTeam && props.selectedTeam) {\n runAsynchronouslyWithAlert(user?.setSelectedTeam(props.selectedTeam));\n }\n }, [props.noUpdateSelectedTeam, props.selectedTeam]);\n\n return (\n <Select\n value={selectedTeam?.id}\n onValueChange={(value) => {\n runAsynchronouslyWithAlert(async () => {\n const team = teams?.find(team => team.id === value);\n if (!team) {\n throw new Error('Team not found, this should not happen');\n }\n\n if (!props.noUpdateSelectedTeam) {\n await user?.setSelectedTeam(team);\n }\n if (props.urlMap) {\n router.push(props.urlMap(team));\n }\n });\n }}\n >\n <SelectTrigger className=\"stack-scope max-w-64\">\n <SelectValue placeholder=\"Select team\"/>\n </SelectTrigger>\n <SelectContent className=\"stack-scope\">\n {user?.selectedTeam ? <SelectGroup>\n <SelectLabel>\n <div className=\"flex items-center justify-between\">\n <span>\n {t('Current team')}\n </span>\n <Button variant='ghost' size='icon' className=\"h-6 w-6\" onClick={() => router.push(`${app.urls.accountSettings}#team-${user.selectedTeam?.id}`)}>\n <Settings className=\"h-4 w-4\"/>\n </Button>\n </div>\n </SelectLabel>\n <SelectItem value={user.selectedTeam.id}>\n <div className=\"flex items-center gap-2\">\n <TeamIcon team={user.selectedTeam} />\n <Typography className=\"max-w-40 truncate\">{user.selectedTeam.displayName}</Typography>\n </div>\n </SelectItem>\n </SelectGroup> : undefined}\n\n {teams?.length ?\n <SelectGroup>\n <SelectLabel>{t('Other teams')}</SelectLabel>\n {teams.filter(team => team.id !== user?.selectedTeam?.id)\n .map(team => (\n <SelectItem value={team.id} key={team.id}>\n <div className=\"flex items-center gap-2\">\n <TeamIcon team={team} />\n <Typography className=\"max-w-64 truncate\">{team.displayName}</Typography>\n </div>\n </SelectItem>\n ))}\n </SelectGroup> :\n <SelectGroup>\n <SelectLabel>{t('No teams yet')}</SelectLabel>\n </SelectGroup>}\n\n {project.config.clientTeamCreationEnabled && <>\n <SelectSeparator/>\n <div>\n <Button\n onClick={() => router.push(`${app.urls.accountSettings}#team-creation`)}\n className=\"w-full\"\n variant='ghost'\n >\n <PlusCircle className=\"mr-2 h-4 w-4\"/> {t('Create a team')}\n </Button>\n </div>\n </>}\n </SelectContent>\n </Select>\n );\n}\n"],"mappings":"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","names":["team"]}
@@ -65,18 +65,10 @@ async function StackHandler(props) {
65
65
  oauthCallback: "oauth-callback",
66
66
  magicLinkCallback: "magic-link-callback",
67
67
  teamInvitation: "team-invitation",
68
+ accountSettings: "account-settings",
68
69
  error: "error"
69
70
  };
70
71
  const path = props.params.stack.join("/");
71
- if (path.startsWith("account-settings")) {
72
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
73
- import_account_settings.AccountSettings,
74
- {
75
- fullPage: props.fullPage,
76
- ...filterUndefinedINU(props.componentProps?.AccountSettings)
77
- }
78
- );
79
- }
80
72
  switch (path) {
81
73
  case availablePaths.signIn: {
82
74
  redirectIfNotHandler("signIn");
@@ -174,6 +166,15 @@ async function StackHandler(props) {
174
166
  }
175
167
  );
176
168
  }
169
+ case availablePaths.accountSettings: {
170
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
171
+ import_account_settings.AccountSettings,
172
+ {
173
+ fullPage: props.fullPage,
174
+ ...filterUndefinedINU(props.componentProps?.AccountSettings)
175
+ }
176
+ );
177
+ }
177
178
  case availablePaths.error: {
178
179
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
179
180
  import_error_page.ErrorPage,
@@ -1 +1 @@
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 { SignIn, SignUp, 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 { FilterUndefined, filterUndefined } from \"@stackframe/stack-shared/dist/utils/objects\";\n\ntype Components = {\n SignIn: typeof SignIn,\n SignUp: typeof SignUp,\n EmailVerification: typeof EmailVerification,\n PasswordReset: typeof PasswordReset,\n ForgotPassword: typeof ForgotPassword,\n SignOut: typeof SignOut,\n OAuthCallback: typeof OAuthCallback,\n MagicLinkCallback: typeof MagicLinkCallback,\n TeamInvitation: typeof TeamInvitation,\n ErrorPage: typeof ErrorPage,\n AccountSettings: typeof AccountSettings,\n};\n\n\nexport default async function StackHandler<HasTokenStore extends boolean>(props: {\n app: StackServerApp<HasTokenStore>,\n params?: { stack?: string[] },\n searchParams?: Record<string, string>,\n fullPage: boolean,\n componentProps?: {\n [K in keyof Components]?: Parameters<Components[K]>;\n },\n}) {\n if (!props.params?.stack) {\n return (\n <MessageCard title=\"Invalid Stack Handler Setup\" fullPage={props.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 = props.app.urls[name];\n const handlerUrl = props.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(props.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 magicLinkCallback: 'magic-link-callback',\n teamInvitation: 'team-invitation',\n error: 'error',\n };\n\n const path = props.params.stack.join('/');\n\n if (path.startsWith('account-settings')) {\n return <AccountSettings\n fullPage={props.fullPage}\n {...filterUndefinedINU(props.componentProps?.AccountSettings)}\n />;\n }\n\n switch (path) {\n case availablePaths.signIn: {\n redirectIfNotHandler('signIn');\n return <SignIn\n fullPage={props.fullPage}\n automaticRedirect\n {...filterUndefinedINU(props.componentProps?.SignIn)}\n />;\n }\n case availablePaths.signUp: {\n redirectIfNotHandler('signUp');\n return <SignUp\n fullPage={props.fullPage}\n automaticRedirect\n {...filterUndefinedINU(props.componentProps?.SignUp)}\n />;\n }\n case availablePaths.emailVerification: {\n redirectIfNotHandler('emailVerification');\n return <EmailVerification\n searchParams={props.searchParams}\n fullPage={props.fullPage}\n {...filterUndefinedINU(props.componentProps?.EmailVerification)}\n />;\n }\n case availablePaths.passwordReset: {\n redirectIfNotHandler('passwordReset');\n return <PasswordReset\n searchParams={props.searchParams || {}}\n fullPage={props.fullPage}\n {...filterUndefinedINU(props.componentProps?.PasswordReset)}\n />;\n }\n case availablePaths.forgotPassword: {\n redirectIfNotHandler('forgotPassword');\n return <ForgotPassword\n fullPage={props.fullPage}\n {...filterUndefinedINU(props.componentProps?.ForgotPassword)}\n />;\n }\n case availablePaths.signOut: {\n redirectIfNotHandler('signOut');\n return <SignOut\n fullPage={props.fullPage}\n {...filterUndefinedINU(props.componentProps?.SignOut)}\n />;\n }\n case availablePaths.oauthCallback: {\n redirectIfNotHandler('oauthCallback');\n return <OAuthCallback\n fullPage={props.fullPage}\n {...filterUndefinedINU(props.componentProps?.OAuthCallback)}\n />;\n }\n case availablePaths.magicLinkCallback: {\n redirectIfNotHandler('magicLinkCallback');\n return <MagicLinkCallback\n searchParams={props.searchParams || {}}\n fullPage={props.fullPage}\n {...filterUndefinedINU(props.componentProps?.MagicLinkCallback)}\n />;\n }\n case availablePaths.teamInvitation: {\n redirectIfNotHandler('teamInvitation');\n return <TeamInvitation\n searchParams={props.searchParams || {}}\n fullPage={props.fullPage}\n {...filterUndefinedINU(props.componentProps?.TeamInvitation)}\n />;\n }\n case availablePaths.error: {\n return <ErrorPage\n searchParams={props.searchParams || {}}\n fullPage={props.fullPage}\n {...filterUndefinedINU(props.componentProps?.ErrorPage)}\n />;\n }\n default: {\n for (const [key, value] of Object.entries(availablePaths)) {\n if (path === value.replaceAll('-', '')) {\n redirect(`${props.app.urls.handler}/${value}`, RedirectType.replace);\n }\n }\n return notFound();\n }\n }\n}\n\n\nfunction filterUndefinedINU<T extends {}>(value: T | undefined): FilterUndefined<T> | undefined {\n return value === undefined ? value : filterUndefined(value);\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 { SignIn, SignUp, 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 { FilterUndefined, filterUndefined } from \"@stackframe/stack-shared/dist/utils/objects\";\n\ntype Components = {\n SignIn: typeof SignIn,\n SignUp: typeof SignUp,\n EmailVerification: typeof EmailVerification,\n PasswordReset: typeof PasswordReset,\n ForgotPassword: typeof ForgotPassword,\n SignOut: typeof SignOut,\n OAuthCallback: typeof OAuthCallback,\n MagicLinkCallback: typeof MagicLinkCallback,\n TeamInvitation: typeof TeamInvitation,\n ErrorPage: typeof ErrorPage,\n AccountSettings: typeof AccountSettings,\n};\n\n\nexport default async function StackHandler<HasTokenStore extends boolean>(props: {\n app: StackServerApp<HasTokenStore>,\n params?: { stack?: string[] },\n searchParams?: Record<string, string>,\n fullPage: boolean,\n componentProps?: {\n [K in keyof Components]?: Parameters<Components[K]>;\n },\n}) {\n if (!props.params?.stack) {\n return (\n <MessageCard title=\"Invalid Stack Handler Setup\" fullPage={props.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 = props.app.urls[name];\n const handlerUrl = props.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(props.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 magicLinkCallback: 'magic-link-callback',\n teamInvitation: 'team-invitation',\n accountSettings: 'account-settings',\n error: 'error',\n };\n\n const path = props.params.stack.join('/');\n\n switch (path) {\n case availablePaths.signIn: {\n redirectIfNotHandler('signIn');\n return <SignIn\n fullPage={props.fullPage}\n automaticRedirect\n {...filterUndefinedINU(props.componentProps?.SignIn)}\n />;\n }\n case availablePaths.signUp: {\n redirectIfNotHandler('signUp');\n return <SignUp\n fullPage={props.fullPage}\n automaticRedirect\n {...filterUndefinedINU(props.componentProps?.SignUp)}\n />;\n }\n case availablePaths.emailVerification: {\n redirectIfNotHandler('emailVerification');\n return <EmailVerification\n searchParams={props.searchParams}\n fullPage={props.fullPage}\n {...filterUndefinedINU(props.componentProps?.EmailVerification)}\n />;\n }\n case availablePaths.passwordReset: {\n redirectIfNotHandler('passwordReset');\n return <PasswordReset\n searchParams={props.searchParams || {}}\n fullPage={props.fullPage}\n {...filterUndefinedINU(props.componentProps?.PasswordReset)}\n />;\n }\n case availablePaths.forgotPassword: {\n redirectIfNotHandler('forgotPassword');\n return <ForgotPassword\n fullPage={props.fullPage}\n {...filterUndefinedINU(props.componentProps?.ForgotPassword)}\n />;\n }\n case availablePaths.signOut: {\n redirectIfNotHandler('signOut');\n return <SignOut\n fullPage={props.fullPage}\n {...filterUndefinedINU(props.componentProps?.SignOut)}\n />;\n }\n case availablePaths.oauthCallback: {\n redirectIfNotHandler('oauthCallback');\n return <OAuthCallback\n fullPage={props.fullPage}\n {...filterUndefinedINU(props.componentProps?.OAuthCallback)}\n />;\n }\n case availablePaths.magicLinkCallback: {\n redirectIfNotHandler('magicLinkCallback');\n return <MagicLinkCallback\n searchParams={props.searchParams || {}}\n fullPage={props.fullPage}\n {...filterUndefinedINU(props.componentProps?.MagicLinkCallback)}\n />;\n }\n case availablePaths.teamInvitation: {\n redirectIfNotHandler('teamInvitation');\n return <TeamInvitation\n searchParams={props.searchParams || {}}\n fullPage={props.fullPage}\n {...filterUndefinedINU(props.componentProps?.TeamInvitation)}\n />;\n }\n case availablePaths.accountSettings: {\n return <AccountSettings\n fullPage={props.fullPage}\n {...filterUndefinedINU(props.componentProps?.AccountSettings)}\n />;\n }\n case availablePaths.error: {\n return <ErrorPage\n searchParams={props.searchParams || {}}\n fullPage={props.fullPage}\n {...filterUndefinedINU(props.componentProps?.ErrorPage)}\n />;\n }\n default: {\n for (const [key, value] of Object.entries(availablePaths)) {\n if (path === value.replaceAll('-', '')) {\n redirect(`${props.app.urls.handler}/${value}`, RedirectType.replace);\n }\n }\n return notFound();\n }\n }\n}\n\n\nfunction filterUndefinedINU<T extends {}>(value: T | undefined): FilterUndefined<T> | undefined {\n return value === undefined ? value : filterUndefined(value);\n}\n"],"mappings":"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","names":[]}
@@ -2,18 +2,21 @@
2
2
  "use client";
3
3
 
4
4
  // src/components/elements/sidebar-layout.tsx
5
+ import { useHash } from "@stackframe/stack-shared/dist/hooks/use-hash";
5
6
  import { Button, Typography, cn } from "@stackframe/stack-ui";
6
7
  import { XIcon } from "lucide-react";
7
8
  import { useRouter } from "next/navigation";
8
- import { useHash } from "@stackframe/stack-shared/dist/hooks/use-hash";
9
+ import { useEffect } from "react";
9
10
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
10
11
  function SidebarLayout(props) {
11
12
  const router = useRouter();
12
13
  const hash = useHash();
13
14
  const selectedIndex = props.items.findIndex((item) => item.id && item.id === hash);
14
- if (selectedIndex === -1) {
15
- router.push("#" + props.items[0].id);
16
- }
15
+ useEffect(() => {
16
+ if (selectedIndex === -1) {
17
+ router.push("#" + props.items[0].id);
18
+ }
19
+ }, [hash]);
17
20
  return /* @__PURE__ */ jsxs(Fragment, { children: [
18
21
  /* @__PURE__ */ jsx("div", { className: cn("hidden sm:flex stack-scope h-full", props.className), children: /* @__PURE__ */ jsx(DesktopLayout, { items: props.items, title: props.title, selectedIndex }) }),
19
22
  /* @__PURE__ */ jsx("div", { className: cn("sm:hidden stack-scope h-full", props.className), children: /* @__PURE__ */ jsx(MobileLayout, { items: props.items, title: props.title, selectedIndex }) })
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/elements/sidebar-layout.tsx"],"sourcesContent":["'use client';\n\nimport { Button, Typography, cn } from '@stackframe/stack-ui';\nimport { LucideIcon, XIcon } from 'lucide-react';\nimport { usePathname, useRouter } from 'next/navigation';\nimport React, { ReactNode } from 'react';\nimport { useHash } from '@stackframe/stack-shared/dist/hooks/use-hash';\n\nexport type SidebarItem = {\n title: React.ReactNode,\n type: 'item' | 'divider',\n description?: React.ReactNode,\n id?: string,\n icon?: LucideIcon,\n content?: React.ReactNode,\n contentTitle?: React.ReactNode,\n}\n\nexport function SidebarLayout(props: { items: SidebarItem[], title?: ReactNode, className?: string }) {\n const router = useRouter();\n const hash = useHash();\n\n const selectedIndex = props.items.findIndex(item => item.id && (item.id === hash));\n if (selectedIndex === -1) {\n router.push('#' + props.items[0].id);\n }\n\n return (\n <>\n <div className={cn(\"hidden sm:flex stack-scope h-full\", props.className)}>\n <DesktopLayout items={props.items} title={props.title} selectedIndex={selectedIndex} />\n </div>\n <div className={cn(\"sm:hidden stack-scope h-full\", props.className)}>\n <MobileLayout items={props.items} title={props.title} selectedIndex={selectedIndex} />\n </div>\n </>\n );\n}\n\nfunction Items(props: { items: SidebarItem[], selectedIndex: number }) {\n const router = useRouter();\n\n return props.items.map((item, index) => (\n item.type === 'item' ?\n <Button\n key={index}\n variant='ghost'\n size='sm'\n className={cn(\n props.selectedIndex === index && \"bg-muted\",\n \"justify-start text-md text-zinc-800 dark:text-zinc-300 px-2 text-left\",\n )}\n onClick={() => {\n if (item.id) {\n router.push('#' + item.id);\n }\n }}\n >\n {item.icon && <item.icon className=\"mr-2 h-4 w-4\" />}\n {item.title}\n </Button> :\n <Typography key={index}>\n {item.title}\n </Typography>\n ));\n\n}\n\nfunction DesktopLayout(props: { items: SidebarItem[], title?: ReactNode, selectedIndex: number }) {\n const selectedItem = props.items[props.selectedIndex === -1 ? 0 : props.selectedIndex];\n\n return (\n <div className=\"stack-scope flex w-full h-full max-w-full relative\">\n <div className=\"flex max-w-[200px] min-w-[200px] border-r flex-col items-stretch gap-2 p-2 overflow-y-auto\">\n {props.title && <div className='mb-2 ml-2'>\n <Typography type='h2' className=\"text-lg font-semibold text-zinc-800 dark:text-zinc-300\">{props.title}</Typography>\n </div>}\n\n <Items items={props.items} selectedIndex={props.selectedIndex} />\n </div>\n <div className=\"flex-1 w-0 flex justify-center gap-4 py-2 px-4\">\n <div className='flex flex-col max-w-[800px] w-[800px]'>\n <div className='mt-4 mb-6'>\n <Typography type='h4' className='font-semibold'>{selectedItem.title}</Typography>\n {selectedItem.description && <Typography variant='secondary' type='label'>{selectedItem.description}</Typography>}\n </div>\n <div className='flex-1'>\n {selectedItem.content}\n </div>\n </div>\n </div>\n </div>\n );\n}\n\nfunction MobileLayout(props: { items: SidebarItem[], title?: ReactNode, selectedIndex: number }) {\n const selectedItem = props.items[props.selectedIndex];\n const router = useRouter();\n\n if (props.selectedIndex === -1) {\n return (\n <div className=\"flex flex-col gap-2 p-2\">\n {props.title && <div className='mb-2 ml-2'>\n <Typography type='h2' className=\"text-lg font-semibold text-zinc-800 dark:text-zinc-300\">{props.title}</Typography>\n </div>}\n\n <Items items={props.items} selectedIndex={props.selectedIndex} />\n </div>\n );\n } else {\n return (\n <div className=\"flex-1 flex flex-col gap-4 py-2 px-4\">\n <div className='flex flex-col'>\n <div className='flex justify-between'>\n <Typography type='h4' className='font-semibold'>{selectedItem.title}</Typography>\n <Button\n variant='ghost'\n size='icon'\n onClick={() => { router.push('#'); }}\n >\n <XIcon className='h-5 w-5' />\n </Button>\n </div>\n {selectedItem.description && <Typography variant='secondary' type='label'>{selectedItem.description}</Typography>}\n </div>\n <div className='flex-1'>\n {selectedItem.content}\n </div>\n </div>\n );\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/components/elements/sidebar-layout.tsx"],"sourcesContent":["'use client';\n\nimport { useHash } from '@stackframe/stack-shared/dist/hooks/use-hash';\nimport { Button, Typography, cn } from '@stackframe/stack-ui';\nimport { LucideIcon, XIcon } from 'lucide-react';\nimport { useRouter } from 'next/navigation';\nimport React, { ReactNode, useEffect } from 'react';\n\nexport type SidebarItem = {\n title: React.ReactNode,\n type: 'item' | 'divider',\n description?: React.ReactNode,\n id?: string,\n icon?: LucideIcon,\n content?: React.ReactNode,\n contentTitle?: React.ReactNode,\n}\n\nexport function SidebarLayout(props: { items: SidebarItem[], title?: ReactNode, className?: string }) {\n const router = useRouter();\n const hash = useHash();\n const selectedIndex = props.items.findIndex(item => item.id && (item.id === hash));\n\n useEffect(() => {\n if (selectedIndex === -1) {\n router.push('#' + props.items[0].id);\n }\n }, [hash]);\n\n return (\n <>\n <div className={cn(\"hidden sm:flex stack-scope h-full\", props.className)}>\n <DesktopLayout items={props.items} title={props.title} selectedIndex={selectedIndex} />\n </div>\n <div className={cn(\"sm:hidden stack-scope h-full\", props.className)}>\n <MobileLayout items={props.items} title={props.title} selectedIndex={selectedIndex} />\n </div>\n </>\n );\n}\n\nfunction Items(props: { items: SidebarItem[], selectedIndex: number }) {\n const router = useRouter();\n\n return props.items.map((item, index) => (\n item.type === 'item' ?\n <Button\n key={index}\n variant='ghost'\n size='sm'\n className={cn(\n props.selectedIndex === index && \"bg-muted\",\n \"justify-start text-md text-zinc-800 dark:text-zinc-300 px-2 text-left\",\n )}\n onClick={() => {\n if (item.id) {\n router.push('#' + item.id);\n }\n }}\n >\n {item.icon && <item.icon className=\"mr-2 h-4 w-4\" />}\n {item.title}\n </Button> :\n <Typography key={index}>\n {item.title}\n </Typography>\n ));\n\n}\n\nfunction DesktopLayout(props: { items: SidebarItem[], title?: ReactNode, selectedIndex: number }) {\n const selectedItem = props.items[props.selectedIndex === -1 ? 0 : props.selectedIndex];\n\n return (\n <div className=\"stack-scope flex w-full h-full max-w-full relative\">\n <div className=\"flex max-w-[200px] min-w-[200px] border-r flex-col items-stretch gap-2 p-2 overflow-y-auto\">\n {props.title && <div className='mb-2 ml-2'>\n <Typography type='h2' className=\"text-lg font-semibold text-zinc-800 dark:text-zinc-300\">{props.title}</Typography>\n </div>}\n\n <Items items={props.items} selectedIndex={props.selectedIndex} />\n </div>\n <div className=\"flex-1 w-0 flex justify-center gap-4 py-2 px-4\">\n <div className='flex flex-col max-w-[800px] w-[800px]'>\n <div className='mt-4 mb-6'>\n <Typography type='h4' className='font-semibold'>{selectedItem.title}</Typography>\n {selectedItem.description && <Typography variant='secondary' type='label'>{selectedItem.description}</Typography>}\n </div>\n <div className='flex-1'>\n {selectedItem.content}\n </div>\n </div>\n </div>\n </div>\n );\n}\n\nfunction MobileLayout(props: { items: SidebarItem[], title?: ReactNode, selectedIndex: number }) {\n const selectedItem = props.items[props.selectedIndex];\n const router = useRouter();\n\n if (props.selectedIndex === -1) {\n return (\n <div className=\"flex flex-col gap-2 p-2\">\n {props.title && <div className='mb-2 ml-2'>\n <Typography type='h2' className=\"text-lg font-semibold text-zinc-800 dark:text-zinc-300\">{props.title}</Typography>\n </div>}\n\n <Items items={props.items} selectedIndex={props.selectedIndex} />\n </div>\n );\n } else {\n return (\n <div className=\"flex-1 flex flex-col gap-4 py-2 px-4\">\n <div className='flex flex-col'>\n <div className='flex justify-between'>\n <Typography type='h4' className='font-semibold'>{selectedItem.title}</Typography>\n <Button\n variant='ghost'\n size='icon'\n onClick={() => { router.push('#'); }}\n >\n <XIcon className='h-5 w-5' />\n </Button>\n </div>\n {selectedItem.description && <Typography variant='secondary' type='label'>{selectedItem.description}</Typography>}\n </div>\n <div className='flex-1'>\n {selectedItem.content}\n </div>\n </div>\n );\n }\n}\n"],"mappings":"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","names":[]}
@@ -60,7 +60,7 @@ function SelectedTeamSwitcher(props) {
60
60
  user?.selectedTeam ? /* @__PURE__ */ jsxs(SelectGroup, { children: [
61
61
  /* @__PURE__ */ jsx(SelectLabel, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
62
62
  /* @__PURE__ */ jsx("span", { children: t("Current team") }),
63
- /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon", className: "h-6 w-6", onClick: () => router.push(`${app.urls.accountSettings}/teams/${user.selectedTeam?.id}`), children: /* @__PURE__ */ jsx(Settings, { className: "h-4 w-4" }) })
63
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon", className: "h-6 w-6", onClick: () => router.push(`${app.urls.accountSettings}#team-${user.selectedTeam?.id}`), children: /* @__PURE__ */ jsx(Settings, { className: "h-4 w-4" }) })
64
64
  ] }) }),
65
65
  /* @__PURE__ */ jsx(SelectItem, { value: user.selectedTeam.id, children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
66
66
  /* @__PURE__ */ jsx(TeamIcon, { team: user.selectedTeam }),
@@ -79,7 +79,7 @@ function SelectedTeamSwitcher(props) {
79
79
  /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(
80
80
  Button,
81
81
  {
82
- onClick: () => router.push(`${app.urls.accountSettings}/team-creation`),
82
+ onClick: () => router.push(`${app.urls.accountSettings}#team-creation`),
83
83
  className: "w-full",
84
84
  variant: "ghost",
85
85
  children: [
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/selected-team-switcher.tsx"],"sourcesContent":["'use client';\nimport { runAsynchronouslyWithAlert } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport {\n Button,\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectSeparator,\n SelectTrigger,\n SelectValue,\n Typography\n} from \"@stackframe/stack-ui\";\nimport { PlusCircle, Settings } from \"lucide-react\";\nimport { useRouter } from \"next/navigation\";\nimport { useEffect, useMemo } from \"react\";\nimport { Team, useStackApp, useUser } from \"..\";\nimport { useTranslation } from \"../lib/translations\";\nimport { TeamIcon } from \"./team-icon\";\n\ntype SelectedTeamSwitcherProps = {\n urlMap?: (team: Team) => string,\n selectedTeam?: Team,\n noUpdateSelectedTeam?: boolean,\n};\n\nexport function SelectedTeamSwitcher(props: SelectedTeamSwitcherProps) {\n const { t } = useTranslation();\n const app = useStackApp();\n const user = useUser();\n const project = app.useProject();\n const router = useRouter();\n const selectedTeam = user?.selectedTeam || props.selectedTeam;\n const rawTeams = user?.useTeams();\n const teams = useMemo(() => rawTeams?.sort((a, b) => b.id === selectedTeam?.id ? 1 : -1), [rawTeams, selectedTeam]);\n\n useEffect(() => {\n if (!props.noUpdateSelectedTeam && props.selectedTeam) {\n runAsynchronouslyWithAlert(user?.setSelectedTeam(props.selectedTeam));\n }\n }, [props.noUpdateSelectedTeam, props.selectedTeam]);\n\n return (\n <Select\n value={selectedTeam?.id}\n onValueChange={(value) => {\n runAsynchronouslyWithAlert(async () => {\n const team = teams?.find(team => team.id === value);\n if (!team) {\n throw new Error('Team not found, this should not happen');\n }\n\n if (!props.noUpdateSelectedTeam) {\n await user?.setSelectedTeam(team);\n }\n if (props.urlMap) {\n router.push(props.urlMap(team));\n }\n });\n }}\n >\n <SelectTrigger className=\"stack-scope max-w-64\">\n <SelectValue placeholder=\"Select team\"/>\n </SelectTrigger>\n <SelectContent className=\"stack-scope\">\n {user?.selectedTeam ? <SelectGroup>\n <SelectLabel>\n <div className=\"flex items-center justify-between\">\n <span>\n {t('Current team')}\n </span>\n <Button variant='ghost' size='icon' className=\"h-6 w-6\" onClick={() => router.push(`${app.urls.accountSettings}/teams/${user.selectedTeam?.id}`)}>\n <Settings className=\"h-4 w-4\"/>\n </Button>\n </div>\n </SelectLabel>\n <SelectItem value={user.selectedTeam.id}>\n <div className=\"flex items-center gap-2\">\n <TeamIcon team={user.selectedTeam} />\n <Typography className=\"max-w-40 truncate\">{user.selectedTeam.displayName}</Typography>\n </div>\n </SelectItem>\n </SelectGroup> : undefined}\n\n {teams?.length ?\n <SelectGroup>\n <SelectLabel>{t('Other teams')}</SelectLabel>\n {teams.filter(team => team.id !== user?.selectedTeam?.id)\n .map(team => (\n <SelectItem value={team.id} key={team.id}>\n <div className=\"flex items-center gap-2\">\n <TeamIcon team={team} />\n <Typography className=\"max-w-64 truncate\">{team.displayName}</Typography>\n </div>\n </SelectItem>\n ))}\n </SelectGroup> :\n <SelectGroup>\n <SelectLabel>{t('No teams yet')}</SelectLabel>\n </SelectGroup>}\n\n {project.config.clientTeamCreationEnabled && <>\n <SelectSeparator/>\n <div>\n <Button\n onClick={() => router.push(`${app.urls.accountSettings}/team-creation`)}\n className=\"w-full\"\n variant='ghost'\n >\n <PlusCircle className=\"mr-2 h-4 w-4\"/> {t('Create a team')}\n </Button>\n </div>\n </>}\n </SelectContent>\n </Select>\n );\n}\n"],"mappings":"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","names":["team"]}
1
+ {"version":3,"sources":["../../../src/components/selected-team-switcher.tsx"],"sourcesContent":["'use client';\nimport { runAsynchronouslyWithAlert } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport {\n Button,\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectSeparator,\n SelectTrigger,\n SelectValue,\n Typography\n} from \"@stackframe/stack-ui\";\nimport { PlusCircle, Settings } from \"lucide-react\";\nimport { useRouter } from \"next/navigation\";\nimport { useEffect, useMemo } from \"react\";\nimport { Team, useStackApp, useUser } from \"..\";\nimport { useTranslation } from \"../lib/translations\";\nimport { TeamIcon } from \"./team-icon\";\n\ntype SelectedTeamSwitcherProps = {\n urlMap?: (team: Team) => string,\n selectedTeam?: Team,\n noUpdateSelectedTeam?: boolean,\n};\n\nexport function SelectedTeamSwitcher(props: SelectedTeamSwitcherProps) {\n const { t } = useTranslation();\n const app = useStackApp();\n const user = useUser();\n const project = app.useProject();\n const router = useRouter();\n const selectedTeam = user?.selectedTeam || props.selectedTeam;\n const rawTeams = user?.useTeams();\n const teams = useMemo(() => rawTeams?.sort((a, b) => b.id === selectedTeam?.id ? 1 : -1), [rawTeams, selectedTeam]);\n\n useEffect(() => {\n if (!props.noUpdateSelectedTeam && props.selectedTeam) {\n runAsynchronouslyWithAlert(user?.setSelectedTeam(props.selectedTeam));\n }\n }, [props.noUpdateSelectedTeam, props.selectedTeam]);\n\n return (\n <Select\n value={selectedTeam?.id}\n onValueChange={(value) => {\n runAsynchronouslyWithAlert(async () => {\n const team = teams?.find(team => team.id === value);\n if (!team) {\n throw new Error('Team not found, this should not happen');\n }\n\n if (!props.noUpdateSelectedTeam) {\n await user?.setSelectedTeam(team);\n }\n if (props.urlMap) {\n router.push(props.urlMap(team));\n }\n });\n }}\n >\n <SelectTrigger className=\"stack-scope max-w-64\">\n <SelectValue placeholder=\"Select team\"/>\n </SelectTrigger>\n <SelectContent className=\"stack-scope\">\n {user?.selectedTeam ? <SelectGroup>\n <SelectLabel>\n <div className=\"flex items-center justify-between\">\n <span>\n {t('Current team')}\n </span>\n <Button variant='ghost' size='icon' className=\"h-6 w-6\" onClick={() => router.push(`${app.urls.accountSettings}#team-${user.selectedTeam?.id}`)}>\n <Settings className=\"h-4 w-4\"/>\n </Button>\n </div>\n </SelectLabel>\n <SelectItem value={user.selectedTeam.id}>\n <div className=\"flex items-center gap-2\">\n <TeamIcon team={user.selectedTeam} />\n <Typography className=\"max-w-40 truncate\">{user.selectedTeam.displayName}</Typography>\n </div>\n </SelectItem>\n </SelectGroup> : undefined}\n\n {teams?.length ?\n <SelectGroup>\n <SelectLabel>{t('Other teams')}</SelectLabel>\n {teams.filter(team => team.id !== user?.selectedTeam?.id)\n .map(team => (\n <SelectItem value={team.id} key={team.id}>\n <div className=\"flex items-center gap-2\">\n <TeamIcon team={team} />\n <Typography className=\"max-w-64 truncate\">{team.displayName}</Typography>\n </div>\n </SelectItem>\n ))}\n </SelectGroup> :\n <SelectGroup>\n <SelectLabel>{t('No teams yet')}</SelectLabel>\n </SelectGroup>}\n\n {project.config.clientTeamCreationEnabled && <>\n <SelectSeparator/>\n <div>\n <Button\n onClick={() => router.push(`${app.urls.accountSettings}#team-creation`)}\n className=\"w-full\"\n variant='ghost'\n >\n <PlusCircle className=\"mr-2 h-4 w-4\"/> {t('Create a team')}\n </Button>\n </div>\n </>}\n </SelectContent>\n </Select>\n );\n}\n"],"mappings":"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","names":["team"]}
@@ -41,18 +41,10 @@ async function StackHandler(props) {
41
41
  oauthCallback: "oauth-callback",
42
42
  magicLinkCallback: "magic-link-callback",
43
43
  teamInvitation: "team-invitation",
44
+ accountSettings: "account-settings",
44
45
  error: "error"
45
46
  };
46
47
  const path = props.params.stack.join("/");
47
- if (path.startsWith("account-settings")) {
48
- return /* @__PURE__ */ jsx(
49
- AccountSettings,
50
- {
51
- fullPage: props.fullPage,
52
- ...filterUndefinedINU(props.componentProps?.AccountSettings)
53
- }
54
- );
55
- }
56
48
  switch (path) {
57
49
  case availablePaths.signIn: {
58
50
  redirectIfNotHandler("signIn");
@@ -150,6 +142,15 @@ async function StackHandler(props) {
150
142
  }
151
143
  );
152
144
  }
145
+ case availablePaths.accountSettings: {
146
+ return /* @__PURE__ */ jsx(
147
+ AccountSettings,
148
+ {
149
+ fullPage: props.fullPage,
150
+ ...filterUndefinedINU(props.componentProps?.AccountSettings)
151
+ }
152
+ );
153
+ }
153
154
  case availablePaths.error: {
154
155
  return /* @__PURE__ */ jsx(
155
156
  ErrorPage,
@@ -1 +1 @@
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 { SignIn, SignUp, 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 { FilterUndefined, filterUndefined } from \"@stackframe/stack-shared/dist/utils/objects\";\n\ntype Components = {\n SignIn: typeof SignIn,\n SignUp: typeof SignUp,\n EmailVerification: typeof EmailVerification,\n PasswordReset: typeof PasswordReset,\n ForgotPassword: typeof ForgotPassword,\n SignOut: typeof SignOut,\n OAuthCallback: typeof OAuthCallback,\n MagicLinkCallback: typeof MagicLinkCallback,\n TeamInvitation: typeof TeamInvitation,\n ErrorPage: typeof ErrorPage,\n AccountSettings: typeof AccountSettings,\n};\n\n\nexport default async function StackHandler<HasTokenStore extends boolean>(props: {\n app: StackServerApp<HasTokenStore>,\n params?: { stack?: string[] },\n searchParams?: Record<string, string>,\n fullPage: boolean,\n componentProps?: {\n [K in keyof Components]?: Parameters<Components[K]>;\n },\n}) {\n if (!props.params?.stack) {\n return (\n <MessageCard title=\"Invalid Stack Handler Setup\" fullPage={props.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 = props.app.urls[name];\n const handlerUrl = props.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(props.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 magicLinkCallback: 'magic-link-callback',\n teamInvitation: 'team-invitation',\n error: 'error',\n };\n\n const path = props.params.stack.join('/');\n\n if (path.startsWith('account-settings')) {\n return <AccountSettings\n fullPage={props.fullPage}\n {...filterUndefinedINU(props.componentProps?.AccountSettings)}\n />;\n }\n\n switch (path) {\n case availablePaths.signIn: {\n redirectIfNotHandler('signIn');\n return <SignIn\n fullPage={props.fullPage}\n automaticRedirect\n {...filterUndefinedINU(props.componentProps?.SignIn)}\n />;\n }\n case availablePaths.signUp: {\n redirectIfNotHandler('signUp');\n return <SignUp\n fullPage={props.fullPage}\n automaticRedirect\n {...filterUndefinedINU(props.componentProps?.SignUp)}\n />;\n }\n case availablePaths.emailVerification: {\n redirectIfNotHandler('emailVerification');\n return <EmailVerification\n searchParams={props.searchParams}\n fullPage={props.fullPage}\n {...filterUndefinedINU(props.componentProps?.EmailVerification)}\n />;\n }\n case availablePaths.passwordReset: {\n redirectIfNotHandler('passwordReset');\n return <PasswordReset\n searchParams={props.searchParams || {}}\n fullPage={props.fullPage}\n {...filterUndefinedINU(props.componentProps?.PasswordReset)}\n />;\n }\n case availablePaths.forgotPassword: {\n redirectIfNotHandler('forgotPassword');\n return <ForgotPassword\n fullPage={props.fullPage}\n {...filterUndefinedINU(props.componentProps?.ForgotPassword)}\n />;\n }\n case availablePaths.signOut: {\n redirectIfNotHandler('signOut');\n return <SignOut\n fullPage={props.fullPage}\n {...filterUndefinedINU(props.componentProps?.SignOut)}\n />;\n }\n case availablePaths.oauthCallback: {\n redirectIfNotHandler('oauthCallback');\n return <OAuthCallback\n fullPage={props.fullPage}\n {...filterUndefinedINU(props.componentProps?.OAuthCallback)}\n />;\n }\n case availablePaths.magicLinkCallback: {\n redirectIfNotHandler('magicLinkCallback');\n return <MagicLinkCallback\n searchParams={props.searchParams || {}}\n fullPage={props.fullPage}\n {...filterUndefinedINU(props.componentProps?.MagicLinkCallback)}\n />;\n }\n case availablePaths.teamInvitation: {\n redirectIfNotHandler('teamInvitation');\n return <TeamInvitation\n searchParams={props.searchParams || {}}\n fullPage={props.fullPage}\n {...filterUndefinedINU(props.componentProps?.TeamInvitation)}\n />;\n }\n case availablePaths.error: {\n return <ErrorPage\n searchParams={props.searchParams || {}}\n fullPage={props.fullPage}\n {...filterUndefinedINU(props.componentProps?.ErrorPage)}\n />;\n }\n default: {\n for (const [key, value] of Object.entries(availablePaths)) {\n if (path === value.replaceAll('-', '')) {\n redirect(`${props.app.urls.handler}/${value}`, RedirectType.replace);\n }\n }\n return notFound();\n }\n }\n}\n\n\nfunction filterUndefinedINU<T extends {}>(value: T | undefined): FilterUndefined<T> | undefined {\n return value === undefined ? value : filterUndefined(value);\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 { SignIn, SignUp, 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 { FilterUndefined, filterUndefined } from \"@stackframe/stack-shared/dist/utils/objects\";\n\ntype Components = {\n SignIn: typeof SignIn,\n SignUp: typeof SignUp,\n EmailVerification: typeof EmailVerification,\n PasswordReset: typeof PasswordReset,\n ForgotPassword: typeof ForgotPassword,\n SignOut: typeof SignOut,\n OAuthCallback: typeof OAuthCallback,\n MagicLinkCallback: typeof MagicLinkCallback,\n TeamInvitation: typeof TeamInvitation,\n ErrorPage: typeof ErrorPage,\n AccountSettings: typeof AccountSettings,\n};\n\n\nexport default async function StackHandler<HasTokenStore extends boolean>(props: {\n app: StackServerApp<HasTokenStore>,\n params?: { stack?: string[] },\n searchParams?: Record<string, string>,\n fullPage: boolean,\n componentProps?: {\n [K in keyof Components]?: Parameters<Components[K]>;\n },\n}) {\n if (!props.params?.stack) {\n return (\n <MessageCard title=\"Invalid Stack Handler Setup\" fullPage={props.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 = props.app.urls[name];\n const handlerUrl = props.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(props.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 magicLinkCallback: 'magic-link-callback',\n teamInvitation: 'team-invitation',\n accountSettings: 'account-settings',\n error: 'error',\n };\n\n const path = props.params.stack.join('/');\n\n switch (path) {\n case availablePaths.signIn: {\n redirectIfNotHandler('signIn');\n return <SignIn\n fullPage={props.fullPage}\n automaticRedirect\n {...filterUndefinedINU(props.componentProps?.SignIn)}\n />;\n }\n case availablePaths.signUp: {\n redirectIfNotHandler('signUp');\n return <SignUp\n fullPage={props.fullPage}\n automaticRedirect\n {...filterUndefinedINU(props.componentProps?.SignUp)}\n />;\n }\n case availablePaths.emailVerification: {\n redirectIfNotHandler('emailVerification');\n return <EmailVerification\n searchParams={props.searchParams}\n fullPage={props.fullPage}\n {...filterUndefinedINU(props.componentProps?.EmailVerification)}\n />;\n }\n case availablePaths.passwordReset: {\n redirectIfNotHandler('passwordReset');\n return <PasswordReset\n searchParams={props.searchParams || {}}\n fullPage={props.fullPage}\n {...filterUndefinedINU(props.componentProps?.PasswordReset)}\n />;\n }\n case availablePaths.forgotPassword: {\n redirectIfNotHandler('forgotPassword');\n return <ForgotPassword\n fullPage={props.fullPage}\n {...filterUndefinedINU(props.componentProps?.ForgotPassword)}\n />;\n }\n case availablePaths.signOut: {\n redirectIfNotHandler('signOut');\n return <SignOut\n fullPage={props.fullPage}\n {...filterUndefinedINU(props.componentProps?.SignOut)}\n />;\n }\n case availablePaths.oauthCallback: {\n redirectIfNotHandler('oauthCallback');\n return <OAuthCallback\n fullPage={props.fullPage}\n {...filterUndefinedINU(props.componentProps?.OAuthCallback)}\n />;\n }\n case availablePaths.magicLinkCallback: {\n redirectIfNotHandler('magicLinkCallback');\n return <MagicLinkCallback\n searchParams={props.searchParams || {}}\n fullPage={props.fullPage}\n {...filterUndefinedINU(props.componentProps?.MagicLinkCallback)}\n />;\n }\n case availablePaths.teamInvitation: {\n redirectIfNotHandler('teamInvitation');\n return <TeamInvitation\n searchParams={props.searchParams || {}}\n fullPage={props.fullPage}\n {...filterUndefinedINU(props.componentProps?.TeamInvitation)}\n />;\n }\n case availablePaths.accountSettings: {\n return <AccountSettings\n fullPage={props.fullPage}\n {...filterUndefinedINU(props.componentProps?.AccountSettings)}\n />;\n }\n case availablePaths.error: {\n return <ErrorPage\n searchParams={props.searchParams || {}}\n fullPage={props.fullPage}\n {...filterUndefinedINU(props.componentProps?.ErrorPage)}\n />;\n }\n default: {\n for (const [key, value] of Object.entries(availablePaths)) {\n if (path === value.replaceAll('-', '')) {\n redirect(`${props.app.urls.handler}/${value}`, RedirectType.replace);\n }\n }\n return notFound();\n }\n }\n}\n\n\nfunction filterUndefinedINU<T extends {}>(value: T | undefined): FilterUndefined<T> | undefined {\n return value === undefined ? value : filterUndefined(value);\n}\n"],"mappings":"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","names":[]}