@burdenoff/microfe-comradecircle 2026.720.2 → 2026.720.3

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 (39) hide show
  1. package/dist/comradecircle/ComradeCircleRoutes.d.ts.map +1 -1
  2. package/dist/comradecircle/ComradeCircleRoutes.js +39 -34
  3. package/dist/comradecircle/ComradeCircleRoutes.js.map +1 -1
  4. package/dist/comradecircle/components/CommentThread.js +1 -1
  5. package/dist/comradecircle/components/MemberIdentity.js +1 -1
  6. package/dist/comradecircle/components/MobileBottomNav.d.ts +4 -0
  7. package/dist/comradecircle/components/MobileBottomNav.d.ts.map +1 -0
  8. package/dist/comradecircle/components/MobileBottomNav.js +65 -0
  9. package/dist/comradecircle/components/MobileBottomNav.js.map +1 -0
  10. package/dist/comradecircle/components/PostCard.d.ts +3 -1
  11. package/dist/comradecircle/components/PostCard.d.ts.map +1 -1
  12. package/dist/comradecircle/components/PostCard.js +86 -73
  13. package/dist/comradecircle/components/PostCard.js.map +1 -1
  14. package/dist/comradecircle/components/PostComposer.d.ts +7 -1
  15. package/dist/comradecircle/components/PostComposer.d.ts.map +1 -1
  16. package/dist/comradecircle/components/PostComposer.js +53 -49
  17. package/dist/comradecircle/components/PostComposer.js.map +1 -1
  18. package/dist/comradecircle/components/ReactionBar.js +1 -1
  19. package/dist/comradecircle/components/index.d.ts +1 -0
  20. package/dist/comradecircle/components/index.d.ts.map +1 -1
  21. package/dist/comradecircle/hooks/useComradeCircleApi.js +37 -22
  22. package/dist/comradecircle/hooks/useComradeCircleApi.js.map +1 -1
  23. package/dist/comradecircle/index.js +1 -1
  24. package/dist/comradecircle/pages/FeedPage.js +1 -1
  25. package/dist/comradecircle/pages/circles/CircleDetailPage.js +242 -219
  26. package/dist/comradecircle/pages/circles/CircleDetailPage.js.map +1 -1
  27. package/dist/comradecircle/pages/circles/CirclesPage.d.ts.map +1 -1
  28. package/dist/comradecircle/pages/circles/CirclesPage.js +72 -39
  29. package/dist/comradecircle/pages/circles/CirclesPage.js.map +1 -1
  30. package/dist/comradecircle/pages/events/EventDetailPage.js +1 -1
  31. package/dist/comradecircle/pages/events/EventsPage.js +1 -1
  32. package/dist/comradecircle/pages/members/MemberProfilePage.js +1 -1
  33. package/dist/comradecircle/pages/members/MembersPage.js +1 -1
  34. package/dist/comradecircle/pages/posts/PostThreadPage.d.ts +14 -0
  35. package/dist/comradecircle/pages/posts/PostThreadPage.d.ts.map +1 -0
  36. package/dist/comradecircle/pages/posts/PostThreadPage.js +48 -0
  37. package/dist/comradecircle/pages/posts/PostThreadPage.js.map +1 -0
  38. package/dist/comradecircle/pages/profile/MyProfilePage.js +1 -1
  39. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ComradeCircleRoutes.d.ts","sourceRoot":"","sources":["../../src/comradecircle/ComradeCircleRoutes.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,KAAK,EAAE,EAAkB,MAAM,OAAO,CAAC;AA2ChD,eAAO,MAAM,mBAAmB,EAAE,EAsCjC,CAAC"}
