@burdenoff/microfe-comradecircle 2026.525.1 → 2026.704.2

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 (107) hide show
  1. package/dist/comradecircle/ComradeCircleRoot.js +75 -95
  2. package/dist/comradecircle/ComradeCircleRoot.js.map +1 -1
  3. package/dist/comradecircle/ComradeCircleRoutes.js +58 -37
  4. package/dist/comradecircle/ComradeCircleRoutes.js.map +1 -1
  5. package/dist/comradecircle/components/Avatar.js +47 -0
  6. package/dist/comradecircle/components/Avatar.js.map +1 -0
  7. package/dist/comradecircle/components/AvatarUploadField.js +80 -0
  8. package/dist/comradecircle/components/AvatarUploadField.js.map +1 -0
  9. package/dist/comradecircle/components/CircleCard.js +118 -0
  10. package/dist/comradecircle/components/CircleCard.js.map +1 -0
  11. package/dist/comradecircle/components/CommentThread.js +105 -0
  12. package/dist/comradecircle/components/CommentThread.js.map +1 -0
  13. package/dist/comradecircle/components/CreateCircleDialog.js +159 -0
  14. package/dist/comradecircle/components/CreateCircleDialog.js.map +1 -0
  15. package/dist/comradecircle/components/CreateEventDialog.js +210 -0
  16. package/dist/comradecircle/components/CreateEventDialog.js.map +1 -0
  17. package/dist/comradecircle/components/EmptyState.js +35 -0
  18. package/dist/comradecircle/components/EmptyState.js.map +1 -0
  19. package/dist/comradecircle/components/EventCard.js +93 -0
  20. package/dist/comradecircle/components/EventCard.js.map +1 -0
  21. package/dist/comradecircle/components/FileImage.js +20 -0
  22. package/dist/comradecircle/components/FileImage.js.map +1 -0
  23. package/dist/comradecircle/components/FilterTabs.js +27 -0
  24. package/dist/comradecircle/components/FilterTabs.js.map +1 -0
  25. package/dist/comradecircle/components/ImageAttachments.js +97 -0
  26. package/dist/comradecircle/components/ImageAttachments.js.map +1 -0
  27. package/dist/comradecircle/components/MemberIdentity.js +44 -0
  28. package/dist/comradecircle/components/MemberIdentity.js.map +1 -0
  29. package/dist/comradecircle/components/MiniBar.js +22 -0
  30. package/dist/comradecircle/components/MiniBar.js.map +1 -0
  31. package/dist/comradecircle/components/PageLayout.js +38 -0
  32. package/dist/comradecircle/components/PageLayout.js.map +1 -0
  33. package/dist/comradecircle/components/Pagination.js +50 -0
  34. package/dist/comradecircle/components/Pagination.js.map +1 -0
  35. package/dist/comradecircle/components/PollCard.js +97 -0
  36. package/dist/comradecircle/components/PollCard.js.map +1 -0
  37. package/dist/comradecircle/components/PostCard.js +163 -0
  38. package/dist/comradecircle/components/PostCard.js.map +1 -0
  39. package/dist/comradecircle/components/PostComposer.js +87 -0
  40. package/dist/comradecircle/components/PostComposer.js.map +1 -0
  41. package/dist/comradecircle/components/ReactionBar.js +122 -0
  42. package/dist/comradecircle/components/ReactionBar.js.map +1 -0
  43. package/dist/comradecircle/components/StateViews.js +49 -0
  44. package/dist/comradecircle/components/StateViews.js.map +1 -0
  45. package/dist/comradecircle/components/StatusBadge.js +68 -0
  46. package/dist/comradecircle/components/StatusBadge.js.map +1 -0
  47. package/dist/comradecircle/components/Tabs.js +31 -0
  48. package/dist/comradecircle/components/Tabs.js.map +1 -0
  49. package/dist/comradecircle/components/TagInput.js +49 -0
  50. package/dist/comradecircle/components/TagInput.js.map +1 -0
  51. package/dist/comradecircle/context/ComradeCircleContext.js +85 -0
  52. package/dist/comradecircle/context/ComradeCircleContext.js.map +1 -0
  53. package/dist/comradecircle/context/index.js +1 -0
  54. package/dist/comradecircle/hooks/index.js +3 -0
  55. package/dist/comradecircle/hooks/useComradeCircleApi.js +419 -0
  56. package/dist/comradecircle/hooks/useComradeCircleApi.js.map +1 -0
  57. package/dist/comradecircle/hooks/useCursorPager.js +25 -0
  58. package/dist/comradecircle/hooks/useCursorPager.js.map +1 -0
  59. package/dist/comradecircle/hooks/useFiles.js +78 -0
  60. package/dist/comradecircle/hooks/useFiles.js.map +1 -0
  61. package/dist/comradecircle/index.js +5 -2
  62. package/dist/comradecircle/lib/graphql-cache.js +9 -0
  63. package/dist/comradecircle/lib/graphql-cache.js.map +1 -0
  64. package/dist/comradecircle/lib/toast.js +39 -0
  65. package/dist/comradecircle/lib/toast.js.map +1 -0
  66. package/dist/comradecircle/pages/FeedPage.js +65 -0
  67. package/dist/comradecircle/pages/FeedPage.js.map +1 -0
  68. package/dist/comradecircle/pages/circles/CircleDetailPage.js +651 -0
  69. package/dist/comradecircle/pages/circles/CircleDetailPage.js.map +1 -0
  70. package/dist/comradecircle/pages/circles/CirclesPage.js +129 -0
  71. package/dist/comradecircle/pages/circles/CirclesPage.js.map +1 -0
  72. package/dist/comradecircle/pages/events/EventDetailPage.js +276 -0
  73. package/dist/comradecircle/pages/events/EventDetailPage.js.map +1 -0
  74. package/dist/comradecircle/pages/events/EventsPage.js +102 -0
  75. package/dist/comradecircle/pages/events/EventsPage.js.map +1 -0
  76. package/dist/comradecircle/pages/members/MemberProfilePage.js +138 -0
  77. package/dist/comradecircle/pages/members/MemberProfilePage.js.map +1 -0
  78. package/dist/comradecircle/pages/members/MembersPage.js +153 -0
  79. package/dist/comradecircle/pages/members/MembersPage.js.map +1 -0
  80. package/dist/comradecircle/pages/profile/MyProfilePage.js +266 -0
  81. package/dist/comradecircle/pages/profile/MyProfilePage.js.map +1 -0
  82. package/dist/comradecircle/utils/cn.js +10 -0
  83. package/dist/comradecircle/utils/cn.js.map +1 -0
  84. package/dist/comradecircle/utils/formatters.js +51 -0
  85. package/dist/comradecircle/utils/formatters.js.map +1 -0
  86. package/dist/comradecircle/utils/navigation.js +2 -1
  87. package/dist/comradecircle/utils/navigation.js.map +1 -1
  88. package/dist/comradecircle/utils/slug.js +8 -0
  89. package/dist/comradecircle/utils/slug.js.map +1 -0
  90. package/dist/index.js +6 -4
  91. package/dist/node_modules/clsx/dist/clsx.js +18 -0
  92. package/dist/node_modules/clsx/dist/clsx.js.map +1 -0
  93. package/dist/node_modules/sonner/dist/index.js +163 -0
  94. package/dist/node_modules/sonner/dist/index.js.map +1 -0
  95. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +1716 -0
  96. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js.map +1 -0
  97. package/package.json +3 -2
  98. package/dist/comradecircle/pages/CommunitiesPage.js +0 -299
  99. package/dist/comradecircle/pages/CommunitiesPage.js.map +0 -1
  100. package/dist/comradecircle/pages/CreatorPage.js +0 -399
  101. package/dist/comradecircle/pages/CreatorPage.js.map +0 -1
  102. package/dist/comradecircle/pages/DashboardPage.js +0 -265
  103. package/dist/comradecircle/pages/DashboardPage.js.map +0 -1
  104. package/dist/comradecircle/providers/ComradeCircleProvider.js +0 -27
  105. package/dist/comradecircle/providers/ComradeCircleProvider.js.map +0 -1
  106. package/dist/comradecircle/store/comradecircleStore.js +0 -345
  107. package/dist/comradecircle/store/comradecircleStore.js.map +0 -1
