@stackframe/stack 2.5.25 → 2.5.28

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 (80) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/components/elements/maybe-full-page.d.mts +2 -3
  3. package/dist/components/elements/maybe-full-page.d.ts +2 -3
  4. package/dist/components/elements/maybe-full-page.js +5 -9
  5. package/dist/components/elements/maybe-full-page.js.map +1 -1
  6. package/dist/components/elements/user-avatar.d.mts +1 -0
  7. package/dist/components/elements/user-avatar.d.ts +1 -0
  8. package/dist/components/elements/user-avatar.js +4 -3
  9. package/dist/components/elements/user-avatar.js.map +1 -1
  10. package/dist/components/message-cards/message-card.js +1 -1
  11. package/dist/components/message-cards/message-card.js.map +1 -1
  12. package/dist/components/profile-image-editor.d.mts +11 -0
  13. package/dist/components/profile-image-editor.d.ts +11 -0
  14. package/dist/components/profile-image-editor.js +160 -0
  15. package/dist/components/profile-image-editor.js.map +1 -0
  16. package/dist/components/team-icon.js +2 -13
  17. package/dist/components/team-icon.js.map +1 -1
  18. package/dist/components-page/account-settings.js +48 -19
  19. package/dist/components-page/account-settings.js.map +1 -1
  20. package/dist/components-page/auth-page.js +1 -1
  21. package/dist/components-page/auth-page.js.map +1 -1
  22. package/dist/components-page/forgot-password.js +1 -1
  23. package/dist/components-page/forgot-password.js.map +1 -1
  24. package/dist/components-page/password-reset.js +1 -1
  25. package/dist/components-page/password-reset.js.map +1 -1
  26. package/dist/components-page/stack-handler.js +5 -1
  27. package/dist/components-page/stack-handler.js.map +1 -1
  28. package/dist/components-page/team-creation.js +1 -1
  29. package/dist/components-page/team-creation.js.map +1 -1
  30. package/dist/esm/components/elements/maybe-full-page.js +5 -9
  31. package/dist/esm/components/elements/maybe-full-page.js.map +1 -1
  32. package/dist/esm/components/elements/user-avatar.js +4 -3
  33. package/dist/esm/components/elements/user-avatar.js.map +1 -1
  34. package/dist/esm/components/message-cards/message-card.js +1 -1
  35. package/dist/esm/components/message-cards/message-card.js.map +1 -1
  36. package/dist/esm/components/profile-image-editor.js +124 -0
  37. package/dist/esm/components/profile-image-editor.js.map +1 -0
  38. package/dist/esm/components/team-icon.js +3 -4
  39. package/dist/esm/components/team-icon.js.map +1 -1
  40. package/dist/esm/components-page/account-settings.js +48 -19
  41. package/dist/esm/components-page/account-settings.js.map +1 -1
  42. package/dist/esm/components-page/auth-page.js +1 -1
  43. package/dist/esm/components-page/auth-page.js.map +1 -1
  44. package/dist/esm/components-page/forgot-password.js +1 -1
  45. package/dist/esm/components-page/forgot-password.js.map +1 -1
  46. package/dist/esm/components-page/password-reset.js +1 -1
  47. package/dist/esm/components-page/password-reset.js.map +1 -1
  48. package/dist/esm/components-page/stack-handler.js +5 -1
  49. package/dist/esm/components-page/stack-handler.js.map +1 -1
  50. package/dist/esm/components-page/team-creation.js +1 -1
  51. package/dist/esm/components-page/team-creation.js.map +1 -1
  52. package/dist/esm/generated/global-css.js +1 -1
  53. package/dist/esm/generated/global-css.js.map +1 -1
  54. package/dist/esm/lib/auth.js +26 -15
  55. package/dist/esm/lib/auth.js.map +1 -1
  56. package/dist/esm/lib/cookie.js +10 -8
  57. package/dist/esm/lib/cookie.js.map +1 -1
  58. package/dist/esm/lib/stack-app.js +15 -4
  59. package/dist/esm/lib/stack-app.js.map +1 -1
  60. package/dist/esm/utils/constants.js +1 -1
  61. package/dist/esm/utils/constants.js.map +1 -1
  62. package/dist/generated/global-css.d.mts +1 -1
  63. package/dist/generated/global-css.d.ts +1 -1
  64. package/dist/generated/global-css.js +1 -1
  65. package/dist/generated/global-css.js.map +1 -1
  66. package/dist/lib/auth.js +24 -13
  67. package/dist/lib/auth.js.map +1 -1
  68. package/dist/lib/cookie.d.mts +4 -5
  69. package/dist/lib/cookie.d.ts +4 -5
  70. package/dist/lib/cookie.js +11 -9
  71. package/dist/lib/cookie.js.map +1 -1
  72. package/dist/lib/stack-app.d.mts +4 -0
  73. package/dist/lib/stack-app.d.ts +4 -0
  74. package/dist/lib/stack-app.js +15 -4
  75. package/dist/lib/stack-app.js.map +1 -1
  76. package/dist/utils/constants.d.mts +1 -1
  77. package/dist/utils/constants.d.ts +1 -1
  78. package/dist/utils/constants.js +1 -1
  79. package/dist/utils/constants.js.map +1 -1
  80. package/package.json +9 -6
