@stackframe/stack 2.6.28 → 2.6.30

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 (62) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/components/elements/sidebar-layout.d.mts +1 -2
  3. package/dist/components/elements/sidebar-layout.d.ts +1 -2
  4. package/dist/components/elements/sidebar-layout.js +1 -1
  5. package/dist/components/elements/sidebar-layout.js.map +1 -1
  6. package/dist/components/message-cards/known-error-message-card.js +2 -2
  7. package/dist/components/message-cards/known-error-message-card.js.map +1 -1
  8. package/dist/components/message-cards/predefined-message-card.js +5 -5
  9. package/dist/components/message-cards/predefined-message-card.js.map +1 -1
  10. package/dist/components-page/account-settings.d.mts +7 -4
  11. package/dist/components-page/account-settings.d.ts +7 -4
  12. package/dist/components-page/account-settings.js +73 -41
  13. package/dist/components-page/account-settings.js.map +1 -1
  14. package/dist/components-page/email-verification.js +3 -3
  15. package/dist/components-page/email-verification.js.map +1 -1
  16. package/dist/components-page/error-page.js +6 -6
  17. package/dist/components-page/error-page.js.map +1 -1
  18. package/dist/components-page/magic-link-callback.js +4 -4
  19. package/dist/components-page/magic-link-callback.js.map +1 -1
  20. package/dist/components-page/team-invitation.js +2 -2
  21. package/dist/components-page/team-invitation.js.map +1 -1
  22. package/dist/esm/components/elements/sidebar-layout.js +1 -1
  23. package/dist/esm/components/elements/sidebar-layout.js.map +1 -1
  24. package/dist/esm/components/message-cards/known-error-message-card.js +2 -2
  25. package/dist/esm/components/message-cards/known-error-message-card.js.map +1 -1
  26. package/dist/esm/components/message-cards/predefined-message-card.js +5 -5
  27. package/dist/esm/components/message-cards/predefined-message-card.js.map +1 -1
  28. package/dist/esm/components-page/account-settings.js +75 -43
  29. package/dist/esm/components-page/account-settings.js.map +1 -1
  30. package/dist/esm/components-page/email-verification.js +3 -3
  31. package/dist/esm/components-page/email-verification.js.map +1 -1
  32. package/dist/esm/components-page/error-page.js +6 -6
  33. package/dist/esm/components-page/error-page.js.map +1 -1
  34. package/dist/esm/components-page/magic-link-callback.js +4 -4
  35. package/dist/esm/components-page/magic-link-callback.js.map +1 -1
  36. package/dist/esm/components-page/team-invitation.js +2 -2
  37. package/dist/esm/components-page/team-invitation.js.map +1 -1
  38. package/dist/esm/generated/global-css.js +1 -1
  39. package/dist/esm/generated/global-css.js.map +1 -1
  40. package/dist/esm/generated/quetzal-translations.js +1233 -1221
  41. package/dist/esm/generated/quetzal-translations.js.map +1 -1
  42. package/dist/esm/lib/stack-app.js +50 -1
  43. package/dist/esm/lib/stack-app.js.map +1 -1
  44. package/dist/esm/providers/theme-provider.js +1 -0
  45. package/dist/esm/providers/theme-provider.js.map +1 -1
  46. package/dist/generated/global-css.d.mts +1 -1
  47. package/dist/generated/global-css.d.ts +1 -1
  48. package/dist/generated/global-css.js +1 -1
  49. package/dist/generated/global-css.js.map +1 -1
  50. package/dist/generated/quetzal-translations.d.mts +2 -2
  51. package/dist/generated/quetzal-translations.d.ts +2 -2
  52. package/dist/generated/quetzal-translations.js +1233 -1221
  53. package/dist/generated/quetzal-translations.js.map +1 -1
  54. package/dist/index.d.mts +1 -1
  55. package/dist/index.d.ts +1 -1
  56. package/dist/lib/stack-app.d.mts +9 -1
  57. package/dist/lib/stack-app.d.ts +9 -1
  58. package/dist/lib/stack-app.js +50 -1
  59. package/dist/lib/stack-app.js.map +1 -1
  60. package/dist/providers/theme-provider.js +1 -0
  61. package/dist/providers/theme-provider.js.map +1 -1
  62. package/package.json +4 -4
