@stackframe/stack 2.7.19 → 2.7.21

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 (150) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/components/credential-sign-in.js +2 -1
  3. package/dist/components/credential-sign-in.js.map +1 -1
  4. package/dist/components/credential-sign-up.js.map +1 -1
  5. package/dist/components/elements/form-warning.js.map +1 -1
  6. package/dist/components/elements/maybe-full-page.js.map +1 -1
  7. package/dist/components/elements/separator-with-text.js.map +1 -1
  8. package/dist/components/elements/sidebar-layout.js +10 -7
  9. package/dist/components/elements/sidebar-layout.js.map +1 -1
  10. package/dist/components/elements/ssr-layout-effect.js.map +1 -1
  11. package/dist/components/elements/user-avatar.js.map +1 -1
  12. package/dist/components/iframe-preventer.js.map +1 -1
  13. package/dist/components/link.d.mts +14 -0
  14. package/dist/components/link.d.ts +14 -0
  15. package/dist/components/link.js +63 -0
  16. package/dist/components/link.js.map +1 -0
  17. package/dist/components/magic-link-sign-in.js.map +1 -1
  18. package/dist/components/message-cards/known-error-message-card.js.map +1 -1
  19. package/dist/components/message-cards/message-card.js.map +1 -1
  20. package/dist/components/message-cards/predefined-message-card.js.map +1 -1
  21. package/dist/components/oauth-button-group.js.map +1 -1
  22. package/dist/components/oauth-button.js.map +1 -1
  23. package/dist/components/passkey-button.js.map +1 -1
  24. package/dist/components/profile-image-editor.js.map +1 -1
  25. package/dist/components/selected-team-switcher.js +4 -5
  26. package/dist/components/selected-team-switcher.js.map +1 -1
  27. package/dist/components/team-icon.js.map +1 -1
  28. package/dist/components/user-button.js.map +1 -1
  29. package/dist/components-page/account-settings.js +2 -3
  30. package/dist/components-page/account-settings.js.map +1 -1
  31. package/dist/components-page/auth-page.js +3 -2
  32. package/dist/components-page/auth-page.js.map +1 -1
  33. package/dist/components-page/email-verification.js.map +1 -1
  34. package/dist/components-page/error-page.js.map +1 -1
  35. package/dist/components-page/forgot-password.js +2 -1
  36. package/dist/components-page/forgot-password.js.map +1 -1
  37. package/dist/components-page/magic-link-callback.js.map +1 -1
  38. package/dist/components-page/oauth-callback.js +4 -4
  39. package/dist/components-page/oauth-callback.js.map +1 -1
  40. package/dist/components-page/password-reset.js.map +1 -1
  41. package/dist/components-page/sign-in.js.map +1 -1
  42. package/dist/components-page/sign-out.js.map +1 -1
  43. package/dist/components-page/sign-up.js.map +1 -1
  44. package/dist/components-page/stack-handler.d.mts +5 -3
  45. package/dist/components-page/stack-handler.d.ts +5 -3
  46. package/dist/components-page/stack-handler.js +173 -157
  47. package/dist/components-page/stack-handler.js.map +1 -1
  48. package/dist/components-page/team-creation.js +2 -3
  49. package/dist/components-page/team-creation.js.map +1 -1
  50. package/dist/components-page/team-invitation.js.map +1 -1
  51. package/dist/esm/components/credential-sign-in.js +2 -1
  52. package/dist/esm/components/credential-sign-in.js.map +1 -1
  53. package/dist/esm/components/credential-sign-up.js.map +1 -1
  54. package/dist/esm/components/elements/form-warning.js.map +1 -1
  55. package/dist/esm/components/elements/maybe-full-page.js.map +1 -1
  56. package/dist/esm/components/elements/separator-with-text.js.map +1 -1
  57. package/dist/esm/components/elements/sidebar-layout.js +10 -7
  58. package/dist/esm/components/elements/sidebar-layout.js.map +1 -1
  59. package/dist/esm/components/elements/ssr-layout-effect.js.map +1 -1
  60. package/dist/esm/components/elements/user-avatar.js.map +1 -1
  61. package/dist/esm/components/iframe-preventer.js.map +1 -1
  62. package/dist/esm/components/link.js +28 -0
  63. package/dist/esm/components/link.js.map +1 -0
  64. package/dist/esm/components/magic-link-sign-in.js.map +1 -1
  65. package/dist/esm/components/message-cards/known-error-message-card.js.map +1 -1
  66. package/dist/esm/components/message-cards/message-card.js.map +1 -1
  67. package/dist/esm/components/message-cards/predefined-message-card.js.map +1 -1
  68. package/dist/esm/components/oauth-button-group.js.map +1 -1
  69. package/dist/esm/components/oauth-button.js.map +1 -1
  70. package/dist/esm/components/passkey-button.js.map +1 -1
  71. package/dist/esm/components/profile-image-editor.js.map +1 -1
  72. package/dist/esm/components/selected-team-switcher.js +4 -5
  73. package/dist/esm/components/selected-team-switcher.js.map +1 -1
  74. package/dist/esm/components/team-icon.js.map +1 -1
  75. package/dist/esm/components/user-button.js.map +1 -1
  76. package/dist/esm/components-page/account-settings.js +2 -3
  77. package/dist/esm/components-page/account-settings.js.map +1 -1
  78. package/dist/esm/components-page/auth-page.js +2 -1
  79. package/dist/esm/components-page/auth-page.js.map +1 -1
  80. package/dist/esm/components-page/email-verification.js.map +1 -1
  81. package/dist/esm/components-page/error-page.js.map +1 -1
  82. package/dist/esm/components-page/forgot-password.js +2 -1
  83. package/dist/esm/components-page/forgot-password.js.map +1 -1
  84. package/dist/esm/components-page/magic-link-callback.js.map +1 -1
  85. package/dist/esm/components-page/oauth-callback.js +4 -4
  86. package/dist/esm/components-page/oauth-callback.js.map +1 -1
  87. package/dist/esm/components-page/password-reset.js.map +1 -1
  88. package/dist/esm/components-page/sign-in.js.map +1 -1
  89. package/dist/esm/components-page/sign-out.js.map +1 -1
  90. package/dist/esm/components-page/sign-up.js.map +1 -1
  91. package/dist/esm/components-page/stack-handler.js +173 -157
  92. package/dist/esm/components-page/stack-handler.js.map +1 -1
  93. package/dist/esm/components-page/team-creation.js +2 -3
  94. package/dist/esm/components-page/team-creation.js.map +1 -1
  95. package/dist/esm/components-page/team-invitation.js.map +1 -1
  96. package/dist/esm/generated/quetzal-translations.js.map +1 -1
  97. package/dist/esm/index.js.map +1 -1
  98. package/dist/esm/lib/auth.js.map +1 -1
  99. package/dist/esm/lib/cookie.js +4 -7
  100. package/dist/esm/lib/cookie.js.map +1 -1
  101. package/dist/esm/lib/hooks.js.map +1 -1
  102. package/dist/esm/lib/stack-app.js +38 -16
  103. package/dist/esm/lib/stack-app.js.map +1 -1
  104. package/dist/esm/lib/translations.js.map +1 -1
  105. package/dist/esm/providers/stack-provider-client.js +1 -2
  106. package/dist/esm/providers/stack-provider-client.js.map +1 -1
  107. package/dist/esm/providers/stack-provider.js +8 -7
  108. package/dist/esm/providers/stack-provider.js.map +1 -1
  109. package/dist/esm/providers/theme-provider.js.map +1 -1
  110. package/dist/esm/providers/translation-provider-client.js.map +1 -1
  111. package/dist/esm/providers/translation-provider.js +1 -1
  112. package/dist/esm/providers/translation-provider.js.map +1 -1
  113. package/dist/esm/utils/browser-script.js.map +1 -1
  114. package/dist/esm/utils/constants.js.map +1 -1
  115. package/dist/esm/utils/url.js +4 -13
  116. package/dist/esm/utils/url.js.map +1 -1
  117. package/dist/generated/quetzal-translations.js.map +1 -1
  118. package/dist/index.js.map +1 -1
  119. package/dist/lib/auth.js.map +1 -1
  120. package/dist/lib/cookie.d.mts +2 -2
  121. package/dist/lib/cookie.d.ts +2 -2
  122. package/dist/lib/cookie.js +5 -8
  123. package/dist/lib/cookie.js.map +1 -1
  124. package/dist/lib/hooks.js.map +1 -1
  125. package/dist/lib/stack-app.d.mts +6 -1
  126. package/dist/lib/stack-app.d.ts +6 -1
  127. package/dist/lib/stack-app.js +37 -15
  128. package/dist/lib/stack-app.js.map +1 -1
  129. package/dist/lib/translations.js.map +1 -1
  130. package/dist/providers/stack-provider-client.d.mts +2 -1
  131. package/dist/providers/stack-provider-client.d.ts +2 -1
  132. package/dist/providers/stack-provider-client.js +1 -2
  133. package/dist/providers/stack-provider-client.js.map +1 -1
  134. package/dist/providers/stack-provider.d.mts +2 -2
  135. package/dist/providers/stack-provider.d.ts +2 -2
  136. package/dist/providers/stack-provider.js +8 -7
  137. package/dist/providers/stack-provider.js.map +1 -1
  138. package/dist/providers/theme-provider.js.map +1 -1
  139. package/dist/providers/translation-provider-client.js.map +1 -1
  140. package/dist/providers/translation-provider.d.mts +1 -1
  141. package/dist/providers/translation-provider.d.ts +1 -1
  142. package/dist/providers/translation-provider.js +1 -1
  143. package/dist/providers/translation-provider.js.map +1 -1
  144. package/dist/utils/browser-script.js.map +1 -1
  145. package/dist/utils/constants.js.map +1 -1
  146. package/dist/utils/url.d.mts +1 -2
  147. package/dist/utils/url.d.ts +1 -2
  148. package/dist/utils/url.js +4 -14
  149. package/dist/utils/url.js.map +1 -1
  150. package/package.json +5 -5
@@ -5,16 +5,17 @@
5
5
  import { useHash } from "@stackframe/stack-shared/dist/hooks/use-hash";
6
6
  import { Button, Typography, cn } from "@stackframe/stack-ui";