package/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # @stackframe/stack
2
2
 
3
+ ## 2.5.28
4
+
5
+ ### Patch Changes
6
+
7
+ - Bugfixes
8
+ - Updated dependencies
9
+ - @stackframe/stack-shared@2.5.28
10
+ - @stackframe/stack-ui@2.5.28
11
+ - @stackframe/stack-sc@2.5.28
12
+
13
+ ## 2.5.27
14
+
15
+ ### Patch Changes
16
+
17
+ - Bugfixes
18
+ - Updated dependencies
19
+ - @stackframe/stack-shared@2.5.27
20
+ - @stackframe/stack-sc@2.5.27
21
+ - @stackframe/stack-ui@2.5.27
22
+
23
+ ## 2.5.26
24
+
25
+ ### Patch Changes
26
+
27
+ - Bugfixes
28
+ - Updated dependencies
29
+ - @stackframe/stack-sc@2.5.26
30
+ - @stackframe/stack-shared@2.5.26
31
+ - @stackframe/stack-ui@2.5.26
32
+
3
33
  ## 2.5.25
4
34
 
5
35
  ### Patch Changes
@@ -1,11 +1,10 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import React from 'react';
3
3
 
4
- declare function MaybeFullPage({ children, fullPage, size, fullVertical, containerClassName, }: {
4
+ declare function MaybeFullPage({ children, fullPage, }: {
5
5
  children: React.ReactNode;
6
- fullPage?: boolean;
6
+ fullPage: boolean;
7
7
  size?: number;
8
- fullVertical?: boolean;
9
8
  containerClassName?: string;
10
9
  }): react_jsx_runtime.JSX.Element;
11
10
 
@@ -1,11 +1,10 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import React from 'react';
3
3
 
4
- declare function MaybeFullPage({ children, fullPage, size, fullVertical, containerClassName, }: {
4
+ declare function MaybeFullPage({ children, fullPage, }: {
5
5
  children: React.ReactNode;
6
- fullPage?: boolean;
6
+ fullPage: boolean;
7
7
  size?: number;
8
- fullVertical?: boolean;
9
8
  containerClassName?: string;
10
9
  }): react_jsx_runtime.JSX.Element;
11
10
 
@@ -25,19 +25,15 @@ __export(maybe_full_page_exports, {
25
25
  MaybeFullPage: () => MaybeFullPage
26
26
  });
27
27
  module.exports = __toCommonJS(maybe_full_page_exports);
28
- var import_stack_ui = require("@stackframe/stack-ui");
29
28
  var import_react = require("react");
30
29
  var import_ssr_layout_effect = require("./ssr-layout-effect");
31
30
  var import_jsx_runtime = require("react/jsx-runtime");
32
31
  function MaybeFullPage({
33
32
  children,
34
- fullPage = true,
35
- size = 380,
36
- fullVertical = false,
37
- containerClassName
33
+ fullPage
38
34
  }) {
39
35
  const uniqueId = (0, import_react.useId)();
40
- const id = `stack-card-frame-${uniqueId}`;
36
+ const id = `stack-full-page-container-${uniqueId}`;
41
37
  const scriptString = `(([id]) => {
42
38
  const el = document.getElementById(id);
43
39
  if (!el) {
@@ -58,11 +54,11 @@ function MaybeFullPage({
58
54
  minHeight: "100vh",
59
55
  alignSelf: "stretch",
60
56
  display: "flex",
61
- alignItems: fullVertical ? "stretch" : "center",
62
- justifyContent: "center"
57
+ justifyContent: "center",
58
+ alignItems: "center"
63
59
  },
64
60
  className: "stack-scope",
65
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Container, { size, className: (0, import_stack_ui.cn)(fullVertical ? void 0 : "p-4", containerClassName), children })
61
+ children
66
62
  }
67
63
  ),
68
64
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ssr_layout_effect.SsrScript, { script: scriptString })
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/elements/maybe-full-page.tsx"],"sourcesContent":["\"use client\";\n\nimport { Container, cn } from \"@stackframe/stack-ui\";\nimport React, { useId } from \"react\";\nimport { SsrScript } from \"./ssr-layout-effect\";\n\nexport function MaybeFullPage({\n children,\n fullPage=true,\n size=380,\n fullVertical=false,\n containerClassName,\n}: {\n children: React.ReactNode,\n fullPage?: boolean,\n size?: number,\n fullVertical?: boolean,\n containerClassName?: string,\n}) {\n const uniqueId = useId();\n const id = `stack-card-frame-${uniqueId}`;\n\n const scriptString = `(([id]) => {\n const el = document.getElementById(id);\n if (!el) {\n // component is not full page\n return;\n }\n const offset = el.getBoundingClientRect().top + document.documentElement.scrollTop;\n el.style.minHeight = \\`calc(100vh - \\${offset}px)\\`;\n })(${JSON.stringify([id])})`;\n\n if (fullPage) {\n return (\n <>\n <div\n id={id}\n suppressHydrationWarning\n style={{\n minHeight: '100vh',\n alignSelf: 'stretch',\n display: 'flex',\n alignItems: fullVertical ? 'stretch' : 'center',\n justifyContent: 'center',\n }}\n className=\"stack-scope\"\n >\n <Container size={size} className={cn(fullVertical ? undefined : 'p-4', containerClassName)}>\n {children}\n </Container>\n </div>\n <SsrScript script={scriptString} />\n </>\n );\n } else {\n return <>\n {children}\n </>;\n }\n\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,sBAA8B;AAC9B,mBAA6B;AAC7B,+BAA0B;AA8BpB;AA5BC,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA,WAAS;AAAA,EACT,OAAK;AAAA,EACL,eAAa;AAAA,EACb;AACF,GAMG;AACD,QAAM,eAAW,oBAAM;AACvB,QAAM,KAAK,oBAAoB,QAAQ;AAEvC,QAAM,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,OAQhB,KAAK,UAAU,CAAC,EAAE,CAAC,CAAC;AAEzB,MAAI,UAAU;AACZ,WACE,4EACE;AAAA;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA,0BAAwB;AAAA,UACxB,OAAO;AAAA,YACL,WAAW;AAAA,YACX,WAAW;AAAA,YACX,SAAS;AAAA,YACT,YAAY,eAAe,YAAY;AAAA,YACvC,gBAAgB;AAAA,UAClB;AAAA,UACA,WAAU;AAAA,UAEV,sDAAC,6BAAU,MAAY,eAAW,oBAAG,eAAe,SAAY,OAAO,kBAAkB,GACtF,UACH;AAAA;AAAA,MACF;AAAA,MACA,4CAAC,sCAAU,QAAQ,cAAc;AAAA,OACnC;AAAA,EAEJ,OAAO;AACL,WAAO,2EACJ,UACH;AAAA,EACF;AAEF;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/elements/maybe-full-page.tsx"],"sourcesContent":["\"use client\";\n\nimport React, { useId } from \"react\";\nimport { SsrScript } from \"./ssr-layout-effect\";\n\nexport function MaybeFullPage({\n children,\n fullPage,\n}: {\n children: React.ReactNode,\n fullPage: boolean,\n size?: number,\n containerClassName?: string,\n}) {\n const uniqueId = useId();\n const id = `stack-full-page-container-${uniqueId}`;\n\n const scriptString = `(([id]) => {\n const el = document.getElementById(id);\n if (!el) {\n // component is not full page\n return;\n }\n const offset = el.getBoundingClientRect().top + document.documentElement.scrollTop;\n el.style.minHeight = \\`calc(100vh - \\${offset}px)\\`;\n })(${JSON.stringify([id])})`;\n\n if (fullPage) {\n return (\n <>\n <div\n id={id}\n suppressHydrationWarning\n style={{\n minHeight: '100vh',\n alignSelf: 'stretch',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n }}\n className=\"stack-scope\"\n >\n {children}\n </div>\n <SsrScript script={scriptString} />\n </>\n );\n } else {\n return <>\n {children}\n </>;\n }\n\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,mBAA6B;AAC7B,+BAA0B;AA0BpB;AAxBC,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AACF,GAKG;AACD,QAAM,eAAW,oBAAM;AACvB,QAAM,KAAK,6BAA6B,QAAQ;AAEhD,QAAM,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,OAQhB,KAAK,UAAU,CAAC,EAAE,CAAC,CAAC;AAEzB,MAAI,UAAU;AACZ,WACE,4EACE;AAAA;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA,0BAAwB;AAAA,UACxB,OAAO;AAAA,YACL,WAAW;AAAA,YACX,WAAW;AAAA,YACX,SAAS;AAAA,YACT,gBAAgB;AAAA,YAChB,YAAY;AAAA,UACd;AAAA,UACA,WAAU;AAAA,UAET;AAAA;AAAA,MACH;AAAA,MACA,4CAAC,sCAAU,QAAQ,cAAc;AAAA,OACnC;AAAA,EAEJ,OAAO;AACL,WAAO,2EACJ,UACH;AAAA,EACF;AAEF;","names":[]}
@@ -7,6 +7,7 @@ declare function UserAvatar(props: {
7
7
  displayName?: string | null;
8
8
  primaryEmail?: string | null;
9
9
  } | null;
10
+ border?: boolean;
10
11
  }): react_jsx_runtime.JSX.Element;
11
12
 
12
13
  export { UserAvatar };
@@ -7,6 +7,7 @@ declare function UserAvatar(props: {
7
7
  displayName?: string | null;
8
8
  primaryEmail?: string | null;
9
9
  } | null;
10
+ border?: boolean;
10
11
  }): react_jsx_runtime.JSX.Element;
11
12
 
12
13
  export { UserAvatar };
@@ -23,14 +23,15 @@ __export(user_avatar_exports, {
23
23
  UserAvatar: () => UserAvatar
24
24
  });
25
25
  module.exports = __toCommonJS(user_avatar_exports);
26
- var import_lucide_react = require("lucide-react");
27
26
  var import_stack_ui = require("@stackframe/stack-ui");
27
+ var import_lucide_react = require("lucide-react");
28
28
  var import_jsx_runtime = require("react/jsx-runtime");
29
+ var defaultSize = 34;
29
30
  function UserAvatar(props) {
30
31
  const user = props.user;
31
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_stack_ui.Avatar, { style: { height: props.size || "34px", width: props.size || "34px" }, children: [
32
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_stack_ui.Avatar, { style: { height: props.size || defaultSize, width: props.size || defaultSize }, className: props.border ? "border" : "", children: [
32
33
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.AvatarImage, { src: user?.profileImageUrl || "" }),
33
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.AvatarFallback, { children: user ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "font-medium", children: (user.displayName || user.primaryEmail)?.slice(0, 2).toUpperCase() }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.UserRound, { className: "h-5 w-5 text-zinc-500" }) })
34
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.AvatarFallback, { children: user ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "font-medium", style: { fontSize: (props.size || defaultSize) * 0.5 }, children: (user.displayName || user.primaryEmail)?.slice(0, 2).toUpperCase() }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.UserRound, { className: "text-zinc-500", size: (props.size || defaultSize) * 0.6 }) })
34
35
  ] });
35
36
  }
