@burdenoff/microfe-comradecircle 2026.819.1 → 2026.830.1
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.
- package/dist/comradecircle/components/AvatarUploadField.js +8 -8
- package/dist/comradecircle/components/CircleCard.js +4 -4
- package/dist/comradecircle/components/CommentThread.d.ts.map +1 -1
- package/dist/comradecircle/components/CommentThread.js +66 -61
- package/dist/comradecircle/components/CommentThread.js.map +1 -1
- package/dist/comradecircle/components/CreateCircleDialog.d.ts.map +1 -1
- package/dist/comradecircle/components/CreateCircleDialog.js +89 -88
- package/dist/comradecircle/components/CreateCircleDialog.js.map +1 -1
- package/dist/comradecircle/components/CreateEventDialog.d.ts.map +1 -1
- package/dist/comradecircle/components/CreateEventDialog.js +28 -27
- package/dist/comradecircle/components/CreateEventDialog.js.map +1 -1
- package/dist/comradecircle/components/DraftsPanel.d.ts +32 -0
- package/dist/comradecircle/components/DraftsPanel.d.ts.map +1 -0
- package/dist/comradecircle/components/DraftsPanel.js +176 -0
- package/dist/comradecircle/components/DraftsPanel.js.map +1 -0
- package/dist/comradecircle/components/EventCard.js +5 -5
- package/dist/comradecircle/components/FileImage.js +5 -5
- package/dist/comradecircle/components/ImageAttachments.js +21 -21
- package/dist/comradecircle/components/MemberIdentity.js +4 -4
- package/dist/comradecircle/components/MobileBottomNav.d.ts.map +1 -1
- package/dist/comradecircle/components/MobileBottomNav.js +37 -30
- package/dist/comradecircle/components/MobileBottomNav.js.map +1 -1
- package/dist/comradecircle/components/Pagination.d.ts.map +1 -1
- package/dist/comradecircle/components/Pagination.js +37 -28
- package/dist/comradecircle/components/Pagination.js.map +1 -1
- package/dist/comradecircle/components/PollCard.js +13 -13
- package/dist/comradecircle/components/PostCard.d.ts.map +1 -1
- package/dist/comradecircle/components/PostCard.js +102 -89
- package/dist/comradecircle/components/PostCard.js.map +1 -1
- package/dist/comradecircle/components/PostComposer.d.ts +11 -5
- package/dist/comradecircle/components/PostComposer.d.ts.map +1 -1
- package/dist/comradecircle/components/PostComposer.js +60 -48
- package/dist/comradecircle/components/PostComposer.js.map +1 -1
- package/dist/comradecircle/components/ReactionBar.d.ts.map +1 -1
- package/dist/comradecircle/components/ReactionBar.js +65 -55
- package/dist/comradecircle/components/ReactionBar.js.map +1 -1
- package/dist/comradecircle/components/StateViews.d.ts.map +1 -1
- package/dist/comradecircle/components/StateViews.js +38 -30
- package/dist/comradecircle/components/StateViews.js.map +1 -1
- package/dist/comradecircle/components/UpcomingEvents.d.ts +26 -0
- package/dist/comradecircle/components/UpcomingEvents.d.ts.map +1 -0
- package/dist/comradecircle/components/UpcomingEvents.js +126 -0
- package/dist/comradecircle/components/UpcomingEvents.js.map +1 -0
- package/dist/comradecircle/components/index.d.ts +2 -0
- package/dist/comradecircle/components/index.d.ts.map +1 -1
- package/dist/comradecircle/hooks/index.d.ts +1 -0
- package/dist/comradecircle/hooks/index.d.ts.map +1 -1
- package/dist/comradecircle/hooks/index.js +1 -0
- package/dist/comradecircle/hooks/useTr.d.ts +18 -0
- package/dist/comradecircle/hooks/useTr.d.ts.map +1 -0
- package/dist/comradecircle/hooks/useTr.js +12 -0
- package/dist/comradecircle/hooks/useTr.js.map +1 -0
- package/dist/comradecircle/pages/FeedPage.d.ts +5 -0
- package/dist/comradecircle/pages/FeedPage.d.ts.map +1 -1
- package/dist/comradecircle/pages/FeedPage.js +76 -62
- package/dist/comradecircle/pages/FeedPage.js.map +1 -1
- package/dist/comradecircle/pages/circles/CircleDetailPage.d.ts.map +1 -1
- package/dist/comradecircle/pages/circles/CircleDetailPage.js +454 -409
- package/dist/comradecircle/pages/circles/CircleDetailPage.js.map +1 -1
- package/dist/comradecircle/pages/circles/CirclesPage.d.ts.map +1 -1
- package/dist/comradecircle/pages/circles/CirclesPage.js +124 -117
- package/dist/comradecircle/pages/circles/CirclesPage.js.map +1 -1
- package/dist/comradecircle/pages/events/EventDetailPage.d.ts.map +1 -1
- package/dist/comradecircle/pages/events/EventDetailPage.js +182 -153
- package/dist/comradecircle/pages/events/EventDetailPage.js.map +1 -1
- package/dist/comradecircle/pages/events/EventsPage.d.ts.map +1 -1
- package/dist/comradecircle/pages/events/EventsPage.js +100 -91
- package/dist/comradecircle/pages/events/EventsPage.js.map +1 -1
- package/dist/comradecircle/pages/members/MemberProfilePage.d.ts.map +1 -1
- package/dist/comradecircle/pages/members/MemberProfilePage.js +172 -159
- package/dist/comradecircle/pages/members/MemberProfilePage.js.map +1 -1
- package/dist/comradecircle/pages/members/MembersPage.d.ts.map +1 -1
- package/dist/comradecircle/pages/members/MembersPage.js +103 -104
- package/dist/comradecircle/pages/members/MembersPage.js.map +1 -1
- package/dist/comradecircle/pages/monetization/MonetizationPage.d.ts.map +1 -1
- package/dist/comradecircle/pages/monetization/MonetizationPage.js +319 -297
- package/dist/comradecircle/pages/monetization/MonetizationPage.js.map +1 -1
- package/dist/comradecircle/pages/posts/PostThreadPage.d.ts.map +1 -1
- package/dist/comradecircle/pages/posts/PostThreadPage.js +37 -32
- package/dist/comradecircle/pages/posts/PostThreadPage.js.map +1 -1
- package/dist/comradecircle/pages/profile/MyProfilePage.d.ts.map +1 -1
- package/dist/comradecircle/pages/profile/MyProfilePage.js +182 -177
- package/dist/comradecircle/pages/profile/MyProfilePage.js.map +1 -1
- package/dist/comradecircle/utils/i18n.js +15 -0
- package/dist/comradecircle/utils/i18n.js.map +1 -0
- package/dist/comradecircle/utils/pageContext.d.ts.map +1 -1
- package/dist/comradecircle/utils/pageContext.js +3 -1
- package/dist/comradecircle/utils/pageContext.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { FILE_FOLDERS as e, uploadImageToFiles as t } from "../hooks/useFiles.js";
|
|
2
|
+
import { cn as n } from "../utils/cn.js";
|
|
3
3
|
import { FileImage as r } from "./FileImage.js";
|
|
4
4
|
import { describeError as i, notify as a } from "../lib/toast.js";
|
|
5
5
|
import { useRef as o, useState as s } from "react";
|
|
@@ -7,11 +7,11 @@ import { ImagePlus as c, Loader2 as l, X as u } from "lucide-react";
|
|
|
7
7
|
import { jsx as d, jsxs as f } from "react/jsx-runtime";
|
|
8
8
|
//#region src/comradecircle/components/ImageAttachments.tsx
|
|
9
9
|
var p = 10 * 1024 * 1024, m = 6;
|
|
10
|
-
function h({ fileIds:
|
|
10
|
+
function h({ fileIds: n, onChange: h, disabled: g = !1 }) {
|
|
11
11
|
let _ = o(null), [v, y] = s(!1), [b, x] = s({}), S = async (r) => {
|
|
12
12
|
let o = Array.from(r.target.files ?? []);
|
|
13
13
|
if (r.target.value = "", o.length === 0) return;
|
|
14
|
-
let s = m -
|
|
14
|
+
let s = m - n.length;
|
|
15
15
|
if (s <= 0) {
|
|
16
16
|
a.warning("Attachment limit reached", `Up to ${m} images per post.`);
|
|
17
17
|
return;
|
|
@@ -19,29 +19,29 @@ function h({ fileIds: e, onChange: h, disabled: g = !1 }) {
|
|
|
19
19
|
y(!0);
|
|
20
20
|
try {
|
|
21
21
|
let r = [], i = {};
|
|
22
|
-
for (let
|
|
23
|
-
if (!
|
|
24
|
-
if (
|
|
25
|
-
a.error("Image too large", `${
|
|
22
|
+
for (let n of o.slice(0, s)) {
|
|
23
|
+
if (!n.type.startsWith("image/")) continue;
|
|
24
|
+
if (n.size > p) {
|
|
25
|
+
a.error("Image too large", `${n.name} exceeds 10 MB.`);
|
|
26
26
|
continue;
|
|
27
27
|
}
|
|
28
|
-
let o = await n
|
|
28
|
+
let o = await t(n, e.posts);
|
|
29
29
|
r.push(o.id), i[o.id] = o.url;
|
|
30
30
|
}
|
|
31
31
|
r.length && (x((e) => ({
|
|
32
32
|
...e,
|
|
33
33
|
...i
|
|
34
|
-
})), h([...
|
|
34
|
+
})), h([...n, ...r]));
|
|
35
35
|
} catch (e) {
|
|
36
36
|
a.error("Upload failed", i(e));
|
|
37
37
|
} finally {
|
|
38
38
|
y(!1);
|
|
39
39
|
}
|
|
40
|
-
}, C = (
|
|
40
|
+
}, C = (e) => h(n.filter((t) => t !== e));
|
|
41
41
|
return /* @__PURE__ */ f("div", { children: [
|
|
42
|
-
|
|
42
|
+
n.length > 0 && /* @__PURE__ */ d("div", {
|
|
43
43
|
className: "mb-2 flex flex-wrap gap-2",
|
|
44
|
-
children:
|
|
44
|
+
children: n.map((e) => /* @__PURE__ */ f("div", {
|
|
45
45
|
className: "relative h-20 w-20 overflow-hidden rounded-lg ring-1 ring-border-seam",
|
|
46
46
|
children: [b[e] ? /* @__PURE__ */ d("img", {
|
|
47
47
|
src: b[e],
|
|
@@ -72,23 +72,23 @@ function h({ fileIds: e, onChange: h, disabled: g = !1 }) {
|
|
|
72
72
|
/* @__PURE__ */ f("button", {
|
|
73
73
|
type: "button",
|
|
74
74
|
onClick: () => _.current?.click(),
|
|
75
|
-
disabled: g || v ||
|
|
75
|
+
disabled: g || v || n.length >= m,
|
|
76
76
|
className: "inline-flex items-center gap-1.5 text-xs font-medium text-text-secondary transition-colors hover:text-text-primary disabled:opacity-50",
|
|
77
77
|
children: [v ? /* @__PURE__ */ d(l, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ d(c, { className: "h-4 w-4" }), v ? "Uploading…" : "Add images"]
|
|
78
78
|
})
|
|
79
79
|
] });
|
|
80
80
|
}
|
|
81
|
-
function g({ fileIds:
|
|
82
|
-
return
|
|
83
|
-
className:
|
|
84
|
-
children:
|
|
85
|
-
className:
|
|
81
|
+
function g({ fileIds: e, className: t }) {
|
|
82
|
+
return e.length === 0 ? null : /* @__PURE__ */ d("div", {
|
|
83
|
+
className: n("mt-3 grid gap-2", e.length === 1 ? "grid-cols-1" : "grid-cols-2 sm:grid-cols-3", t),
|
|
84
|
+
children: e.map((t) => /* @__PURE__ */ d("div", {
|
|
85
|
+
className: n("overflow-hidden rounded-xl ring-1 ring-border-seam", e.length === 1 ? "max-h-96" : "aspect-square"),
|
|
86
86
|
children: /* @__PURE__ */ d(r, {
|
|
87
|
-
fileId:
|
|
87
|
+
fileId: t,
|
|
88
88
|
alt: "Post attachment",
|
|
89
89
|
className: "h-full w-full"
|
|
90
90
|
})
|
|
91
|
-
},
|
|
91
|
+
}, t))
|
|
92
92
|
});
|
|
93
93
|
}
|
|
94
94
|
//#endregion
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { useComradeCircle as e } from "../context/ComradeCircleContext.js";
|
|
2
2
|
import "../context/index.js";
|
|
3
|
-
import {
|
|
4
|
-
import { useComProfile as n } from "../hooks/useComradeCircleApi.js";
|
|
3
|
+
import { useComProfile as t } from "../hooks/useComradeCircleApi.js";
|
|
5
4
|
import "../hooks/index.js";
|
|
5
|
+
import { cn as n } from "../utils/cn.js";
|
|
6
6
|
import { Avatar as r } from "./Avatar.js";
|
|
7
7
|
import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
8
8
|
//#region src/comradecircle/components/MemberIdentity.tsx
|
|
@@ -10,11 +10,11 @@ function o(e, t) {
|
|
|
10
10
|
return e ? { name: t ? `${e} (You)` : e } : { name: t ? "You" : "Member" };
|
|
11
11
|
}
|
|
12
12
|
var s = ({ memberId: s, variant: c = "inline", size: l = "sm", suffix: u, showPresence: d = !1, onClick: f, className: p }) => {
|
|
13
|
-
let { currentUser: m } = e(), h = !!(m?.id && m.id === s), { data: g } =
|
|
13
|
+
let { currentUser: m } = e(), h = !!(m?.id && m.id === s), { data: g } = t(s), { name: _ } = o(g?.displayName ?? void 0, h), v = g?.displayName ?? (h ? m?.name ?? "You" : s), y = d ? g?.presence ?? null : null;
|
|
14
14
|
return /* @__PURE__ */ a(f ? "button" : "div", {
|
|
15
15
|
type: f ? "button" : void 0,
|
|
16
16
|
onClick: f,
|
|
17
|
-
className:
|
|
17
|
+
className: n("flex items-center gap-2.5 text-left", f && "rounded-lg transition-colors hover:opacity-80", p),
|
|
18
18
|
children: [/* @__PURE__ */ i(r, {
|
|
19
19
|
name: v,
|
|
20
20
|
seed: s,
|
|
@@ -1 +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;
|
|
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;AAsDhC,eAAO,MAAM,eAAe,EAAE,EA0C7B,CAAC"}
|
|
@@ -1,58 +1,65 @@
|
|
|
1
1
|
import { useComradeCircle as e } from "../context/ComradeCircleContext.js";
|
|
2
2
|
import "../context/index.js";
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
3
|
+
import { useTr as t } from "../hooks/useTr.js";
|
|
4
|
+
import "../hooks/index.js";
|
|
5
|
+
import { cn as n } from "../utils/cn.js";
|
|
6
|
+
import { CalendarDays as r, Contact as i, Newspaper as a, UserCircle as o, Users as s } from "lucide-react";
|
|
7
|
+
import { useLocation as c } from "react-router";
|
|
8
|
+
import { jsx as l, jsxs as u } from "react/jsx-runtime";
|
|
7
9
|
//#region src/comradecircle/components/MobileBottomNav.tsx
|
|
8
|
-
var
|
|
10
|
+
var d = [
|
|
9
11
|
{
|
|
10
12
|
id: "feed",
|
|
11
|
-
|
|
13
|
+
labelKey: "comradecircle.nav.feed",
|
|
14
|
+
labelFallback: "Home",
|
|
12
15
|
path: "",
|
|
13
|
-
icon:
|
|
16
|
+
icon: a
|
|
14
17
|
},
|
|
15
18
|
{
|
|
16
19
|
id: "circles",
|
|
17
|
-
|
|
20
|
+
labelKey: "comradecircle.nav.circles",
|
|
21
|
+
labelFallback: "Circles",
|
|
18
22
|
path: "circles",
|
|
19
|
-
icon:
|
|
23
|
+
icon: s
|
|
20
24
|
},
|
|
21
25
|
{
|
|
22
26
|
id: "events",
|
|
23
|
-
|
|
27
|
+
labelKey: "comradecircle.nav.events",
|
|
28
|
+
labelFallback: "Events",
|
|
24
29
|
path: "events",
|
|
25
|
-
icon:
|
|
30
|
+
icon: r
|
|
26
31
|
},
|
|
27
32
|
{
|
|
28
33
|
id: "members",
|
|
29
|
-
|
|
34
|
+
labelKey: "comradecircle.nav.members",
|
|
35
|
+
labelFallback: "Members",
|
|
30
36
|
path: "members",
|
|
31
|
-
icon:
|
|
37
|
+
icon: i
|
|
32
38
|
},
|
|
33
39
|
{
|
|
34
40
|
id: "profile",
|
|
35
|
-
|
|
41
|
+
labelKey: "comradecircle.nav.profile",
|
|
42
|
+
labelFallback: "Profile",
|
|
36
43
|
path: "profile",
|
|
37
|
-
icon:
|
|
44
|
+
icon: o
|
|
38
45
|
}
|
|
39
|
-
],
|
|
40
|
-
let { getPath:
|
|
41
|
-
return /* @__PURE__ */
|
|
42
|
-
"aria-label": "ComradeCircle mobile navigation",
|
|
43
|
-
className:
|
|
44
|
-
children: /* @__PURE__ */
|
|
46
|
+
], f = () => {
|
|
47
|
+
let { getPath: r, navigateTo: i } = e(), a = c(), o = t();
|
|
48
|
+
return /* @__PURE__ */ l("nav", {
|
|
49
|
+
"aria-label": o("comradecircle.nav.mobileAriaLabel", "ComradeCircle mobile navigation"),
|
|
50
|
+
className: n("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)]"),
|
|
51
|
+
children: /* @__PURE__ */ l("ul", {
|
|
45
52
|
className: "flex",
|
|
46
|
-
children:
|
|
47
|
-
let
|
|
48
|
-
return /* @__PURE__ */
|
|
53
|
+
children: d.map((e) => {
|
|
54
|
+
let t = r(e.path), s = e.path === "" ? a.pathname === t : a.pathname === t || a.pathname.startsWith(`${t}/`), c = e.icon;
|
|
55
|
+
return /* @__PURE__ */ l("li", {
|
|
49
56
|
className: "flex-1",
|
|
50
|
-
children: /* @__PURE__ */
|
|
57
|
+
children: /* @__PURE__ */ u("button", {
|
|
51
58
|
type: "button",
|
|
52
|
-
"aria-current":
|
|
53
|
-
onClick: () =>
|
|
54
|
-
className:
|
|
55
|
-
children: [/* @__PURE__ */ c
|
|
59
|
+
"aria-current": s ? "page" : void 0,
|
|
60
|
+
onClick: () => i(e.path),
|
|
61
|
+
className: n("flex w-full flex-col items-center gap-1 py-2.5 text-[11px] font-medium transition-colors", s ? "text-accent" : "text-text-tertiary hover:text-text-secondary"),
|
|
62
|
+
children: [/* @__PURE__ */ l(c, { className: n("h-5 w-5", s && "text-accent") }), o(e.labelKey, e.labelFallback)]
|
|
56
63
|
})
|
|
57
64
|
}, e.id);
|
|
58
65
|
})
|
|
@@ -60,6 +67,6 @@ var u = [
|
|
|
60
67
|
});
|
|
61
68
|
};
|
|
62
69
|
//#endregion
|
|
63
|
-
export {
|
|
70
|
+
export { f as MobileBottomNav };
|
|
64
71
|
|
|
65
72
|
//# sourceMappingURL=MobileBottomNav.js.map
|
|
@@ -1 +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';\nimport { useComradeCircle } from '../context';\nimport { cn } from '../utils/cn';\n\ninterface TabDef {\n id: string;\n
|
|
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';\nimport { useComradeCircle } from '../context';\nimport { useTr } from '../hooks';\nimport { cn } from '../utils/cn';\n\ninterface TabDef {\n id: string;\n labelKey: string;\n labelFallback: string;\n /** Path relative to basePath, '' for the home feed. */\n path: string;\n icon: FC<{ className?: string }>;\n}\n\nconst TABS: TabDef[] = [\n {\n id: 'feed',\n labelKey: 'comradecircle.nav.feed',\n labelFallback: 'Home',\n path: '',\n icon: Newspaper,\n },\n {\n id: 'circles',\n labelKey: 'comradecircle.nav.circles',\n labelFallback: 'Circles',\n path: 'circles',\n icon: Users,\n },\n {\n id: 'events',\n labelKey: 'comradecircle.nav.events',\n labelFallback: 'Events',\n path: 'events',\n icon: CalendarDays,\n },\n {\n id: 'members',\n labelKey: 'comradecircle.nav.members',\n labelFallback: 'Members',\n path: 'members',\n icon: Contact,\n },\n {\n id: 'profile',\n labelKey: 'comradecircle.nav.profile',\n labelFallback: 'Profile',\n path: 'profile',\n icon: UserCircle,\n },\n];\n\nexport const MobileBottomNav: FC = () => {\n const { getPath, navigateTo } = useComradeCircle();\n const location = useLocation();\n const tr = useTr();\n\n return (\n <nav\n aria-label={tr('comradecircle.nav.mobileAriaLabel', '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 {tr(tab.labelKey, tab.labelFallback)}\n </button>\n </li>\n );\n })}\n </ul>\n </nav>\n );\n};\n"],"mappings":";;;;;;;;;AAoCA,IAAM,IAAiB;CACrB;EACE,IAAI;EACJ,UAAU;EACV,eAAe;EACf,MAAM;EACN,MAAM;CACR;CACA;EACE,IAAI;EACJ,UAAU;EACV,eAAe;EACf,MAAM;EACN,MAAM;CACR;CACA;EACE,IAAI;EACJ,UAAU;EACV,eAAe;EACf,MAAM;EACN,MAAM;CACR;CACA;EACE,IAAI;EACJ,UAAU;EACV,eAAe;EACf,MAAM;EACN,MAAM;CACR;CACA;EACE,IAAI;EACJ,UAAU;EACV,eAAe;EACf,MAAM;EACN,MAAM;CACR;AACF,GAEa,UAA4B;CACvC,IAAM,EAAE,YAAS,kBAAe,EAAiB,GAC3C,IAAW,EAAY,GACvB,IAAK,EAAM;CAEjB,OACE,kBAAC,OAAD;EACE,cAAY,EAAG,qCAAqC,iCAAiC;EACrF,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,EAAG,EAAI,UAAU,EAAI,aAAa,CAC7B;;IACN,GAbK,EAAI,EAaT;GAER,CAAC;EACC,CAAA;CACD,CAAA;AAET"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Pagination.d.ts","sourceRoot":"","sources":["../../../src/comradecircle/components/Pagination.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"Pagination.d.ts","sourceRoot":"","sources":["../../../src/comradecircle/components/Pagination.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAOH,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,0CAA0C;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,wDAAwD;IACxD,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,UAAU,CAAC,EACzB,IAAI,EACJ,QAAQ,EACR,SAAS,EACT,OAAO,EACP,YAAY,EACZ,SAAS,GACV,EAAE,eAAe,kDA2CjB"}
|
|
@@ -1,50 +1,59 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { useTr as e } from "../hooks/useTr.js";
|
|
2
|
+
import "../hooks/index.js";
|
|
3
|
+
import { cn as t } from "../utils/cn.js";
|
|
4
|
+
import { ChevronLeft as n, ChevronRight as r } from "lucide-react";
|
|
5
|
+
import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
6
|
+
import { Button as o } from "@burdenoff/fe-libs/ui";
|
|
5
7
|
//#region src/comradecircle/components/Pagination.tsx
|
|
6
|
-
function
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
function s({ page: s, pageSize: c, itemCount: l, hasMore: u, onPageChange: d, className: f }) {
|
|
9
|
+
let p = e();
|
|
10
|
+
if (s === 0 && !u) return null;
|
|
11
|
+
let m = l === 0 ? 0 : s * c + 1, h = s * c + l;
|
|
12
|
+
return /* @__PURE__ */ a("div", {
|
|
13
|
+
className: t("mt-4 flex flex-col items-center justify-between gap-3 sm:flex-row", f),
|
|
11
14
|
children: [/* @__PURE__ */ i("p", {
|
|
12
15
|
className: "text-sm text-text-secondary tabular-nums",
|
|
13
16
|
"aria-live": "polite",
|
|
14
|
-
children:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
]
|
|
20
|
-
}), /* @__PURE__ */ i("div", {
|
|
17
|
+
children: p("comradecircle.components.pagination.showing", "Showing {{from}}–{{to}}", {
|
|
18
|
+
from: m,
|
|
19
|
+
to: h
|
|
20
|
+
})
|
|
21
|
+
}), /* @__PURE__ */ a("div", {
|
|
21
22
|
className: "flex items-center gap-2",
|
|
22
23
|
children: [
|
|
23
|
-
/* @__PURE__ */
|
|
24
|
+
/* @__PURE__ */ a(o, {
|
|
24
25
|
variant: "outline",
|
|
25
26
|
size: "sm",
|
|
26
|
-
onClick: () =>
|
|
27
|
-
disabled:
|
|
28
|
-
"aria-label": "Previous page",
|
|
29
|
-
children: [
|
|
27
|
+
onClick: () => d(s - 1),
|
|
28
|
+
disabled: s === 0,
|
|
29
|
+
"aria-label": p("comradecircle.components.pagination.previousAriaLabel", "Previous page"),
|
|
30
|
+
children: [
|
|
31
|
+
/* @__PURE__ */ i(n, { className: "mr-1 h-4 w-4" }),
|
|
32
|
+
" ",
|
|
33
|
+
p("comradecircle.components.pagination.previous", "Previous")
|
|
34
|
+
]
|
|
30
35
|
}),
|
|
31
36
|
/* @__PURE__ */ i("span", {
|
|
32
37
|
className: "min-w-[4.5rem] text-center text-sm text-text-secondary tabular-nums",
|
|
33
|
-
children:
|
|
38
|
+
children: p("comradecircle.components.pagination.page", "Page {{page}}", { page: s + 1 })
|
|
34
39
|
}),
|
|
35
|
-
/* @__PURE__ */
|
|
40
|
+
/* @__PURE__ */ a(o, {
|
|
36
41
|
variant: "outline",
|
|
37
42
|
size: "sm",
|
|
38
|
-
onClick: () =>
|
|
39
|
-
disabled: !
|
|
40
|
-
"aria-label": "Next page",
|
|
41
|
-
children: [
|
|
43
|
+
onClick: () => d(s + 1),
|
|
44
|
+
disabled: !u,
|
|
45
|
+
"aria-label": p("comradecircle.components.pagination.nextAriaLabel", "Next page"),
|
|
46
|
+
children: [
|
|
47
|
+
p("comradecircle.components.pagination.next", "Next"),
|
|
48
|
+
" ",
|
|
49
|
+
/* @__PURE__ */ i(r, { className: "ml-1 h-4 w-4" })
|
|
50
|
+
]
|
|
42
51
|
})
|
|
43
52
|
]
|
|
44
53
|
})]
|
|
45
54
|
});
|
|
46
55
|
}
|
|
47
56
|
//#endregion
|
|
48
|
-
export {
|
|
57
|
+
export { s as Pagination };
|
|
49
58
|
|
|
50
59
|
//# sourceMappingURL=Pagination.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Pagination.js","names":[],"sources":["../../../src/comradecircle/components/Pagination.tsx"],"sourcesContent":["/**\n * Pagination — cursor-aware Prev/Next control for Com* connection lists.\n * @module comradecircle/components\n *\n * The svc list connections return `pageInfo { cursor, hasMore }` and paginate by\n * cursor (offset is a no-op). Pages track a 0-indexed `page` for display and a\n * cursor stack for navigation; this control exposes Prev/Next, disabling Prev on\n * page 0 and Next when the server reports no more rows.\n */\n\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { cn } from '../utils/cn';\n\ninterface PaginationProps {\n page: number;\n pageSize: number;\n /** Number of rows on the current page. */\n itemCount: number;\n /** Server flag: are there more rows after this page? */\n hasMore: boolean;\n onPageChange: (page: number) => void;\n className?: string;\n}\n\nexport function Pagination({\n page,\n pageSize,\n itemCount,\n hasMore,\n onPageChange,\n className,\n}: PaginationProps) {\n // Nothing to paginate: single page that also has no more rows.\n if (page === 0 && !hasMore) return null;\n\n const from = itemCount === 0 ? 0 : page * pageSize + 1;\n const to = page * pageSize + itemCount;\n\n return (\n <div\n className={cn('mt-4 flex flex-col items-center justify-between gap-3 sm:flex-row', className)}\n >\n <p className=\"text-sm text-text-secondary tabular-nums\" aria-live=\"polite\">\n Showing {from}–{to}\n </p>\n <div className=\"flex items-center gap-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => onPageChange(page - 1)}\n disabled={page === 0}\n aria-label
|
|
1
|
+
{"version":3,"file":"Pagination.js","names":[],"sources":["../../../src/comradecircle/components/Pagination.tsx"],"sourcesContent":["/**\n * Pagination — cursor-aware Prev/Next control for Com* connection lists.\n * @module comradecircle/components\n *\n * The svc list connections return `pageInfo { cursor, hasMore }` and paginate by\n * cursor (offset is a no-op). Pages track a 0-indexed `page` for display and a\n * cursor stack for navigation; this control exposes Prev/Next, disabling Prev on\n * page 0 and Next when the server reports no more rows.\n */\n\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { useTr } from '../hooks';\nimport { cn } from '../utils/cn';\n\ninterface PaginationProps {\n page: number;\n pageSize: number;\n /** Number of rows on the current page. */\n itemCount: number;\n /** Server flag: are there more rows after this page? */\n hasMore: boolean;\n onPageChange: (page: number) => void;\n className?: string;\n}\n\nexport function Pagination({\n page,\n pageSize,\n itemCount,\n hasMore,\n onPageChange,\n className,\n}: PaginationProps) {\n const tr = useTr();\n\n // Nothing to paginate: single page that also has no more rows.\n if (page === 0 && !hasMore) return null;\n\n const from = itemCount === 0 ? 0 : page * pageSize + 1;\n const to = page * pageSize + itemCount;\n\n return (\n <div\n className={cn('mt-4 flex flex-col items-center justify-between gap-3 sm:flex-row', className)}\n >\n <p className=\"text-sm text-text-secondary tabular-nums\" aria-live=\"polite\">\n {tr('comradecircle.components.pagination.showing', 'Showing {{from}}–{{to}}', { from, to })}\n </p>\n <div className=\"flex items-center gap-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => onPageChange(page - 1)}\n disabled={page === 0}\n aria-label={tr('comradecircle.components.pagination.previousAriaLabel', 'Previous page')}\n >\n <ChevronLeft className=\"mr-1 h-4 w-4\" />{' '}\n {tr('comradecircle.components.pagination.previous', 'Previous')}\n </Button>\n <span className=\"min-w-[4.5rem] text-center text-sm text-text-secondary tabular-nums\">\n {tr('comradecircle.components.pagination.page', 'Page {{page}}', { page: page + 1 })}\n </span>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => onPageChange(page + 1)}\n disabled={!hasMore}\n aria-label={tr('comradecircle.components.pagination.nextAriaLabel', 'Next page')}\n >\n {tr('comradecircle.components.pagination.next', 'Next')}{' '}\n <ChevronRight className=\"ml-1 h-4 w-4\" />\n </Button>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;AA0BA,SAAgB,EAAW,EACzB,SACA,aACA,cACA,YACA,iBACA,gBACkB;CAClB,IAAM,IAAK,EAAM;CAGjB,IAAI,MAAS,KAAK,CAAC,GAAS,OAAO;CAEnC,IAAM,IAAO,MAAc,IAAI,IAAI,IAAO,IAAW,GAC/C,IAAK,IAAO,IAAW;CAE7B,OACE,kBAAC,OAAD;EACE,WAAW,EAAG,qEAAqE,CAAS;YAD9F,CAGE,kBAAC,KAAD;GAAG,WAAU;GAA2C,aAAU;aAC/D,EAAG,+CAA+C,2BAA2B;IAAE;IAAM;GAAG,CAAC;EACzF,CAAA,GACH,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,GAAD;KACE,SAAQ;KACR,MAAK;KACL,eAAe,EAAa,IAAO,CAAC;KACpC,UAAU,MAAS;KACnB,cAAY,EAAG,yDAAyD,eAAe;eALzF;MAOE,kBAAC,GAAD,EAAa,WAAU,eAAgB,CAAA;MAAE;MACxC,EAAG,gDAAgD,UAAU;KACxD;;IACR,kBAAC,QAAD;KAAM,WAAU;eACb,EAAG,4CAA4C,iBAAiB,EAAE,MAAM,IAAO,EAAE,CAAC;IAC/E,CAAA;IACN,kBAAC,GAAD;KACE,SAAQ;KACR,MAAK;KACL,eAAe,EAAa,IAAO,CAAC;KACpC,UAAU,CAAC;KACX,cAAY,EAAG,qDAAqD,WAAW;eALjF;MAOG,EAAG,4CAA4C,MAAM;MAAG;MACzD,kBAAC,GAAD,EAAc,WAAU,eAAgB,CAAA;KAClC;;GACL;IACF;;AAET"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { useComClosePoll as t, useComVotePoll as n } from "../hooks/useComradeCircleApi.js";
|
|
1
|
+
import { useComClosePoll as e, useComVotePoll as t } from "../hooks/useComradeCircleApi.js";
|
|
3
2
|
import "../hooks/index.js";
|
|
3
|
+
import { cn as n } from "../utils/cn.js";
|
|
4
4
|
import { describeError as r, notify as i } from "../lib/toast.js";
|
|
5
5
|
import { formatNumber as a, formatRelativeTime as o } from "../utils/formatters.js";
|
|
6
6
|
import { StatusBadge as s } from "./StatusBadge.js";
|
|
@@ -11,7 +11,7 @@ import { jsx as m, jsxs as h } from "react/jsx-runtime";
|
|
|
11
11
|
import { Button as g, GlassCard as _ } from "@burdenoff/fe-libs/ui";
|
|
12
12
|
//#region src/comradecircle/components/PollCard.tsx
|
|
13
13
|
function v({ poll: v, canManage: y = !1 }) {
|
|
14
|
-
let b =
|
|
14
|
+
let b = t(), x = e(), [S, C] = u(/* @__PURE__ */ new Set()), w = v.options.reduce((e, t) => e + t.voteCount, 0), T = v.status === "CLOSED", E = l(() => v.options.reduce((e, t) => Math.max(e, t.voteCount), 0), [v.options]), D = S.size > 0, O = async (e) => {
|
|
15
15
|
if (!T) try {
|
|
16
16
|
await b.mutateAsync({
|
|
17
17
|
pollId: v.id,
|
|
@@ -41,14 +41,14 @@ function v({ poll: v, canManage: y = !1 }) {
|
|
|
41
41
|
}),
|
|
42
42
|
/* @__PURE__ */ m("div", {
|
|
43
43
|
className: "mt-4 flex flex-col gap-2.5",
|
|
44
|
-
children: [...v.options].sort((e, t) => e.position - t.position).map((
|
|
45
|
-
let
|
|
44
|
+
children: [...v.options].sort((e, t) => e.position - t.position).map((e) => {
|
|
45
|
+
let t = w > 0 ? e.voteCount / w * 100 : 0, r = w > 0 && e.voteCount === E, i = S.has(e.id);
|
|
46
46
|
return /* @__PURE__ */ h("button", {
|
|
47
47
|
type: "button",
|
|
48
|
-
onClick: () => O(
|
|
48
|
+
onClick: () => O(e.id),
|
|
49
49
|
disabled: T || b.isPending,
|
|
50
50
|
"aria-pressed": i,
|
|
51
|
-
className:
|
|
51
|
+
className: n("group w-full rounded-xl border px-3 py-2.5 text-left transition-all duration-200", i ? "border-accent bg-[var(--color-accent-soft)]/40" : "border-border-seam", !T && !i && "hover:-translate-y-px hover:border-accent hover:bg-bg-sunken/60", T && "cursor-default"),
|
|
52
52
|
children: [/* @__PURE__ */ h("div", {
|
|
53
53
|
className: "flex items-center justify-between gap-2",
|
|
54
54
|
children: [/* @__PURE__ */ h("span", {
|
|
@@ -59,8 +59,8 @@ function v({ poll: v, canManage: y = !1 }) {
|
|
|
59
59
|
"aria-hidden": "true"
|
|
60
60
|
}),
|
|
61
61
|
/* @__PURE__ */ m("span", {
|
|
62
|
-
className:
|
|
63
|
-
children:
|
|
62
|
+
className: n("truncate text-sm", r ? "font-semibold text-text-primary" : "font-medium text-text-secondary"),
|
|
63
|
+
children: e.label
|
|
64
64
|
}),
|
|
65
65
|
r && w > 1 && /* @__PURE__ */ m(f, {
|
|
66
66
|
className: "h-3.5 w-3.5 shrink-0 text-status-warning-text",
|
|
@@ -70,18 +70,18 @@ function v({ poll: v, canManage: y = !1 }) {
|
|
|
70
70
|
}), /* @__PURE__ */ h("span", {
|
|
71
71
|
className: "shrink-0 text-xs tabular-nums text-text-secondary",
|
|
72
72
|
children: [
|
|
73
|
-
a(
|
|
73
|
+
a(e.voteCount),
|
|
74
74
|
" · ",
|
|
75
|
-
Math.round(
|
|
75
|
+
Math.round(t),
|
|
76
76
|
"%"
|
|
77
77
|
]
|
|
78
78
|
})]
|
|
79
79
|
}), /* @__PURE__ */ m(c, {
|
|
80
|
-
value:
|
|
80
|
+
value: t,
|
|
81
81
|
className: "mt-2",
|
|
82
82
|
barClassName: r ? "bg-gradient-to-r from-accent to-[var(--color-accent-soft)]" : "bg-accent/40"
|
|
83
83
|
})]
|
|
84
|
-
},
|
|
84
|
+
}, e.id);
|
|
85
85
|
})
|
|
86
86
|
}),
|
|
87
87
|
/* @__PURE__ */ h("div", {
|
|
@@ -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;IAC1B,yFAAyF;IACzF,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,wBAAgB,QAAQ,CAAC,EAAE,IAAI,EAAE,eAAuB,EAAE,cAAsB,EAAE,EAAE,aAAa,
|
|
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,2CAiNhG"}
|