@@ -1,107 +1,87 @@
1
- import { ComradeCircleProvider as e } from "./providers/ComradeCircleProvider.js";
2
- import { ComradeCircleRoutes as t } from "./ComradeCircleRoutes.js";
3
- import { joinPath as n } from "./utils/navigation.js";
4
- import { useEffect as r } from "react";
5
- import { useI18n as i } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
6
- import { Cookie as a, FileText as o, Home as s, LayoutDashboard as c, LogIn as l, Palette as u, ShieldCheck as d, UserPlus as f, Users as p } from "lucide-react";
1
+ import { joinPath as e } from "./utils/navigation.js";
2
+ import { ComradeCircleProvider as t } from "./context/ComradeCircleContext.js";
3
+ import { ComradeCircleRoutes as n } from "./ComradeCircleRoutes.js";
4
+ import { useCallback as r, useEffect as i } from "react";
5
+ import { QueryClient as a, QueryClientProvider as o } from "@tanstack/react-query";
6
+ import { FeatureFlagProvider as s } from "@burdenoff/fe-libs/shared/feature-flags";
7
+ import { useI18n as c } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
8
+ import { CalendarDays as l, Contact as u, Newspaper as d, UserCircle as f, Users as p } from "lucide-react";
7
9
  import { jsx as m } from "react/jsx-runtime";
8
- import { FeatureFlagProvider as h } from "@burdenoff/fe-libs/shared/feature-flags";
9
10
  //#region src/comradecircle/ComradeCircleRoot.tsx