36
37
  // Annotate the CommonJS export names for ESM import in node:
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/elements/user-avatar.tsx"],"sourcesContent":["import { UserRound } from \"lucide-react\";\nimport { User } from \"../../lib/stack-app\";\nimport { Avatar, AvatarFallback, AvatarImage } from \"@stackframe/stack-ui\";\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}) {\n const user = props.user;\n return (\n <Avatar style={{ height: props.size || '34px', width: props.size || '34px' }}>\n <AvatarImage src={user?.profileImageUrl || ''} />\n <AvatarFallback>\n {user ?\n <div className='font-medium'>\n {(user.displayName || user.primaryEmail)?.slice(0, 2).toUpperCase()}\n </div> :\n <UserRound className=\"h-5 w-5 text-zinc-500\" />}\n </AvatarFallback>\n </Avatar>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAA0B;AAE1B,sBAAoD;AAYhD;AAVG,SAAS,WAAW,OAOxB;AACD,QAAM,OAAO,MAAM;AACnB,SACE,6CAAC,0BAAO,OAAO,EAAE,QAAQ,MAAM,QAAQ,QAAQ,OAAO,MAAM,QAAQ,OAAO,GACzE;AAAA,gDAAC,+BAAY,KAAK,MAAM,mBAAmB,IAAI;AAAA,IAC/C,4CAAC,kCACE,iBACC,4CAAC,SAAI,WAAU,eACX,gBAAK,eAAe,KAAK,eAAe,MAAM,GAAG,CAAC,EAAE,YAAY,GACpE,IACA,4CAAC,iCAAU,WAAU,yBAAwB,GACjD;AAAA,KACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/elements/user-avatar.tsx"],"sourcesContent":["import { 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.5 }}>\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}"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAAoD;AACpD,0BAA0B;AAetB;AAbJ,IAAM,cAAc;AAEb,SAAS,WAAW,OAQxB;AACD,QAAM,OAAO,MAAM;AACnB,SACE,6CAAC,0BAAO,OAAO,EAAE,QAAQ,MAAM,QAAQ,aAAa,OAAO,MAAM,QAAQ,YAAY,GAAG,WAAW,MAAM,SAAS,WAAW,IAC3H;AAAA,gDAAC,+BAAY,KAAK,MAAM,mBAAmB,IAAI;AAAA,IAC/C,4CAAC,kCACE,iBACC,4CAAC,SAAI,WAAU,eAAc,OAAO,EAAE,WAAW,MAAM,QAAQ,eAAe,IAAI,GAC9E,gBAAK,eAAe,KAAK,eAAe,MAAM,GAAG,CAAC,EAAE,YAAY,GACpE,IACA,4CAAC,iCAAU,WAAU,iBAAgB,OAAO,MAAM,QAAQ,eAAe,KAAK,GAClF;AAAA,KACF;AAEJ;","names":[]}
@@ -29,7 +29,7 @@ var import_maybe_full_page = require("../elements/maybe-full-page");
29
29
  var import_stack_ui = require("@stackframe/stack-ui");
30
30
  var import_jsx_runtime = require("react/jsx-runtime");
31
31
  function MessageCard({ fullPage = false, ...props }) {
32
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_maybe_full_page.MaybeFullPage, { fullPage, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "text-center stack-scope flex flex-col gap-4", children: [
32
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_maybe_full_page.MaybeFullPage, { fullPage, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "text-center stack-scope flex flex-col gap-4", style: { width: "380px", padding: fullPage ? "1rem" : 0 }, children: [
33
33
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { type: "h3", children: props.title }),
34
34
  props.children,
35
35
  (props.primaryButtonText || props.secondaryButtonText) && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex justify-center gap-4 my-5", children: [
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/message-cards/message-card.tsx"],"sourcesContent":["'use client';\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\">\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":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,6BAA8B;AAC9B,sBAAmC;AAiB3B;AAfD,SAAS,YACd,EAAE,WAAS,OAAO,GAAG,MAAM,GAU3B;AACA,SACE,4CAAC,wCAAc,UACb,uDAAC,SAAI,WAAU,+CACb;AAAA,gDAAC,8BAAW,MAAK,MAAM,gBAAM,OAAM;AAAA,IAClC,MAAM;AAAA,KACL,MAAM,qBAAqB,MAAM,wBACjC,6CAAC,SAAI,WAAU,kCACZ;AAAA,YAAM,uBACL,4CAAC,0BAAO,SAAQ,aAAY,SAAS,MAAM,iBACxC,gBAAM,qBACT;AAAA,MAED,MAAM,qBACL,4CAAC,0BAAO,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\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={{ width: '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":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,6BAA8B;AAC9B,sBAAmC;AAiB3B;AAfD,SAAS,YACd,EAAE,WAAS,OAAO,GAAG,MAAM,GAU3B;AACA,SACE,4CAAC,wCAAc,UACb,uDAAC,SAAI,WAAU,+CAA8C,OAAO,EAAE,OAAO,SAAS,SAAS,WAAW,SAAS,EAAE,GACnH;AAAA,gDAAC,8BAAW,MAAK,MAAM,gBAAM,OAAM;AAAA,IAClC,MAAM;AAAA,KACL,MAAM,qBAAqB,MAAM,wBACjC,6CAAC,SAAI,WAAU,kCACZ;AAAA,YAAM,uBACL,4CAAC,0BAAO,SAAQ,aAAY,SAAS,MAAM,iBACxC,gBAAM,qBACT;AAAA,MAED,MAAM,qBACL,4CAAC,0BAAO,SAAS,MAAM,eACpB,gBAAM,mBACT;AAAA,OAEJ;AAAA,KAEJ,GACF;AAEJ;","names":[]}
@@ -0,0 +1,11 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ComponentProps } from 'react';
3
+ import { UserAvatar } from './elements/user-avatar.mjs';
4
+
5
+ declare function checkImageUrl(url: string): Promise<boolean>;
6
+ declare function ProfileImageEditor(props: {
7
+ user: NonNullable<ComponentProps<typeof UserAvatar>['user']>;
8
+ onProfileImageUrlChange: (profileImageUrl: string | null) => void | Promise<void>;
9
+ }): react_jsx_runtime.JSX.Element;
10
+
11
+ export { ProfileImageEditor, checkImageUrl };
@@ -0,0 +1,11 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ComponentProps } from 'react';
3
+ import { UserAvatar } from './elements/user-avatar.js';
4
+
5
+ declare function checkImageUrl(url: string): Promise<boolean>;
6
+ declare function ProfileImageEditor(props: {
7
+ user: NonNullable<ComponentProps<typeof UserAvatar>['user']>;
8
+ onProfileImageUrlChange: (profileImageUrl: string | null) => void | Promise<void>;
9
+ }): react_jsx_runtime.JSX.Element;
10
+
11
+ export { ProfileImageEditor, checkImageUrl };
@@ -0,0 +1,160 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/components/profile-image-editor.tsx
31
+ var profile_image_editor_exports = {};
32
+ __export(profile_image_editor_exports, {
33
+ ProfileImageEditor: () => ProfileImageEditor,
34
+ checkImageUrl: () => checkImageUrl
35
+ });
36
+ module.exports = __toCommonJS(profile_image_editor_exports);
37
+ var import_base64 = require("@stackframe/stack-shared/dist/utils/base64");
38
+ var import_stack_ui = require("@stackframe/stack-ui");
39
+ var import_browser_image_compression = __toESM(require("browser-image-compression"));
40
+ var import_lucide_react = require("lucide-react");
41
+ var import_react = require("react");
42
+ var import_react_avatar_editor = __toESM(require("react-avatar-editor"));
43
+ var import_user_avatar = require("./elements/user-avatar");
44
+ var import_jsx_runtime = require("react/jsx-runtime");
45
+ async function checkImageUrl(url) {
46
+ try {
47
+ const res = await fetch(url, { method: "HEAD" });
48
+ const buff = await res.blob();
49
+ return buff.type.startsWith("image/");
50
+ } catch (e) {
51
+ return false;
52
+ }
53
+ }
54
+ function ProfileImageEditor(props) {
55
+ const cropRef = (0, import_react.useRef)(null);
56
+ const [slideValue, setSlideValue] = (0, import_react.useState)(1);
57
+ const [rawUrl, setRawUrl] = (0, import_react.useState)(null);
58
+ const [error, setError] = (0, import_react.useState)(null);
59
+ function reset() {
60
+ setSlideValue(1);
61
+ setRawUrl(null);
62
+ setError(null);
63
+ }
64
+ function upload() {
65
+ const input = document.createElement("input");
66
+ input.type = "file";
67
+ input.onchange = (e) => {
68
+ const file = e.target.files?.[0];
69
+ if (!file) return;
70
+ (0, import_base64.fileToBase64)(file).then(async (rawUrl2) => {
71
+ if (await checkImageUrl(rawUrl2)) {
72
+ setRawUrl(rawUrl2);
73
+ setError(null);
74
+ } else {
75
+ setError("Invalid image");
76
+ }
77
+ }).then(() => input.remove()).catch(console.error);
78
+ };
79
+ input.click();
80
+ }
81
+ if (!rawUrl) {
82
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col", children: [
83
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "cursor-pointer relative", onClick: upload, children: [
84
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
85
+ import_user_avatar.UserAvatar,
86
+ {
87
+ size: 100,
88
+ user: props.user,
89
+ border: true
90
+ }
91
+ ),
92
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "absolute top-0 left-0 h-[100px] w-[100px] bg-gray-500/20 backdrop-blur-sm items-center justify-center rounded-full flex opacity-0 hover:opacity-100 transition-opacity", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "bg-background p-2 rounded-full", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Upload, { className: "h-5 w-5" }) }) })
93
+ ] }),
94
+ error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "destructive", type: "label", children: error })
95
+ ] });
96
+ }
97
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col items-center gap-4", children: [
98
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
99
+ import_react_avatar_editor.default,
100
+ {
101
+ ref: cropRef,
102
+ image: rawUrl || props.user.profileImageUrl || "",
103
+ borderRadius: 1e3,
104
+ color: [0, 0, 0, 0.72],
105
+ scale: slideValue,
106
+ rotate: 0,
107
+ border: 20,
108
+ className: "border"
109
+ }
110
+ ),
111
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
112
+ import_stack_ui.Slider,
113
+ {
114
+ min: 1,
115
+ max: 5,
116
+ step: 0.1,
117
+ defaultValue: [slideValue],
118
+ value: [slideValue],
119
+ onValueChange: (v) => setSlideValue(v[0])
120
+ }
121
+ ),
122
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-row gap-2", children: [
123
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
124
+ import_stack_ui.Button,
125
+ {
126
+ onClick: async () => {
127
+ if (cropRef.current && rawUrl) {
128
+ const croppedUrl = cropRef.current.getImage().toDataURL("image/jpeg");
129
+ const compressedFile = await (0, import_browser_image_compression.default)(
130
+ await import_browser_image_compression.default.getFilefromDataUrl(croppedUrl, "profile-image"),
131
+ {
132
+ maxSizeMB: 0.1,
133
+ fileType: "image/jpeg"
134
+ }
135
+ );
136
+ const compressedUrl = await import_browser_image_compression.default.getDataUrlFromFile(compressedFile);
137
+ await props.onProfileImageUrlChange(compressedUrl);
138
+ reset();
139
+ }
140
+ },
141
+ children: "Save"
142
+ }
143
+ ),
144
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
145
+ import_stack_ui.Button,
146
+ {
147
+ variant: "secondary",
148
+ onClick: reset,
149
+ children: "Cancel"
150
+ }
151
+ )
152
+ ] })
153
+ ] });
154
+ }
155
+ // Annotate the CommonJS export names for ESM import in node:
156
+ 0 && (module.exports = {
157
+ ProfileImageEditor,
158
+ checkImageUrl
159
+ });
160
+ //# sourceMappingURL=profile-image-editor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/profile-image-editor.tsx"],"sourcesContent":["import { 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 { 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 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('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={100}\n user={props.user}\n border\n />\n <div className='absolute top-0 left-0 h-[100px] w-[100px] 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 Save\n </Button>\n <Button\n variant=\"secondary\"\n onClick={reset}\n >\n Cancel\n </Button>\n </div>\n </div>\n );\n}"],"mappings":"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","names":["rawUrl","AvatarEditor","imageCompression"]}
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
- var __create = Object.create;
3
2
  var __defProp = Object.defineProperty;