1
+ {"version":3,"file":"ComradeCircleRoutes.d.ts","sourceRoot":"","sources":["../../src/comradecircle/ComradeCircleRoutes.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,KAAK,EAAE,EAAkB,MAAM,OAAO,CAAC;AAiDhD,eAAO,MAAM,mBAAmB,EAAE,EAyCjC,CAAC"}
@@ -1,64 +1,69 @@
1
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";
2
+ import { MobileBottomNav as t } from "./components/MobileBottomNav.js";
3
+ import { FeedPage as n } from "./pages/FeedPage.js";
4
+ import { Suspense as r, lazy as i } from "react";
5
+ import { Navigate as a, Route as o, Routes as s, useLocation as c } from "react-router-dom";
6
+ import { jsx as l, jsxs as u } from "react/jsx-runtime";
7
+ import { Spinner as d } from "@burdenoff/fe-libs/ui";
7
8
  //#region src/comradecircle/ComradeCircleRoutes.tsx
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
+ var f = i(() => import("./pages/circles/CirclesPage.js").then((e) => ({ default: e.CirclesPage }))), p = i(() => import("./pages/circles/CircleDetailPage.js").then((e) => ({ default: e.CircleDetailPage }))), m = i(() => import("./pages/events/EventsPage.js").then((e) => ({ default: e.EventsPage }))), h = i(() => import("./pages/events/EventDetailPage.js").then((e) => ({ default: e.EventDetailPage }))), g = i(() => import("./pages/members/MembersPage.js").then((e) => ({ default: e.MembersPage }))), _ = i(() => import("./pages/members/MemberProfilePage.js").then((e) => ({ default: e.MemberProfilePage }))), v = i(() => import("./pages/profile/MyProfilePage.js").then((e) => ({ default: e.MyProfilePage }))), y = i(() => import("./pages/posts/PostThreadPage.js").then((e) => ({ default: e.PostThreadPage }))), b = () => /* @__PURE__ */ l("div", {
9
10
  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, {
11
+ children: /* @__PURE__ */ l(d, { size: "lg" })
12
+ }), x = () => {
13
+ let { basePath: i, isStandalone: d } = e(), x = c(), S = i === "/" ? "" : (i ?? "").replace(/\/$/, "");
14
+ return S && !d && !(x.pathname === S || x.pathname.startsWith(S + "/")) ? null : /* @__PURE__ */ u("div", {
15
+ className: "flex min-h-full flex-col pb-16 lg:pb-0",
16
+ children: [/* @__PURE__ */ l(r, {
17
+ fallback: /* @__PURE__ */ l(b, {}),
18
+ children: /* @__PURE__ */ u(s, { children: [
19
+ /* @__PURE__ */ l(o, {
19
20
  index: !0,
20
- element: /* @__PURE__ */ c(t, {})
21
+ element: /* @__PURE__ */ l(n, {})
21
22
  }),
22
- /* @__PURE__ */ c(a, {
23
+ /* @__PURE__ */ l(o, {
23
24
  path: "circles",
24
- element: /* @__PURE__ */ c(d, {})
25
+ element: /* @__PURE__ */ l(f, {})
25
26
  }),
26
- /* @__PURE__ */ c(a, {
27
+ /* @__PURE__ */ l(o, {
27
28
  path: "circles/:id",
28
- element: /* @__PURE__ */ c(f, {})
29
+ element: /* @__PURE__ */ l(p, {})
29
30
  }),
30
- /* @__PURE__ */ c(a, {
31
+ /* @__PURE__ */ l(o, {
31
32
  path: "events",
32
- element: /* @__PURE__ */ c(p, {})
33
+ element: /* @__PURE__ */ l(m, {})
33
34
  }),
34
- /* @__PURE__ */ c(a, {
35
+ /* @__PURE__ */ l(o, {
35
36
  path: "events/:id",
36
- element: /* @__PURE__ */ c(m, {})
37
+ element: /* @__PURE__ */ l(h, {})
37
38
  }),
38
- /* @__PURE__ */ c(a, {
39
+ /* @__PURE__ */ l(o, {
39
40
  path: "members",
40
- element: /* @__PURE__ */ c(h, {})
41
+ element: /* @__PURE__ */ l(g, {})
41
42
  }),
42
- /* @__PURE__ */ c(a, {
43
+ /* @__PURE__ */ l(o, {
43
44
  path: "members/:memberId",
44
- element: /* @__PURE__ */ c(g, {})
45
+ element: /* @__PURE__ */ l(_, {})
45
46
  }),
46
- /* @__PURE__ */ c(a, {
47
+ /* @__PURE__ */ l(o, {
48
+ path: "posts/:postId",
49
+ element: /* @__PURE__ */ l(y, {})
50
+ }),
51
+ /* @__PURE__ */ l(o, {
47
52
  path: "profile",
48
- element: /* @__PURE__ */ c(_, {})
53
+ element: /* @__PURE__ */ l(v, {})
49
54
  }),
50
- /* @__PURE__ */ c(a, {
55
+ /* @__PURE__ */ l(o, {
51
56
  path: "*",
52
- element: /* @__PURE__ */ c(i, {
57
+ element: /* @__PURE__ */ l(a, {
53
58
  to: "",
54
59
  replace: !0
55
60
  })
56
61
  })
57
62
  ] })
58
- })
63
+ }), /* @__PURE__ */ l(t, {})]
59
64
  });
60
65
  };
61
66
  //#endregion
62
- export { y as ComradeCircleRoutes };
67
+ export { x as ComradeCircleRoutes };
63
68
 
64
69
  //# sourceMappingURL=ComradeCircleRoutes.js.map
@@ -1 +1 @@
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,YAAY,EAAE,CAChF,GACM,IAAmB,QACvB,OAAO,uCAAoC,MAAM,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,CAC1F,GAGM,IAAa,QACjB,OAAO,gCAA6B,MAAM,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,CAC7E,GACM,IAAkB,QACtB,OAAO,qCAAkC,MAAM,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,CACvF,GAGM,IAAc,QAClB,OAAO,kCAA+B,MAAM,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,CAChF,GACM,IAAoB,QACxB,OAAO,wCAAqC,MAAM,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAC5F,GAGM,IAAgB,QACpB,OAAO,oCAAiC,MAAM,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,CACpF,GAEM,UACJ,kBAAC,OAAD;CAAK,WAAU;WACb,kBAAC,GAAD,EAAS,MAAK,KAAM,CAAA;AACjB,CAAA,GAGM,UAAgC;CAC3C,IAAM,EAAE,aAAU,oBAAiB,EAAiB,GAC9C,IAAW,EAAY,GAEvB,IAAqB,MAAa,MAAM,MAAM,KAAY,IAAI,QAAQ,OAAO,EAAE;CAYrF,OATI,KAAsB,CAAC,KAIrB,EAFF,EAAS,aAAa,KACtB,EAAS,SAAS,WAAW,IAAqB,GAAG,KAE9C,OAKT,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,GAAD;GAAU,UAAU,kBAAC,GAAD,CAAa,CAAA;aAC/B,kBAAC,GAAD,EAAA,UAAA;IACE,kBAAC,GAAD;KAAO,OAAA;KAAM,SAAS,kBAAC,GAAD,CAAW,CAAA;IAAI,CAAA;IAErC,kBAAC,GAAD;KAAO,MAAK;KAAU,SAAS,kBAAC,GAAD,CAAc,CAAA;IAAI,CAAA;IACjD,kBAAC,GAAD;KAAO,MAAK;KAAc,SAAS,kBAAC,GAAD,CAAmB,CAAA;IAAI,CAAA;IAE1D,kBAAC,GAAD;KAAO,MAAK;KAAS,SAAS,kBAAC,GAAD,CAAa,CAAA;IAAI,CAAA;IAC/C,kBAAC,GAAD;KAAO,MAAK;KAAa,SAAS,kBAAC,GAAD,CAAkB,CAAA;IAAI,CAAA;IAExD,kBAAC,GAAD;KAAO,MAAK;KAAU,SAAS,kBAAC,GAAD,CAAc,CAAA;IAAI,CAAA;IACjD,kBAAC,GAAD;KAAO,MAAK;KAAoB,SAAS,kBAAC,GAAD,CAAoB,CAAA;IAAI,CAAA;IAEjE,kBAAC,GAAD;KAAO,MAAK;KAAU,SAAS,kBAAC,GAAD,CAAgB,CAAA;IAAI,CAAA;IAEnD,kBAAC,GAAD;KAAO,MAAK;KAAI,SAAS,kBAAC,GAAD;MAAU,IAAG;MAAG,SAAA;KAAS,CAAA;IAAI,CAAA;GAChD,EAAA,CAAA;EACA,CAAA;CACP,CAAA;AAET"}
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';\nimport { MobileBottomNav } from './components/MobileBottomNav';\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\n// Post thread — focused single-post + comments surface (BOFF-3955)\nconst PostThreadPage = lazy(() =>\n import('./pages/posts/PostThreadPage').then((m) => ({ default: m.PostThreadPage }))\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 pb-16 lg:pb-0\">\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=\"posts/:postId\" element={<PostThreadPage />} />\n\n <Route path=\"profile\" element={<MyProfilePage />} />\n\n <Route path=\"*\" element={<Navigate to=\"\" replace />} />\n </Routes>\n </Suspense>\n <MobileBottomNav />\n </div>\n );\n};\n"],"mappings":";;;;;;;;AAkBA,IAAM,IAAc,QAClB,OAAO,kCAA+B,MAAM,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,CAChF,GACM,IAAmB,QACvB,OAAO,uCAAoC,MAAM,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,CAC1F,GAGM,IAAa,QACjB,OAAO,gCAA6B,MAAM,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,CAC7E,GACM,IAAkB,QACtB,OAAO,qCAAkC,MAAM,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,CACvF,GAGM,IAAc,QAClB,OAAO,kCAA+B,MAAM,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,CAChF,GACM,IAAoB,QACxB,OAAO,wCAAqC,MAAM,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAC5F,GAGM,IAAgB,QACpB,OAAO,oCAAiC,MAAM,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,CACpF,GAGM,IAAiB,QACrB,OAAO,mCAAgC,MAAM,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,CACpF,GAEM,UACJ,kBAAC,OAAD;CAAK,WAAU;WACb,kBAAC,GAAD,EAAS,MAAK,KAAM,CAAA;AACjB,CAAA,GAGM,UAAgC;CAC3C,IAAM,EAAE,aAAU,oBAAiB,EAAiB,GAC9C,IAAW,EAAY,GAEvB,IAAqB,MAAa,MAAM,MAAM,KAAY,IAAI,QAAQ,OAAO,EAAE;CAYrF,OATI,KAAsB,CAAC,KAIrB,EAFF,EAAS,aAAa,KACtB,EAAS,SAAS,WAAW,IAAqB,GAAG,KAE9C,OAKT,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,GAAD;GAAU,UAAU,kBAAC,GAAD,CAAa,CAAA;aAC/B,kBAAC,GAAD,EAAA,UAAA;IACE,kBAAC,GAAD;KAAO,OAAA;KAAM,SAAS,kBAAC,GAAD,CAAW,CAAA;IAAI,CAAA;IAErC,kBAAC,GAAD;KAAO,MAAK;KAAU,SAAS,kBAAC,GAAD,CAAc,CAAA;IAAI,CAAA;IACjD,kBAAC,GAAD;KAAO,MAAK;KAAc,SAAS,kBAAC,GAAD,CAAmB,CAAA;IAAI,CAAA;IAE1D,kBAAC,GAAD;KAAO,MAAK;KAAS,SAAS,kBAAC,GAAD,CAAa,CAAA;IAAI,CAAA;IAC/C,kBAAC,GAAD;KAAO,MAAK;KAAa,SAAS,kBAAC,GAAD,CAAkB,CAAA;IAAI,CAAA;IAExD,kBAAC,GAAD;KAAO,MAAK;KAAU,SAAS,kBAAC,GAAD,CAAc,CAAA;IAAI,CAAA;IACjD,kBAAC,GAAD;KAAO,MAAK;KAAoB,SAAS,kBAAC,GAAD,CAAoB,CAAA;IAAI,CAAA;IAEjE,kBAAC,GAAD;KAAO,MAAK;KAAgB,SAAS,kBAAC,GAAD,CAAiB,CAAA;IAAI,CAAA;IAE1D,kBAAC,GAAD;KAAO,MAAK;KAAU,SAAS,kBAAC,GAAD,CAAgB,CAAA;IAAI,CAAA;IAEnD,kBAAC,GAAD;KAAO,MAAK;KAAI,SAAS,kBAAC,GAAD;MAAU,IAAG;MAAG,SAAA;KAAS,CAAA;IAAI,CAAA;GAChD,EAAA,CAAA;EACA,CAAA,GACV,kBAAC,GAAD,CAAkB,CAAA,CACf;;AAET"}
@@ -1,6 +1,6 @@
1
1
  import { useComradeCircle as e } from "../context/ComradeCircleContext.js";
2
- import { cn as t } from "../utils/cn.js";
3
2
  import "../context/index.js";
3
+ import { cn as t } from "../utils/cn.js";
4
4
  import { useComAddComment as n, useComComments as r } from "../hooks/useComradeCircleApi.js";
5
5
  import "../hooks/index.js";
6
6
  import { Avatar as i } from "./Avatar.js";
@@ -1,6 +1,6 @@
1
1
  import { useComradeCircle as e } from "../context/ComradeCircleContext.js";
2
- import { cn as t } from "../utils/cn.js";
3
2
  import "../context/index.js";
3
+ import { cn as t } from "../utils/cn.js";
4
4
  import { useComProfile as n } from "../hooks/useComradeCircleApi.js";
5
5
  import "../hooks/index.js";
6
6
  import { Avatar as r } from "./Avatar.js";
@@ -0,0 +1,4 @@
1
+ import { FC } from 'react';
2
+
3
+ export declare const MobileBottomNav: FC;
4
+ //# sourceMappingURL=MobileBottomNav.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MobileBottomNav.d.ts","sourceRoot":"","sources":["../../../src/comradecircle/components/MobileBottomNav.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAsBhC,eAAO,MAAM,eAAe,EAAE,EAyC7B,CAAC"}
@@ -0,0 +1,65 @@
1
+ import { useComradeCircle as e } from "../context/ComradeCircleContext.js";
2
+ import "../context/index.js";
3
+ import { cn as t } from "../utils/cn.js";
4
+ import { CalendarDays as n, Contact as r, Newspaper as i, UserCircle as a, Users as o } from "lucide-react";
5
+ import { useLocation as s } from "react-router-dom";
6
+ import { jsx as c, jsxs as l } from "react/jsx-runtime";
7
+ //#region src/comradecircle/components/MobileBottomNav.tsx
8
+ var u = [
9
+ {
10
+ id: "feed",
11
+ label: "Home",
12
+ path: "",
13
+ icon: i
14
+ },
15
+ {
16
+ id: "circles",
17
+ label: "Circles",
18
+ path: "circles",
19
+ icon: o
20
+ },
21
+ {
22
+ id: "events",
23
+ label: "Events",
24
+ path: "events",
25
+ icon: n
26
+ },
27
+ {
28
+ id: "members",
29
+ label: "Members",
30
+ path: "members",
31
+ icon: r
32
+ },
33
+ {
34
+ id: "profile",
35
+ label: "Profile",
36
+ path: "profile",
37
+ icon: a
38
+ }
39
+ ], d = () => {
40
+ let { getPath: n, navigateTo: r } = e(), i = s();
41
+ return /* @__PURE__ */ c("nav", {
42
+ "aria-label": "ComradeCircle mobile navigation",
43
+ className: t("fixed inset-x-0 bottom-0 z-40 lg:hidden", "border-t border-border-seam bg-bg-surface/95 backdrop-blur-sm", "pb-[max(env(safe-area-inset-bottom),0px)]"),
44
+ children: /* @__PURE__ */ c("ul", {
45
+ className: "flex",
46
+ children: u.map((e) => {
47
+ let a = n(e.path), o = e.path === "" ? i.pathname === a : i.pathname === a || i.pathname.startsWith(`${a}/`), s = e.icon;
48
+ return /* @__PURE__ */ c("li", {
49
+ className: "flex-1",
50
+ children: /* @__PURE__ */ l("button", {
51
+ type: "button",
52
+ "aria-current": o ? "page" : void 0,
53
+ onClick: () => r(e.path),
54
+ className: t("flex w-full flex-col items-center gap-1 py-2.5 text-[11px] font-medium transition-colors", o ? "text-accent" : "text-text-tertiary hover:text-text-secondary"),
55
+ children: [/* @__PURE__ */ c(s, { className: t("h-5 w-5", o && "text-accent") }), e.label]
56
+ })
57
+ }, e.id);
58
+ })
59
+ })
60
+ });
61
+ };
62
+ //#endregion
63
+ export { d as MobileBottomNav };
64
+
65
+ //# sourceMappingURL=MobileBottomNav.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MobileBottomNav.js","names":[],"sources":["../../../src/comradecircle/components/MobileBottomNav.tsx"],"sourcesContent":["/**\n * MobileBottomNav — ComradeCircle's product-specific mobile tab bar (BOFF-3957).\n * @module comradecircle/components\n *\n * The mobile mocks (`comradecircle-00-mobile-app-preview.png`,\n * `comradecircle-19/20/21-mobile-*.png`) show a fixed Home / Circles / Events /\n * Members / Profile bottom tab bar instead of the shared app-shell's\n * collapsible sidebar/hamburger menu. Mirrors the same five items registered\n * with the host shell in `ComradeCircleRoot` (id/path/icon/order) so the two\n * navs never drift.\n *\n * Fixed at the bottom of the viewport, hidden at and above the `lg` breakpoint\n * to match every other responsive split already used in this MFE (see the\n * `lg:hidden` mobile channel picker / `hidden lg:block` desktop rail in\n * `CircleDetailPage`). Uses `flex` with each tab `flex-1` rather than a CSS\n * grid: build-time MFE composition means only utility classes the host\n * shell's own Tailwind build already emits reach this MFE at runtime, and\n * `grid`/`grid-cols-*` is not reliably among them.\n */\n\nimport type { FC } from 'react';\nimport { Newspaper, Users, CalendarDays, Contact, UserCircle } from 'lucide-react';\nimport { useLocation } from 'react-router-dom';\nimport { useComradeCircle } from '../context';\nimport { cn } from '../utils/cn';\n\ninterface TabDef {\n id: string;\n label: string;\n /** Path relative to basePath, '' for the home feed. */\n path: string;\n icon: FC<{ className?: string }>;\n}\n\nconst TABS: TabDef[] = [\n { id: 'feed', label: 'Home', path: '', icon: Newspaper },\n { id: 'circles', label: 'Circles', path: 'circles', icon: Users },\n { id: 'events', label: 'Events', path: 'events', icon: CalendarDays },\n { id: 'members', label: 'Members', path: 'members', icon: Contact },\n { id: 'profile', label: 'Profile', path: 'profile', icon: UserCircle },\n];\n\nexport const MobileBottomNav: FC = () => {\n const { getPath, navigateTo } = useComradeCircle();\n const location = useLocation();\n\n return (\n <nav\n aria-label=\"ComradeCircle mobile navigation\"\n className={cn(\n 'fixed inset-x-0 bottom-0 z-40 lg:hidden',\n 'border-t border-border-seam bg-bg-surface/95 backdrop-blur-sm',\n 'pb-[max(env(safe-area-inset-bottom),0px)]'\n )}\n >\n <ul className=\"flex\">\n {TABS.map((tab) => {\n const target = getPath(tab.path);\n const isActive =\n tab.path === ''\n ? location.pathname === target\n : location.pathname === target || location.pathname.startsWith(`${target}/`);\n const Icon = tab.icon;\n return (\n <li key={tab.id} className=\"flex-1\">\n <button\n type=\"button\"\n aria-current={isActive ? 'page' : undefined}\n onClick={() => navigateTo(tab.path)}\n className={cn(\n 'flex w-full flex-col items-center gap-1 py-2.5 text-[11px] font-medium transition-colors',\n isActive ? 'text-accent' : 'text-text-tertiary hover:text-text-secondary'\n )}\n >\n <Icon className={cn('h-5 w-5', isActive && 'text-accent')} />\n {tab.label}\n </button>\n </li>\n );\n })}\n </ul>\n </nav>\n );\n};\n"],"mappings":";;;;;;;AAkCA,IAAM,IAAiB;CACrB;EAAE,IAAI;EAAQ,OAAO;EAAQ,MAAM;EAAI,MAAM;CAAU;CACvD;EAAE,IAAI;EAAW,OAAO;EAAW,MAAM;EAAW,MAAM;CAAM;CAChE;EAAE,IAAI;EAAU,OAAO;EAAU,MAAM;EAAU,MAAM;CAAa;CACpE;EAAE,IAAI;EAAW,OAAO;EAAW,MAAM;EAAW,MAAM;CAAQ;CAClE;EAAE,IAAI;EAAW,OAAO;EAAW,MAAM;EAAW,MAAM;CAAW;AACvE,GAEa,UAA4B;CACvC,IAAM,EAAE,YAAS,kBAAe,EAAiB,GAC3C,IAAW,EAAY;CAE7B,OACE,kBAAC,OAAD;EACE,cAAW;EACX,WAAW,EACT,2CACA,iEACA,2CACF;YAEA,kBAAC,MAAD;GAAI,WAAU;aACX,EAAK,KAAK,MAAQ;IACjB,IAAM,IAAS,EAAQ,EAAI,IAAI,GACzB,IACJ,EAAI,SAAS,KACT,EAAS,aAAa,IACtB,EAAS,aAAa,KAAU,EAAS,SAAS,WAAW,GAAG,EAAO,EAAE,GACzE,IAAO,EAAI;IACjB,OACE,kBAAC,MAAD;KAAiB,WAAU;eACzB,kBAAC,UAAD;MACE,MAAK;MACL,gBAAc,IAAW,SAAS,KAAA;MAClC,eAAe,EAAW,EAAI,IAAI;MAClC,WAAW,EACT,4FACA,IAAW,gBAAgB,8CAC7B;gBAPF,CASE,kBAAC,GAAD,EAAM,WAAW,EAAG,WAAW,KAAY,aAAa,EAAI,CAAA,GAC3D,EAAI,KACC;;IACN,GAbK,EAAI,EAaT;GAER,CAAC;EACC,CAAA;CACD,CAAA;AAET"}
@@ -4,7 +4,9 @@ interface PostCardProps {
4
4
  post: ComPost;
5
5
  /** Start with the comment thread open. */
6
6
  defaultExpanded?: boolean;
7
+ /** Hide the "open thread" link — set when already rendered on the thread page itself. */
8
+ hideThreadLink?: boolean;
7
9
  }
8
- export declare function PostCard({ post, defaultExpanded }: PostCardProps): import("react/jsx-runtime").JSX.Element;
10
+ export declare function PostCard({ post, defaultExpanded, hideThreadLink }: PostCardProps): import("react/jsx-runtime").JSX.Element;
9
11
  export {};
10
12
  //# sourceMappingURL=PostCard.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PostCard.d.ts","sourceRoot":"","sources":["../../../src/comradecircle/components/PostCard.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAuBH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAExC,UAAU,aAAa;IACrB,IAAI,EAAE,OAAO,CAAC;IACd,0CAA0C;IAC1C,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,wBAAgB,QAAQ,CAAC,EAAE,IAAI,EAAE,eAAuB,EAAE,EAAE,aAAa,2CAqKxE"}
1
+ {"version":3,"file":"PostCard.d.ts","sourceRoot":"","sources":["../../../src/comradecircle/components/PostCard.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAuBH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAExC,UAAU,aAAa;IACrB,IAAI,EAAE,OAAO,CAAC;IACd,0CAA0C;IAC1C,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,yFAAyF;IACzF,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,wBAAgB,QAAQ,CAAC,EAAE,IAAI,EAAE,eAAuB,EAAE,cAAsB,EAAE,EAAE,aAAa,2CAoLhG"}
@@ -1,6 +1,6 @@
1
1
  import { useComradeCircle as e } from "../context/ComradeCircleContext.js";
2
- import { cn as t } from "../utils/cn.js";
3
2
  import "../context/index.js";
3
+ import { cn as t } from "../utils/cn.js";
4
4
  import { useComRemovePost as n, useComUpdatePost as r } from "../hooks/useComradeCircleApi.js";
5
5
  import "../hooks/index.js";
6
6
  import { MemberIdentity as i } from "./MemberIdentity.js";
@@ -10,154 +10,167 @@ import { formatRelativeTime as c } from "../utils/formatters.js";
10
10
  import { CommentThread as l } from "./CommentThread.js";
11
11
  import { AttachmentGrid as u } from "./ImageAttachments.js";
12
12
  import { useState as d } from "react";
13
- import { MessageSquare as f, MoreHorizontal as p, Pencil as m, Pin as h, Trash2 as g } from "lucide-react";
14
- import { jsx as _, jsxs as v } from "react/jsx-runtime";
15
- import { Button as y, DropdownMenu as b, DropdownMenuContent as x, DropdownMenuItem as S, DropdownMenuSeparator as C, DropdownMenuTrigger as w, GlassCard as T, Textarea as E } from "@burdenoff/fe-libs/ui";
13
+ import { ArrowUpRight as f, MessageSquare as p, MoreHorizontal as m, Pencil as h, Pin as g, Trash2 as _ } from "lucide-react";
14
+ import { jsx as v, jsxs as y } from "react/jsx-runtime";
15
+ import { Button as b, DropdownMenu as x, DropdownMenuContent as S, DropdownMenuItem as C, DropdownMenuSeparator as w, DropdownMenuTrigger as T, GlassCard as E, Textarea as D } from "@burdenoff/fe-libs/ui";
16
16
  //#region src/comradecircle/components/PostCard.tsx
17
- function D({ post: D, defaultExpanded: O = !1 }) {
18
- let { currentUser: k } = e(), A = r(), j = n(), [M, N] = d(O), [P, F] = d(!1), [I, L] = d(D.body), R = !!(k?.id && k.id === D.authorId);
19
- return /* @__PURE__ */ v(T, {
17
+ function O({ post: O, defaultExpanded: k = !1, hideThreadLink: A = !1 }) {
18
+ let { currentUser: j, navigateTo: M } = e(), N = r(), P = n(), [F, I] = d(k), [L, R] = d(!1), [z, B] = d(O.body), V = !!(j?.id && j.id === O.authorId);
19
+ return /* @__PURE__ */ y(E, {
20
20
  treatment: "plain",
21
- className: t("p-4 transition-all duration-200 motion-safe:hover:-translate-y-0.5 hover:border-[var(--color-accent-soft)]", D.isPinned && "ring-1 ring-accent/40"),
21
+ className: t("p-4 transition-all duration-200 motion-safe:hover:-translate-y-0.5 hover:border-[var(--color-accent-soft)]", O.isPinned && "ring-1 ring-accent/40"),
22
22
  children: [
23
- /* @__PURE__ */ v("div", {
23
+ /* @__PURE__ */ y("div", {
24
24
  className: "flex items-start justify-between gap-3",
25
- children: [/* @__PURE__ */ _(i, {
26
- memberId: D.authorId,
25
+ children: [/* @__PURE__ */ v(i, {
26
+ memberId: O.authorId,
27
27
  variant: "row",
28
28
  size: "md",
29
- suffix: c(D.createdAt),
29
+ suffix: c(O.createdAt),
30
30
  showPresence: !0
31
- }), /* @__PURE__ */ v("div", {
31
+ }), /* @__PURE__ */ y("div", {
32
32
  className: "flex items-center gap-1",
33
- children: [D.isPinned && /* @__PURE__ */ v("span", {
33
+ children: [O.isPinned && /* @__PURE__ */ y("span", {
34
34
  className: "inline-flex items-center gap-1 rounded-full bg-[var(--color-accent-soft)] px-2 py-0.5 text-xs font-medium text-text-primary",
35
- children: [/* @__PURE__ */ _(h, { className: "h-3 w-3" }), " Pinned"]
36
- }), R && /* @__PURE__ */ v(b, { children: [/* @__PURE__ */ _(w, {
35
+ children: [/* @__PURE__ */ v(g, { className: "h-3 w-3" }), " Pinned"]
36
+ }), V && /* @__PURE__ */ y(x, { children: [/* @__PURE__ */ v(T, {
37
37
  asChild: !0,
38
- children: /* @__PURE__ */ _("button", {
38
+ children: /* @__PURE__ */ v("button", {
39
39
  type: "button",
40
40
  "aria-label": "Post actions",
41
41
  className: "rounded-lg p-1.5 text-text-tertiary transition-colors hover:bg-bg-sunken hover:text-text-primary",
42
- children: /* @__PURE__ */ _(p, { className: "h-4 w-4" })
42
+ children: /* @__PURE__ */ v(m, { className: "h-4 w-4" })
43
43
  })
44
- }), /* @__PURE__ */ v(x, {
44
+ }), /* @__PURE__ */ y(S, {
45
45
  align: "end",
46
46
  children: [
47
- /* @__PURE__ */ v(S, {
48
- onClick: () => F(!0),
49
- children: [/* @__PURE__ */ _(m, { className: "mr-2 h-4 w-4" }), " Edit"]
47
+ /* @__PURE__ */ y(C, {
48
+ onClick: () => R(!0),
49
+ children: [/* @__PURE__ */ v(h, { className: "mr-2 h-4 w-4" }), " Edit"]
50
50
  }),
51
- /* @__PURE__ */ v(S, {
51
+ /* @__PURE__ */ y(C, {
52
52
  onClick: async () => {
53
53
  try {
54
- await A.mutateAsync({
55
- id: D.id,
56
- input: { isPinned: !D.isPinned }
57
- }), o.success(D.isPinned ? "Post unpinned" : "Post pinned");
54
+ await N.mutateAsync({
55
+ id: O.id,
56
+ input: { isPinned: !O.isPinned }
57
+ }), o.success(O.isPinned ? "Post unpinned" : "Post pinned");
58
58
  } catch (e) {
59
59
  o.error("Could not update post", a(e));
60
60
  }
61
61
  },
62
62
  children: [
63
- /* @__PURE__ */ _(h, { className: "mr-2 h-4 w-4" }),
63
+ /* @__PURE__ */ v(g, { className: "mr-2 h-4 w-4" }),
64
64
  " ",
65
- D.isPinned ? "Unpin" : "Pin"
65
+ O.isPinned ? "Unpin" : "Pin"
66
66
  ]
67
67
  }),
68
- /* @__PURE__ */ _(C, {}),
69
- /* @__PURE__ */ v(S, {
68
+ /* @__PURE__ */ v(w, {}),
69
+ /* @__PURE__ */ y(C, {
70
70
  onClick: async () => {
71
71
  try {
72
- await j.mutateAsync({
73
- id: D.id,
74
- channelId: D.channelId
72
+ await P.mutateAsync({
73
+ id: O.id,
74
+ channelId: O.channelId
75
75
  }), o.success("Post removed");
76
76
  } catch (e) {
77
77
  o.error("Could not remove post", a(e));
78
78
  }
79
79
  },
80
80
  className: "text-status-error-text focus:text-status-error-text",
81
- children: [/* @__PURE__ */ _(g, { className: "mr-2 h-4 w-4" }), " Delete"]
81
+ children: [/* @__PURE__ */ v(_, { className: "mr-2 h-4 w-4" }), " Delete"]
82
82
  })
83
83
  ]
84
84
  })] })]
85
85
  })]
86
86
  }),
87
- P ? /* @__PURE__ */ v("div", {
87
+ L ? /* @__PURE__ */ y("div", {
88
88
  className: "mt-3",
89
- children: [/* @__PURE__ */ _(E, {
90
- value: I,
91
- onChange: (e) => L(e.target.value),
89
+ children: [/* @__PURE__ */ v(D, {
90
+ value: z,
91
+ onChange: (e) => B(e.target.value),
92
92
  rows: 3,
93
93
  className: "resize-none"
94
- }), /* @__PURE__ */ v("div", {
94
+ }), /* @__PURE__ */ y("div", {
95
95
  className: "mt-2 flex justify-end gap-2",
96
- children: [/* @__PURE__ */ _(y, {
96
+ children: [/* @__PURE__ */ v(b, {
97
97
  variant: "outline",
98
98
  size: "sm",
99
99
  onClick: () => {
100
- L(D.body), F(!1);
100
+ B(O.body), R(!1);
101
101
  },
102
102
  children: "Cancel"
103
- }), /* @__PURE__ */ _(y, {
103
+ }), /* @__PURE__ */ v(b, {
104
104
  size: "sm",
105
105
  onClick: async () => {
106
- let e = I.trim();
107
- if (!e || e === D.body) {
108
- F(!1);
106
+ let e = z.trim();
107
+ if (!e || e === O.body) {
108
+ R(!1);
109
109
  return;
110
110
  }
111
111
  try {
112
- await A.mutateAsync({
113
- id: D.id,
112
+ await N.mutateAsync({
113
+ id: O.id,
114
114
  input: { body: e }
115
- }), F(!1), o.success("Post updated");
115
+ }), R(!1), o.success("Post updated");
116
116
  } catch (e) {
117
117
  o.error("Could not update post", a(e));
118
118
  }
119
119
  },
120
- disabled: A.isPending,
120
+ disabled: N.isPending,
121
121
  children: "Save"
122
122
  })]
123
123
  })]
124
- }) : /* @__PURE__ */ _("p", {
124
+ }) : /* @__PURE__ */ v("p", {
125
125
  className: "mt-3 whitespace-pre-wrap break-words text-sm text-text-primary",
126
- children: D.body
126
+ children: O.body
127
127
  }),
128
- D.tags.length > 0 && /* @__PURE__ */ _("div", {
128
+ O.tags.length > 0 && /* @__PURE__ */ v("div", {
129
129
  className: "mt-2 flex flex-wrap gap-1.5",
130
- children: D.tags.map((e) => /* @__PURE__ */ v("span", {
130
+ children: O.tags.map((e) => /* @__PURE__ */ y("span", {
131
131
  className: "rounded-full bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-secondary",
132
132
  children: ["#", e]
133
133
  }, e))
134
134
  }),
135
- D.attachmentFileIds.length > 0 && /* @__PURE__ */ _(u, { fileIds: D.attachmentFileIds }),
136
- /* @__PURE__ */ v("div", {
135
+ O.attachmentFileIds.length > 0 && /* @__PURE__ */ v(u, { fileIds: O.attachmentFileIds }),
136
+ /* @__PURE__ */ y("div", {
137
137
  className: "mt-3 flex items-center justify-between gap-3 border-t border-border-seam pt-3",
138
- children: [/* @__PURE__ */ _(s, { post: D }), /* @__PURE__ */ v("button", {
139
- type: "button",
140
- onClick: () => N((e) => !e),
141
- "aria-expanded": M,
142
- className: t("inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-xs font-medium transition-colors", M ? "bg-[var(--color-accent-soft)] text-text-primary" : "text-text-secondary hover:bg-bg-sunken hover:text-text-primary"),
143
- children: [
144
- /* @__PURE__ */ _(f, { className: "h-3.5 w-3.5" }),
145
- /* @__PURE__ */ _("span", {
146
- className: "tabular-nums",
147
- children: D.commentCount
148
- }),
149
- /* @__PURE__ */ _("span", {
138
+ children: [/* @__PURE__ */ v(s, { post: O }), /* @__PURE__ */ y("div", {
139
+ className: "flex items-center gap-1",
140
+ children: [/* @__PURE__ */ y("button", {
141
+ type: "button",
142
+ onClick: () => I((e) => !e),
143
+ "aria-expanded": F,
144
+ className: t("inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-xs font-medium transition-colors", F ? "bg-[var(--color-accent-soft)] text-text-primary" : "text-text-secondary hover:bg-bg-sunken hover:text-text-primary"),
145
+ children: [
146
+ /* @__PURE__ */ v(p, { className: "h-3.5 w-3.5" }),
147
+ /* @__PURE__ */ v("span", {
148
+ className: "tabular-nums",
149
+ children: O.commentCount
150
+ }),
151
+ /* @__PURE__ */ v("span", {
152
+ className: "hidden sm:inline",
153
+ children: O.commentCount === 1 ? "comment" : "comments"
154
+ })
155
+ ]
156
+ }), !A && /* @__PURE__ */ y("button", {
157
+ type: "button",
158
+ onClick: () => M(`posts/${O.id}`),
159
+ "aria-label": "Open thread",
160
+ title: "Open thread",
161
+ className: "inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-xs font-medium text-text-tertiary transition-colors hover:bg-bg-sunken hover:text-text-primary",
162
+ children: [/* @__PURE__ */ v(f, { className: "h-3.5 w-3.5" }), /* @__PURE__ */ v("span", {
150
163
  className: "hidden sm:inline",
151
- children: D.commentCount === 1 ? "comment" : "comments"
152
- })
153
- ]
164
+ children: "Open thread"
165
+ })]
166
+ })]
154
167
  })]
155
168
  }),
156
- M && /* @__PURE__ */ _(l, { postId: D.id })
169
+ F && /* @__PURE__ */ v(l, { postId: O.id })
157
170
  ]
158
171
  });
159
172
  }
160
173
  //#endregion
161
- export { D as PostCard };
174
+ export { O as PostCard };
162
175
 
163
176
  //# sourceMappingURL=PostCard.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PostCard.js","names":[],"sources":["../../../src/comradecircle/components/PostCard.tsx"],"sourcesContent":["/**\n * PostCard — a single post with reactions and a collapsible comment thread.\n * @module comradecircle/components\n *\n * Reads its data from a `ComPost`; writes via `comUpdatePost` (edit / pin) and\n * `comRemovePost` (delete). Reactions + comments are delegated to\n * {@link ReactionBar} and {@link CommentThread}. Author-only actions (edit, pin,\n * delete) are gated on `authorId === currentUser.id`.\n */\n\nimport { useState } from 'react';\nimport { MessageSquare, MoreHorizontal, Pin, Pencil, Trash2 } from 'lucide-react';\nimport {\n GlassCard,\n Button,\n Textarea,\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n} from '@burdenoff/fe-libs/ui';\nimport { cn } from '../utils/cn';\nimport { MemberIdentity } from './MemberIdentity';\nimport { ReactionBar } from './ReactionBar';\nimport { CommentThread } from './CommentThread';\nimport { AttachmentGrid } from './ImageAttachments';\nimport { useComUpdatePost, useComRemovePost } from '../hooks';\nimport { useComradeCircle } from '../context';\nimport { formatRelativeTime } from '../utils/formatters';\nimport { notify, describeError } from '../lib/toast';\nimport type { ComPost } from '../types';\n\ninterface PostCardProps {\n post: ComPost;\n /** Start with the comment thread open. */\n defaultExpanded?: boolean;\n}\n\nexport function PostCard({ post, defaultExpanded = false }: PostCardProps) {\n const { currentUser } = useComradeCircle();\n const updatePost = useComUpdatePost();\n const removePost = useComRemovePost();\n const [expanded, setExpanded] = useState(defaultExpanded);\n const [editing, setEditing] = useState(false);\n const [draft, setDraft] = useState(post.body);\n\n const isAuthor = Boolean(currentUser?.id && currentUser.id === post.authorId);\n\n const saveEdit = async () => {\n const text = draft.trim();\n if (!text || text === post.body) {\n setEditing(false);\n return;\n }\n try {\n await updatePost.mutateAsync({ id: post.id, input: { body: text } });\n setEditing(false);\n notify.success('Post updated');\n } catch (err) {\n notify.error('Could not update post', describeError(err));\n }\n };\n\n const togglePin = async () => {\n try {\n await updatePost.mutateAsync({ id: post.id, input: { isPinned: !post.isPinned } });\n notify.success(post.isPinned ? 'Post unpinned' : 'Post pinned');\n } catch (err) {\n notify.error('Could not update post', describeError(err));\n }\n };\n\n const remove = async () => {\n try {\n await removePost.mutateAsync({ id: post.id, channelId: post.channelId });\n notify.success('Post removed');\n } catch (err) {\n notify.error('Could not remove post', describeError(err));\n }\n };\n\n return (\n <GlassCard\n treatment=\"plain\"\n className={cn(\n 'p-4 transition-all duration-200 motion-safe:hover:-translate-y-0.5 hover:border-[var(--color-accent-soft)]',\n post.isPinned && 'ring-1 ring-accent/40'\n )}\n >\n <div className=\"flex items-start justify-between gap-3\">\n <MemberIdentity\n memberId={post.authorId}\n variant=\"row\"\n size=\"md\"\n suffix={formatRelativeTime(post.createdAt)}\n showPresence\n />\n <div className=\"flex items-center gap-1\">\n {post.isPinned && (\n <span className=\"inline-flex items-center gap-1 rounded-full bg-[var(--color-accent-soft)] px-2 py-0.5 text-xs font-medium text-text-primary\">\n <Pin className=\"h-3 w-3\" /> Pinned\n </span>\n )}\n {isAuthor && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n aria-label=\"Post actions\"\n className=\"rounded-lg p-1.5 text-text-tertiary transition-colors hover:bg-bg-sunken hover:text-text-primary\"\n >\n <MoreHorizontal className=\"h-4 w-4\" />\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onClick={() => setEditing(true)}>\n <Pencil className=\"mr-2 h-4 w-4\" /> Edit\n </DropdownMenuItem>\n <DropdownMenuItem onClick={togglePin}>\n <Pin className=\"mr-2 h-4 w-4\" /> {post.isPinned ? 'Unpin' : 'Pin'}\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem\n onClick={remove}\n className=\"text-status-error-text focus:text-status-error-text\"\n >\n <Trash2 className=\"mr-2 h-4 w-4\" /> Delete\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n </div>\n </div>\n\n {editing ? (\n <div className=\"mt-3\">\n <Textarea\n value={draft}\n onChange={(e) => setDraft(e.target.value)}\n rows={3}\n className=\"resize-none\"\n />\n <div className=\"mt-2 flex justify-end gap-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => {\n setDraft(post.body);\n setEditing(false);\n }}\n >\n Cancel\n </Button>\n <Button size=\"sm\" onClick={saveEdit} disabled={updatePost.isPending}>\n Save\n </Button>\n </div>\n </div>\n ) : (\n <p className=\"mt-3 whitespace-pre-wrap break-words text-sm text-text-primary\">\n {post.body}\n </p>\n )}\n\n {post.tags.length > 0 && (\n <div className=\"mt-2 flex flex-wrap gap-1.5\">\n {post.tags.map((tag) => (\n <span\n key={tag}\n className=\"rounded-full bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-secondary\"\n >\n #{tag}\n </span>\n ))}\n </div>\n )}\n\n {post.attachmentFileIds.length > 0 && <AttachmentGrid fileIds={post.attachmentFileIds} />}\n\n <div className=\"mt-3 flex items-center justify-between gap-3 border-t border-border-seam pt-3\">\n <ReactionBar post={post} />\n <button\n type=\"button\"\n onClick={() => setExpanded((s) => !s)}\n aria-expanded={expanded}\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-xs font-medium transition-colors',\n expanded\n ? 'bg-[var(--color-accent-soft)] text-text-primary'\n : 'text-text-secondary hover:bg-bg-sunken hover:text-text-primary'\n )}\n >\n <MessageSquare className=\"h-3.5 w-3.5\" />\n <span className=\"tabular-nums\">{post.commentCount}</span>\n <span className=\"hidden sm:inline\">\n {post.commentCount === 1 ? 'comment' : 'comments'}\n </span>\n </button>\n </div>\n\n {expanded && <CommentThread postId={post.id} />}\n </GlassCard>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"PostCard.js","names":[],"sources":["../../../src/comradecircle/components/PostCard.tsx"],"sourcesContent":["/**\n * PostCard — a single post with reactions and a collapsible comment thread.\n * @module comradecircle/components\n *\n * Reads its data from a `ComPost`; writes via `comUpdatePost` (edit / pin) and\n * `comRemovePost` (delete). Reactions + comments are delegated to\n * {@link ReactionBar} and {@link CommentThread}. Author-only actions (edit, pin,\n * delete) are gated on `authorId === currentUser.id`.\n */\n\nimport { useState } from 'react';\nimport { MessageSquare, MoreHorizontal, Pin, Pencil, Trash2, ArrowUpRight } from 'lucide-react';\nimport {\n GlassCard,\n Button,\n Textarea,\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n} from '@burdenoff/fe-libs/ui';\nimport { cn } from '../utils/cn';\nimport { MemberIdentity } from './MemberIdentity';\nimport { ReactionBar } from './ReactionBar';\nimport { CommentThread } from './CommentThread';\nimport { AttachmentGrid } from './ImageAttachments';\nimport { useComUpdatePost, useComRemovePost } from '../hooks';\nimport { useComradeCircle } from '../context';\nimport { formatRelativeTime } from '../utils/formatters';\nimport { notify, describeError } from '../lib/toast';\nimport type { ComPost } from '../types';\n\ninterface PostCardProps {\n post: ComPost;\n /** Start with the comment thread open. */\n defaultExpanded?: boolean;\n /** Hide the \"open thread\" link — set when already rendered on the thread page itself. */\n hideThreadLink?: boolean;\n}\n\nexport function PostCard({ post, defaultExpanded = false, hideThreadLink = false }: PostCardProps) {\n const { currentUser, navigateTo } = useComradeCircle();\n const updatePost = useComUpdatePost();\n const removePost = useComRemovePost();\n const [expanded, setExpanded] = useState(defaultExpanded);\n const [editing, setEditing] = useState(false);\n const [draft, setDraft] = useState(post.body);\n\n const isAuthor = Boolean(currentUser?.id && currentUser.id === post.authorId);\n\n const saveEdit = async () => {\n const text = draft.trim();\n if (!text || text === post.body) {\n setEditing(false);\n return;\n }\n try {\n await updatePost.mutateAsync({ id: post.id, input: { body: text } });\n setEditing(false);\n notify.success('Post updated');\n } catch (err) {\n notify.error('Could not update post', describeError(err));\n }\n };\n\n const togglePin = async () => {\n try {\n await updatePost.mutateAsync({ id: post.id, input: { isPinned: !post.isPinned } });\n notify.success(post.isPinned ? 'Post unpinned' : 'Post pinned');\n } catch (err) {\n notify.error('Could not update post', describeError(err));\n }\n };\n\n const remove = async () => {\n try {\n await removePost.mutateAsync({ id: post.id, channelId: post.channelId });\n notify.success('Post removed');\n } catch (err) {\n notify.error('Could not remove post', describeError(err));\n }\n };\n\n return (\n <GlassCard\n treatment=\"plain\"\n className={cn(\n 'p-4 transition-all duration-200 motion-safe:hover:-translate-y-0.5 hover:border-[var(--color-accent-soft)]',\n post.isPinned && 'ring-1 ring-accent/40'\n )}\n >\n <div className=\"flex items-start justify-between gap-3\">\n <MemberIdentity\n memberId={post.authorId}\n variant=\"row\"\n size=\"md\"\n suffix={formatRelativeTime(post.createdAt)}\n showPresence\n />\n <div className=\"flex items-center gap-1\">\n {post.isPinned && (\n <span className=\"inline-flex items-center gap-1 rounded-full bg-[var(--color-accent-soft)] px-2 py-0.5 text-xs font-medium text-text-primary\">\n <Pin className=\"h-3 w-3\" /> Pinned\n </span>\n )}\n {isAuthor && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n aria-label=\"Post actions\"\n className=\"rounded-lg p-1.5 text-text-tertiary transition-colors hover:bg-bg-sunken hover:text-text-primary\"\n >\n <MoreHorizontal className=\"h-4 w-4\" />\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onClick={() => setEditing(true)}>\n <Pencil className=\"mr-2 h-4 w-4\" /> Edit\n </DropdownMenuItem>\n <DropdownMenuItem onClick={togglePin}>\n <Pin className=\"mr-2 h-4 w-4\" /> {post.isPinned ? 'Unpin' : 'Pin'}\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem\n onClick={remove}\n className=\"text-status-error-text focus:text-status-error-text\"\n >\n <Trash2 className=\"mr-2 h-4 w-4\" /> Delete\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n </div>\n </div>\n\n {editing ? (\n <div className=\"mt-3\">\n <Textarea\n value={draft}\n onChange={(e) => setDraft(e.target.value)}\n rows={3}\n className=\"resize-none\"\n />\n <div className=\"mt-2 flex justify-end gap-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => {\n setDraft(post.body);\n setEditing(false);\n }}\n >\n Cancel\n </Button>\n <Button size=\"sm\" onClick={saveEdit} disabled={updatePost.isPending}>\n Save\n </Button>\n </div>\n </div>\n ) : (\n <p className=\"mt-3 whitespace-pre-wrap break-words text-sm text-text-primary\">\n {post.body}\n </p>\n )}\n\n {post.tags.length > 0 && (\n <div className=\"mt-2 flex flex-wrap gap-1.5\">\n {post.tags.map((tag) => (\n <span\n key={tag}\n className=\"rounded-full bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-secondary\"\n >\n #{tag}\n </span>\n ))}\n </div>\n )}\n\n {post.attachmentFileIds.length > 0 && <AttachmentGrid fileIds={post.attachmentFileIds} />}\n\n <div className=\"mt-3 flex items-center justify-between gap-3 border-t border-border-seam pt-3\">\n <ReactionBar post={post} />\n <div className=\"flex items-center gap-1\">\n <button\n type=\"button\"\n onClick={() => setExpanded((s) => !s)}\n aria-expanded={expanded}\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-xs font-medium transition-colors',\n expanded\n ? 'bg-[var(--color-accent-soft)] text-text-primary'\n : 'text-text-secondary hover:bg-bg-sunken hover:text-text-primary'\n )}\n >\n <MessageSquare className=\"h-3.5 w-3.5\" />\n <span className=\"tabular-nums\">{post.commentCount}</span>\n <span className=\"hidden sm:inline\">\n {post.commentCount === 1 ? 'comment' : 'comments'}\n </span>\n </button>\n\n {!hideThreadLink && (\n <button\n type=\"button\"\n onClick={() => navigateTo(`posts/${post.id}`)}\n aria-label=\"Open thread\"\n title=\"Open thread\"\n className=\"inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-xs font-medium text-text-tertiary transition-colors hover:bg-bg-sunken hover:text-text-primary\"\n >\n <ArrowUpRight className=\"h-3.5 w-3.5\" />\n <span className=\"hidden sm:inline\">Open thread</span>\n </button>\n )}\n </div>\n </div>\n\n {expanded && <CommentThread postId={post.id} />}\n </GlassCard>\n );\n}\n"],"mappings":"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"}
@@ -10,7 +10,13 @@ interface PostComposerProps {
10
10
  channelId: string;
11
11
  channelName?: string;
12
12
  onPosted?: () => void;
13
+ /**
14
+ * 'announcement' renders the manager-only broadcast composer with distinct
15
+ * styling (accent border + "New announcement" affordance) per BOFF-3969's
16
+ * mock; 'default' is the regular post composer used on TEXT/FORUM channels.
17
+ */
18
+ variant?: 'default' | 'announcement';
13
19
  }
14
- export declare function PostComposer({ channelId, channelName, onPosted }: PostComposerProps): import("react/jsx-runtime").JSX.Element;
20
+ export declare function PostComposer({ channelId, channelName, onPosted, variant, }: PostComposerProps): import("react/jsx-runtime").JSX.Element;
15
21
  export {};
16
22
  //# sourceMappingURL=PostComposer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PostComposer.d.ts","sourceRoot":"","sources":["../../../src/comradecircle/components/PostComposer.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAYH,UAAU,iBAAiB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB;AAED,wBAAgB,YAAY,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,EAAE,iBAAiB,2CA+EnF"}
1
+ {"version":3,"file":"PostComposer.d.ts","sourceRoot":"","sources":["../../../src/comradecircle/components/PostComposer.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAaH,UAAU,iBAAiB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB;;;;OAIG;IACH,OAAO,CAAC,EAAE,SAAS,GAAG,cAAc,CAAC;CACtC;AAED,wBAAgB,YAAY,CAAC,EAC3B,SAAS,EACT,WAAW,EACX,QAAQ,EACR,OAAmB,GACpB,EAAE,iBAAiB,2CAyGnB"}