10
- var g = (g) => {
11
- let { registerNavItems: _, registerFooterItems: v, basePath: y = "/" } = g, { t: b } = i();
12
- return r(() => {
13
- if (_) return _({
14
- id: "comradecircle",
15
- label: b("comradecircle.nav.root", { defaultValue: "ComradeCircle" }),
16
- path: y,
17
- icon: /* @__PURE__ */ m(p, { size: 20 }),
18
- order: 80,
19
- group: "products",
20
- children: [
21
- {
22
- id: "comradecircle-dashboard",
23
- label: b("comradecircle.nav.dashboard", { defaultValue: "Dashboard" }),
24
- path: y,
25
- icon: /* @__PURE__ */ m(c, { size: 16 }),
26
- order: 0
27
- },
28
- {
29
- id: "comradecircle-home",
30
- label: b("comradecircle.nav.home", { defaultValue: "Home" }),
31
- path: n(y, "home"),
32
- icon: /* @__PURE__ */ m(s, { size: 16 }),
33
- order: 1
34
- },
35
- {
36
- id: "comradecircle-communities",
37
- label: b("comradecircle.nav.communities", { defaultValue: "Communities" }),
38
- path: n(y, "communities"),
39
- icon: /* @__PURE__ */ m(p, { size: 16 }),
40
- order: 2
41
- },
42
- {
43
- id: "comradecircle-creator",
44
- label: b("comradecircle.nav.creatorHub", { defaultValue: "Creator Hub" }),
45
- path: n(y, "creator"),
46
- icon: /* @__PURE__ */ m(u, { size: 16 }),
47
- order: 3
48
- },
49
- {
50
- id: "comradecircle-login",
51
- label: b("comradecircle.nav.login", { defaultValue: "Login" }),
52
- path: n(y, "login"),
53
- icon: /* @__PURE__ */ m(l, { size: 16 }),
54
- order: 4
55
- },
56
- {
57
- id: "comradecircle-signup",
58
- label: b("comradecircle.nav.signup", { defaultValue: "Signup" }),
59
- path: n(y, "signup"),
60
- icon: /* @__PURE__ */ m(f, { size: 16 }),
61
- order: 5
62
- },
63
- {
64
- id: "comradecircle-privacy",
65
- label: b("comradecircle.nav.privacy", { defaultValue: "Privacy" }),
66
- path: n(y, "privacy"),
67
- icon: /* @__PURE__ */ m(d, { size: 16 }),
68
- order: 6
69
- },
70
- {
71
- id: "comradecircle-terms",
72
- label: b("comradecircle.nav.terms", { defaultValue: "Terms" }),
73
- path: n(y, "terms"),
74
- icon: /* @__PURE__ */ m(o, { size: 16 }),
75
- order: 7
76
- },
77
- {
78
- id: "comradecircle-cookies",
79
- label: b("comradecircle.nav.cookies", { defaultValue: "Cookies" }),
80
- path: n(y, "cookies"),
81
- icon: /* @__PURE__ */ m(a, { size: 16 }),
82
- order: 8
83
- }
84
- ]
85
- });
11
+ var h = new a({ defaultOptions: { queries: {
12
+ staleTime: 60 * 1e3,
13
+ retry: 1,
14
+ refetchOnWindowFocus: !1
15
+ } } }), g = (a) => {
16
+ let { registerNavItems: g, registerFooterItems: _, basePath: v = "/" } = a, { t: y } = c(), b = r((e, t) => {
17
+ let n = y(e);
18
+ return n === e ? t : n;
19
+ }, [y]);
20
+ return i(() => {
21
+ if (g) return g([
22
+ {
23
+ id: "comradecircle-feed",
24
+ label: b("comradecircle.nav.feed", "Home"),
25
+ path: e(v, ""),
26
+ icon: /* @__PURE__ */ m(d, { size: 20 }),
27
+ order: 0,
28
+ group: "products"
29
+ },
30
+ {
31
+ id: "comradecircle-circles",
32
+ label: b("comradecircle.nav.circles", "Circles"),
33
+ path: e(v, "circles"),
34
+ icon: /* @__PURE__ */ m(p, { size: 20 }),
35
+ order: 1,
36
+ group: "products"
37
+ },
38
+ {
39
+ id: "comradecircle-events",
40
+ label: b("comradecircle.nav.events", "Events"),
41
+ path: e(v, "events"),
42
+ icon: /* @__PURE__ */ m(l, { size: 20 }),
43
+ order: 2,
44
+ group: "products"
45
+ },
46
+ {
47
+ id: "comradecircle-members",
48
+ label: b("comradecircle.nav.members", "Members"),
49
+ path: e(v, "members"),
50
+ icon: /* @__PURE__ */ m(u, { size: 20 }),
51
+ order: 3,
52
+ group: "products"
53
+ },
54
+ {
55
+ id: "comradecircle-profile",
56
+ label: b("comradecircle.nav.profile", "My Profile"),
57
+ path: e(v, "profile"),
58
+ icon: /* @__PURE__ */ m(f, { size: 20 }),
59
+ order: 4,
60
+ group: "products"
61
+ }
62
+ ]);
86
63
  }, [
87
- _,
88
- y,
64
+ g,
65
+ v,
89
66
  b
90
- ]), r(() => {
91
- if (v) return v([{
67
+ ]), i(() => {
68
+ if (_) return _([{
92
69
  id: "comradecircle-status",
93
- label: b("comradecircle.footer.ready", { defaultValue: "ComradeCircle Ready" }),
70
+ label: b("comradecircle.footer.ready", "ComradeCircle Ready"),
94
71
  type: "status",
95
72
  section: "left",
96
73
  order: 10
97
74
  }]);
98
- }, [v, b]), /* @__PURE__ */ m(h, {
99
- workspaceId: null,
100
- gateway: "global",
101
- defaultEnabled: !0,
102
- children: /* @__PURE__ */ m(e, {
103
- ...g,
104
- children: /* @__PURE__ */ m(t, {})
75
+ }, [_, b]), /* @__PURE__ */ m(o, {
76
+ client: h,
77
+ children: /* @__PURE__ */ m(s, {
78
+ workspaceId: null,
79
+ gateway: "global",
80
+ defaultEnabled: !0,
81
+ children: /* @__PURE__ */ m(t, {
82
+ ...a,
83
+ children: /* @__PURE__ */ m(n, {})
84
+ })
105
85
  })
106
86
  });
107
87
  };
@@ -1 +1 @@
1
- {"version":3,"file":"ComradeCircleRoot.js","names":[],"sources":["../../src/comradecircle/ComradeCircleRoot.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useEffect } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport {\n LayoutDashboard,\n Home,\n Users,\n Palette,\n LogIn,\n UserPlus,\n ShieldCheck,\n FileText,\n Cookie,\n} from 'lucide-react';\nimport { ComradeCircleProvider } from './providers/ComradeCircleProvider';\nimport { FeatureFlagProvider } from '@burdenoff/fe-libs/shared/feature-flags';\nimport type { NavItem, ComradeCircleRootProps } from './types';\nimport { ComradeCircleRoutes } from './ComradeCircleRoutes';\nimport { joinPath } from './utils/navigation';\n\nexport const ComradeCircleRoot: FC<ComradeCircleRootProps> = (props) => {\n const { registerNavItems, registerFooterItems, basePath = '/' } = props;\n const { t } = useI18n();\n\n useEffect(() => {\n if (!registerNavItems) return;\n const navItem: NavItem = {\n id: 'comradecircle',\n label: t('comradecircle.nav.root', { defaultValue: 'ComradeCircle' }),\n path: basePath,\n icon: <Users size={20} />,\n order: 80,\n group: 'products',\n children: [\n {\n id: 'comradecircle-dashboard',\n label: t('comradecircle.nav.dashboard', { defaultValue: 'Dashboard' }),\n path: basePath,\n icon: <LayoutDashboard size={16} />,\n order: 0,\n },\n {\n id: 'comradecircle-home',\n label: t('comradecircle.nav.home', { defaultValue: 'Home' }),\n path: joinPath(basePath, 'home'),\n icon: <Home size={16} />,\n order: 1,\n },\n {\n id: 'comradecircle-communities',\n label: t('comradecircle.nav.communities', { defaultValue: 'Communities' }),\n path: joinPath(basePath, 'communities'),\n icon: <Users size={16} />,\n order: 2,\n },\n {\n id: 'comradecircle-creator',\n label: t('comradecircle.nav.creatorHub', { defaultValue: 'Creator Hub' }),\n path: joinPath(basePath, 'creator'),\n icon: <Palette size={16} />,\n order: 3,\n },\n {\n id: 'comradecircle-login',\n label: t('comradecircle.nav.login', { defaultValue: 'Login' }),\n path: joinPath(basePath, 'login'),\n icon: <LogIn size={16} />,\n order: 4,\n },\n {\n id: 'comradecircle-signup',\n label: t('comradecircle.nav.signup', { defaultValue: 'Signup' }),\n path: joinPath(basePath, 'signup'),\n icon: <UserPlus size={16} />,\n order: 5,\n },\n {\n id: 'comradecircle-privacy',\n label: t('comradecircle.nav.privacy', { defaultValue: 'Privacy' }),\n path: joinPath(basePath, 'privacy'),\n icon: <ShieldCheck size={16} />,\n order: 6,\n },\n {\n id: 'comradecircle-terms',\n label: t('comradecircle.nav.terms', { defaultValue: 'Terms' }),\n path: joinPath(basePath, 'terms'),\n icon: <FileText size={16} />,\n order: 7,\n },\n {\n id: 'comradecircle-cookies',\n label: t('comradecircle.nav.cookies', { defaultValue: 'Cookies' }),\n path: joinPath(basePath, 'cookies'),\n icon: <Cookie size={16} />,\n order: 8,\n },\n ],\n };\n return registerNavItems(navItem);\n }, [registerNavItems, basePath, t]);\n\n useEffect(() => {\n if (!registerFooterItems) return;\n return registerFooterItems([\n {\n id: 'comradecircle-status',\n label: t('comradecircle.footer.ready', { defaultValue: 'ComradeCircle Ready' }),\n type: 'status',\n section: 'left',\n order: 10,\n },\n ]);\n }, [registerFooterItems, t]);\n\n return (\n <FeatureFlagProvider workspaceId={null} gateway=\"global\" defaultEnabled={true}>\n <ComradeCircleProvider {...props}>\n <ComradeCircleRoutes />\n </ComradeCircleProvider>\n </FeatureFlagProvider>\n );\n};\n"],"mappings":";;;;;;;;;AAoBA,IAAa,KAAiD,MAAU;CACtE,IAAM,EAAE,qBAAkB,wBAAqB,cAAW,QAAQ,GAC5D,EAAE,SAAM,GAAS;AA6FvB,QA3FA,QAAgB;AACT,QA0EL,QAAO,EAzEkB;GACvB,IAAI;GACJ,OAAO,EAAE,0BAA0B,EAAE,cAAc,iBAAiB,CAAC;GACrE,MAAM;GACN,MAAM,kBAAC,GAAD,EAAO,MAAM,IAAM,CAAA;GACzB,OAAO;GACP,OAAO;GACP,UAAU;IACR;KACE,IAAI;KACJ,OAAO,EAAE,+BAA+B,EAAE,cAAc,aAAa,CAAC;KACtE,MAAM;KACN,MAAM,kBAAC,GAAD,EAAiB,MAAM,IAAM,CAAA;KACnC,OAAO;KACR;IACD;KACE,IAAI;KACJ,OAAO,EAAE,0BAA0B,EAAE,cAAc,QAAQ,CAAC;KAC5D,MAAM,EAAS,GAAU,OAAO;KAChC,MAAM,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA;KACxB,OAAO;KACR;IACD;KACE,IAAI;KACJ,OAAO,EAAE,iCAAiC,EAAE,cAAc,eAAe,CAAC;KAC1E,MAAM,EAAS,GAAU,cAAc;KACvC,MAAM,kBAAC,GAAD,EAAO,MAAM,IAAM,CAAA;KACzB,OAAO;KACR;IACD;KACE,IAAI;KACJ,OAAO,EAAE,gCAAgC,EAAE,cAAc,eAAe,CAAC;KACzE,MAAM,EAAS,GAAU,UAAU;KACnC,MAAM,kBAAC,GAAD,EAAS,MAAM,IAAM,CAAA;KAC3B,OAAO;KACR;IACD;KACE,IAAI;KACJ,OAAO,EAAE,2BAA2B,EAAE,cAAc,SAAS,CAAC;KAC9D,MAAM,EAAS,GAAU,QAAQ;KACjC,MAAM,kBAAC,GAAD,EAAO,MAAM,IAAM,CAAA;KACzB,OAAO;KACR;IACD;KACE,IAAI;KACJ,OAAO,EAAE,4BAA4B,EAAE,cAAc,UAAU,CAAC;KAChE,MAAM,EAAS,GAAU,SAAS;KAClC,MAAM,kBAAC,GAAD,EAAU,MAAM,IAAM,CAAA;KAC5B,OAAO;KACR;IACD;KACE,IAAI;KACJ,OAAO,EAAE,6BAA6B,EAAE,cAAc,WAAW,CAAC;KAClE,MAAM,EAAS,GAAU,UAAU;KACnC,MAAM,kBAAC,GAAD,EAAa,MAAM,IAAM,CAAA;KAC/B,OAAO;KACR;IACD;KACE,IAAI;KACJ,OAAO,EAAE,2BAA2B,EAAE,cAAc,SAAS,CAAC;KAC9D,MAAM,EAAS,GAAU,QAAQ;KACjC,MAAM,kBAAC,GAAD,EAAU,MAAM,IAAM,CAAA;KAC5B,OAAO;KACR;IACD;KACE,IAAI;KACJ,OAAO,EAAE,6BAA6B,EAAE,cAAc,WAAW,CAAC;KAClE,MAAM,EAAS,GAAU,UAAU;KACnC,MAAM,kBAAC,GAAD,EAAQ,MAAM,IAAM,CAAA;KAC1B,OAAO;KACR;IACF;GACF,CAC+B;IAC/B;EAAC;EAAkB;EAAU;EAAE,CAAC,EAEnC,QAAgB;AACT,QACL,QAAO,EAAoB,CACzB;GACE,IAAI;GACJ,OAAO,EAAE,8BAA8B,EAAE,cAAc,uBAAuB,CAAC;GAC/E,MAAM;GACN,SAAS;GACT,OAAO;GACR,CACF,CAAC;IACD,CAAC,GAAqB,EAAE,CAAC,EAG1B,kBAAC,GAAD;EAAqB,aAAa;EAAM,SAAQ;EAAS,gBAAgB;YACvE,kBAAC,GAAD;GAAuB,GAAI;aACzB,kBAAC,GAAD,EAAuB,CAAA;GACD,CAAA;EACJ,CAAA"}
1
+ {"version":3,"file":"ComradeCircleRoot.js","names":[],"sources":["../../src/comradecircle/ComradeCircleRoot.tsx"],"sourcesContent":["/**\n * ComradeCircle Root Component\n * @module comradecircle\n *\n * Host-contract entry point. Registers the product's sidebar nav (five sections\n * that map to the wspace-comradecircle-svc `com*` backend) and mounts the routed\n * pages inside the shared QueryClient + FeatureFlag providers.\n */\n\nimport type { FC } from 'react';\nimport { useCallback, useEffect } from 'react';\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query';\nimport { FeatureFlagProvider } from '@burdenoff/fe-libs/shared/feature-flags';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { Newspaper, Users, CalendarDays, Contact, UserCircle } from 'lucide-react';\nimport { ComradeCircleProvider } from './context/ComradeCircleContext';\nimport { ComradeCircleRoutes } from './ComradeCircleRoutes';\nimport { joinPath } from './utils/navigation';\nimport type { ComradeCircleRootProps, NavItem } from './types';\n\nconst queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: 60 * 1000,\n retry: 1,\n refetchOnWindowFocus: false,\n },\n },\n});\n\nexport const ComradeCircleRoot: FC<ComradeCircleRootProps> = (props) => {\n const { registerNavItems, registerFooterItems, basePath = '/' } = props;\n const { t: translate } = useI18n();\n const t = useCallback(\n (key: string, fallback: string): string => {\n const value = translate(key);\n return value === key ? fallback : value;\n },\n [translate]\n );\n\n // Register navigation items with the shell on mount. Ids/paths/orders match\n // the app-shell static NavRegistration block so the two are a single,\n // consistent source of truth.\n useEffect(() => {\n if (!registerNavItems) return;\n\n const navItems: NavItem[] = [\n {\n id: 'comradecircle-feed',\n label: t('comradecircle.nav.feed', 'Home'),\n path: joinPath(basePath, ''),\n icon: <Newspaper size={20} />,\n order: 0,\n group: 'products',\n },\n {\n id: 'comradecircle-circles',\n label: t('comradecircle.nav.circles', 'Circles'),\n path: joinPath(basePath, 'circles'),\n icon: <Users size={20} />,\n order: 1,\n group: 'products',\n },\n {\n id: 'comradecircle-events',\n label: t('comradecircle.nav.events', 'Events'),\n path: joinPath(basePath, 'events'),\n icon: <CalendarDays size={20} />,\n order: 2,\n group: 'products',\n },\n {\n id: 'comradecircle-members',\n label: t('comradecircle.nav.members', 'Members'),\n path: joinPath(basePath, 'members'),\n icon: <Contact size={20} />,\n order: 3,\n group: 'products',\n },\n {\n id: 'comradecircle-profile',\n label: t('comradecircle.nav.profile', 'My Profile'),\n path: joinPath(basePath, 'profile'),\n icon: <UserCircle size={20} />,\n order: 4,\n group: 'products',\n },\n ];\n\n return registerNavItems(navItems);\n }, [registerNavItems, basePath, t]);\n\n useEffect(() => {\n if (!registerFooterItems) return;\n return registerFooterItems([\n {\n id: 'comradecircle-status',\n label: t('comradecircle.footer.ready', 'ComradeCircle Ready'),\n type: 'status',\n section: 'left',\n order: 10,\n },\n ]);\n }, [registerFooterItems, t]);\n\n return (\n <QueryClientProvider client={queryClient}>\n <FeatureFlagProvider workspaceId={null} gateway=\"global\" defaultEnabled={true}>\n <ComradeCircleProvider {...props}>\n <ComradeCircleRoutes />\n </ComradeCircleProvider>\n </FeatureFlagProvider>\n </QueryClientProvider>\n );\n};\n"],"mappings":";;;;;;;;;;AAoBA,IAAM,IAAc,IAAI,EAAY,EAClC,gBAAgB,EACd,SAAS;CACP,WAAW,KAAK;CAChB,OAAO;CACP,sBAAsB;CACvB,EACF,EACF,CAAC,EAEW,KAAiD,MAAU;CACtE,IAAM,EAAE,qBAAkB,wBAAqB,cAAW,QAAQ,GAC5D,EAAE,GAAG,MAAc,GAAS,EAC5B,IAAI,GACP,GAAa,MAA6B;EACzC,IAAM,IAAQ,EAAU,EAAI;AAC5B,SAAO,MAAU,IAAM,IAAW;IAEpC,CAAC,EAAU,CACZ;AAmED,QA9DA,QAAgB;AACT,QA6CL,QAAO,EA3CqB;GAC1B;IACE,IAAI;IACJ,OAAO,EAAE,0BAA0B,OAAO;IAC1C,MAAM,EAAS,GAAU,GAAG;IAC5B,MAAM,kBAAC,GAAD,EAAW,MAAM,IAAM,CAAA;IAC7B,OAAO;IACP,OAAO;IACR;GACD;IACE,IAAI;IACJ,OAAO,EAAE,6BAA6B,UAAU;IAChD,MAAM,EAAS,GAAU,UAAU;IACnC,MAAM,kBAAC,GAAD,EAAO,MAAM,IAAM,CAAA;IACzB,OAAO;IACP,OAAO;IACR;GACD;IACE,IAAI;IACJ,OAAO,EAAE,4BAA4B,SAAS;IAC9C,MAAM,EAAS,GAAU,SAAS;IAClC,MAAM,kBAAC,GAAD,EAAc,MAAM,IAAM,CAAA;IAChC,OAAO;IACP,OAAO;IACR;GACD;IACE,IAAI;IACJ,OAAO,EAAE,6BAA6B,UAAU;IAChD,MAAM,EAAS,GAAU,UAAU;IACnC,MAAM,kBAAC,GAAD,EAAS,MAAM,IAAM,CAAA;IAC3B,OAAO;IACP,OAAO;IACR;GACD;IACE,IAAI;IACJ,OAAO,EAAE,6BAA6B,aAAa;IACnD,MAAM,EAAS,GAAU,UAAU;IACnC,MAAM,kBAAC,GAAD,EAAY,MAAM,IAAM,CAAA;IAC9B,OAAO;IACP,OAAO;IACR;GACF,CAEgC;IAChC;EAAC;EAAkB;EAAU;EAAE,CAAC,EAEnC,QAAgB;AACT,QACL,QAAO,EAAoB,CACzB;GACE,IAAI;GACJ,OAAO,EAAE,8BAA8B,sBAAsB;GAC7D,MAAM;GACN,SAAS;GACT,OAAO;GACR,CACF,CAAC;IACD,CAAC,GAAqB,EAAE,CAAC,EAG1B,kBAAC,GAAD;EAAqB,QAAQ;YAC3B,kBAAC,GAAD;GAAqB,aAAa;GAAM,SAAQ;GAAS,gBAAgB;aACvE,kBAAC,GAAD;IAAuB,GAAI;cACzB,kBAAC,GAAD,EAAuB,CAAA;IACD,CAAA;GACJ,CAAA;EACF,CAAA"}
@@ -1,43 +1,64 @@
1
- import { DashboardPage as e } from "./pages/DashboardPage.js";
2
- import { Suspense as t, lazy as n } from "react";
3
- import { Loader2 as r } from "lucide-react";
4
- import { Navigate as i, Route as a, Routes as o } from "react-router-dom";
5
- import { jsx as s, jsxs as c } from "react/jsx-runtime";
1
+ import { useComradeCircle as e } from "./context/ComradeCircleContext.js";
2
+ import { FeedPage as t } from "./pages/FeedPage.js";
3
+ import { Suspense as n, lazy as r } from "react";
4
+ import { Navigate as i, Route as a, Routes as o, useLocation as s } from "react-router-dom";
5
+ import { jsx as c, jsxs as l } from "react/jsx-runtime";
6
+ import { Spinner as u } from "@burdenoff/fe-libs/ui";
6
7
  //#region src/comradecircle/ComradeCircleRoutes.tsx
7
- var l = n(() => import("./pages/CreatorPage.js").then((e) => ({ default: e.CreatorPage }))), u = n(() => import("./pages/CommunitiesPage.js").then((e) => ({ default: e.CommunitiesPage })));
8
- function d() {
9
- return /* @__PURE__ */ s("div", {
10
- className: "flex min-h-[320px] items-center justify-center",
11
- children: /* @__PURE__ */ s(r, { className: "h-8 w-8 animate-spin text-primary" })
12
- });
13
- }
14
- function f() {
15
- return /* @__PURE__ */ s(t, {
16
- fallback: /* @__PURE__ */ s(d, {}),
17
- children: /* @__PURE__ */ c(o, { children: [
18
- /* @__PURE__ */ s(a, {
19
- index: !0,
20
- element: /* @__PURE__ */ s(e, {})
21
- }),
22
- /* @__PURE__ */ s(a, {
23
- path: "creator",
24
- element: /* @__PURE__ */ s(l, {})
25
- }),
26
- /* @__PURE__ */ s(a, {
27
- path: "communities",
28
- element: /* @__PURE__ */ s(u, {})
29
- }),
30
- /* @__PURE__ */ s(a, {
31
- path: "*",
32
- element: /* @__PURE__ */ s(i, {
33
- to: "",
34
- replace: !0
8
+ var d = r(() => import("./pages/circles/CirclesPage.js").then((e) => ({ default: e.CirclesPage }))), f = r(() => import("./pages/circles/CircleDetailPage.js").then((e) => ({ default: e.CircleDetailPage }))), p = r(() => import("./pages/events/EventsPage.js").then((e) => ({ default: e.EventsPage }))), m = r(() => import("./pages/events/EventDetailPage.js").then((e) => ({ default: e.EventDetailPage }))), h = r(() => import("./pages/members/MembersPage.js").then((e) => ({ default: e.MembersPage }))), g = r(() => import("./pages/members/MemberProfilePage.js").then((e) => ({ default: e.MemberProfilePage }))), _ = r(() => import("./pages/profile/MyProfilePage.js").then((e) => ({ default: e.MyProfilePage }))), v = () => /* @__PURE__ */ c("div", {
9
+ className: "flex min-h-[400px] items-center justify-center",
10
+ children: /* @__PURE__ */ c(u, { size: "lg" })
11
+ }), y = () => {
12
+ let { basePath: r, isStandalone: u } = e(), y = s(), b = r === "/" ? "" : (r ?? "").replace(/\/$/, "");
13
+ return b && !u && !(y.pathname === b || y.pathname.startsWith(b + "/")) ? null : /* @__PURE__ */ c("div", {
14
+ className: "flex min-h-full flex-col",
15
+ children: /* @__PURE__ */ c(n, {
16
+ fallback: /* @__PURE__ */ c(v, {}),
17
+ children: /* @__PURE__ */ l(o, { children: [
18
+ /* @__PURE__ */ c(a, {
19
+ index: !0,
20
+ element: /* @__PURE__ */ c(t, {})
21
+ }),
22
+ /* @__PURE__ */ c(a, {
23
+ path: "circles",
24
+ element: /* @__PURE__ */ c(d, {})
25
+ }),
26
+ /* @__PURE__ */ c(a, {
27
+ path: "circles/:id",
28
+ element: /* @__PURE__ */ c(f, {})
29
+ }),
30
+ /* @__PURE__ */ c(a, {
31
+ path: "events",
32
+ element: /* @__PURE__ */ c(p, {})
33
+ }),
34
+ /* @__PURE__ */ c(a, {
35
+ path: "events/:id",
36
+ element: /* @__PURE__ */ c(m, {})
37
+ }),
38
+ /* @__PURE__ */ c(a, {
39
+ path: "members",
40
+ element: /* @__PURE__ */ c(h, {})
41
+ }),
42
+ /* @__PURE__ */ c(a, {
43
+ path: "members/:memberId",
44
+ element: /* @__PURE__ */ c(g, {})
45
+ }),
46
+ /* @__PURE__ */ c(a, {
47
+ path: "profile",
48
+ element: /* @__PURE__ */ c(_, {})
49
+ }),
50
+ /* @__PURE__ */ c(a, {
51
+ path: "*",
52
+ element: /* @__PURE__ */ c(i, {
53
+ to: "",
54
+ replace: !0
55
+ })
35
56
  })
36
- })
37
- ] })
57
+ ] })
58
+ })
38
59
  });
39
- }
60
+ };
40
61
  //#endregion
41
- export { f as ComradeCircleRoutes };
62
+ export { y as ComradeCircleRoutes };
42
63
 
43
64
  //# sourceMappingURL=ComradeCircleRoutes.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ComradeCircleRoutes.js","names":[],"sources":["../../src/comradecircle/ComradeCircleRoutes.tsx"],"sourcesContent":["import { lazy, Suspense } from 'react';\nimport { Navigate, Route, Routes } from 'react-router-dom';\nimport { Loader2 } from 'lucide-react';\nimport { DashboardPage as IndexPage } from './pages/DashboardPage';\n\nconst CreatorPage = lazy(() =>\n import('./pages/CreatorPage').then((m) => ({ default: m.CreatorPage }))\n);\nconst CommunitiesPage = lazy(() =>\n import('./pages/CommunitiesPage').then((m) => ({ default: m.CommunitiesPage }))\n);\n\nfunction PageLoader() {\n return (\n <div className=\"flex min-h-[320px] items-center justify-center\">\n <Loader2 className=\"h-8 w-8 animate-spin text-primary\" />\n </div>\n );\n}\n\nexport function ComradeCircleRoutes() {\n return (\n <Suspense fallback={<PageLoader />}>\n <Routes>\n <Route index element={<IndexPage />} />\n <Route path=\"creator\" element={<CreatorPage />} />\n <Route path=\"communities\" element={<CommunitiesPage />} />\n <Route path=\"*\" element={<Navigate to=\"\" replace />} />\n </Routes>\n </Suspense>\n );\n}\n"],"mappings":";;;;;;AAKA,IAAM,IAAc,QAClB,OAAO,0BAAuB,MAAM,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,CACxE,EACK,IAAkB,QACtB,OAAO,8BAA2B,MAAM,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,CAChF;AAED,SAAS,IAAa;AACpB,QACE,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,GAAD,EAAS,WAAU,qCAAsC,CAAA;EACrD,CAAA;;AAIV,SAAgB,IAAsB;AACpC,QACE,kBAAC,GAAD;EAAU,UAAU,kBAAC,GAAD,EAAc,CAAA;YAChC,kBAAC,GAAD,EAAA,UAAA;GACE,kBAAC,GAAD;IAAO,OAAA;IAAM,SAAS,kBAAC,GAAD,EAAa,CAAA;IAAI,CAAA;GACvC,kBAAC,GAAD;IAAO,MAAK;IAAU,SAAS,kBAAC,GAAD,EAAe,CAAA;IAAI,CAAA;GAClD,kBAAC,GAAD;IAAO,MAAK;IAAc,SAAS,kBAAC,GAAD,EAAmB,CAAA;IAAI,CAAA;GAC1D,kBAAC,GAAD;IAAO,MAAK;IAAI,SAAS,kBAAC,GAAD;KAAU,IAAG;KAAG,SAAA;KAAU,CAAA;IAAI,CAAA;GAChD,EAAA,CAAA;EACA,CAAA"}
1
+ {"version":3,"file":"ComradeCircleRoutes.js","names":[],"sources":["../../src/comradecircle/ComradeCircleRoutes.tsx"],"sourcesContent":["/**\n * ComradeCircle Routes\n * @module comradecircle\n *\n * Domain routes. The home feed is eager-loaded (primary landing); all other\n * pages are lazy-loaded. Every route maps to a real `com*` backend capability.\n */\n\nimport { type FC, lazy, Suspense } from 'react';\nimport { Routes, Route, Navigate, useLocation } from 'react-router-dom';\nimport { Spinner } from '@burdenoff/fe-libs/ui';\nimport { useComradeCircle } from './context/ComradeCircleContext';\n\n// Eager — primary landing\nimport { FeedPage } from './pages/FeedPage';\n\n// Circles (communities → channels → posts)\nconst CirclesPage = lazy(() =>\n import('./pages/circles/CirclesPage').then((m) => ({ default: m.CirclesPage }))\n);\nconst CircleDetailPage = lazy(() =>\n import('./pages/circles/CircleDetailPage').then((m) => ({ default: m.CircleDetailPage }))\n);\n\n// Events + RSVPs\nconst EventsPage = lazy(() =>\n import('./pages/events/EventsPage').then((m) => ({ default: m.EventsPage }))\n);\nconst EventDetailPage = lazy(() =>\n import('./pages/events/EventDetailPage').then((m) => ({ default: m.EventDetailPage }))\n);\n\n// Member directory + profiles\nconst MembersPage = lazy(() =>\n import('./pages/members/MembersPage').then((m) => ({ default: m.MembersPage }))\n);\nconst MemberProfilePage = lazy(() =>\n import('./pages/members/MemberProfilePage').then((m) => ({ default: m.MemberProfilePage }))\n);\n\n// My profile (edit)\nconst MyProfilePage = lazy(() =>\n import('./pages/profile/MyProfilePage').then((m) => ({ default: m.MyProfilePage }))\n);\n\nconst PageLoader: FC = () => (\n <div className=\"flex min-h-[400px] items-center justify-center\">\n <Spinner size=\"lg\" />\n </div>\n);\n\nexport const ComradeCircleRoutes: FC = () => {\n const { basePath, isStandalone } = useComradeCircle();\n const location = useLocation();\n\n const normalizedBasePath = basePath === '/' ? '' : (basePath ?? '').replace(/\\/$/, '');\n\n // Guard: only render if the current path matches basePath (integrated mode).\n if (normalizedBasePath && !isStandalone) {\n const pathMatches =\n location.pathname === normalizedBasePath ||\n location.pathname.startsWith(normalizedBasePath + '/');\n if (!pathMatches) {\n return null;\n }\n }\n\n return (\n <div className=\"flex min-h-full flex-col\">\n <Suspense fallback={<PageLoader />}>\n <Routes>\n <Route index element={<FeedPage />} />\n\n <Route path=\"circles\" element={<CirclesPage />} />\n <Route path=\"circles/:id\" element={<CircleDetailPage />} />\n\n <Route path=\"events\" element={<EventsPage />} />\n <Route path=\"events/:id\" element={<EventDetailPage />} />\n\n <Route path=\"members\" element={<MembersPage />} />\n <Route path=\"members/:memberId\" element={<MemberProfilePage />} />\n\n <Route path=\"profile\" element={<MyProfilePage />} />\n\n <Route path=\"*\" element={<Navigate to=\"\" replace />} />\n </Routes>\n </Suspense>\n </div>\n );\n};\n"],"mappings":";;;;;;;AAiBA,IAAM,IAAc,QAClB,OAAO,kCAA+B,MAAM,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,CAChF,EACK,IAAmB,QACvB,OAAO,uCAAoC,MAAM,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAC1F,EAGK,IAAa,QACjB,OAAO,gCAA6B,MAAM,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,CAC7E,EACK,IAAkB,QACtB,OAAO,qCAAkC,MAAM,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,CACvF,EAGK,IAAc,QAClB,OAAO,kCAA+B,MAAM,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,CAChF,EACK,IAAoB,QACxB,OAAO,wCAAqC,MAAM,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,CAC5F,EAGK,IAAgB,QACpB,OAAO,oCAAiC,MAAM,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,CACpF,EAEK,UACJ,kBAAC,OAAD;CAAK,WAAU;WACb,kBAAC,GAAD,EAAS,MAAK,MAAO,CAAA;CACjB,CAAA,EAGK,UAAgC;CAC3C,IAAM,EAAE,aAAU,oBAAiB,GAAkB,EAC/C,IAAW,GAAa,EAExB,IAAqB,MAAa,MAAM,MAAM,KAAY,IAAI,QAAQ,OAAO,GAAG;AAYtF,QATI,KAAsB,CAAC,KAIrB,EAFF,EAAS,aAAa,KACtB,EAAS,SAAS,WAAW,IAAqB,IAAI,IAE/C,OAKT,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,GAAD;GAAU,UAAU,kBAAC,GAAD,EAAc,CAAA;aAChC,kBAAC,GAAD,EAAA,UAAA;IACE,kBAAC,GAAD;KAAO,OAAA;KAAM,SAAS,kBAAC,GAAD,EAAY,CAAA;KAAI,CAAA;IAEtC,kBAAC,GAAD;KAAO,MAAK;KAAU,SAAS,kBAAC,GAAD,EAAe,CAAA;KAAI,CAAA;IAClD,kBAAC,GAAD;KAAO,MAAK;KAAc,SAAS,kBAAC,GAAD,EAAoB,CAAA;KAAI,CAAA;IAE3D,kBAAC,GAAD;KAAO,MAAK;KAAS,SAAS,kBAAC,GAAD,EAAc,CAAA;KAAI,CAAA;IAChD,kBAAC,GAAD;KAAO,MAAK;KAAa,SAAS,kBAAC,GAAD,EAAmB,CAAA;KAAI,CAAA;IAEzD,kBAAC,GAAD;KAAO,MAAK;KAAU,SAAS,kBAAC,GAAD,EAAe,CAAA;KAAI,CAAA;IAClD,kBAAC,GAAD;KAAO,MAAK;KAAoB,SAAS,kBAAC,GAAD,EAAqB,CAAA;KAAI,CAAA;IAElE,kBAAC,GAAD;KAAO,MAAK;KAAU,SAAS,kBAAC,GAAD,EAAiB,CAAA;KAAI,CAAA;IAEpD,kBAAC,GAAD;KAAO,MAAK;KAAI,SAAS,kBAAC,GAAD;MAAU,IAAG;MAAG,SAAA;MAAU,CAAA;KAAI,CAAA;IAChD,EAAA,CAAA;GACA,CAAA;EACP,CAAA"}
@@ -0,0 +1,47 @@
1
+ import { cn as e } from "../utils/cn.js";
2
+ import { FileImage as t } from "./FileImage.js";
3
+ import { jsx as n, jsxs as r } from "react/jsx-runtime";
4
+ //#region src/comradecircle/components/Avatar.tsx
5
+ var i = {
6
+ xs: "h-6 w-6 text-[0.6rem]",
7
+ sm: "h-8 w-8 text-xs",
8
+ md: "h-10 w-10 text-sm",
9
+ lg: "h-14 w-14 text-lg",
10
+ xl: "h-20 w-20 text-2xl"
11
+ }, a = {
12
+ ONLINE: "bg-status-success-text",
13
+ AWAY: "bg-status-warning-text",
14
+ BUSY: "bg-status-error-text",
15
+ OFFLINE: "bg-text-tertiary"
16
+ };
17
+ function o(e) {
18
+ if (!e) return "?";
19
+ let t = e.trim().split(/\s+/).filter(Boolean);
20
+ return t.length === 0 ? "?" : t.length === 1 ? t[0].slice(0, 2).toUpperCase() : (t[0][0] + t[t.length - 1][0]).toUpperCase();
21
+ }
22
+ var s = ({ name: s, size: c = "md", presence: l, fileId: u, className: d }) => {
23
+ let f = /* @__PURE__ */ n("span", {
24
+ "aria-hidden": "true",
25
+ className: e("flex h-full w-full items-center justify-center rounded-full bg-[var(--color-accent-soft)] font-semibold text-text-primary", i[c]),
26
+ children: o(s)
27
+ });
28
+ return /* @__PURE__ */ r("span", {
29
+ className: e("relative inline-flex shrink-0", d),
30
+ children: [/* @__PURE__ */ n("span", {
31
+ className: e("inline-flex items-center justify-center overflow-hidden rounded-full ring-1 ring-border-seam", i[c]),
32
+ children: u ? /* @__PURE__ */ n(t, {
33
+ fileId: u,
34
+ alt: s ?? "Avatar",
35
+ className: "h-full w-full rounded-full",
36
+ fallback: f
37
+ }) : f
38
+ }), l && /* @__PURE__ */ n("span", {
39
+ className: e("absolute -bottom-0.5 -right-0.5 h-2.5 w-2.5 rounded-full ring-2 ring-bg-surface", a[l], l === "ONLINE" && "motion-safe:animate-vc-glow-pulse"),
40
+ "aria-label": `Presence: ${l.toLowerCase()}`
41
+ })]
42
+ });
43
+ };
44
+ //#endregion
45
+ export { s as Avatar };
46
+
47
+ //# sourceMappingURL=Avatar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Avatar.js","names":[],"sources":["../../../src/comradecircle/components/Avatar.tsx"],"sourcesContent":["/**\n * Avatar — initials-based, token-only avatar with an optional presence dot.\n * @module comradecircle/components\n *\n * File-backed avatars are not rendered here: in this subgraph `File` resolves\n * `id` only (no URL), so we render deterministic initials on the brand\n * accent-soft tint. Clean, theme-aware, and never a broken image.\n */\n\nimport type { FC } from 'react';\nimport { cn } from '../utils/cn';\nimport { FileImage } from './FileImage';\nimport type { ComPresence } from '../types';\n\ntype AvatarSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n\nconst sizeClass: Record<AvatarSize, string> = {\n xs: 'h-6 w-6 text-[0.6rem]',\n sm: 'h-8 w-8 text-xs',\n md: 'h-10 w-10 text-sm',\n lg: 'h-14 w-14 text-lg',\n xl: 'h-20 w-20 text-2xl',\n};\n\nconst presenceDot: Record<ComPresence, string> = {\n ONLINE: 'bg-status-success-text',\n AWAY: 'bg-status-warning-text',\n BUSY: 'bg-status-error-text',\n OFFLINE: 'bg-text-tertiary',\n};\n\nexport function initialsOf(name: string | null | undefined): string {\n if (!name) return '?';\n const parts = name.trim().split(/\\s+/).filter(Boolean);\n if (parts.length === 0) return '?';\n if (parts.length === 1) return parts[0]!.slice(0, 2).toUpperCase();\n return (parts[0]![0]! + parts[parts.length - 1]![0]!).toUpperCase();\n}\n\ninterface AvatarProps {\n name?: string | null;\n size?: AvatarSize;\n presence?: ComPresence | null;\n /** wspace-files-svc file id — when set + resolvable, renders the image. */\n fileId?: string | null;\n className?: string;\n}\n\nexport const Avatar: FC<AvatarProps> = ({ name, size = 'md', presence, fileId, className }) => {\n const initials = (\n <span\n aria-hidden=\"true\"\n className={cn(\n 'flex h-full w-full items-center justify-center rounded-full bg-[var(--color-accent-soft)] font-semibold text-text-primary',\n sizeClass[size]\n )}\n >\n {initialsOf(name)}\n </span>\n );\n\n return (\n <span className={cn('relative inline-flex shrink-0', className)}>\n <span\n className={cn(\n 'inline-flex items-center justify-center overflow-hidden rounded-full ring-1 ring-border-seam',\n sizeClass[size]\n )}\n >\n {fileId ? (\n <FileImage\n fileId={fileId}\n alt={name ?? 'Avatar'}\n className=\"h-full w-full rounded-full\"\n fallback={initials}\n />\n ) : (\n initials\n )}\n </span>\n {presence && (\n <span\n className={cn(\n 'absolute -bottom-0.5 -right-0.5 h-2.5 w-2.5 rounded-full ring-2 ring-bg-surface',\n presenceDot[presence],\n presence === 'ONLINE' && 'motion-safe:animate-vc-glow-pulse'\n )}\n aria-label={`Presence: ${presence.toLowerCase()}`}\n />\n )}\n </span>\n );\n};\n"],"mappings":";;;;AAgBA,IAAM,IAAwC;CAC5C,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACL,EAEK,IAA2C;CAC/C,QAAQ;CACR,MAAM;CACN,MAAM;CACN,SAAS;CACV;AAED,SAAgB,EAAW,GAAyC;AAClE,KAAI,CAAC,EAAM,QAAO;CAClB,IAAM,IAAQ,EAAK,MAAM,CAAC,MAAM,MAAM,CAAC,OAAO,QAAQ;AAGtD,QAFI,EAAM,WAAW,IAAU,MAC3B,EAAM,WAAW,IAAU,EAAM,GAAI,MAAM,GAAG,EAAE,CAAC,aAAa,IAC1D,EAAM,GAAI,KAAM,EAAM,EAAM,SAAS,GAAI,IAAK,aAAa;;AAYrE,IAAa,KAA2B,EAAE,SAAM,UAAO,MAAM,aAAU,WAAQ,mBAAgB;CAC7F,IAAM,IACJ,kBAAC,QAAD;EACE,eAAY;EACZ,WAAW,EACT,6HACA,EAAU,GACX;YAEA,EAAW,EAAK;EACZ,CAAA;AAGT,QACE,kBAAC,QAAD;EAAM,WAAW,EAAG,iCAAiC,EAAU;YAA/D,CACE,kBAAC,QAAD;GACE,WAAW,EACT,gGACA,EAAU,GACX;aAEA,IACC,kBAAC,GAAD;IACU;IACR,KAAK,KAAQ;IACb,WAAU;IACV,UAAU;IACV,CAAA,GAEF;GAEG,CAAA,EACN,KACC,kBAAC,QAAD;GACE,WAAW,EACT,mFACA,EAAY,IACZ,MAAa,YAAY,oCAC1B;GACD,cAAY,aAAa,EAAS,aAAa;GAC/C,CAAA,CAEC"}
@@ -0,0 +1,80 @@
1
+ import { cn as e } from "../utils/cn.js";
2
+ import { FILE_FOLDERS as t, uploadImageToFiles as n } from "../hooks/useFiles.js";
3
+ import { Avatar as r } from "./Avatar.js";
4
+ import { describeError as i, notify as a } from "../lib/toast.js";
5
+ import { useId as o, useRef as s, useState as c } from "react";
6
+ import { Camera as l, Loader2 as u } from "lucide-react";
7
+ import { jsx as d, jsxs as f } from "react/jsx-runtime";
8
+ //#region src/comradecircle/components/AvatarUploadField.tsx
9
+ var p = 5 * 1024 * 1024;
10
+ function m({ fileId: m, name: h, onUploaded: g, label: _ = "Upload avatar", disabled: v = !1 }) {
11
+ let y = s(null), b = o(), [x, S] = c(!1), [C, w] = c(null);
12
+ return /* @__PURE__ */ f("div", {
13
+ className: "flex items-center gap-4",
14
+ children: [/* @__PURE__ */ f("div", {
15
+ className: "relative",
16
+ children: [C ? /* @__PURE__ */ d("img", {
17
+ src: C,
18
+ alt: h ?? "Avatar",
19
+ className: "h-16 w-16 rounded-full object-cover ring-1 ring-border-seam"
20
+ }) : /* @__PURE__ */ d(r, {
21
+ name: h,
22
+ fileId: m,
23
+ size: "lg"
24
+ }), x && /* @__PURE__ */ d("span", {
25
+ className: "absolute inset-0 flex items-center justify-center rounded-full bg-bg-canvas/60",
26
+ children: /* @__PURE__ */ d(u, { className: "h-5 w-5 animate-spin text-text-primary" })
27
+ })]
28
+ }), /* @__PURE__ */ f("div", { children: [
29
+ /* @__PURE__ */ d("input", {
30
+ ref: y,
31
+ id: b,
32
+ type: "file",
33
+ accept: "image/*",
34
+ className: "sr-only",
35
+ onChange: async (e) => {
36
+ let r = e.target.files?.[0];
37
+ if (e.target.value = "", r) {
38
+ if (!r.type.startsWith("image/")) {
39
+ a.error("Unsupported file", "Please choose an image.");
40
+ return;
41
+ }
42
+ if (r.size > p) {
43
+ a.error("Image too large", "Please choose an image under 5 MB.");
44
+ return;
45
+ }
46
+ S(!0);
47
+ try {
48
+ let e = await n(r, t.avatars);
49
+ w(e.url), g(e.id), a.success("Avatar updated");
50
+ } catch (e) {
51
+ a.error("Upload failed", i(e));
52
+ } finally {
53
+ S(!1);
54
+ }
55
+ }
56
+ },
57
+ disabled: v || x
58
+ }),
59
+ /* @__PURE__ */ f("button", {
60
+ type: "button",
61
+ onClick: () => y.current?.click(),
62
+ disabled: v || x,
63
+ className: e("inline-flex items-center gap-2 rounded-lg border border-border-seam bg-bg-surface px-3 py-1.5 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken", (v || x) && "cursor-not-allowed opacity-60"),
64
+ children: [
65
+ /* @__PURE__ */ d(l, { className: "h-4 w-4" }),
66
+ " ",
67
+ _
68
+ ]
69
+ }),
70
+ /* @__PURE__ */ d("p", {
71
+ className: "mt-1 text-xs text-text-tertiary",
72
+ children: "PNG or JPG, up to 5 MB."
73
+ })
74
+ ] })]
75
+ });
76
+ }
77
+ //#endregion
78
+ export { m as AvatarUploadField };
79
+
80
+ //# sourceMappingURL=AvatarUploadField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AvatarUploadField.js","names":[],"sources":["../../../src/comradecircle/components/AvatarUploadField.tsx"],"sourcesContent":["/**\n * AvatarUploadField — upload a circular avatar image to wspace-files-svc.\n * @module comradecircle/components\n *\n * On select, uploads via {@link uploadImageToFiles} and hands the resulting file\n * id back to the caller (persisted as avatarFileId). Shows the current avatar\n * (by file id) or the freshly-uploaded preview; falls back to initials.\n */\n\nimport { useId, useRef, useState } from 'react';\nimport { Camera, Loader2 } from 'lucide-react';\nimport { cn } from '../utils/cn';\nimport { Avatar } from './Avatar';\nimport { uploadImageToFiles, FILE_FOLDERS } from '../hooks/useFiles';\nimport { notify, describeError } from '../lib/toast';\n\ninterface AvatarUploadFieldProps {\n /** Current avatar file id (persisted). */\n fileId?: string | null;\n /** Name used for the initials fallback. */\n name?: string | null;\n /** Called with the new file id after a successful upload. */\n onUploaded: (fileId: string) => void;\n label?: string;\n disabled?: boolean;\n}\n\nconst MAX_BYTES = 5 * 1024 * 1024;\n\nexport function AvatarUploadField({\n fileId,\n name,\n onUploaded,\n label = 'Upload avatar',\n disabled = false,\n}: AvatarUploadFieldProps) {\n const inputRef = useRef<HTMLInputElement | null>(null);\n const inputId = useId();\n const [uploading, setUploading] = useState(false);\n const [previewUrl, setPreviewUrl] = useState<string | null>(null);\n\n const handleSelect = async (event: React.ChangeEvent<HTMLInputElement>) => {\n const file = event.target.files?.[0];\n event.target.value = '';\n if (!file) return;\n if (!file.type.startsWith('image/')) {\n notify.error('Unsupported file', 'Please choose an image.');\n return;\n }\n if (file.size > MAX_BYTES) {\n notify.error('Image too large', 'Please choose an image under 5 MB.');\n return;\n }\n setUploading(true);\n try {\n const uploaded = await uploadImageToFiles(file, FILE_FOLDERS.avatars);\n setPreviewUrl(uploaded.url);\n onUploaded(uploaded.id);\n notify.success('Avatar updated');\n } catch (err) {\n notify.error('Upload failed', describeError(err));\n } finally {\n setUploading(false);\n }\n };\n\n return (\n <div className=\"flex items-center gap-4\">\n <div className=\"relative\">\n {previewUrl ? (\n <img\n src={previewUrl}\n alt={name ?? 'Avatar'}\n className=\"h-16 w-16 rounded-full object-cover ring-1 ring-border-seam\"\n />\n ) : (\n <Avatar name={name} fileId={fileId} size=\"lg\" />\n )}\n {uploading && (\n <span className=\"absolute inset-0 flex items-center justify-center rounded-full bg-bg-canvas/60\">\n <Loader2 className=\"h-5 w-5 animate-spin text-text-primary\" />\n </span>\n )}\n </div>\n <div>\n <input\n ref={inputRef}\n id={inputId}\n type=\"file\"\n accept=\"image/*\"\n className=\"sr-only\"\n onChange={handleSelect}\n disabled={disabled || uploading}\n />\n <button\n type=\"button\"\n onClick={() => inputRef.current?.click()}\n disabled={disabled || uploading}\n className={cn(\n 'inline-flex items-center gap-2 rounded-lg border border-border-seam bg-bg-surface px-3 py-1.5 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken',\n (disabled || uploading) && 'cursor-not-allowed opacity-60'\n )}\n >\n <Camera className=\"h-4 w-4\" /> {label}\n </button>\n <p className=\"mt-1 text-xs text-text-tertiary\">PNG or JPG, up to 5 MB.</p>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;AA2BA,IAAM,IAAY,IAAI,OAAO;AAE7B,SAAgB,EAAkB,EAChC,WACA,SACA,eACA,WAAQ,iBACR,cAAW,MACc;CACzB,IAAM,IAAW,EAAgC,KAAK,EAChD,IAAU,GAAO,EACjB,CAAC,GAAW,KAAgB,EAAS,GAAM,EAC3C,CAAC,GAAY,KAAiB,EAAwB,KAAK;AA2BjE,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACG,IACC,kBAAC,OAAD;IACE,KAAK;IACL,KAAK,KAAQ;IACb,WAAU;IACV,CAAA,GAEF,kBAAC,GAAD;IAAc;IAAc;IAAQ,MAAK;IAAO,CAAA,EAEjD,KACC,kBAAC,QAAD;IAAM,WAAU;cACd,kBAAC,GAAD,EAAS,WAAU,0CAA2C,CAAA;IACzD,CAAA,CAEL;MACN,kBAAC,OAAD,EAAA,UAAA;GACE,kBAAC,SAAD;IACE,KAAK;IACL,IAAI;IACJ,MAAK;IACL,QAAO;IACP,WAAU;IACV,UAlDa,OAAO,MAA+C;KACzE,IAAM,IAAO,EAAM,OAAO,QAAQ;AAClC,WAAM,OAAO,QAAQ,IAChB,GACL;UAAI,CAAC,EAAK,KAAK,WAAW,SAAS,EAAE;AACnC,SAAO,MAAM,oBAAoB,0BAA0B;AAC3D;;AAEF,UAAI,EAAK,OAAO,GAAW;AACzB,SAAO,MAAM,mBAAmB,qCAAqC;AACrE;;AAEF,QAAa,GAAK;AAClB,UAAI;OACF,IAAM,IAAW,MAAM,EAAmB,GAAM,EAAa,QAAQ;AAGrE,OAFA,EAAc,EAAS,IAAI,EAC3B,EAAW,EAAS,GAAG,EACvB,EAAO,QAAQ,iBAAiB;eACzB,GAAK;AACZ,SAAO,MAAM,iBAAiB,EAAc,EAAI,CAAC;gBACzC;AACR,SAAa,GAAM;;;;IA8Bf,UAAU,KAAY;IACtB,CAAA;GACF,kBAAC,UAAD;IACE,MAAK;IACL,eAAe,EAAS,SAAS,OAAO;IACxC,UAAU,KAAY;IACtB,WAAW,EACT,6KACC,KAAY,MAAc,gCAC5B;cAPH;KASE,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA;;KAAE;KACzB;;GACT,kBAAC,KAAD;IAAG,WAAU;cAAkC;IAA2B,CAAA;GACtE,EAAA,CAAA,CACF"}
@@ -0,0 +1,118 @@
1
+ import { useComJoinCircle as e, useComLeaveCircle as t } from "../hooks/useComradeCircleApi.js";
2
+ import "../hooks/index.js";
3
+ import { Avatar as n } from "./Avatar.js";
4
+ import { describeError as r, notify as i } from "../lib/toast.js";
5
+ import { formatEnumLabel as a, formatNumber as o } from "../utils/formatters.js";
6
+ import { StatusBadge as s } from "./StatusBadge.js";
7
+ import { Hash as c, Users as l } from "lucide-react";
8
+ import { Fragment as u, jsx as d, jsxs as f } from "react/jsx-runtime";
9
+ import { Button as p, GlassCard as m } from "@burdenoff/fe-libs/ui";
10
+ //#region src/comradecircle/components/CircleCard.tsx
11
+ function h({ circle: h, membership: g, onOpen: _ }) {
12
+ let v = e(), y = t(), b = g?.status === "ACTIVE";
13
+ return /* @__PURE__ */ f(m, {
14
+ treatment: "plain",
15
+ className: "flex flex-col p-5",
16
+ children: [
17
+ /* @__PURE__ */ f("div", {
18
+ className: "flex items-start gap-3",
19
+ children: [/* @__PURE__ */ d(n, {
20
+ name: h.name,
21
+ size: "lg",
22
+ fileId: h.avatar?.id
23
+ }), /* @__PURE__ */ f("div", {
24
+ className: "min-w-0 flex-1",
25
+ children: [
26
+ /* @__PURE__ */ d("button", {
27
+ type: "button",
28
+ onClick: _,
29
+ className: "truncate text-left text-base font-semibold text-text-primary hover:underline",
30
+ children: h.name
31
+ }),
32
+ h.topic && /* @__PURE__ */ d("p", {
33
+ className: "truncate text-sm text-text-secondary",
34
+ children: h.topic
35
+ }),
36
+ /* @__PURE__ */ f("div", {
37
+ className: "mt-1.5 flex flex-wrap items-center gap-1.5",
38
+ children: [
39
+ /* @__PURE__ */ d(s, { status: h.visibility }),
40
+ h.status !== "ACTIVE" && /* @__PURE__ */ d(s, { status: h.status }),
41
+ b && g && /* @__PURE__ */ d(s, { status: g.role })
42
+ ]
43
+ })
44
+ ]
45
+ })]
46
+ }),
47
+ h.description && /* @__PURE__ */ d("p", {
48
+ className: "mt-3 line-clamp-2 text-sm text-text-secondary",
49
+ children: h.description
50
+ }),
51
+ h.tags.length > 0 && /* @__PURE__ */ d("div", {
52
+ className: "mt-3 flex flex-wrap gap-1.5",
53
+ children: h.tags.slice(0, 4).map((e) => /* @__PURE__ */ f("span", {
54
+ className: "rounded-full bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-secondary",
55
+ children: ["#", e]
56
+ }, e))
57
+ }),
58
+ /* @__PURE__ */ f("div", {
59
+ className: "mt-4 flex items-center justify-between gap-3 border-t border-border-seam pt-3",
60
+ children: [/* @__PURE__ */ f("div", {
61
+ className: "flex items-center gap-3 text-xs text-text-tertiary",
62
+ children: [/* @__PURE__ */ f("span", {
63
+ className: "inline-flex items-center gap-1",
64
+ children: [
65
+ /* @__PURE__ */ d(l, { className: "h-3.5 w-3.5" }),
66
+ " ",
67
+ o(h.memberCount)
68
+ ]
69
+ }), /* @__PURE__ */ f("span", {
70
+ className: "inline-flex items-center gap-1",
71
+ children: [
72
+ /* @__PURE__ */ d(c, { className: "h-3.5 w-3.5" }),
73
+ " ",
74
+ h.channels?.length ?? 0
75
+ ]
76
+ })]
77
+ }), /* @__PURE__ */ d("div", {
78
+ className: "flex items-center gap-2",
79
+ children: b ? /* @__PURE__ */ f(u, { children: [/* @__PURE__ */ d(p, {
80
+ size: "sm",
81
+ variant: "outline",
82
+ onClick: async () => {
83
+ try {
84
+ await y.mutateAsync(h.id), i.success("Left circle", `You have left ${h.name}.`);
85
+ } catch (e) {
86
+ i.error("Could not leave", r(e));
87
+ }
88
+ },
89
+ disabled: y.isPending,
90
+ children: "Leave"
91
+ }), /* @__PURE__ */ d(p, {
92
+ size: "sm",
93
+ onClick: _,
94
+ children: "Open"
95
+ })] }) : h.status === "ACTIVE" ? /* @__PURE__ */ d(p, {
96
+ size: "sm",
97
+ onClick: async () => {
98
+ try {
99
+ await v.mutateAsync(h.id), i.success("Joined circle", `You are now a member of ${h.name}.`);
100
+ } catch (e) {
101
+ i.error("Could not join", r(e));
102
+ }
103
+ },
104
+ disabled: v.isPending,
105
+ children: "Join"
106
+ }) : /* @__PURE__ */ d("span", {
107
+ className: "text-xs text-text-tertiary",
108
+ children: a(h.status)
109
+ })
110
+ })]
111
+ })
112
+ ]
113
+ });
114
+ }
115
+ //#endregion
116
+ export { h as CircleCard };
117
+
118
+ //# sourceMappingURL=CircleCard.js.map