4
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
6
  var __export = (target, all) => {
9
7
  for (var name in all)
@@ -17,14 +15,6 @@ var __copyProps = (to, from, except, desc) => {
17
15
  }
18
16
  return to;
19
17
  };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
19
 
30
20
  // src/components/team-icon.tsx
@@ -33,14 +23,13 @@ __export(team_icon_exports, {
33
23
  TeamIcon: () => TeamIcon
34
24
  });
35
25
  module.exports = __toCommonJS(team_icon_exports);
36
- var import_image = __toESM(require("next/image"));
37
26
  var import_stack_ui = require("@stackframe/stack-ui");
38
27
  var import_jsx_runtime = require("react/jsx-runtime");
39
28
  function TeamIcon(props) {
40
29
  if (props.team.profileImageUrl) {
41
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "w-6 h-6 rounded bg-gray-200 overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_image.default, { src: props.team.profileImageUrl, alt: props.team.displayName, className: "w-6 h-6" }) });
30
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Avatar, { className: "w-6 h-6 rounded", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.AvatarImage, { src: props.team.profileImageUrl, alt: props.team.displayName }) });
42
31
  } else {
43
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex items-center justify-center w-6 h-6 rounded bg-gray-200", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { children: props.team.displayName.slice(0, 1).toUpperCase() }) });
32
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex items-center justify-center w-6 h-6 rounded bg-zinc-200", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { className: "text-zinc-800 dark:text-zinc-800", children: props.team.displayName.slice(0, 1).toUpperCase() }) });
44
33
  }