7
7
  import { XIcon } from "lucide-react";
8
- import { useRouter } from "next/navigation";
9
8
  import { useEffect } from "react";
9
+ import { useStackApp } from "../..";
10
10
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
11
11
  function SidebarLayout(props) {
12
- const router = useRouter();
12
+ const app = useStackApp();
13
+ const navigate = app.useNavigate();
13
14
  const hash = useHash();
14
15
  const selectedIndex = props.items.findIndex((item) => item.id && item.id === hash);
15
16
  useEffect(() => {
16
17
  if (selectedIndex === -1) {
17
- router.push("#" + props.items[0].id);
18
+ navigate("#" + props.items[0].id);
18
19
  }
19
20
  }, [hash]);
20
21
  return /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -23,7 +24,8 @@ function SidebarLayout(props) {
23
24
  ] });
24
25
  }
25
26
  function Items(props) {
26
- const router = useRouter();
27
+ const app = useStackApp();
28
+ const navigate = app.useNavigate();
27
29
  return props.items.map((item, index) => item.type === "item" ? /* @__PURE__ */ jsxs(
28
30
  Button,
29
31
  {
@@ -35,7 +37,7 @@ function Items(props) {
35
37
  ),
36
38
  onClick: () => {
37
39
  if (item.id) {
38
- router.push("#" + item.id);
40
+ navigate("#" + item.id);
39
41
  }
40
42
  },
41
43
  children: [
@@ -64,7 +66,8 @@ function DesktopLayout(props) {
64
66
  }
65
67
  function MobileLayout(props) {
66
68
  const selectedItem = props.items[props.selectedIndex];
67
- const router = useRouter();
69
+ const app = useStackApp();
70
+ const navigate = app.useNavigate();
68
71
  if (props.selectedIndex === -1) {
69
72
  return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 p-2", children: [
70
73
  props.title && /* @__PURE__ */ jsx("div", { className: "mb-2 ml-2", children: /* @__PURE__ */ jsx(Typography, { type: "h2", className: "text-lg font-semibold text-zinc-800 dark:text-zinc-300", children: props.title }) }),
@@ -81,7 +84,7 @@ function MobileLayout(props) {
81
84
  variant: "ghost",
82
85
  size: "icon",
83
86
  onClick: () => {
84
- router.push("#");
87
+ navigate("#");
85
88
  },
86
89
  children: /* @__PURE__ */ jsx(XIcon, { className: "h-5 w-5" })
87
90
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/elements/sidebar-layout.tsx"],"sourcesContent":["'use client';\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\n\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":";;;AAOA,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":[]}
1
+ {"version":3,"sources":["../../../../src/components/elements/sidebar-layout.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\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 React, { ReactNode, useEffect } from 'react';\nimport { useStackApp } from '../..';\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 app = useStackApp();\n const navigate = app.useNavigate();\n const hash = useHash();\n const selectedIndex = props.items.findIndex(item => item.id && (item.id === hash));\n\n useEffect(() => {\n if (selectedIndex === -1) {\n navigate('#' + 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 app = useStackApp();\n const navigate = app.useNavigate();\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 navigate('#' + 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 app = useStackApp();\n const navigate = app.useNavigate();\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={() => { navigate('#'); }}\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 +1 @@
1
- {"version":3,"sources":["../../../../src/components/elements/ssr-layout-effect.tsx"],"sourcesContent":["\"use client\";\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\n\nimport { useLayoutEffect } from \"react\";\n\nexport function SsrScript(props: { script: string, nonce?: string }) {\n useLayoutEffect(() => {\n // TODO fix workaround: React has a bug where it doesn't run the script on the first CSR render if SSR has been skipped due to suspense\n // As a workaround, we run the script in the <script> tag again after the first render\n // Note that we do an indirect eval as described here: https://esbuild.github.io/content-types/#direct-eval\n (0, eval)(props.script);\n }, []);\n\n return (\n <script\n suppressHydrationWarning // the transpiler is setup differently for client/server targets, so if `script` was generated with Function.toString they will differ\n nonce={props.nonce}\n dangerouslySetInnerHTML={{ __html: props.script }}\n />\n );\n}\n"],"mappings":";;;AAMA,SAAS,uBAAuB;AAW5B;AATG,SAAS,UAAU,OAA2C;AACnE,kBAAgB,MAAM;AAIpB,KAAC,GAAG,MAAM,MAAM,MAAM;AAAA,EACxB,GAAG,CAAC,CAAC;AAEL,SACE;AAAA,IAAC;AAAA;AAAA,MACC,0BAAwB;AAAA,MACxB,OAAO,MAAM;AAAA,MACb,yBAAyB,EAAE,QAAQ,MAAM,OAAO;AAAA;AAAA,EAClD;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../../src/components/elements/ssr-layout-effect.tsx"],"sourcesContent":["\"use client\";\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\nimport { useLayoutEffect } from \"react\";\n\nexport function SsrScript(props: { script: string, nonce?: string }) {\n useLayoutEffect(() => {\n // TODO fix workaround: React has a bug where it doesn't run the script on the first CSR render if SSR has been skipped due to suspense\n // As a workaround, we run the script in the <script> tag again after the first render\n // Note that we do an indirect eval as described here: https://esbuild.github.io/content-types/#direct-eval\n (0, eval)(props.script);\n }, []);\n\n return (\n <script\n suppressHydrationWarning // the transpiler is setup differently for client/server targets, so if `script` was generated with Function.toString they will differ\n nonce={props.nonce}\n dangerouslySetInnerHTML={{ __html: props.script }}\n />\n );\n}\n"],"mappings":";;;AAMA,SAAS,uBAAuB;AAW5B;AATG,SAAS,UAAU,OAA2C;AACnE,kBAAgB,MAAM;AAIpB,KAAC,GAAG,MAAM,MAAM,MAAM;AAAA,EACxB,GAAG,CAAC,CAAC;AAEL,SACE;AAAA,IAAC;AAAA;AAAA,MACC,0BAAwB;AAAA,MACxB,OAAO,MAAM;AAAA,MACb,yBAAyB,EAAE,QAAQ,MAAM,OAAO;AAAA;AAAA,EAClD;AAEJ;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/elements/user-avatar.tsx"],"sourcesContent":["//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@stackframe/stack-ui\";\nimport { UserRound } from \"lucide-react\";\n\nconst defaultSize = 34;\n\nexport function UserAvatar(props: {\n size?: number,\n user?: {\n profileImageUrl?: string | null,\n displayName?: string | null,\n primaryEmail?: string | null,\n } | null,\n border?: boolean,\n}) {\n const user = props.user;\n return (\n <Avatar style={{ height: props.size || defaultSize, width: props.size || defaultSize }} className={props.border ? 'border' : ''}>\n <AvatarImage src={user?.profileImageUrl || ''} />\n <AvatarFallback>\n {user ?\n <div className='font-medium' style={{ fontSize: (props.size || defaultSize) * 0.4 }}>\n {(user.displayName || user.primaryEmail)?.slice(0, 2).toUpperCase()}\n </div> :\n <UserRound className=\"text-zinc-500\" size={(props.size || defaultSize) * 0.6} />}\n </AvatarFallback>\n </Avatar>\n );\n}\n"],"mappings":";AAIA,SAAS,QAAQ,gBAAgB,mBAAmB;AACpD,SAAS,iBAAiB;AAetB,SACE,KADF;AAbJ,IAAM,cAAc;AAEb,SAAS,WAAW,OAQxB;AACD,QAAM,OAAO,MAAM;AACnB,SACE,qBAAC,UAAO,OAAO,EAAE,QAAQ,MAAM,QAAQ,aAAa,OAAO,MAAM,QAAQ,YAAY,GAAG,WAAW,MAAM,SAAS,WAAW,IAC3H;AAAA,wBAAC,eAAY,KAAK,MAAM,mBAAmB,IAAI;AAAA,IAC/C,oBAAC,kBACE,iBACC,oBAAC,SAAI,WAAU,eAAc,OAAO,EAAE,WAAW,MAAM,QAAQ,eAAe,IAAI,GAC9E,gBAAK,eAAe,KAAK,eAAe,MAAM,GAAG,CAAC,EAAE,YAAY,GACpE,IACA,oBAAC,aAAU,WAAU,iBAAgB,OAAO,MAAM,QAAQ,eAAe,KAAK,GAClF;AAAA,KACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../../src/components/elements/user-avatar.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\nimport { Avatar, AvatarFallback, AvatarImage } from \"@stackframe/stack-ui\";\nimport { UserRound } from \"lucide-react\";\n\nconst defaultSize = 34;\n\nexport function UserAvatar(props: {\n size?: number,\n user?: {\n profileImageUrl?: string | null,\n displayName?: string | null,\n primaryEmail?: string | null,\n } | null,\n border?: boolean,\n}) {\n const user = props.user;\n return (\n <Avatar style={{ height: props.size || defaultSize, width: props.size || defaultSize }} className={props.border ? 'border' : ''}>\n <AvatarImage src={user?.profileImageUrl || ''} />\n <AvatarFallback>\n {user ?\n <div className='font-medium' style={{ fontSize: (props.size || defaultSize) * 0.4 }}>\n {(user.displayName || user.primaryEmail)?.slice(0, 2).toUpperCase()}\n </div> :\n <UserRound className=\"text-zinc-500\" size={(props.size || defaultSize) * 0.6} />}\n </AvatarFallback>\n </Avatar>\n );\n}\n"],"mappings":";AAIA,SAAS,QAAQ,gBAAgB,mBAAmB;AACpD,SAAS,iBAAiB;AAetB,SACE,KADF;AAbJ,IAAM,cAAc;AAEb,SAAS,WAAW,OAQxB;AACD,QAAM,OAAO,MAAM;AACnB,SACE,qBAAC,UAAO,OAAO,EAAE,QAAQ,MAAM,QAAQ,aAAa,OAAO,MAAM,QAAQ,YAAY,GAAG,WAAW,MAAM,SAAS,WAAW,IAC3H;AAAA,wBAAC,eAAY,KAAK,MAAM,mBAAmB,IAAI;AAAA,IAC/C,oBAAC,kBACE,iBACC,oBAAC,SAAI,WAAU,eAAc,OAAO,EAAE,WAAW,MAAM,QAAQ,eAAe,IAAI,GAC9E,gBAAK,eAAe,KAAK,eAAe,MAAM,GAAG,CAAC,EAAE,YAAY,GACpE,IACA,oBAAC,aAAU,WAAU,iBAAgB,OAAO,MAAM,QAAQ,eAAe,KAAK,GAClF;AAAA,KACF;AAEJ;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/iframe-preventer.tsx"],"sourcesContent":["'use client';\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\n\nimport { useEffect, useState } from \"react\";\n\nexport function IframePreventer({ children }: {\n children: React.ReactNode,\n}) {\n const [isIframe, setIsIframe] = useState(false);\n useEffect(() => {\n if (window.self !== window.top) {\n setIsIframe(true);\n }\n }, []);\n\n if (isIframe) {\n return <div>Stack Auth components may not run in an {'<'}iframe{'>'}.</div>;\n }\n\n return children;\n}\n"],"mappings":";;;AAMA,SAAS,WAAW,gBAAgB;AAazB;AAXJ,SAAS,gBAAgB,EAAE,SAAS,GAExC;AACD,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAC9C,YAAU,MAAM;AACd,QAAI,OAAO,SAAS,OAAO,KAAK;AAC9B,kBAAY,IAAI;AAAA,IAClB;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,MAAI,UAAU;AACZ,WAAO,qBAAC,SAAI;AAAA;AAAA,MAAyC;AAAA,MAAI;AAAA,MAAO;AAAA,MAAI;AAAA,OAAC;AAAA,EACvE;AAEA,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/iframe-preventer.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\nimport { useEffect, useState } from \"react\";\n\nexport function IframePreventer({ children }: {\n children: React.ReactNode,\n}) {\n const [isIframe, setIsIframe] = useState(false);\n useEffect(() => {\n if (window.self !== window.top) {\n setIsIframe(true);\n }\n }, []);\n\n if (isIframe) {\n return <div>Stack Auth components may not run in an {'<'}iframe{'>'}.</div>;\n }\n\n return children;\n}\n"],"mappings":";;;AAMA,SAAS,WAAW,gBAAgB;AAazB;AAXJ,SAAS,gBAAgB,EAAE,SAAS,GAExC;AACD,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAC9C,YAAU,MAAM;AACd,QAAI,OAAO,SAAS,OAAO,KAAK;AAC9B,kBAAY,IAAI;AAAA,IAClB;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,MAAI,UAAU;AACZ,WAAO,qBAAC,SAAI;AAAA;AAAA,MAAyC;AAAA,MAAI;AAAA,MAAO;AAAA,MAAI;AAAA,OAAC;AAAA,EACvE;AAEA,SAAO;AACT;","names":[]}
@@ -0,0 +1,28 @@
1
+ "use client";
2
+ "use client";
3
+
4
+ // src/components/link.tsx
5
+ import { cn } from "@stackframe/stack-ui";
6
+ import NextLink from "next/link";
7
+ import { jsx } from "react/jsx-runtime";
8
+ function Link(props) {
9
+ return /* @__PURE__ */ jsx(
10
+ NextLink,
11
+ {
12
+ href: props.href,
13
+ target: props.target,
14
+ className: props.className,
15
+ prefetch: props.prefetch,
16
+ onClick: props.onClick,
17
+ children: props.children
18
+ }
19
+ );
20
+ }
21
+ function StyledLink(props) {
22
+ return /* @__PURE__ */ jsx(Link, { ...props, className: cn("underline font-medium", props.className), children: props.children });
23
+ }
24
+ export {
25
+ Link,
26
+ StyledLink
27
+ };
28
+ //# sourceMappingURL=link.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/link.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\n\nimport { cn } from \"@stackframe/stack-ui\";\nimport NextLink from 'next/link';\n\ntype LinkProps = {\n href: string,\n children: React.ReactNode,\n className?: string,\n target?: string,\n onClick?: React.MouseEventHandler<HTMLAnchorElement>,\n prefetch?: boolean,\n};\n\nfunction Link(props: LinkProps) {\n return <NextLink\n href={props.href}\n target={props.target}\n className={props.className}\n prefetch={props.prefetch}\n onClick={props.onClick}\n >\n {props.children}\n </NextLink>;\n}\n\nfunction StyledLink(props: LinkProps) {\n return (\n <Link {...props} className={cn(\"underline font-medium\", props.className)}>\n {props.children}\n </Link>\n );\n}\n\nexport { Link, StyledLink };\n"],"mappings":";;;AAOA,SAAS,UAAU;AACnB,OAAO,cAAc;AAYZ;AADT,SAAS,KAAK,OAAkB;AAC9B,SAAO;AAAA,IAAC;AAAA;AAAA,MACN,MAAM,MAAM;AAAA,MACZ,QAAQ,MAAM;AAAA,MACd,WAAW,MAAM;AAAA,MACjB,UAAU,MAAM;AAAA,MAChB,SAAS,MAAM;AAAA,MAEd,gBAAM;AAAA;AAAA,EACT;AACF;AAEA,SAAS,WAAW,OAAkB;AACpC,SACE,oBAAC,QAAM,GAAG,OAAO,WAAW,GAAG,yBAAyB,MAAM,SAAS,GACpE,gBAAM,UACT;AAEJ;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/magic-link-sign-in.tsx"],"sourcesContent":["'use client';\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\n\n\nimport { yupResolver } from \"@hookform/resolvers/yup\";\nimport { KnownErrors } from \"@stackframe/stack-shared\";\nimport { strictEmailSchema, yupObject } from \"@stackframe/stack-shared/dist/schema-fields\";\nimport { runAsynchronouslyWithAlert } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { Button, Input, InputOTP, InputOTPGroup, InputOTPSlot, Label, Typography } from \"@stackframe/stack-ui\";\nimport { useEffect, useState } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport * as yup from \"yup\";\nimport { useStackApp } from \"..\";\nimport { useTranslation } from \"../lib/translations\";\nimport { FormWarningText } from \"./elements/form-warning\";\n\nfunction OTP(props: {\n onBack: () => void,\n nonce: string,\n}) {\n const { t } = useTranslation();\n const [otp, setOtp] = useState<string>('');\n const [submitting, setSubmitting] = useState<boolean>(false);\n const stackApp = useStackApp();\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n if (otp.length === 6 && !submitting) {\n setSubmitting(true);\n stackApp.signInWithMagicLink(otp + props.nonce)\n .then(result => {\n if (result.status === 'error') {\n if (result.error instanceof KnownErrors.VerificationCodeError) {\n setError(t(\"Invalid code\"));\n } else if (result.error instanceof KnownErrors.InvalidTotpCode) {\n setError(t(\"Invalid TOTP code\"));\n } else {\n throw result.error;\n }\n }\n })\n .catch(e => console.error(e))\n .finally(() => {\n setSubmitting(false);\n setOtp('');\n });\n }\n if (otp.length !== 0 && otp.length !== 6) {\n setError(null);\n }\n }, [otp, submitting]);\n\n return (\n <div className=\"flex flex-col items-stretch stack-scope\">\n <form className='w-full flex flex-col items-center mb-2'>\n <Typography className='mb-2' >{t('Enter the code from your email')}</Typography>\n <InputOTP\n maxLength={6}\n type=\"text\"\n inputMode=\"text\"\n pattern={\"^[a-zA-Z0-9]+$\"}\n value={otp}\n onChange={value => setOtp(value.toUpperCase())}\n disabled={submitting}\n >\n <InputOTPGroup>\n {[0, 1, 2, 3, 4, 5].map((index) => (\n <InputOTPSlot key={index} index={index} size='lg' />\n ))}\n </InputOTPGroup>\n </InputOTP>\n {error && <FormWarningText text={error} />}\n </form>\n <Button variant='link' onClick={props.onBack} className='underline'>{t('Cancel')}</Button>\n </div>\n );\n}\n\nexport function MagicLinkSignIn() {\n const { t } = useTranslation();\n const app = useStackApp();\n const [loading, setLoading] = useState(false);\n const [nonce, setNonce] = useState<string | null>(null);\n\n const schema = yupObject({\n email: strictEmailSchema(t('Please enter a valid email')).defined().nonEmpty(t('Please enter your email'))\n });\n\n const { register, handleSubmit, setError, formState: { errors } } = useForm({\n resolver: yupResolver(schema)\n });\n\n const onSubmit = async (data: yup.InferType<typeof schema>) => {\n setLoading(true);\n try {\n const { email } = data;\n const result = await app.sendMagicLinkEmail(email);\n if (result.status === 'error') {\n setError('email', { type: 'manual', message: result.error.message });\n return;\n } else {\n setNonce(result.data.nonce);\n }\n } catch (e) {\n if (e instanceof KnownErrors.SignUpNotEnabled) {\n setError('email', { type: 'manual', message: t('New account registration is not allowed') });\n } else {\n throw e;\n }\n } finally {\n setLoading(false);\n }\n };\n\n if (nonce) {\n return <OTP nonce={nonce} onBack={() => setNonce(null)} />;\n } else {\n return (\n <form\n className=\"flex flex-col items-stretch stack-scope\"\n onSubmit={e => runAsynchronouslyWithAlert(handleSubmit(onSubmit)(e))}\n noValidate\n >\n <Label htmlFor=\"email\" className=\"mb-1\">{t('Email')}</Label>\n <Input\n id=\"email\"\n type=\"email\"\n autoComplete=\"email\"\n {...register('email')}\n />\n <FormWarningText text={errors.email?.message?.toString()} />\n\n <Button type=\"submit\" className=\"mt-6\" loading={loading}>\n {t('Send email')}\n </Button>\n </form>\n );\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/components/magic-link-sign-in.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\n\nimport { yupResolver } from \"@hookform/resolvers/yup\";\nimport { KnownErrors } from \"@stackframe/stack-shared\";\nimport { strictEmailSchema, yupObject } from \"@stackframe/stack-shared/dist/schema-fields\";\nimport { runAsynchronouslyWithAlert } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { Button, Input, InputOTP, InputOTPGroup, InputOTPSlot, Label, Typography } from \"@stackframe/stack-ui\";\nimport { useEffect, useState } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport * as yup from \"yup\";\nimport { useStackApp } from \"..\";\nimport { useTranslation } from \"../lib/translations\";\nimport { FormWarningText } from \"./elements/form-warning\";\n\nfunction OTP(props: {\n onBack: () => void,\n nonce: string,\n}) {\n const { t } = useTranslation();\n const [otp, setOtp] = useState<string>('');\n const [submitting, setSubmitting] = useState<boolean>(false);\n const stackApp = useStackApp();\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n if (otp.length === 6 && !submitting) {\n setSubmitting(true);\n stackApp.signInWithMagicLink(otp + props.nonce)\n .then(result => {\n if (result.status === 'error') {\n if (result.error instanceof KnownErrors.VerificationCodeError) {\n setError(t(\"Invalid code\"));\n } else if (result.error instanceof KnownErrors.InvalidTotpCode) {\n setError(t(\"Invalid TOTP code\"));\n } else {\n throw result.error;\n }\n }\n })\n .catch(e => console.error(e))\n .finally(() => {\n setSubmitting(false);\n setOtp('');\n });\n }\n if (otp.length !== 0 && otp.length !== 6) {\n setError(null);\n }\n }, [otp, submitting]);\n\n return (\n <div className=\"flex flex-col items-stretch stack-scope\">\n <form className='w-full flex flex-col items-center mb-2'>\n <Typography className='mb-2' >{t('Enter the code from your email')}</Typography>\n <InputOTP\n maxLength={6}\n type=\"text\"\n inputMode=\"text\"\n pattern={\"^[a-zA-Z0-9]+$\"}\n value={otp}\n onChange={value => setOtp(value.toUpperCase())}\n disabled={submitting}\n >\n <InputOTPGroup>\n {[0, 1, 2, 3, 4, 5].map((index) => (\n <InputOTPSlot key={index} index={index} size='lg' />\n ))}\n </InputOTPGroup>\n </InputOTP>\n {error && <FormWarningText text={error} />}\n </form>\n <Button variant='link' onClick={props.onBack} className='underline'>{t('Cancel')}</Button>\n </div>\n );\n}\n\nexport function MagicLinkSignIn() {\n const { t } = useTranslation();\n const app = useStackApp();\n const [loading, setLoading] = useState(false);\n const [nonce, setNonce] = useState<string | null>(null);\n\n const schema = yupObject({\n email: strictEmailSchema(t('Please enter a valid email')).defined().nonEmpty(t('Please enter your email'))\n });\n\n const { register, handleSubmit, setError, formState: { errors } } = useForm({\n resolver: yupResolver(schema)\n });\n\n const onSubmit = async (data: yup.InferType<typeof schema>) => {\n setLoading(true);\n try {\n const { email } = data;\n const result = await app.sendMagicLinkEmail(email);\n if (result.status === 'error') {\n setError('email', { type: 'manual', message: result.error.message });\n return;\n } else {\n setNonce(result.data.nonce);\n }\n } catch (e) {\n if (e instanceof KnownErrors.SignUpNotEnabled) {\n setError('email', { type: 'manual', message: t('New account registration is not allowed') });\n } else {\n throw e;\n }\n } finally {\n setLoading(false);\n }\n };\n\n if (nonce) {\n return <OTP nonce={nonce} onBack={() => setNonce(null)} />;\n } else {\n return (\n <form\n className=\"flex flex-col items-stretch stack-scope\"\n onSubmit={e => runAsynchronouslyWithAlert(handleSubmit(onSubmit)(e))}\n noValidate\n >\n <Label htmlFor=\"email\" className=\"mb-1\">{t('Email')}</Label>\n <Input\n id=\"email\"\n type=\"email\"\n autoComplete=\"email\"\n {...register('email')}\n />\n <FormWarningText text={errors.email?.message?.toString()} />\n\n <Button type=\"submit\" className=\"mt-6\" loading={loading}>\n {t('Send email')}\n </Button>\n </form>\n );\n }\n}\n"],"mappings":"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","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/message-cards/known-error-message-card.tsx"],"sourcesContent":["\"use client\";\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\n\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":";;;AAQA,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":[]}
1
+ {"version":3,"sources":["../../../../src/components/message-cards/known-error-message-card.tsx"],"sourcesContent":["\"use client\";\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\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":";;;AAQA,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":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/message-cards/message-card.tsx"],"sourcesContent":["'use client';\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\n\n\nimport React from \"react\";\nimport { MaybeFullPage } from \"../elements/maybe-full-page\";\nimport { Button, Typography } from \"@stackframe/stack-ui\";\n\nexport function MessageCard(\n { fullPage=false, ...props }:\n {\n children?: React.ReactNode,\n title: string,\n fullPage?: boolean,\n primaryButtonText?: string,\n primaryAction?: () => Promise<void> | void,\n secondaryButtonText?: string,\n secondaryAction?: () => Promise<void> | void,\n }\n) {\n return (\n <MaybeFullPage fullPage={fullPage}>\n <div className=\"text-center stack-scope flex flex-col gap-4\" style={{ maxWidth: '380px', flexBasis: '380px', padding: fullPage ? '1rem' : 0 }}>\n <Typography type='h3'>{props.title}</Typography>\n {props.children}\n {(props.primaryButtonText || props.secondaryButtonText) && (\n <div className=\"flex justify-center gap-4 my-5\">\n {props.secondaryButtonText && (\n <Button variant=\"secondary\" onClick={props.secondaryAction}>\n {props.secondaryButtonText}\n </Button>\n )}\n {props.primaryButtonText && (\n <Button onClick={props.primaryAction}>\n {props.primaryButtonText}\n </Button>\n )}\n </div>\n )}\n </div>\n </MaybeFullPage>\n );\n}\n"],"mappings":";;;AAQA,SAAS,qBAAqB;AAC9B,SAAS,QAAQ,kBAAkB;AAiB3B,cAGE,YAHF;AAfD,SAAS,YACd,EAAE,WAAS,OAAO,GAAG,MAAM,GAU3B;AACA,SACE,oBAAC,iBAAc,UACb,+BAAC,SAAI,WAAU,+CAA8C,OAAO,EAAE,UAAU,SAAS,WAAW,SAAS,SAAS,WAAW,SAAS,EAAE,GAC1I;AAAA,wBAAC,cAAW,MAAK,MAAM,gBAAM,OAAM;AAAA,IAClC,MAAM;AAAA,KACL,MAAM,qBAAqB,MAAM,wBACjC,qBAAC,SAAI,WAAU,kCACZ;AAAA,YAAM,uBACL,oBAAC,UAAO,SAAQ,aAAY,SAAS,MAAM,iBACxC,gBAAM,qBACT;AAAA,MAED,MAAM,qBACL,oBAAC,UAAO,SAAS,MAAM,eACpB,gBAAM,mBACT;AAAA,OAEJ;AAAA,KAEJ,GACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../../src/components/message-cards/message-card.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\n\nimport React from \"react\";\nimport { MaybeFullPage } from \"../elements/maybe-full-page\";\nimport { Button, Typography } from \"@stackframe/stack-ui\";\n\nexport function MessageCard(\n { fullPage=false, ...props }:\n {\n children?: React.ReactNode,\n title: string,\n fullPage?: boolean,\n primaryButtonText?: string,\n primaryAction?: () => Promise<void> | void,\n secondaryButtonText?: string,\n secondaryAction?: () => Promise<void> | void,\n }\n) {\n return (\n <MaybeFullPage fullPage={fullPage}>\n <div className=\"text-center stack-scope flex flex-col gap-4\" style={{ maxWidth: '380px', flexBasis: '380px', padding: fullPage ? '1rem' : 0 }}>\n <Typography type='h3'>{props.title}</Typography>\n {props.children}\n {(props.primaryButtonText || props.secondaryButtonText) && (\n <div className=\"flex justify-center gap-4 my-5\">\n {props.secondaryButtonText && (\n <Button variant=\"secondary\" onClick={props.secondaryAction}>\n {props.secondaryButtonText}\n </Button>\n )}\n {props.primaryButtonText && (\n <Button onClick={props.primaryAction}>\n {props.primaryButtonText}\n </Button>\n )}\n </div>\n )}\n </div>\n </MaybeFullPage>\n );\n}\n"],"mappings":";;;AAQA,SAAS,qBAAqB;AAC9B,SAAS,QAAQ,kBAAkB;AAiB3B,cAGE,YAHF;AAfD,SAAS,YACd,EAAE,WAAS,OAAO,GAAG,MAAM,GAU3B;AACA,SACE,oBAAC,iBAAc,UACb,+BAAC,SAAI,WAAU,+CAA8C,OAAO,EAAE,UAAU,SAAS,WAAW,SAAS,SAAS,WAAW,SAAS,EAAE,GAC1I;AAAA,wBAAC,cAAW,MAAK,MAAM,gBAAM,OAAM;AAAA,IAClC,MAAM;AAAA,KACL,MAAM,qBAAqB,MAAM,wBACjC,qBAAC,SAAI,WAAU,kCACZ;AAAA,YAAM,uBACL,oBAAC,UAAO,SAAQ,aAAY,SAAS,MAAM,iBACxC,gBAAM,qBACT;AAAA,MAED,MAAM,qBACL,oBAAC,UAAO,SAAS,MAAM,eACpB,gBAAM,mBACT;AAAA,OAEJ;AAAA,KAEJ,GACF;AAEJ;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/message-cards/predefined-message-card.tsx"],"sourcesContent":["\"use client\";\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\n\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":";;;AAOA,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":[]}
1
+ {"version":3,"sources":["../../../../src/components/message-cards/predefined-message-card.tsx"],"sourcesContent":["\"use client\";\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\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":";;;AAOA,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":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/oauth-button-group.tsx"],"sourcesContent":["'use client';\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\n\n\nimport { useStackApp } from \"../lib/hooks\";\nimport { OAuthButton } from \"./oauth-button\";\n\nexport function OAuthButtonGroup({\n type,\n mockProject,\n}: {\n type: 'sign-in' | 'sign-up',\n mockProject?: {\n config: {\n oauthProviders: {\n id: string,\n }[],\n },\n },\n}) {\n const stackApp = useStackApp();\n const project = mockProject || stackApp.useProject();\n return (\n <div className='gap-4 flex flex-col items-stretch stack-scope'>\n {project.config.oauthProviders.map(p => (\n <OAuthButton key={p.id} provider={p.id} type={type}/>\n ))}\n </div>\n );\n}\n"],"mappings":";;;AAOA,SAAS,mBAAmB;AAC5B,SAAS,mBAAmB;AAoBpB;AAlBD,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA;AACF,GASG;AACD,QAAM,WAAW,YAAY;AAC7B,QAAM,UAAU,eAAe,SAAS,WAAW;AACnD,SACE,oBAAC,SAAI,WAAU,iDACZ,kBAAQ,OAAO,eAAe,IAAI,OACjC,oBAAC,eAAuB,UAAU,EAAE,IAAI,QAAtB,EAAE,EAA+B,CACpD,GACH;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/oauth-button-group.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\n\nimport { useStackApp } from \"../lib/hooks\";\nimport { OAuthButton } from \"./oauth-button\";\n\nexport function OAuthButtonGroup({\n type,\n mockProject,\n}: {\n type: 'sign-in' | 'sign-up',\n mockProject?: {\n config: {\n oauthProviders: {\n id: string,\n }[],\n },\n },\n}) {\n const stackApp = useStackApp();\n const project = mockProject || stackApp.useProject();\n return (\n <div className='gap-4 flex flex-col items-stretch stack-scope'>\n {project.config.oauthProviders.map(p => (\n <OAuthButton key={p.id} provider={p.id} type={type}/>\n ))}\n </div>\n );\n}\n"],"mappings":";;;AAOA,SAAS,mBAAmB;AAC5B,SAAS,mBAAmB;AAoBpB;AAlBD,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA;AACF,GASG;AACD,QAAM,WAAW,YAAY;AAC7B,QAAM,UAAU,eAAe,SAAS,WAAW;AACnD,SACE,oBAAC,SAAI,WAAU,iDACZ,kBAAQ,OAAO,eAAe,IAAI,OACjC,oBAAC,eAAuB,UAAU,EAAE,IAAI,QAAtB,EAAE,EAA+B,CACpD,GACH;AAEJ;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/oauth-button.tsx"],"sourcesContent":["'use client';\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\n\n\nimport { BrandIcons, Button } from '@stackframe/stack-ui';\nimport Color from 'color';\nimport { useEffect, useId, useState } from 'react';\nimport { useStackApp } from '..';\nimport { useTranslation } from '../lib/translations';\n\nconst iconSize = 22;\n\nconst changeColor = (c: Color, value: number) => {\n if (c.isLight()) {\n value = -value;\n }\n return c.hsl(c.hue(), c.saturationl(), c.lightness() + value).toString();\n};\n\nexport function OAuthButton({\n provider,\n type,\n}: {\n provider: string,\n type: 'sign-in' | 'sign-up',\n}) {\n const { t } = useTranslation();\n const stackApp = useStackApp();\n const styleId = useId().replaceAll(':', '-');\n\n const [lastUsed, setLastUsed] = useState<string | null>(null);\n useEffect(() => {\n setLastUsed(localStorage.getItem('_STACK_AUTH.lastUsed'));\n }, []);\n\n let style : {\n backgroundColor?: string,\n textColor?: string,\n name: string,\n icon: JSX.Element | null,\n border?: string,\n };\n switch (provider) {\n case 'google': {\n style = {\n backgroundColor: '#fff',\n textColor: '#000',\n name: 'Google',\n border: '1px solid #ddd',\n icon: <BrandIcons.Google iconSize={iconSize} />,\n };\n break;\n }\n case 'github': {\n style = {\n backgroundColor: '#111',\n textColor: '#fff',\n border: '1px solid #333',\n name: 'GitHub',\n icon: <BrandIcons.GitHub iconSize={iconSize} />,\n };\n break;\n }\n case 'facebook': {\n style = {\n backgroundColor: '#1877F2',\n textColor: '#fff',\n name: 'Facebook',\n icon: <BrandIcons.Facebook iconSize={iconSize} />,\n };\n break;\n }\n case 'microsoft': {\n style = {\n backgroundColor: '#2f2f2f',\n textColor: '#fff',\n name: 'Microsoft',\n icon: <BrandIcons.Microsoft iconSize={iconSize} />,\n };\n break;\n }\n case 'spotify': {\n style = {\n backgroundColor: '#1DB954',\n textColor: '#fff',\n name: 'Spotify',\n icon: <BrandIcons.Spotify iconSize={iconSize} />,\n };\n break;\n }\n case 'discord': {\n style = {\n backgroundColor: '#5865F2',\n textColor: '#fff',\n name: 'Discord',\n icon: <BrandIcons.Discord iconSize={iconSize} />,\n };\n break;\n }\n case 'gitlab': {\n style = {\n backgroundColor: \"#111\",\n textColor: \"#fff\",\n border: \"1px solid #333\",\n name: \"Gitlab\",\n icon: <BrandIcons.Gitlab iconSize={iconSize} />,\n };\n break;\n }\n case 'apple': {\n style = {\n backgroundColor: \"#000\",\n textColor: \"#fff\",\n border: \"1px solid #333\",\n name: \"Apple\",\n icon: <BrandIcons.Apple iconSize={iconSize} />,\n };\n break;\n }\n case \"bitbucket\": {\n style = {\n backgroundColor: \"#fff\",\n textColor: \"#000\",\n border: \"1px solid #ddd\",\n name: \"Bitbucket\",\n icon: <BrandIcons.Bitbucket iconSize={iconSize} />,\n };\n break;\n }\n case 'linkedin': {\n style = {\n backgroundColor: \"#0073b1\",\n textColor: \"#fff\",\n name: \"LinkedIn\",\n icon: <BrandIcons.LinkedIn iconSize={iconSize} />,\n };\n break;\n }\n case 'x': {\n style = {\n backgroundColor: \"#000\",\n textColor: \"#fff\",\n name: \"X\",\n icon: <BrandIcons.X iconSize={iconSize} />,\n };\n break;\n }\n default: {\n style = {\n name: provider,\n icon: null,\n };\n }\n }\n\n const styleSheet = `\n .stack-oauth-button-${styleId} {\n background-color: ${style.backgroundColor} !important;\n color: ${style.textColor} !important;\n border: ${style.border} !important;\n }\n .stack-oauth-button-${styleId}:hover {\n background-color: ${changeColor(Color(style.backgroundColor), 10)} !important;\n }\n `;\n\n return (\n <>\n <style>{styleSheet}</style>\n <Button\n onClick={async () => {\n localStorage.setItem('_STACK_AUTH.lastUsed', provider);\n await stackApp.signInWithOAuth(provider);\n }}\n className={`stack-oauth-button-${styleId} stack-scope relative`}\n >\n {lastUsed === provider && (\n <span className=\"absolute -top-2 -right-2 bg-blue-500 text-white text-xs px-2 py-1 rounded-md\">\n last\n </span>\n )}\n <div className='flex items-center w-full gap-4'>\n {style.icon}\n <span className='flex-1'>\n {type === 'sign-up' ?\n t('Sign up with {provider}', { provider: style.name }) :\n t('Sign in with {provider}', { provider: style.name })\n }\n </span>\n </div>\n </Button>\n </>\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/components/oauth-button.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\n\nimport { BrandIcons, Button } from '@stackframe/stack-ui';\nimport Color from 'color';\nimport { useEffect, useId, useState } from 'react';\nimport { useStackApp } from '..';\nimport { useTranslation } from '../lib/translations';\n\nconst iconSize = 22;\n\nconst changeColor = (c: Color, value: number) => {\n if (c.isLight()) {\n value = -value;\n }\n return c.hsl(c.hue(), c.saturationl(), c.lightness() + value).toString();\n};\n\nexport function OAuthButton({\n provider,\n type,\n}: {\n provider: string,\n type: 'sign-in' | 'sign-up',\n}) {\n const { t } = useTranslation();\n const stackApp = useStackApp();\n const styleId = useId().replaceAll(':', '-');\n\n const [lastUsed, setLastUsed] = useState<string | null>(null);\n useEffect(() => {\n setLastUsed(localStorage.getItem('_STACK_AUTH.lastUsed'));\n }, []);\n\n let style : {\n backgroundColor?: string,\n textColor?: string,\n name: string,\n icon: JSX.Element | null,\n border?: string,\n };\n switch (provider) {\n case 'google': {\n style = {\n backgroundColor: '#fff',\n textColor: '#000',\n name: 'Google',\n border: '1px solid #ddd',\n icon: <BrandIcons.Google iconSize={iconSize} />,\n };\n break;\n }\n case 'github': {\n style = {\n backgroundColor: '#111',\n textColor: '#fff',\n border: '1px solid #333',\n name: 'GitHub',\n icon: <BrandIcons.GitHub iconSize={iconSize} />,\n };\n break;\n }\n case 'facebook': {\n style = {\n backgroundColor: '#1877F2',\n textColor: '#fff',\n name: 'Facebook',\n icon: <BrandIcons.Facebook iconSize={iconSize} />,\n };\n break;\n }\n case 'microsoft': {\n style = {\n backgroundColor: '#2f2f2f',\n textColor: '#fff',\n name: 'Microsoft',\n icon: <BrandIcons.Microsoft iconSize={iconSize} />,\n };\n break;\n }\n case 'spotify': {\n style = {\n backgroundColor: '#1DB954',\n textColor: '#fff',\n name: 'Spotify',\n icon: <BrandIcons.Spotify iconSize={iconSize} />,\n };\n break;\n }\n case 'discord': {\n style = {\n backgroundColor: '#5865F2',\n textColor: '#fff',\n name: 'Discord',\n icon: <BrandIcons.Discord iconSize={iconSize} />,\n };\n break;\n }\n case 'gitlab': {\n style = {\n backgroundColor: \"#111\",\n textColor: \"#fff\",\n border: \"1px solid #333\",\n name: \"Gitlab\",\n icon: <BrandIcons.Gitlab iconSize={iconSize} />,\n };\n break;\n }\n case 'apple': {\n style = {\n backgroundColor: \"#000\",\n textColor: \"#fff\",\n border: \"1px solid #333\",\n name: \"Apple\",\n icon: <BrandIcons.Apple iconSize={iconSize} />,\n };\n break;\n }\n case \"bitbucket\": {\n style = {\n backgroundColor: \"#fff\",\n textColor: \"#000\",\n border: \"1px solid #ddd\",\n name: \"Bitbucket\",\n icon: <BrandIcons.Bitbucket iconSize={iconSize} />,\n };\n break;\n }\n case 'linkedin': {\n style = {\n backgroundColor: \"#0073b1\",\n textColor: \"#fff\",\n name: \"LinkedIn\",\n icon: <BrandIcons.LinkedIn iconSize={iconSize} />,\n };\n break;\n }\n case 'x': {\n style = {\n backgroundColor: \"#000\",\n textColor: \"#fff\",\n name: \"X\",\n icon: <BrandIcons.X iconSize={iconSize} />,\n };\n break;\n }\n default: {\n style = {\n name: provider,\n icon: null,\n };\n }\n }\n\n const styleSheet = `\n .stack-oauth-button-${styleId} {\n background-color: ${style.backgroundColor} !important;\n color: ${style.textColor} !important;\n border: ${style.border} !important;\n }\n .stack-oauth-button-${styleId}:hover {\n background-color: ${changeColor(Color(style.backgroundColor), 10)} !important;\n }\n `;\n\n return (\n <>\n <style>{styleSheet}</style>\n <Button\n onClick={async () => {\n localStorage.setItem('_STACK_AUTH.lastUsed', provider);\n await stackApp.signInWithOAuth(provider);\n }}\n className={`stack-oauth-button-${styleId} stack-scope relative`}\n >\n {lastUsed === provider && (\n <span className=\"absolute -top-2 -right-2 bg-blue-500 text-white text-xs px-2 py-1 rounded-md\">\n last\n </span>\n )}\n <div className='flex items-center w-full gap-4'>\n {style.icon}\n <span className='flex-1'>\n {type === 'sign-up' ?\n t('Sign up with {provider}', { provider: style.name }) :\n t('Sign in with {provider}', { provider: style.name })\n }\n </span>\n </div>\n </Button>\n </>\n );\n}\n"],"mappings":"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","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/passkey-button.tsx"],"sourcesContent":["'use client';\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\n\n\nimport { Button } from '@stackframe/stack-ui';\nimport { useId } from 'react';\nimport { useStackApp } from '..';\nimport { useTranslation } from '../lib/translations';\nimport { KeyRound } from 'lucide-react';\n\n\nexport function PasskeyButton({\n type,\n}: {\n type: 'sign-in' | 'sign-up',\n}) {\n const { t } = useTranslation();\n const stackApp = useStackApp();\n const styleId = useId().replaceAll(':', '-');\n\n\n return (\n <>\n <Button\n onClick={async () => { await stackApp.signInWithPasskey(); }}\n className={`stack-oauth-button-${styleId} stack-scope`}\n >\n <div className='flex items-center w-full gap-4'>\n <KeyRound />\n <span className='flex-1'>\n {type === 'sign-up' ?\n t('Sign up with Passkey') :\n t('Sign in with Passkey')\n }\n </span>\n </div>\n </Button>\n </>\n );\n}\n"],"mappings":";;;AAOA,SAAS,cAAc;AACvB,SAAS,aAAa;AACtB,SAAS,mBAAmB;AAC5B,SAAS,sBAAsB;AAC/B,SAAS,gBAAgB;AAcrB,mBAMM,KADF,YALJ;AAXG,SAAS,cAAc;AAAA,EAC5B;AACF,GAEG;AACD,QAAM,EAAE,EAAE,IAAI,eAAe;AAC7B,QAAM,WAAW,YAAY;AAC7B,QAAM,UAAU,MAAM,EAAE,WAAW,KAAK,GAAG;AAG3C,SACE,gCACE;AAAA,IAAC;AAAA;AAAA,MACC,SAAS,YAAY;AAAE,cAAM,SAAS,kBAAkB;AAAA,MAAG;AAAA,MAC3D,WAAW,sBAAsB,OAAO;AAAA,MAExC,+BAAC,SAAI,WAAU,kCACb;AAAA,4BAAC,YAAS;AAAA,QACV,oBAAC,UAAK,WAAU,UACb,mBAAS,YACR,EAAE,sBAAsB,IACxB,EAAE,sBAAsB,GAE5B;AAAA,SACF;AAAA;AAAA,EACF,GACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/passkey-button.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\n\nimport { Button } from '@stackframe/stack-ui';\nimport { useId } from 'react';\nimport { useStackApp } from '..';\nimport { useTranslation } from '../lib/translations';\nimport { KeyRound } from 'lucide-react';\n\n\nexport function PasskeyButton({\n type,\n}: {\n type: 'sign-in' | 'sign-up',\n}) {\n const { t } = useTranslation();\n const stackApp = useStackApp();\n const styleId = useId().replaceAll(':', '-');\n\n\n return (\n <>\n <Button\n onClick={async () => { await stackApp.signInWithPasskey(); }}\n className={`stack-oauth-button-${styleId} stack-scope`}\n >\n <div className='flex items-center w-full gap-4'>\n <KeyRound />\n <span className='flex-1'>\n {type === 'sign-up' ?\n t('Sign up with Passkey') :\n t('Sign in with Passkey')\n }\n </span>\n </div>\n </Button>\n </>\n );\n}\n"],"mappings":";;;AAOA,SAAS,cAAc;AACvB,SAAS,aAAa;AACtB,SAAS,mBAAmB;AAC5B,SAAS,sBAAsB;AAC/B,SAAS,gBAAgB;AAcrB,mBAMM,KADF,YALJ;AAXG,SAAS,cAAc;AAAA,EAC5B;AACF,GAEG;AACD,QAAM,EAAE,EAAE,IAAI,eAAe;AAC7B,QAAM,WAAW,YAAY;AAC7B,QAAM,UAAU,MAAM,EAAE,WAAW,KAAK,GAAG;AAG3C,SACE,gCACE;AAAA,IAAC;AAAA;AAAA,MACC,SAAS,YAAY;AAAE,cAAM,SAAS,kBAAkB;AAAA,MAAG;AAAA,MAC3D,WAAW,sBAAsB,OAAO;AAAA,MAExC,+BAAC,SAAI,WAAU,kCACb;AAAA,4BAAC,YAAS;AAAA,QACV,oBAAC,UAAK,WAAU,UACb,mBAAS,YACR,EAAE,sBAAsB,IACxB,EAAE,sBAAsB,GAE5B;AAAA,SACF;AAAA;AAAA,EACF,GACF;AAEJ;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/profile-image-editor.tsx"],"sourcesContent":["//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\n\nimport { fileToBase64 } from '@stackframe/stack-shared/dist/utils/base64';\nimport { Button, Slider, Typography } from '@stackframe/stack-ui';\nimport imageCompression from 'browser-image-compression';\nimport { Upload } from 'lucide-react';\nimport { ComponentProps, useRef, useState } from 'react';\nimport AvatarEditor from 'react-avatar-editor';\nimport { useTranslation } from '../lib/translations';\nimport { UserAvatar } from './elements/user-avatar';\n\nexport async function checkImageUrl(url: string){\n try {\n const res = await fetch(url, { method: 'HEAD' });\n const buff = await res.blob();\n return buff.type.startsWith('image/');\n } catch (e) {\n return false;\n }\n}\n\nexport function ProfileImageEditor(props: {\n user: NonNullable<ComponentProps<typeof UserAvatar>['user']>,\n onProfileImageUrlChange: (profileImageUrl: string | null) => void | Promise<void>,\n}) {\n const { t } = useTranslation();\n const cropRef = useRef<AvatarEditor>(null);\n const [slideValue, setSlideValue] = useState(1);\n const [rawUrl, setRawUrl] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n function reset() {\n setSlideValue(1);\n setRawUrl(null);\n setError(null);\n }\n\n function upload() {\n const input = document.createElement('input');\n input.type = 'file';\n input.onchange = (e) => {\n const file = (e.target as HTMLInputElement).files?.[0];\n if (!file) return;\n fileToBase64(file)\n .then(async (rawUrl) => {\n if (await checkImageUrl(rawUrl)) {\n setRawUrl(rawUrl);\n setError(null);\n } else {\n setError(t('Invalid image'));\n }\n })\n .then(() => input.remove())\n .catch(console.error);\n };\n input.click();\n }\n\n if (!rawUrl) {\n return <div className='flex flex-col'>\n <div className='cursor-pointer relative' onClick={upload}>\n <UserAvatar\n size={60}\n user={props.user}\n border\n />\n <div className='absolute top-0 left-0 h-[60px] w-[60px] bg-gray-500/20 backdrop-blur-sm items-center justify-center rounded-full flex opacity-0 hover:opacity-100 transition-opacity'>\n <div className='bg-background p-2 rounded-full'>\n <Upload className='h-5 w-5' />\n </div>\n </div>\n </div>\n {error && <Typography variant='destructive' type='label'>{error}</Typography>}\n </div>;\n }\n\n return (\n <div className='flex flex-col items-center gap-4'>\n <AvatarEditor\n ref={cropRef}\n image={rawUrl || props.user.profileImageUrl || \"\"}\n borderRadius={1000}\n color={[0, 0, 0, 0.72]}\n scale={slideValue}\n rotate={0}\n border={20}\n className='border'\n />\n <Slider\n min={1}\n max={5}\n step={0.1}\n defaultValue={[slideValue]}\n value={[slideValue]}\n onValueChange={(v) => setSlideValue(v[0])}\n />\n\n <div className='flex flex-row gap-2'>\n <Button\n onClick={async () => {\n if (cropRef.current && rawUrl) {\n const croppedUrl = cropRef.current.getImage().toDataURL('image/jpeg');\n const compressedFile = await imageCompression(\n await imageCompression.getFilefromDataUrl(croppedUrl, 'profile-image'),\n {\n maxSizeMB: 0.1,\n fileType: \"image/jpeg\",\n }\n );\n const compressedUrl = await imageCompression.getDataUrlFromFile(compressedFile);\n await props.onProfileImageUrlChange(compressedUrl);\n reset();\n }\n }}\n >\n {t('Save')}\n </Button>\n <Button\n variant=\"secondary\"\n onClick={reset}\n >\n {t('Cancel')}\n </Button>\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":["rawUrl"]}
1
+ {"version":3,"sources":["../../../src/components/profile-image-editor.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\nimport { fileToBase64 } from '@stackframe/stack-shared/dist/utils/base64';\nimport { Button, Slider, Typography } from '@stackframe/stack-ui';\nimport imageCompression from 'browser-image-compression';\nimport { Upload } from 'lucide-react';\nimport { ComponentProps, useRef, useState } from 'react';\nimport AvatarEditor from 'react-avatar-editor';\nimport { useTranslation } from '../lib/translations';\nimport { UserAvatar } from './elements/user-avatar';\n\nexport async function checkImageUrl(url: string){\n try {\n const res = await fetch(url, { method: 'HEAD' });\n const buff = await res.blob();\n return buff.type.startsWith('image/');\n } catch (e) {\n return false;\n }\n}\n\nexport function ProfileImageEditor(props: {\n user: NonNullable<ComponentProps<typeof UserAvatar>['user']>,\n onProfileImageUrlChange: (profileImageUrl: string | null) => void | Promise<void>,\n}) {\n const { t } = useTranslation();\n const cropRef = useRef<AvatarEditor>(null);\n const [slideValue, setSlideValue] = useState(1);\n const [rawUrl, setRawUrl] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n function reset() {\n setSlideValue(1);\n setRawUrl(null);\n setError(null);\n }\n\n function upload() {\n const input = document.createElement('input');\n input.type = 'file';\n input.onchange = (e) => {\n const file = (e.target as HTMLInputElement).files?.[0];\n if (!file) return;\n fileToBase64(file)\n .then(async (rawUrl) => {\n if (await checkImageUrl(rawUrl)) {\n setRawUrl(rawUrl);\n setError(null);\n } else {\n setError(t('Invalid image'));\n }\n })\n .then(() => input.remove())\n .catch(console.error);\n };\n input.click();\n }\n\n if (!rawUrl) {\n return <div className='flex flex-col'>\n <div className='cursor-pointer relative' onClick={upload}>\n <UserAvatar\n size={60}\n user={props.user}\n border\n />\n <div className='absolute top-0 left-0 h-[60px] w-[60px] bg-gray-500/20 backdrop-blur-sm items-center justify-center rounded-full flex opacity-0 hover:opacity-100 transition-opacity'>\n <div className='bg-background p-2 rounded-full'>\n <Upload className='h-5 w-5' />\n </div>\n </div>\n </div>\n {error && <Typography variant='destructive' type='label'>{error}</Typography>}\n </div>;\n }\n\n return (\n <div className='flex flex-col items-center gap-4'>\n <AvatarEditor\n ref={cropRef}\n image={rawUrl || props.user.profileImageUrl || \"\"}\n borderRadius={1000}\n color={[0, 0, 0, 0.72]}\n scale={slideValue}\n rotate={0}\n border={20}\n className='border'\n />\n <Slider\n min={1}\n max={5}\n step={0.1}\n defaultValue={[slideValue]}\n value={[slideValue]}\n onValueChange={(v) => setSlideValue(v[0])}\n />\n\n <div className='flex flex-row gap-2'>\n <Button\n onClick={async () => {\n if (cropRef.current && rawUrl) {\n const croppedUrl = cropRef.current.getImage().toDataURL('image/jpeg');\n const compressedFile = await imageCompression(\n await imageCompression.getFilefromDataUrl(croppedUrl, 'profile-image'),\n {\n maxSizeMB: 0.1,\n fileType: \"image/jpeg\",\n }\n );\n const compressedUrl = await imageCompression.getDataUrlFromFile(compressedFile);\n await props.onProfileImageUrlChange(compressedUrl);\n reset();\n }\n }}\n >\n {t('Save')}\n </Button>\n <Button\n variant=\"secondary\"\n onClick={reset}\n >\n {t('Cancel')}\n </Button>\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":["rawUrl"]}
@@ -17,7 +17,6 @@ import {
17
17
  Typography
18
18
  } from "@stackframe/stack-ui";
19
19
  import { PlusCircle, Settings } from "lucide-react";
20
- import { useRouter } from "next/navigation";
21
20
  import { Suspense, useEffect, useMemo } from "react";
22
21
  import { useStackApp, useUser } from "..";
23
22
  import { useTranslation } from "../lib/translations";
@@ -34,7 +33,7 @@ function Inner(props) {
34
33
  const app = useStackApp();
35
34
  const user = useUser();
36
35
  const project = app.useProject();
37
- const router = useRouter();
36
+ const navigate = app.useNavigate();
38
37
  const selectedTeam = user?.selectedTeam || props.selectedTeam;
39
38
  const rawTeams = user?.useTeams();
40
39
  const teams = useMemo(() => rawTeams?.sort((a, b) => b.id === selectedTeam?.id ? 1 : -1), [rawTeams, selectedTeam]);
@@ -57,7 +56,7 @@ function Inner(props) {
57
56
  await user?.setSelectedTeam(team);
58
57
  }
59
58
  if (props.urlMap) {
60
- router.push(props.urlMap(team));
59
+ navigate(props.urlMap(team));
61
60
  }
62
61
  });