@@ -1 +1 @@
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":[]}
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 { 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?: React.ReactNode,\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}\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":";;;AAEA,SAAS,eAAe;AACxB,SAAS,QAAQ,YAAY,UAAU;AACvC,SAAS,aAAa;AACtB,SAAS,iBAAiB;AAC1B,SAA2B,iBAAiB;AAwBxC,mBAEI,KAFJ;AAZG,SAAS,cAAc,OAAwE;AACpG,QAAM,SAAS,UAAU;AACzB,QAAM,OAAO,QAAQ;AACrB,QAAM,gBAAgB,MAAM,MAAM,UAAU,UAAQ,KAAK,MAAO,KAAK,OAAO,IAAK;AAEjF,YAAU,MAAM;AACd,QAAI,kBAAkB,IAAI;AACxB,aAAO,KAAK,MAAM,MAAM,MAAM,CAAC,EAAE,EAAE;AAAA,IACrC;AAAA,EACF,GAAG,CAAC,IAAI,CAAC;AAET,SACE,iCACE;AAAA,wBAAC,SAAI,WAAW,GAAG,qCAAqC,MAAM,SAAS,GACrE,8BAAC,iBAAc,OAAO,MAAM,OAAO,OAAO,MAAM,OAAO,eAA8B,GACvF;AAAA,IACA,oBAAC,SAAI,WAAW,GAAG,gCAAgC,MAAM,SAAS,GAChE,8BAAC,gBAAa,OAAO,MAAM,OAAO,OAAO,MAAM,OAAO,eAA8B,GACtF;AAAA,KACF;AAEJ;AAEA,SAAS,MAAM,OAAwD;AACrE,QAAM,SAAS,UAAU;AAEzB,SAAO,MAAM,MAAM,IAAI,CAAC,MAAM,UAC5B,KAAK,SAAS,SACZ;AAAA,IAAC;AAAA;AAAA,MAEC,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,WAAW;AAAA,QACT,MAAM,kBAAkB,SAAS;AAAA,QACjC;AAAA,MACF;AAAA,MACA,SAAS,MAAM;AACb,YAAI,KAAK,IAAI;AACX,iBAAO,KAAK,MAAM,KAAK,EAAE;AAAA,QAC3B;AAAA,MACF;AAAA,MAEC;AAAA,aAAK;AAAA,QACL,KAAK;AAAA;AAAA;AAAA,IAdD;AAAA,EAeP,IACA,oBAAC,cACE,eAAK,SADS,KAEjB,CACH;AAEH;AAEA,SAAS,cAAc,OAA2E;AAChG,QAAM,eAAe,MAAM,MAAM,MAAM,kBAAkB,KAAK,IAAI,MAAM,aAAa;AAErF,SACE,qBAAC,SAAI,WAAU,sDACb;AAAA,yBAAC,SAAI,WAAU,8FACZ;AAAA,YAAM,SAAS,oBAAC,SAAI,WAAU,aAC7B,8BAAC,cAAW,MAAK,MAAK,WAAU,0DAA0D,gBAAM,OAAM,GACxG;AAAA,MAEA,oBAAC,SAAM,OAAO,MAAM,OAAO,eAAe,MAAM,eAAe;AAAA,OACjE;AAAA,IACA,oBAAC,SAAI,WAAU,kDACb,+BAAC,SAAI,WAAU,yCACb;AAAA,2BAAC,SAAI,WAAU,aACb;AAAA,4BAAC,cAAW,MAAK,MAAK,WAAU,iBAAiB,uBAAa,OAAM;AAAA,QACnE,aAAa,eAAe,oBAAC,cAAW,SAAQ,aAAY,MAAK,SAAS,uBAAa,aAAY;AAAA,SACtG;AAAA,MACA,oBAAC,SAAI,WAAU,UACZ,uBAAa,SAChB;AAAA,OACF,GACF;AAAA,KACF;AAEJ;AAEA,SAAS,aAAa,OAA2E;AAC/F,QAAM,eAAe,MAAM,MAAM,MAAM,aAAa;AACpD,QAAM,SAAS,UAAU;AAEzB,MAAI,MAAM,kBAAkB,IAAI;AAC9B,WACE,qBAAC,SAAI,WAAU,2BACZ;AAAA,YAAM,SAAS,oBAAC,SAAI,WAAU,aAC7B,8BAAC,cAAW,MAAK,MAAK,WAAU,0DAA0D,gBAAM,OAAM,GACxG;AAAA,MAEA,oBAAC,SAAM,OAAO,MAAM,OAAO,eAAe,MAAM,eAAe;AAAA,OACjE;AAAA,EAEJ,OAAO;AACL,WACE,qBAAC,SAAI,WAAU,wCACb;AAAA,2BAAC,SAAI,WAAU,iBACb;AAAA,6BAAC,SAAI,WAAU,wBACb;AAAA,8BAAC,cAAW,MAAK,MAAK,WAAU,iBAAiB,uBAAa,OAAM;AAAA,UACpE;AAAA,YAAC;AAAA;AAAA,cACC,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,SAAS,MAAM;AAAE,uBAAO,KAAK,GAAG;AAAA,cAAG;AAAA,cAEnC,8BAAC,SAAM,WAAU,WAAU;AAAA;AAAA,UAC7B;AAAA,WACF;AAAA,QACC,aAAa,eAAe,oBAAC,cAAW,SAAQ,aAAY,MAAK,SAAS,uBAAa,aAAY;AAAA,SACtG;AAAA,MACA,oBAAC,SAAI,WAAU,UACZ,uBAAa,SAChB;AAAA,OACF;AAAA,EAEJ;AACF;","names":[]}
@@ -2,8 +2,8 @@
2
2
  "use client";