45
34
  }
46
35
  // Annotate the CommonJS export names for ESM import in node:
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/team-icon.tsx"],"sourcesContent":["import Image from \"next/image\";\nimport { Team } from \"..\";\nimport { Typography } from \"@stackframe/stack-ui\";\n\nexport function TeamIcon(props: { team: Team }) {\n if (props.team.profileImageUrl) {\n return (\n <div className=\"w-6 h-6 rounded bg-gray-200 overflow-hidden\">\n <Image src={props.team.profileImageUrl} alt={props.team.displayName} className=\"w-6 h-6\" />\n </div>\n );\n } else {\n return (\n <div className=\"flex items-center justify-center w-6 h-6 rounded bg-gray-200\">\n <Typography>{props.team.displayName.slice(0, 1).toUpperCase()}</Typography>\n </div>\n );\n }\n}"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAkB;AAElB,sBAA2B;AAMnB;AAJD,SAAS,SAAS,OAAuB;AAC9C,MAAI,MAAM,KAAK,iBAAiB;AAC9B,WACE,4CAAC,SAAI,WAAU,+CACb,sDAAC,aAAAA,SAAA,EAAM,KAAK,MAAM,KAAK,iBAAiB,KAAK,MAAM,KAAK,aAAa,WAAU,WAAU,GAC3F;AAAA,EAEJ,OAAO;AACL,WACE,4CAAC,SAAI,WAAU,gEACb,sDAAC,8BAAY,gBAAM,KAAK,YAAY,MAAM,GAAG,CAAC,EAAE,YAAY,GAAE,GAChE;AAAA,EAEJ;AACF;","names":["Image"]}
1
+ {"version":3,"sources":["../../src/components/team-icon.tsx"],"sourcesContent":["import Image from \"next/image\";\nimport { Team } from \"..\";\nimport { Avatar, AvatarImage, Typography } from \"@stackframe/stack-ui\";\n\nexport function TeamIcon(props: { team: Team }) {\n if (props.team.profileImageUrl) {\n return (\n <Avatar className=\"w-6 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 w-6 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}"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,sBAAgD;AAMxC;AAJD,SAAS,SAAS,OAAuB;AAC9C,MAAI,MAAM,KAAK,iBAAiB;AAC9B,WACE,4CAAC,0BAAO,WAAU,mBAChB,sDAAC,+BAAY,KAAK,MAAM,KAAK,iBAAiB,KAAK,MAAM,KAAK,aAAa,GAC7E;AAAA,EAEJ,OAAO;AACL,WACE,4CAAC,SAAI,WAAU,gEACb,sDAAC,8BAAW,WAAU,oCAAoC,gBAAM,KAAK,YAAY,MAAM,GAAG,CAAC,EAAE,YAAY,GAAE,GAC7G;AAAA,EAEJ;AACF;","names":[]}
@@ -54,14 +54,16 @@ var import__ = require("..");
54
54
  var import_form_warning = require("../components/elements/form-warning");
55
55
  var import_sidebar_layout = require("../components/elements/sidebar-layout");
56
56
  var import_user_avatar = require("../components/elements/user-avatar");
57
+ var import_profile_image_editor = require("../components/profile-image-editor");
57
58
  var import_team_icon = require("../components/team-icon");
59
+ var import_maybe_full_page = require("../components/elements/maybe-full-page");
58
60
  var import_jsx_runtime = require("react/jsx-runtime");
59
61
  function AccountSettings({ fullPage = false }) {
60
62
  const user = (0, import__.useUser)({ or: "redirect" });
61
63
  const teams = user.useTeams();
62
64
  const stackApp = (0, import__.useStackApp)();
63
65
  const project = stackApp.useProject();
64
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
66
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_maybe_full_page.MaybeFullPage, { fullPage, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { alignSelf: "stretch", flexGrow: 1 }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
65
67
  import_sidebar_layout.SidebarLayout,
66
68
  {
67
69
  items: [
@@ -120,16 +122,30 @@ function AccountSettings({ fullPage = false }) {
120
122
  title: "Account Settings",
121
123
  basePath: stackApp.urls.accountSettings
122
124
  }
123
- );
125
+ ) }) });
124
126
  }