63
62
  },
@@ -67,7 +66,7 @@ function Inner(props) {
67
66
  user?.selectedTeam ? /* @__PURE__ */ jsxs(SelectGroup, { children: [
68
67
  /* @__PURE__ */ jsx(SelectLabel, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
69
68
  /* @__PURE__ */ jsx("span", { children: t("Current team") }),
70
- /* @__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" }) })
69
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon", className: "h-6 w-6", onClick: () => navigate(`${app.urls.accountSettings}#team-${user.selectedTeam?.id}`), children: /* @__PURE__ */ jsx(Settings, { className: "h-4 w-4" }) })
71
70
  ] }) }),
72
71
  /* @__PURE__ */ jsx(SelectItem, { value: user.selectedTeam.id, children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
73
72
  /* @__PURE__ */ jsx(TeamIcon, { team: user.selectedTeam }),
@@ -86,7 +85,7 @@ function Inner(props) {
86
85
  /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(
87
86
  Button,
88
87
  {
89
- onClick: () => router.push(`${app.urls.accountSettings}#team-creation`),
88
+ onClick: () => navigate(`${app.urls.accountSettings}#team-creation`),
90
89
  className: "w-full",
91
90
  variant: "ghost",
92
91
  children: [
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/selected-team-switcher.tsx"],"sourcesContent":["'use client';\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\n\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 Skeleton,\n Typography\n} from \"@stackframe/stack-ui\";\nimport { PlusCircle, Settings } from \"lucide-react\";\nimport { useRouter } from \"next/navigation\";\nimport { Suspense, 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 return <Suspense fallback={<Fallback />}>\n <Inner {...props} />\n </Suspense>;\n}\n\nfunction Fallback() {\n return <Skeleton className=\"h-9 w-full max-w-64 stack-scope\" />;\n}\n\nfunction Inner(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"]}
1
+ {"version":3,"sources":["../../../src/components/selected-team-switcher.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\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 Skeleton,\n Typography\n} from \"@stackframe/stack-ui\";\nimport { PlusCircle, Settings } from \"lucide-react\";\nimport { Suspense, 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 return <Suspense fallback={<Fallback />}>\n <Inner {...props} />\n </Suspense>;\n}\n\nfunction Fallback() {\n return <Skeleton className=\"h-9 w-full max-w-64 stack-scope\" />;\n}\n\nfunction Inner(props: SelectedTeamSwitcherProps) {\n const { t } = useTranslation();\n const app = useStackApp();\n const user = useUser();\n const project = app.useProject();\n const navigate = app.useNavigate();\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 navigate(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={() => navigate(`${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={() => navigate(`${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 +1 @@
1
- {"version":3,"sources":["../../../src/components/team-icon.tsx"],"sourcesContent":["//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\n\nimport { Avatar, AvatarImage, Typography } from \"@stackframe/stack-ui\";\nimport { Team } from \"..\";\n\nexport function TeamIcon(props: { team: Team }) {\n if (props.team.profileImageUrl) {\n return (\n <Avatar className=\"min-w-6 min-h-6 max-w-6 max-h-6 rounded\">\n <AvatarImage src={props.team.profileImageUrl} alt={props.team.displayName} />\n </Avatar>\n );\n } else {\n return (\n <div className=\"flex items-center justify-center min-w-6 min-h-6 max-w-6 max-h-6 rounded bg-zinc-200\">\n <Typography className=\"text-zinc-800 dark:text-zinc-800\">{props.team.displayName.slice(0, 1).toUpperCase()}</Typography>\n </div>\n );\n }\n}\n"],"mappings":";AAIA,SAAS,QAAQ,aAAa,kBAAkB;AAOxC;AAJD,SAAS,SAAS,OAAuB;AAC9C,MAAI,MAAM,KAAK,iBAAiB;AAC9B,WACE,oBAAC,UAAO,WAAU,2CAChB,8BAAC,eAAY,KAAK,MAAM,KAAK,iBAAiB,KAAK,MAAM,KAAK,aAAa,GAC7E;AAAA,EAEJ,OAAO;AACL,WACE,oBAAC,SAAI,WAAU,wFACb,8BAAC,cAAW,WAAU,oCAAoC,gBAAM,KAAK,YAAY,MAAM,GAAG,CAAC,EAAE,YAAY,GAAE,GAC7G;AAAA,EAEJ;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/team-icon.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\nimport { Avatar, AvatarImage, Typography } from \"@stackframe/stack-ui\";\nimport { Team } from \"..\";\n\nexport function TeamIcon(props: { team: Team }) {\n if (props.team.profileImageUrl) {\n return (\n <Avatar className=\"min-w-6 min-h-6 max-w-6 max-h-6 rounded\">\n <AvatarImage src={props.team.profileImageUrl} alt={props.team.displayName} />\n </Avatar>\n );\n } else {\n return (\n <div className=\"flex items-center justify-center min-w-6 min-h-6 max-w-6 max-h-6 rounded bg-zinc-200\">\n <Typography className=\"text-zinc-800 dark:text-zinc-800\">{props.team.displayName.slice(0, 1).toUpperCase()}</Typography>\n </div>\n );\n }\n}\n"],"mappings":";AAIA,SAAS,QAAQ,aAAa,kBAAkB;AAOxC;AAJD,SAAS,SAAS,OAAuB;AAC9C,MAAI,MAAM,KAAK,iBAAiB;AAC9B,WACE,oBAAC,UAAO,WAAU,2CAChB,8BAAC,eAAY,KAAK,MAAM,KAAK,iBAAiB,KAAK,MAAM,KAAK,aAAa,GAC7E;AAAA,EAEJ,OAAO;AACL,WACE,oBAAC,SAAI,WAAU,wFACb,8BAAC,cAAW,WAAU,oCAAoC,gBAAM,KAAK,YAAY,MAAM,GAAG,CAAC,EAAE,YAAY,GAAE,GAC7G;AAAA,EAEJ;AACF;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/user-button.tsx"],"sourcesContent":["'use client';\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\n\n\nimport { runAsynchronouslyWithAlert } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, Skeleton, Typography } from \"@stackframe/stack-ui\";\nimport { CircleUser, LogIn, LogOut, SunMoon, UserPlus } from \"lucide-react\";\nimport React, { Suspense } from \"react\";\nimport { CurrentUser, useStackApp, useUser } from \"..\";\nimport { useTranslation } from \"../lib/translations\";\nimport { UserAvatar } from \"./elements/user-avatar\";\n\nfunction Item(props: { text: string, icon: React.ReactNode, onClick: () => void | Promise<void> }) {\n return (\n <DropdownMenuItem onClick={() => runAsynchronouslyWithAlert(props.onClick)}>\n <div className=\"flex gap-2 items-center\">\n {props.icon}\n <Typography>{props.text}</Typography>\n </div>\n </DropdownMenuItem>\n );\n}\n\ntype UserButtonProps = {\n showUserInfo?: boolean,\n colorModeToggle?: () => void | Promise<void>,\n extraItems?: {\n text: string,\n icon: React.ReactNode,\n onClick: () => void | Promise<void>,\n }[],\n};\n\nexport function UserButton(props: UserButtonProps) {\n return (\n <Suspense fallback={<Skeleton className=\"h-[34px] w-[34px] rounded-full stack-scope\" />}>\n <UserButtonInner {...props} />\n </Suspense>\n );\n}\n\nfunction UserButtonInner(props: UserButtonProps) {\n const user = useUser();\n return <UserButtonInnerInner {...props} user={user} />;\n}\n\n\nfunction UserButtonInnerInner(props: UserButtonProps & { user: CurrentUser | null }) {\n const { t } = useTranslation();\n const user = props.user;\n const app = useStackApp();\n\n const iconProps = { size: 20, className: 'h-4 w-4' };\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger className=\"outline-none stack-scope\">\n <div className=\"flex gap-2 items-center\">\n <UserAvatar user={user} />\n {user && props.showUserInfo &&\n <div className=\"flex flex-col justify-center text-left\">\n <Typography className=\"max-w-40 truncate\">{user.displayName}</Typography>\n <Typography className=\"max-w-40 truncate\" variant=\"secondary\" type='label'>{user.primaryEmail}</Typography>\n </div>\n }\n </div>\n </DropdownMenuTrigger>\n <DropdownMenuContent className=\"stack-scope\">\n <DropdownMenuLabel>\n <div className=\"flex gap-2 items-center\">\n <UserAvatar user={user} />\n <div>\n {user && <Typography className=\"max-w-40 truncate\">{user.displayName}</Typography>}\n {user && <Typography className=\"max-w-40 truncate\" variant=\"secondary\" type='label'>{user.primaryEmail}</Typography>}\n {!user && <Typography>{t('Not signed in')}</Typography>}\n </div>\n </div>\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n {user && <Item\n text={t('Account settings')}\n onClick={async () => await app.redirectToAccountSettings()}\n icon={<CircleUser {...iconProps} />}\n />}\n {!user && <Item\n text={t('Sign in')}\n onClick={async () => await app.redirectToSignIn()}\n icon={<LogIn {...iconProps} />}\n />}\n {!user && <Item\n text={t('Sign up')}\n onClick={async () => await app.redirectToSignUp()}\n icon={<UserPlus {...iconProps}/> }\n />}\n {user && props.extraItems && props.extraItems.map((item, index) => (\n <Item key={index} {...item} />\n ))}\n {props.colorModeToggle && (\n <Item\n text={t('Toggle theme')}\n onClick={props.colorModeToggle}\n icon={<SunMoon {...iconProps} />}\n />\n )}\n {user && <Item\n text={t('Sign out')}\n onClick={() => user.signOut()}\n icon={<LogOut {...iconProps} />}\n />}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/components/user-button.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\n\nimport { runAsynchronouslyWithAlert } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, Skeleton, Typography } from \"@stackframe/stack-ui\";\nimport { CircleUser, LogIn, LogOut, SunMoon, UserPlus } from \"lucide-react\";\nimport React, { Suspense } from \"react\";\nimport { CurrentUser, useStackApp, useUser } from \"..\";\nimport { useTranslation } from \"../lib/translations\";\nimport { UserAvatar } from \"./elements/user-avatar\";\n\nfunction Item(props: { text: string, icon: React.ReactNode, onClick: () => void | Promise<void> }) {\n return (\n <DropdownMenuItem onClick={() => runAsynchronouslyWithAlert(props.onClick)}>\n <div className=\"flex gap-2 items-center\">\n {props.icon}\n <Typography>{props.text}</Typography>\n </div>\n </DropdownMenuItem>\n );\n}\n\ntype UserButtonProps = {\n showUserInfo?: boolean,\n colorModeToggle?: () => void | Promise<void>,\n extraItems?: {\n text: string,\n icon: React.ReactNode,\n onClick: () => void | Promise<void>,\n }[],\n};\n\nexport function UserButton(props: UserButtonProps) {\n return (\n <Suspense fallback={<Skeleton className=\"h-[34px] w-[34px] rounded-full stack-scope\" />}>\n <UserButtonInner {...props} />\n </Suspense>\n );\n}\n\nfunction UserButtonInner(props: UserButtonProps) {\n const user = useUser();\n return <UserButtonInnerInner {...props} user={user} />;\n}\n\n\nfunction UserButtonInnerInner(props: UserButtonProps & { user: CurrentUser | null }) {\n const { t } = useTranslation();\n const user = props.user;\n const app = useStackApp();\n\n const iconProps = { size: 20, className: 'h-4 w-4' };\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger className=\"outline-none stack-scope\">\n <div className=\"flex gap-2 items-center\">\n <UserAvatar user={user} />\n {user && props.showUserInfo &&\n <div className=\"flex flex-col justify-center text-left\">\n <Typography className=\"max-w-40 truncate\">{user.displayName}</Typography>\n <Typography className=\"max-w-40 truncate\" variant=\"secondary\" type='label'>{user.primaryEmail}</Typography>\n </div>\n }\n </div>\n </DropdownMenuTrigger>\n <DropdownMenuContent className=\"stack-scope\">\n <DropdownMenuLabel>\n <div className=\"flex gap-2 items-center\">\n <UserAvatar user={user} />\n <div>\n {user && <Typography className=\"max-w-40 truncate\">{user.displayName}</Typography>}\n {user && <Typography className=\"max-w-40 truncate\" variant=\"secondary\" type='label'>{user.primaryEmail}</Typography>}\n {!user && <Typography>{t('Not signed in')}</Typography>}\n </div>\n </div>\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n {user && <Item\n text={t('Account settings')}\n onClick={async () => await app.redirectToAccountSettings()}\n icon={<CircleUser {...iconProps} />}\n />}\n {!user && <Item\n text={t('Sign in')}\n onClick={async () => await app.redirectToSignIn()}\n icon={<LogIn {...iconProps} />}\n />}\n {!user && <Item\n text={t('Sign up')}\n onClick={async () => await app.redirectToSignUp()}\n icon={<UserPlus {...iconProps}/> }\n />}\n {user && props.extraItems && props.extraItems.map((item, index) => (\n <Item key={index} {...item} />\n ))}\n {props.colorModeToggle && (\n <Item\n text={t('Toggle theme')}\n onClick={props.colorModeToggle}\n icon={<SunMoon {...iconProps} />}\n />\n )}\n {user && <Item\n text={t('Sign out')}\n onClick={() => user.signOut()}\n icon={<LogOut {...iconProps} />}\n />}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n"],"mappings":"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","names":[]}
@@ -12,7 +12,6 @@ import { throwErr } from "@stackframe/stack-shared/dist/utils/errors";
12
12
  import { runAsynchronously, runAsynchronouslyWithAlert } from "@stackframe/stack-shared/dist/utils/promises";
13
13
  import { Accordion, AccordionContent, AccordionItem, AccordionTrigger, ActionCell, Badge, Button, Input, Label, PasswordInput, Separator, Skeleton, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Typography } from "@stackframe/stack-ui";
14
14
  import { Edit, Trash, icons } from "lucide-react";
15
- import { useRouter } from "next/navigation";
16
15
  import { TOTPController, createTOTPKeyURI } from "oslo/otp";
17
16
  import * as QRCode from "qrcode";
18
17
  import React, { Suspense, useEffect, useState } from "react";
@@ -921,7 +920,7 @@ function TeamCreation() {
921
920
  const app = useStackApp();
922
921
  const project = app.useProject();
923
922
  const user = useUser({ or: "redirect" });
924
- const router = useRouter();
923
+ const navigate = app.useNavigate();
925
924
  const [loading, setLoading] = useState(false);
926
925
  if (!project.config.clientTeamCreationEnabled) {
927
926
  return /* @__PURE__ */ jsx(MessageCard, { title: t("Team creation is not enabled") });
@@ -934,7 +933,7 @@ function TeamCreation() {
934
933
  } finally {
935
934
  setLoading(false);
936
935
  }
937
- router.push(`#team-${team.id}`);
936
+ navigate(`#team-${team.id}`);
938
937
  };
939
938
  return /* @__PURE__ */ jsx(PageLayout, { children: /* @__PURE__ */ jsx(Section, { title: t("Create a Team"), description: t("Enter a display name for your new team"), children: /* @__PURE__ */ jsxs(
940
939
  "form",