3
3
 
4
4
  // src/components/message-cards/known-error-message-card.tsx
5
- import { useStackApp } from "../..";
6
5
  import { Typography } from "@stackframe/stack-ui";
6
+ import { useStackApp } from "../..";
7
7
  import { MessageCard } from "./message-card";
8
8
  import { jsxs } from "react/jsx-runtime";
9
9
  function KnownErrorMessageCard({
@@ -16,7 +16,7 @@ function KnownErrorMessageCard({
16
16
  {
17
17
  title: "An error occurred",
18
18
  fullPage,
19
- primaryButtonText: "Go to Home",
19
+ primaryButtonText: "Go Home",
20
20
  primaryAction: () => stackApp.redirectToHome(),
21
21
  children: [
22
22
  /* @__PURE__ */ jsxs(Typography, { children: [
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/message-cards/known-error-message-card.tsx"],"sourcesContent":["\"use client\";\n\nimport { useStackApp } from \"../..\";\nimport { Typography } from \"@stackframe/stack-ui\";\nimport { MessageCard } from \"./message-card\";\nimport { KnownError } from \"@stackframe/stack-shared\";\n\nexport function KnownErrorMessageCard({\n error,\n fullPage=false,\n}: {\n error: KnownError,\n fullPage?: boolean,\n}) {\n const stackApp = useStackApp();\n\n return (\n <MessageCard\n title={\"An error occurred\"}\n fullPage={fullPage}\n primaryButtonText={\"Go to Home\"}\n primaryAction={() => stackApp.redirectToHome()}\n >\n {<Typography>Error Code: {error.errorCode}</Typography>}\n {<Typography>Error Message: {error.message}</Typography>}\n </MessageCard>\n );\n}\n"],"mappings":";;;AAEA,SAAS,mBAAmB;AAC5B,SAAS,kBAAkB;AAC3B,SAAS,mBAAmB;AAmBrB;AAhBA,SAAS,sBAAsB;AAAA,EACpC;AAAA,EACA,WAAS;AACX,GAGG;AACD,QAAM,WAAW,YAAY;AAE7B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,MACP;AAAA,MACA,mBAAmB;AAAA,MACnB,eAAe,MAAM,SAAS,eAAe;AAAA,MAE5C;AAAA,6BAAC,cAAW;AAAA;AAAA,UAAa,MAAM;AAAA,WAAU;AAAA,QACzC,qBAAC,cAAW;AAAA;AAAA,UAAgB,MAAM;AAAA,WAAQ;AAAA;AAAA;AAAA,EAC7C;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../../src/components/message-cards/known-error-message-card.tsx"],"sourcesContent":["\"use client\";\n\nimport { KnownError } from \"@stackframe/stack-shared\";\nimport { Typography } from \"@stackframe/stack-ui\";\nimport { useStackApp } from \"../..\";\nimport { MessageCard } from \"./message-card\";\n\nexport function KnownErrorMessageCard({\n error,\n fullPage=false,\n}: {\n error: KnownError,\n fullPage?: boolean,\n}) {\n const stackApp = useStackApp();\n\n return (\n <MessageCard\n title={\"An error occurred\"}\n fullPage={fullPage}\n primaryButtonText={\"Go Home\"}\n primaryAction={() => stackApp.redirectToHome()}\n >\n {<Typography>Error Code: {error.errorCode}</Typography>}\n {<Typography>Error Message: {error.message}</Typography>}\n </MessageCard>\n );\n}\n"],"mappings":";;;AAGA,SAAS,kBAAkB;AAC3B,SAAS,mBAAmB;AAC5B,SAAS,mBAAmB;AAkBrB;AAhBA,SAAS,sBAAsB;AAAA,EACpC;AAAA,EACA,WAAS;AACX,GAGG;AACD,QAAM,WAAW,YAAY;AAE7B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,MACP;AAAA,MACA,mBAAmB;AAAA,MACnB,eAAe,MAAM,SAAS,eAAe;AAAA,MAE5C;AAAA,6BAAC,cAAW;AAAA;AAAA,UAAa,MAAM;AAAA,WAAU;AAAA,QACzC,qBAAC,cAAW;AAAA;AAAA,UAAgB,MAAM;AAAA,WAAQ;AAAA;AAAA;AAAA,EAC7C;AAEJ;","names":[]}
@@ -4,8 +4,8 @@
4
4
  // src/components/message-cards/predefined-message-card.tsx
5
5
  import { Typography } from "@stackframe/stack-ui";
6
6
  import { useStackApp } from "../..";
7
- import { MessageCard } from "./message-card";
8
7
  import { useTranslation } from "../../lib/translations";
8
+ import { MessageCard } from "./message-card";
9
9
  import { jsx } from "react/jsx-runtime";
10
10
  function PredefinedMessageCard({
11
11
  type,
@@ -24,7 +24,7 @@ function PredefinedMessageCard({
24
24
  title = t("You are already signed in");
25
25
  primaryAction = () => stackApp.redirectToHome();
26
26
  secondaryAction = () => stackApp.redirectToSignOut();
27
- primaryButton = t("Go to home");
27
+ primaryButton = t("Go home");
28
28
  secondaryButton = t("Sign out");
29
29
  break;
30
30
  }
@@ -38,7 +38,7 @@ function PredefinedMessageCard({
38
38
  title = t("Sign up for new users is not enabled at the moment.");
39
39
  primaryAction = () => stackApp.redirectToHome();
40
40
  secondaryAction = () => stackApp.redirectToSignIn();
41
- primaryButton = t("Go to home");
41
+ primaryButton = t("Go home");
42
42
  secondaryButton = t("Sign in");
43
43
  break;
44
44
  }
@@ -46,7 +46,7 @@ function PredefinedMessageCard({
46
46
  title = t("Email sent!");
47
47
  message = t("If the user with this e-mail address exists, an e-mail was sent to your inbox. Make sure to check your spam folder.");
48
48
  primaryAction = () => stackApp.redirectToHome();
49
- primaryButton = t("Go to home");
49
+ primaryButton = t("Go home");
50
50
  break;
51
51
  }
52
52
  case "passwordReset": {
@@ -60,7 +60,7 @@ function PredefinedMessageCard({
60
60
  title = t("An unknown error occurred");
61
61
  message = t("Please try again and if the problem persists, contact support.");
62
62
  primaryAction = () => stackApp.redirectToHome();
63
- primaryButton = t("Go to home");
63
+ primaryButton = t("Go home");
64
64
  break;
65
65
  }
66
66
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/message-cards/predefined-message-card.tsx"],"sourcesContent":["\"use client\";\n\nimport { Typography } from \"@stackframe/stack-ui\";\nimport { useStackApp, useUser } from \"../..\";\nimport { MessageCard } from \"./message-card\";\nimport { useTranslation } from \"../../lib/translations\";\n\nexport function PredefinedMessageCard({\n type,\n fullPage=false,\n}: {\n type: 'signedIn' | 'signedOut' | 'emailSent' | 'passwordReset' | 'unknownError' | 'signUpDisabled',\n fullPage?: boolean,\n}) {\n const stackApp = useStackApp();\n const { t } = useTranslation();\n\n let title: string;\n let message: string | null = null;\n let primaryButton: string | null = null;\n let secondaryButton: string | null = null;\n let primaryAction: (() => Promise<void> | void) | null = null;\n let secondaryAction: (() => Promise<void> | void) | null = null;\n\n switch (type) {\n case 'signedIn': {\n title = t(\"You are already signed in\");\n primaryAction = () => stackApp.redirectToHome();\n secondaryAction = () => stackApp.redirectToSignOut();\n primaryButton = t(\"Go to home\");\n secondaryButton = t(\"Sign out\");\n break;\n }\n case 'signedOut': {\n title = t(\"You are not currently signed in.\");\n primaryAction = () => stackApp.redirectToSignIn();\n primaryButton = t(\"Sign in\");\n break;\n }\n case 'signUpDisabled': {\n title = t(\"Sign up for new users is not enabled at the moment.\");\n primaryAction = () => stackApp.redirectToHome();\n secondaryAction = () => stackApp.redirectToSignIn();\n primaryButton = t(\"Go to home\");\n secondaryButton = t(\"Sign in\");\n break;\n }\n case 'emailSent': {\n title = t(\"Email sent!\");\n message = t(\"If the user with this e-mail address exists, an e-mail was sent to your inbox. Make sure to check your spam folder.\");\n primaryAction = () => stackApp.redirectToHome();\n primaryButton = t(\"Go to home\");\n break;\n }\n case 'passwordReset': {\n title = t(\"Password reset successfully!\");\n message = t(\"Your password has been reset. You can now sign in with your new password.\");\n primaryAction = () => stackApp.redirectToSignIn({ noRedirectBack: true });\n primaryButton = t(\"Sign in\");\n break;\n }\n case 'unknownError': {\n title = t(\"An unknown error occurred\");\n message = t(\"Please try again and if the problem persists, contact support.\");\n primaryAction = () => stackApp.redirectToHome();\n primaryButton = t(\"Go to home\");\n break;\n }\n }\n\n return (\n <MessageCard\n title={title}\n fullPage={fullPage}\n primaryButtonText={primaryButton}\n primaryAction={primaryAction}\n secondaryButtonText={secondaryButton || undefined}\n secondaryAction={secondaryAction || undefined}\n >\n {message && <Typography>{message}</Typography>}\n </MessageCard>\n );\n}\n"],"mappings":";;;AAEA,SAAS,kBAAkB;AAC3B,SAAS,mBAA4B;AACrC,SAAS,mBAAmB;AAC5B,SAAS,sBAAsB;AA0Eb;AAxEX,SAAS,sBAAsB;AAAA,EACpC;AAAA,EACA,WAAS;AACX,GAGG;AACD,QAAM,WAAW,YAAY;AAC7B,QAAM,EAAE,EAAE,IAAI,eAAe;AAE7B,MAAI;AACJ,MAAI,UAAyB;AAC7B,MAAI,gBAA+B;AACnC,MAAI,kBAAiC;AACrC,MAAI,gBAAqD;AACzD,MAAI,kBAAuD;AAE3D,UAAQ,MAAM;AAAA,IACZ,KAAK,YAAY;AACf,cAAQ,EAAE,2BAA2B;AACrC,sBAAgB,MAAM,SAAS,eAAe;AAC9C,wBAAkB,MAAM,SAAS,kBAAkB;AACnD,sBAAgB,EAAE,YAAY;AAC9B,wBAAkB,EAAE,UAAU;AAC9B;AAAA,IACF;AAAA,IACA,KAAK,aAAa;AAChB,cAAQ,EAAE,kCAAkC;AAC5C,sBAAgB,MAAM,SAAS,iBAAiB;AAChD,sBAAgB,EAAE,SAAS;AAC3B;AAAA,IACF;AAAA,IACA,KAAK,kBAAkB;AACrB,cAAQ,EAAE,qDAAqD;AAC/D,sBAAgB,MAAM,SAAS,eAAe;AAC9C,wBAAkB,MAAM,SAAS,iBAAiB;AAClD,sBAAgB,EAAE,YAAY;AAC9B,wBAAkB,EAAE,SAAS;AAC7B;AAAA,IACF;AAAA,IACA,KAAK,aAAa;AAChB,cAAQ,EAAE,aAAa;AACvB,gBAAU,EAAE,qHAAqH;AACjI,sBAAgB,MAAM,SAAS,eAAe;AAC9C,sBAAgB,EAAE,YAAY;AAC9B;AAAA,IACF;AAAA,IACA,KAAK,iBAAiB;AACpB,cAAQ,EAAE,8BAA8B;AACxC,gBAAU,EAAE,2EAA2E;AACvF,sBAAgB,MAAM,SAAS,iBAAiB,EAAE,gBAAgB,KAAK,CAAC;AACxE,sBAAgB,EAAE,SAAS;AAC3B;AAAA,IACF;AAAA,IACA,KAAK,gBAAgB;AACnB,cAAQ,EAAE,2BAA2B;AACrC,gBAAU,EAAE,gEAAgE;AAC5E,sBAAgB,MAAM,SAAS,eAAe;AAC9C,sBAAgB,EAAE,YAAY;AAC9B;AAAA,IACF;AAAA,EACF;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,mBAAmB;AAAA,MACnB;AAAA,MACA,qBAAqB,mBAAmB;AAAA,MACxC,iBAAiB,mBAAmB;AAAA,MAEnC,qBAAW,oBAAC,cAAY,mBAAQ;AAAA;AAAA,EACnC;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../../src/components/message-cards/predefined-message-card.tsx"],"sourcesContent":["\"use client\";\n\nimport { Typography } from \"@stackframe/stack-ui\";\nimport { useStackApp } from \"../..\";\nimport { useTranslation } from \"../../lib/translations\";\nimport { MessageCard } from \"./message-card\";\n\nexport function PredefinedMessageCard({\n type,\n fullPage=false,\n}: {\n type: 'signedIn' | 'signedOut' | 'emailSent' | 'passwordReset' | 'unknownError' | 'signUpDisabled',\n fullPage?: boolean,\n}) {\n const stackApp = useStackApp();\n const { t } = useTranslation();\n\n let title: string;\n let message: string | null = null;\n let primaryButton: string | null = null;\n let secondaryButton: string | null = null;\n let primaryAction: (() => Promise<void> | void) | null = null;\n let secondaryAction: (() => Promise<void> | void) | null = null;\n\n switch (type) {\n case 'signedIn': {\n title = t(\"You are already signed in\");\n primaryAction = () => stackApp.redirectToHome();\n secondaryAction = () => stackApp.redirectToSignOut();\n primaryButton = t(\"Go home\");\n secondaryButton = t(\"Sign out\");\n break;\n }\n case 'signedOut': {\n title = t(\"You are not currently signed in.\");\n primaryAction = () => stackApp.redirectToSignIn();\n primaryButton = t(\"Sign in\");\n break;\n }\n case 'signUpDisabled': {\n title = t(\"Sign up for new users is not enabled at the moment.\");\n primaryAction = () => stackApp.redirectToHome();\n secondaryAction = () => stackApp.redirectToSignIn();\n primaryButton = t(\"Go home\");\n secondaryButton = t(\"Sign in\");\n break;\n }\n case 'emailSent': {\n title = t(\"Email sent!\");\n message = t(\"If the user with this e-mail address exists, an e-mail was sent to your inbox. Make sure to check your spam folder.\");\n primaryAction = () => stackApp.redirectToHome();\n primaryButton = t(\"Go home\");\n break;\n }\n case 'passwordReset': {\n title = t(\"Password reset successfully!\");\n message = t(\"Your password has been reset. You can now sign in with your new password.\");\n primaryAction = () => stackApp.redirectToSignIn({ noRedirectBack: true });\n primaryButton = t(\"Sign in\");\n break;\n }\n case 'unknownError': {\n title = t(\"An unknown error occurred\");\n message = t(\"Please try again and if the problem persists, contact support.\");\n primaryAction = () => stackApp.redirectToHome();\n primaryButton = t(\"Go home\");\n break;\n }\n }\n\n return (\n <MessageCard\n title={title}\n fullPage={fullPage}\n primaryButtonText={primaryButton}\n primaryAction={primaryAction}\n secondaryButtonText={secondaryButton || undefined}\n secondaryAction={secondaryAction || undefined}\n >\n {message && <Typography>{message}</Typography>}\n </MessageCard>\n );\n}\n"],"mappings":";;;AAEA,SAAS,kBAAkB;AAC3B,SAAS,mBAAmB;AAC5B,SAAS,sBAAsB;AAC/B,SAAS,mBAAmB;AA0EV;AAxEX,SAAS,sBAAsB;AAAA,EACpC;AAAA,EACA,WAAS;AACX,GAGG;AACD,QAAM,WAAW,YAAY;AAC7B,QAAM,EAAE,EAAE,IAAI,eAAe;AAE7B,MAAI;AACJ,MAAI,UAAyB;AAC7B,MAAI,gBAA+B;AACnC,MAAI,kBAAiC;AACrC,MAAI,gBAAqD;AACzD,MAAI,kBAAuD;AAE3D,UAAQ,MAAM;AAAA,IACZ,KAAK,YAAY;AACf,cAAQ,EAAE,2BAA2B;AACrC,sBAAgB,MAAM,SAAS,eAAe;AAC9C,wBAAkB,MAAM,SAAS,kBAAkB;AACnD,sBAAgB,EAAE,SAAS;AAC3B,wBAAkB,EAAE,UAAU;AAC9B;AAAA,IACF;AAAA,IACA,KAAK,aAAa;AAChB,cAAQ,EAAE,kCAAkC;AAC5C,sBAAgB,MAAM,SAAS,iBAAiB;AAChD,sBAAgB,EAAE,SAAS;AAC3B;AAAA,IACF;AAAA,IACA,KAAK,kBAAkB;AACrB,cAAQ,EAAE,qDAAqD;AAC/D,sBAAgB,MAAM,SAAS,eAAe;AAC9C,wBAAkB,MAAM,SAAS,iBAAiB;AAClD,sBAAgB,EAAE,SAAS;AAC3B,wBAAkB,EAAE,SAAS;AAC7B;AAAA,IACF;AAAA,IACA,KAAK,aAAa;AAChB,cAAQ,EAAE,aAAa;AACvB,gBAAU,EAAE,qHAAqH;AACjI,sBAAgB,MAAM,SAAS,eAAe;AAC9C,sBAAgB,EAAE,SAAS;AAC3B;AAAA,IACF;AAAA,IACA,KAAK,iBAAiB;AACpB,cAAQ,EAAE,8BAA8B;AACxC,gBAAU,EAAE,2EAA2E;AACvF,sBAAgB,MAAM,SAAS,iBAAiB,EAAE,gBAAgB,KAAK,CAAC;AACxE,sBAAgB,EAAE,SAAS;AAC3B;AAAA,IACF;AAAA,IACA,KAAK,gBAAgB;AACnB,cAAQ,EAAE,2BAA2B;AACrC,gBAAU,EAAE,gEAAgE;AAC5E,sBAAgB,MAAM,SAAS,eAAe;AAC9C,sBAAgB,EAAE,SAAS;AAC3B;AAAA,IACF;AAAA,EACF;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,mBAAmB;AAAA,MACnB;AAAA,MACA,qBAAqB,mBAAmB;AAAA,MACxC,iBAAiB,mBAAmB;AAAA,MAEnC,qBAAW,oBAAC,cAAY,mBAAQ;AAAA;AAAA,EACnC;AAEJ;","names":[]}
@@ -5,12 +5,12 @@
5
5
  import { yupResolver } from "@hookform/resolvers/yup";
6
6
  import { getPasswordError } from "@stackframe/stack-shared/dist/helpers/password";
7
7
  import { useAsyncCallback } from "@stackframe/stack-shared/dist/hooks/use-async-callback";
8
- import { emailSchema, passwordSchema as schemaFieldsPasswordSchema, strictEmailSchema, yupObject, yupString } from "@stackframe/stack-shared/dist/schema-fields";
8
+ import { passwordSchema as schemaFieldsPasswordSchema, strictEmailSchema, yupObject, yupString } from "@stackframe/stack-shared/dist/schema-fields";
9
9
  import { generateRandomValues } from "@stackframe/stack-shared/dist/utils/crypto";
10
10
  import { throwErr } from "@stackframe/stack-shared/dist/utils/errors";
11
11
  import { runAsynchronously, runAsynchronouslyWithAlert } from "@stackframe/stack-shared/dist/utils/promises";
12
12
  import { Accordion, AccordionContent, AccordionItem, AccordionTrigger, ActionCell, Badge, Button, Input, Label, PasswordInput, Separator, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Typography } from "@stackframe/stack-ui";
13
- import { CirclePlus, Contact, Edit, Settings, ShieldCheck } from "lucide-react";
13
+ import { Edit, Trash, icons } from "lucide-react";
14
14
  import { useRouter } from "next/navigation";
15
15
  import { TOTPController, createTOTPKeyURI } from "oslo/otp";
16
16
  import * as QRCode from "qrcode";
@@ -26,6 +26,10 @@ import { ProfileImageEditor } from "../components/profile-image-editor";
26
26
  import { TeamIcon } from "../components/team-icon";
27
27
  import { useTranslation } from "../lib/translations";
28
28
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
29
+ var Icon = ({ name }) => {
30
+ const LucideIcon = icons[name];
31
+ return /* @__PURE__ */ jsx(LucideIcon, { className: "mr-2 h-4 w-4" });
32
+ };
29
33
  function AccountSettings(props) {
30
34
  const { t } = useTranslation();
31
35
  const user = useUser({ or: "redirect" });
@@ -40,28 +44,36 @@ function AccountSettings(props) {
40
44
  title: t("My Profile"),
41
45
  type: "item",
42
46
  id: "profile",
43
- icon: Contact,
47
+ icon: /* @__PURE__ */ jsx(Icon, { name: "Contact" }),
44
48
  content: /* @__PURE__ */ jsx(ProfilePage, {})
45
49
  },
46
50
  {
47
51
  title: t("Emails & Auth"),
48
52
  type: "item",
49
53
  id: "auth",
50
- icon: ShieldCheck,
54
+ icon: /* @__PURE__ */ jsx(Icon, { name: "ShieldCheck" }),
51
55
  content: /* @__PURE__ */ jsx(EmailsAndAuthPage, {})
52
56
  },
53
57
  {
54
58
  title: t("Settings"),
55
59
  type: "item",
56
60
  id: "settings",
57
- icon: Settings,
61
+ icon: /* @__PURE__ */ jsx(Icon, { name: "Settings" }),
58
62
  content: /* @__PURE__ */ jsx(SettingsPage, {})
59
63
  },
60
64
  ...props.extraItems?.map((item) => ({
61
65
  title: item.title,
62
66
  type: "item",
63
67
  id: item.id,
64
- icon: item.icon,
68
+ icon: (() => {
69
+ const iconName = item.iconName;
70
+ if (iconName) {
71
+ return /* @__PURE__ */ jsx(Icon, { name: iconName });
72
+ } else if (item.icon) {
73
+ return item.icon;
74
+ }
75
+ return null;
76
+ })(),
65
77
  content: item.content
66
78
  })) || [],
67
79
  ...teams.length > 0 || project.config.clientTeamCreationEnabled ? [{
@@ -79,7 +91,7 @@ function AccountSettings(props) {
79
91
  })),
80
92
  ...project.config.clientTeamCreationEnabled ? [{
81
93
  title: t("Create a team"),
82
- icon: CirclePlus,
94
+ icon: /* @__PURE__ */ jsx(Icon, { name: "CirclePlus" }),
83
95
  type: "item",
84
96
  id: "team-creation",
85
97
  content: /* @__PURE__ */ jsx(TeamCreation, {})
@@ -164,11 +176,11 @@ function EmailsSection() {
164
176
  });
165
177
  }
166
178
  }, [contactChannels, addedEmail]);
167
- const emailSchema2 = yupObject({
179
+ const emailSchema = yupObject({
168
180
  email: strictEmailSchema(t("Please enter a valid email address")).notOneOf(contactChannels.map((x) => x.value), t("Email already exists")).defined().nonEmpty(t("Email is required"))
169
181
  });
170
182
  const { register, handleSubmit, formState: { errors }, reset } = useForm({
171
- resolver: yupResolver(emailSchema2)
183
+ resolver: yupResolver(emailSchema)
172
184
  });
173
185
  const onSubmit = async (data) => {
174
186
  setAddingEmailLoading(true);
@@ -660,8 +672,8 @@ function TeamPage(props) {
660
672
  const memberListSection = useMemberListSection(props);
661
673
  return /* @__PURE__ */ jsxs(PageLayout, { children: [
662
674
  teamUserProfileSection,
663
- memberInvitationSection,
664
675
  memberListSection,
676
+ memberInvitationSection,
665
677
  teamProfileImageSection,
666
678
  teamDisplayNameSection,
667
679
  leaveTeamSection
@@ -780,13 +792,19 @@ function useTeamUserProfileSection(props) {
780
792
  function useMemberInvitationSection(props) {
781
793
  const { t } = useTranslation();
782
794
  const invitationSchema = yupObject({
783
- email: emailSchema.defined().nonEmpty(t("Please enter an email address"))
795
+ email: strictEmailSchema(t("Please enter a valid email address")).defined().nonEmpty(t("Please enter an email address"))
784
796
  });
785
797
  const user = useUser({ or: "redirect" });
786
798
  const inviteMemberPermission = user.usePermission(props.team, "$invite_members");
799
+ const readMemberPermission = user.usePermission(props.team, "$read_members");
800
+ const removeMemberPermission = user.usePermission(props.team, "$remove_members");
787
801
  if (!inviteMemberPermission) {
788
802
  return null;
789
803
  }
804
+ let invitationsToShow = [];
805
+ if (readMemberPermission) {
806
+ invitationsToShow = props.team.useInvitations();
807
+ }
790
808
  const { register, handleSubmit, formState: { errors }, watch } = useForm({
791
809
  resolver: yupResolver(invitationSchema)
792
810
  });
@@ -804,38 +822,52 @@ function useMemberInvitationSection(props) {
804
822
  useEffect(() => {
805
823
  setInvitedEmail(null);
806
824
  }, [watch("email")]);
807
- return /* @__PURE__ */ jsx(
808
- Section,
809
- {
810
- title: t("Invite member"),
811
- description: t("Invite a user to your team through email"),
812
- children: /* @__PURE__ */ jsxs(
813
- "form",
814
- {
815
- onSubmit: (e) => runAsynchronouslyWithAlert(handleSubmit(onSubmit)(e)),
816
- noValidate: true,
817
- className: "w-full",
818
- children: [
819
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4 sm:flex-row w-full", children: [
820
- /* @__PURE__ */ jsx(
821
- Input,
822
- {
823
- placeholder: t("Email"),
824
- ...register("email")
825
- }
826
- ),
827
- /* @__PURE__ */ jsx(Button, { type: "submit", loading, children: t("Invite User") })
828
- ] }),
829
- /* @__PURE__ */ jsx(FormWarningText, { text: errors.email?.message?.toString() }),
830
- invitedEmail && /* @__PURE__ */ jsxs(Typography, { type: "label", variant: "secondary", children: [
831
- "Invited ",
832
- invitedEmail
833
- ] })
834
- ]
835
- }
836
- )
837
- }
838
- );
825
+ return /* @__PURE__ */ jsxs("div", { children: [
826
+ /* @__PURE__ */ jsx(
827
+ Section,
828
+ {
829
+ title: t("Invite member"),
830
+ description: t("Invite a user to your team through email"),
831
+ children: /* @__PURE__ */ jsxs(
832
+ "form",
833
+ {
834
+ onSubmit: (e) => runAsynchronouslyWithAlert(handleSubmit(onSubmit)(e)),
835
+ noValidate: true,
836
+ className: "w-full",
837
+ children: [
838
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4 sm:flex-row w-full", children: [
839
+ /* @__PURE__ */ jsx(
840
+ Input,
841
+ {
842
+ placeholder: t("Email"),
843
+ ...register("email")
844
+ }
845
+ ),
846
+ /* @__PURE__ */ jsx(Button, { type: "submit", loading, children: t("Invite User") })
847
+ ] }),
848
+ /* @__PURE__ */ jsx(FormWarningText, { text: errors.email?.message?.toString() }),
849
+ invitedEmail && /* @__PURE__ */ jsxs(Typography, { type: "label", variant: "secondary", children: [
850
+ "Invited ",
851
+ invitedEmail
852
+ ] })
853
+ ]
854
+ }
855
+ )
856
+ }
857
+ ),
858
+ invitationsToShow.length > 0 && /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(Table, { className: "mt-6", children: [
859
+ /* @__PURE__ */ jsx(TableHeader, { children: /* @__PURE__ */ jsxs(TableRow, { children: [
860
+ /* @__PURE__ */ jsx(TableHead, { className: "w-[200px]", children: t("Outstanding invitations") }),
861
+ /* @__PURE__ */ jsx(TableHead, { className: "w-[60px]", children: t("Expires") }),
862
+ /* @__PURE__ */ jsx(TableHead, { className: "w-[36px] max-w-[36px]" })
863
+ ] }) }),
864
+ /* @__PURE__ */ jsx(TableBody, { children: invitationsToShow.map((invitation, i) => /* @__PURE__ */ jsxs(TableRow, { children: [
865
+ /* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsx(Typography, { children: invitation.recipientEmail }) }),
866
+ /* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsx(Typography, { variant: "secondary", children: invitation.expiresAt.toLocaleString() }) }),
867
+ /* @__PURE__ */ jsx(TableCell, { align: "right", className: "max-w-[36px]", children: removeMemberPermission && /* @__PURE__ */ jsx(Button, { onClick: async () => await invitation.revoke(), size: "icon", variant: "ghost", children: /* @__PURE__ */ jsx(Trash, { className: "w-4 h-4" }) }) })
868
+ ] }, invitation.id)) })
869
+ ] }) })
870
+ ] });
839
871
  }
840
872
  function useMemberListSection(props) {
841
873
  const { t } = useTranslation();