125
127
  function ProfileSection() {
126
128
  const user = (0, import__.useUser)({ or: "redirect" });
127
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
128
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Label, { children: "Display name" }),
129
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.EditableText, { value: user.displayName || "", onSave: async (newDisplayName) => {
130
- await user.update({ displayName: newDisplayName });
131
- } })
132
- ] }) });
129
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col gap-8", children: [
130
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col items-start", children: [
131
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Label, { className: "mb-2", children: "Profile image" }),
132
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
133
+ import_profile_image_editor.ProfileImageEditor,
134
+ {
135
+ user,
136
+ onProfileImageUrlChange: async (profileImageUrl) => {
137
+ await user.update({ profileImageUrl });
138
+ }
139
+ }
140
+ )
141
+ ] }),
142
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col", children: [
143
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Label, { children: "Display name" }),
144
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.EditableText, { value: user.displayName || "", onSave: async (newDisplayName) => {
145
+ await user.update({ displayName: newDisplayName });
146
+ } })
147
+ ] })
148
+ ] });
133
149
  }
134
150
  function EmailVerificationSection() {
135
151
  const user = (0, import__.useUser)({ or: "redirect" });
@@ -348,7 +364,6 @@ function SignOutSection() {
348
364
  ) }) });
349
365
  }
350
366
  function UserSettings(props) {
351
- const app = (0, import__.useStackApp)();
352
367
  const user = (0, import__.useUser)({ or: "redirect" });
353
368
  const [leaving, setLeaving] = (0, import_react.useState)(false);
354
369
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex flex-col gap-2", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: !leaving ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
@@ -375,16 +390,30 @@ function ManagementSettings(props) {
375
390
  if (!updateTeamPermission) {
376
391
  return null;
377
392
  }
378
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
379
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Label, { children: "Team display name" }),
380
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
381
- import_stack_ui.EditableText,
382
- {
383
- value: props.team.displayName,
384
- onSave: async (newDisplayName) => await props.team.update({ displayName: newDisplayName })
385
- }
386
- )
387
- ] }) });
393
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
394
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col", children: [
395
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Label, { children: "Team display name" }),
396
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
397
+ import_profile_image_editor.ProfileImageEditor,
398
+ {
399
+ user: props.team,
400
+ onProfileImageUrlChange: async (profileImageUrl) => {
401
+ await props.team.update({ profileImageUrl });
402
+ }
403
+ }
404
+ )
405
+ ] }),
406
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col", children: [
407
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Label, { children: "Team display name" }),
408
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
409
+ import_stack_ui.EditableText,
410
+ {
411
+ value: props.team.displayName,
412
+ onSave: async (newDisplayName) => await props.team.update({ displayName: newDisplayName })
413
+ }
414
+ )
415
+ ] })
416
+ ] });
388
417
  }
389
418
  function ProfileSettings(props) {
390
419
  const user = (0, import__.useUser)({ or: "redirect" });