@burdenoff/microfe-comradecircle 2026.704.2 → 2026.704.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 (41) hide show
  1. package/dist/comradecircle/components/Avatar.js +40 -17
  2. package/dist/comradecircle/components/Avatar.js.map +1 -1
  3. package/dist/comradecircle/components/AvatarUploadField.js +25 -14
  4. package/dist/comradecircle/components/AvatarUploadField.js.map +1 -1
  5. package/dist/comradecircle/components/CircleCard.js +54 -52
  6. package/dist/comradecircle/components/CircleCard.js.map +1 -1
  7. package/dist/comradecircle/components/CommentThread.js +80 -64
  8. package/dist/comradecircle/components/CommentThread.js.map +1 -1
  9. package/dist/comradecircle/components/EventCard.js +84 -58
  10. package/dist/comradecircle/components/EventCard.js.map +1 -1
  11. package/dist/comradecircle/components/MemberIdentity.js +2 -1
  12. package/dist/comradecircle/components/MemberIdentity.js.map +1 -1
  13. package/dist/comradecircle/components/PollCard.js +65 -44
  14. package/dist/comradecircle/components/PollCard.js.map +1 -1
  15. package/dist/comradecircle/components/PostCard.js +1 -1
  16. package/dist/comradecircle/components/PostCard.js.map +1 -1
  17. package/dist/comradecircle/components/ReactionBar.js +1 -1
  18. package/dist/comradecircle/components/ReactionBar.js.map +1 -1
  19. package/dist/comradecircle/components/StateViews.js +1 -16
  20. package/dist/comradecircle/components/StateViews.js.map +1 -1
  21. package/dist/comradecircle/components/StatusBadge.js +1 -1
  22. package/dist/comradecircle/components/StatusBadge.js.map +1 -1
  23. package/dist/comradecircle/hooks/useComradeCircleApi.js +1 -1
  24. package/dist/comradecircle/hooks/useComradeCircleApi.js.map +1 -1
  25. package/dist/comradecircle/pages/FeedPage.js +79 -33
  26. package/dist/comradecircle/pages/FeedPage.js.map +1 -1
  27. package/dist/comradecircle/pages/circles/CircleDetailPage.js +354 -243
  28. package/dist/comradecircle/pages/circles/CircleDetailPage.js.map +1 -1
  29. package/dist/comradecircle/pages/circles/CirclesPage.js +97 -47
  30. package/dist/comradecircle/pages/circles/CirclesPage.js.map +1 -1
  31. package/dist/comradecircle/pages/events/EventDetailPage.js +193 -126
  32. package/dist/comradecircle/pages/events/EventDetailPage.js.map +1 -1
  33. package/dist/comradecircle/pages/events/EventsPage.js +74 -34
  34. package/dist/comradecircle/pages/events/EventsPage.js.map +1 -1
  35. package/dist/comradecircle/pages/members/MemberProfilePage.js +154 -82
  36. package/dist/comradecircle/pages/members/MemberProfilePage.js.map +1 -1
  37. package/dist/comradecircle/pages/members/MembersPage.js +140 -71
  38. package/dist/comradecircle/pages/members/MembersPage.js.map +1 -1
  39. package/dist/comradecircle/pages/profile/MyProfilePage.js +298 -202
  40. package/dist/comradecircle/pages/profile/MyProfilePage.js.map +1 -1
  41. package/package.json +1 -1
@@ -4,8 +4,9 @@ import "../../context/index.js";
4
4
  import { useComEvents as n } from "../../hooks/useComradeCircleApi.js";
5
5
  import { useCursorPager as r } from "../../hooks/useCursorPager.js";
6
6
  import "../../hooks/index.js";
7
- import { EmptyState as i } from "../../components/EmptyState.js";
8
- import { ErrorView as a, LoadingView as o } from "../../components/StateViews.js";
7
+ import { formatNumber as i } from "../../utils/formatters.js";
8
+ import { EmptyState as a } from "../../components/EmptyState.js";
9
+ import { ErrorView as o } from "../../components/StateViews.js";
9
10
  import { Pagination as s } from "../../components/Pagination.js";
10
11
  import { EventCard as c } from "../../components/EventCard.js";
11
12
  import { CreateEventDialog as l } from "../../components/CreateEventDialog.js";
@@ -13,9 +14,9 @@ import { FilterTabs as u } from "../../components/FilterTabs.js";
13
14
  import { useState as d } from "react";
14
15
  import { CalendarDays as f, Plus as p } from "lucide-react";
15
16
  import { jsx as m, jsxs as h } from "react/jsx-runtime";
16
- import { Button as g } from "@burdenoff/fe-libs/ui";
17
+ import { Button as g, GlassCard as _, Skeleton as v } from "@burdenoff/fe-libs/ui";
17
18
  //#region src/comradecircle/pages/events/EventsPage.tsx
18
- var _ = 12, v = [
19
+ var y = 12, b = [
19
20
  {
20
21
  value: "ALL",
21
22
  label: "All"
@@ -37,66 +38,105 @@ var _ = 12, v = [
37
38
  label: "Cancelled"
38
39
  }
39
40
  ];
40
- function y() {
41
- let { navigateTo: y } = e(), b = r(), [x, S] = d("ALL"), [C, w] = d(!1), { data: T, isLoading: E, isError: D, refetch: O } = n({
41
+ function x() {
42
+ return /* @__PURE__ */ h(_, {
43
+ treatment: "plain",
44
+ className: "flex flex-col p-5",
45
+ "aria-hidden": "true",
46
+ children: [
47
+ /* @__PURE__ */ h("div", {
48
+ className: "flex items-start justify-between gap-3",
49
+ children: [/* @__PURE__ */ m(v, { className: "h-5 w-20 rounded-full" }), /* @__PURE__ */ m(v, { className: "h-4 w-14" })]
50
+ }),
51
+ /* @__PURE__ */ m(v, { className: "mt-2 h-5 w-3/5" }),
52
+ /* @__PURE__ */ m(v, { className: "mt-2 h-3.5 w-full" }),
53
+ /* @__PURE__ */ m(v, { className: "mt-1.5 h-3.5 w-4/5" }),
54
+ /* @__PURE__ */ h("div", {
55
+ className: "mt-3 flex flex-col gap-2",
56
+ children: [/* @__PURE__ */ m(v, { className: "h-4 w-40" }), /* @__PURE__ */ m(v, { className: "h-4 w-32" })]
57
+ }),
58
+ /* @__PURE__ */ m(v, { className: "mt-3 h-1 w-full rounded-full" }),
59
+ /* @__PURE__ */ h("div", {
60
+ className: "mt-4 flex items-center justify-end gap-2 border-t border-border-seam pt-3",
61
+ children: [/* @__PURE__ */ m(v, { className: "h-8 w-20 rounded-md" }), /* @__PURE__ */ m(v, { className: "h-8 w-24 rounded-md" })]
62
+ })
63
+ ]
64
+ });
65
+ }
66
+ function S() {
67
+ return /* @__PURE__ */ m("div", {
68
+ className: "grid gap-4 md:grid-cols-2",
69
+ "aria-hidden": "true",
70
+ children: Array.from({ length: 4 }, (e, t) => /* @__PURE__ */ m(x, {}, t))
71
+ });
72
+ }
73
+ function C() {
74
+ let { navigateTo: _ } = e(), v = r(), [x, C] = d("ALL"), [w, T] = d(!1), { data: E, isLoading: D, isError: O, refetch: k } = n({
42
75
  status: x === "ALL" ? void 0 : x,
43
76
  pagination: {
44
- limit: _,
45
- cursor: b.cursor
77
+ limit: y,
78
+ cursor: v.cursor
46
79
  }
47
- }), k = T?.items ?? [];
80
+ }), A = E?.items ?? [], j = E?.pageInfo.hasMore ?? !1, M = (e) => {
81
+ C(e), v.reset();
82
+ }, N = x === "ALL" ? "" : ` ${x.toLowerCase()}`, P = `${i(A.length)}${N} ${A.length === 1 ? "event" : "events"}` + (v.page > 0 ? ` · page ${v.page + 1}` : j ? " · more available" : "");
48
83
  return /* @__PURE__ */ h(t, {
49
84
  title: "Events",
50
85
  description: "Upcoming and past gatherings across all the circles you belong to.",
51
86
  actions: /* @__PURE__ */ h(g, {
52
- onClick: () => w(!0),
87
+ onClick: () => T(!0),
53
88
  children: [/* @__PURE__ */ m(p, { className: "mr-1.5 h-4 w-4" }), " New event"]
54
89
  }),
55
90
  children: [
56
91
  /* @__PURE__ */ m(u, {
57
- options: v,
92
+ options: b,
58
93
  value: x,
59
- onChange: (e) => {
60
- S(e), b.reset();
61
- },
94
+ onChange: M,
62
95
  className: "mb-5"
63
96
  }),
64
- E ? /* @__PURE__ */ m(o, { label: "Loading events…" }) : D ? /* @__PURE__ */ m(a, {
97
+ D ? /* @__PURE__ */ m(S, {}) : O ? /* @__PURE__ */ m(o, {
65
98
  message: "We couldn't load events.",
66
- onRetry: () => O()
67
- }) : k.length === 0 && b.page === 0 ? /* @__PURE__ */ m(i, {
99
+ onRetry: () => k()
100
+ }) : A.length === 0 && v.page === 0 ? /* @__PURE__ */ m(a, {
68
101
  illustration: "empty-data",
69
102
  icon: /* @__PURE__ */ m(f, { className: "h-10 w-10" }),
70
103
  title: x === "ALL" ? "No events yet" : "No events match this filter",
71
104
  description: x === "ALL" ? "Schedule a gathering for one of your circles — online, in person, or hybrid." : "Try a different status, or schedule a new gathering for one of your circles.",
72
105
  action: /* @__PURE__ */ h(g, {
73
- onClick: () => w(!0),
106
+ onClick: () => T(!0),
74
107
  children: [/* @__PURE__ */ m(p, { className: "mr-1.5 h-4 w-4" }), " New event"]
75
108
  })
76
109
  }) : /* @__PURE__ */ h("div", {
77
110
  className: "flex flex-col gap-4",
78
- children: [/* @__PURE__ */ m("div", {
79
- className: "grid gap-4 md:grid-cols-2",
80
- children: k.map((e) => /* @__PURE__ */ m(c, {
81
- event: e,
82
- onOpen: () => y("events/" + e.id)
83
- }, e.id))
84
- }), /* @__PURE__ */ m(s, {
85
- page: b.page,
86
- pageSize: _,
87
- itemCount: k.length,
88
- hasMore: T?.pageInfo.hasMore ?? !1,
89
- onPageChange: (e) => b.onPageChange(e, T?.pageInfo.cursor)
90
- })]
111
+ children: [
112
+ /* @__PURE__ */ m("p", {
113
+ className: "text-xs font-medium text-text-tertiary",
114
+ children: P
115
+ }),
116
+ /* @__PURE__ */ m("div", {
117
+ className: "grid gap-4 md:grid-cols-2",
118
+ children: A.map((e) => /* @__PURE__ */ m(c, {
119
+ event: e,
120
+ onOpen: () => _("events/" + e.id)
121
+ }, e.id))
122
+ }),
123
+ /* @__PURE__ */ m(s, {
124
+ page: v.page,
125
+ pageSize: y,
126
+ itemCount: A.length,
127
+ hasMore: E?.pageInfo.hasMore ?? !1,
128
+ onPageChange: (e) => v.onPageChange(e, E?.pageInfo.cursor)
129
+ })
130
+ ]
91
131
  }),
92
132
  /* @__PURE__ */ m(l, {
93
- open: C,
94
- onOpenChange: w
133
+ open: w,
134
+ onOpenChange: T
95
135
  })
96
136
  ]
97
137
  });
98
138
  }
99
139
  //#endregion
100
- export { y as EventsPage };
140
+ export { C as EventsPage };
101
141
 
102
142
  //# sourceMappingURL=EventsPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"EventsPage.js","names":[],"sources":["../../../../src/comradecircle/pages/events/EventsPage.tsx"],"sourcesContent":["/**\n * EventsPage — every event across the circles the member belongs to.\n * @module comradecircle/pages/events\n *\n * Reads `comListEvents` (all circles, newest-scheduled first) with a lifecycle\n * status filter (scheduled → live → completed → cancelled). Scheduling a new\n * event opens the shared {@link CreateEventDialog} without a fixed circle, so it\n * shows its own active-circle picker.\n */\n\nimport { useState } from 'react';\nimport { CalendarDays, Plus } from 'lucide-react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { FilterTabs, type FilterOption } from '../../components/FilterTabs';\nimport { EventCard } from '../../components/EventCard';\nimport { CreateEventDialog } from '../../components/CreateEventDialog';\nimport { EmptyState } from '../../components/EmptyState';\nimport { LoadingView, ErrorView } from '../../components/StateViews';\nimport { Pagination } from '../../components/Pagination';\nimport { useComEvents, useCursorPager } from '../../hooks';\nimport { useComradeCircle } from '../../context';\nimport type { ComEventStatus } from '../../types';\n\nconst PAGE_SIZE = 12;\n\ntype StatusFilter = 'ALL' | ComEventStatus;\n\nconst STATUS_FILTERS: FilterOption<StatusFilter>[] = [\n { value: 'ALL', label: 'All' },\n { value: 'SCHEDULED', label: 'Scheduled' },\n { value: 'LIVE', label: 'Live' },\n { value: 'COMPLETED', label: 'Completed' },\n { value: 'CANCELLED', label: 'Cancelled' },\n];\n\nexport function EventsPage() {\n const { navigateTo } = useComradeCircle();\n const pager = useCursorPager();\n const [status, setStatus] = useState<StatusFilter>('ALL');\n const [createOpen, setCreateOpen] = useState(false);\n\n const { data, isLoading, isError, refetch } = useComEvents({\n status: status === 'ALL' ? undefined : status,\n pagination: { limit: PAGE_SIZE, cursor: pager.cursor },\n });\n\n const events = data?.items ?? [];\n\n const changeStatus = (next: StatusFilter) => {\n setStatus(next);\n pager.reset();\n };\n\n return (\n <PageLayout\n title=\"Events\"\n description=\"Upcoming and past gatherings across all the circles you belong to.\"\n actions={\n <Button onClick={() => setCreateOpen(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" /> New event\n </Button>\n }\n >\n <FilterTabs\n options={STATUS_FILTERS}\n value={status}\n onChange={changeStatus}\n className=\"mb-5\"\n />\n\n {isLoading ? (\n <LoadingView label=\"Loading events…\" />\n ) : isError ? (\n <ErrorView message=\"We couldn't load events.\" onRetry={() => refetch()} />\n ) : events.length === 0 && pager.page === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<CalendarDays className=\"h-10 w-10\" />}\n title={status === 'ALL' ? 'No events yet' : 'No events match this filter'}\n description={\n status === 'ALL'\n ? 'Schedule a gathering for one of your circles — online, in person, or hybrid.'\n : 'Try a different status, or schedule a new gathering for one of your circles.'\n }\n action={\n <Button onClick={() => setCreateOpen(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" /> New event\n </Button>\n }\n />\n ) : (\n <div className=\"flex flex-col gap-4\">\n <div className=\"grid gap-4 md:grid-cols-2\">\n {events.map((event) => (\n <EventCard\n key={event.id}\n event={event}\n onOpen={() => navigateTo('events/' + event.id)}\n />\n ))}\n </div>\n <Pagination\n page={pager.page}\n pageSize={PAGE_SIZE}\n itemCount={events.length}\n hasMore={data?.pageInfo.hasMore ?? false}\n onPageChange={(target) => pager.onPageChange(target, data?.pageInfo.cursor)}\n />\n </div>\n )}\n\n <CreateEventDialog open={createOpen} onOpenChange={setCreateOpen} />\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAwBA,IAAM,IAAY,IAIZ,IAA+C;CACnD;EAAE,OAAO;EAAO,OAAO;EAAO;CAC9B;EAAE,OAAO;EAAa,OAAO;EAAa;CAC1C;EAAE,OAAO;EAAQ,OAAO;EAAQ;CAChC;EAAE,OAAO;EAAa,OAAO;EAAa;CAC1C;EAAE,OAAO;EAAa,OAAO;EAAa;CAC3C;AAED,SAAgB,IAAa;CAC3B,IAAM,EAAE,kBAAe,GAAkB,EACnC,IAAQ,GAAgB,EACxB,CAAC,GAAQ,KAAa,EAAuB,MAAM,EACnD,CAAC,GAAY,KAAiB,EAAS,GAAM,EAE7C,EAAE,SAAM,cAAW,YAAS,eAAY,EAAa;EACzD,QAAQ,MAAW,QAAQ,KAAA,IAAY;EACvC,YAAY;GAAE,OAAO;GAAW,QAAQ,EAAM;GAAQ;EACvD,CAAC,EAEI,IAAS,GAAM,SAAS,EAAE;AAOhC,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SACE,kBAAC,GAAD;GAAQ,eAAe,EAAc,GAAK;aAA1C,CACE,kBAAC,GAAD,EAAM,WAAU,kBAAmB,CAAA,EAAA,aAC5B;;YANb;GASE,kBAAC,GAAD;IACE,SAAS;IACT,OAAO;IACP,WAlBgB,MAAuB;AAE3C,KADA,EAAU,EAAK,EACf,EAAM,OAAO;;IAiBT,WAAU;IACV,CAAA;GAED,IACC,kBAAC,GAAD,EAAa,OAAM,mBAAoB,CAAA,GACrC,IACF,kBAAC,GAAD;IAAW,SAAQ;IAA2B,eAAe,GAAS;IAAI,CAAA,GACxE,EAAO,WAAW,KAAK,EAAM,SAAS,IACxC,kBAAC,GAAD;IACE,cAAa;IACb,MAAM,kBAAC,GAAD,EAAc,WAAU,aAAc,CAAA;IAC5C,OAAO,MAAW,QAAQ,kBAAkB;IAC5C,aACE,MAAW,QACP,iFACA;IAEN,QACE,kBAAC,GAAD;KAAQ,eAAe,EAAc,GAAK;eAA1C,CACE,kBAAC,GAAD,EAAM,WAAU,kBAAmB,CAAA,EAAA,aAC5B;;IAEX,CAAA,GAEF,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAO,KAAK,MACX,kBAAC,GAAD;MAES;MACP,cAAc,EAAW,YAAY,EAAM,GAAG;MAC9C,EAHK,EAAM,GAGX,CACF;KACE,CAAA,EACN,kBAAC,GAAD;KACE,MAAM,EAAM;KACZ,UAAU;KACV,WAAW,EAAO;KAClB,SAAS,GAAM,SAAS,WAAW;KACnC,eAAe,MAAW,EAAM,aAAa,GAAQ,GAAM,SAAS,OAAO;KAC3E,CAAA,CACE;;GAGR,kBAAC,GAAD;IAAmB,MAAM;IAAY,cAAc;IAAiB,CAAA;GACzD"}
1
+ {"version":3,"file":"EventsPage.js","names":[],"sources":["../../../../src/comradecircle/pages/events/EventsPage.tsx"],"sourcesContent":["/**\n * EventsPage — every event across the circles the member belongs to.\n * @module comradecircle/pages/events\n *\n * Reads `comListEvents` (all circles, newest-scheduled first) with a lifecycle\n * status filter (scheduled → live → completed → cancelled). Scheduling a new\n * event opens the shared {@link CreateEventDialog} without a fixed circle, so it\n * shows its own active-circle picker.\n */\n\nimport { useState } from 'react';\nimport { CalendarDays, Plus } from 'lucide-react';\nimport { Button, GlassCard, Skeleton } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { FilterTabs, type FilterOption } from '../../components/FilterTabs';\nimport { EventCard } from '../../components/EventCard';\nimport { CreateEventDialog } from '../../components/CreateEventDialog';\nimport { EmptyState } from '../../components/EmptyState';\nimport { ErrorView } from '../../components/StateViews';\nimport { Pagination } from '../../components/Pagination';\nimport { useComEvents, useCursorPager } from '../../hooks';\nimport { useComradeCircle } from '../../context';\nimport { formatNumber } from '../../utils/formatters';\nimport type { ComEventStatus } from '../../types';\n\nconst PAGE_SIZE = 12;\n\ntype StatusFilter = 'ALL' | ComEventStatus;\n\nconst STATUS_FILTERS: FilterOption<StatusFilter>[] = [\n { value: 'ALL', label: 'All' },\n { value: 'SCHEDULED', label: 'Scheduled' },\n { value: 'LIVE', label: 'Live' },\n { value: 'COMPLETED', label: 'Completed' },\n { value: 'CANCELLED', label: 'Cancelled' },\n];\n\n/** One placeholder tile that mirrors {@link EventCard}'s glass + section rhythm. */\nfunction EventCardSkeleton() {\n return (\n <GlassCard treatment=\"plain\" className=\"flex flex-col p-5\" aria-hidden=\"true\">\n <div className=\"flex items-start justify-between gap-3\">\n <Skeleton className=\"h-5 w-20 rounded-full\" />\n <Skeleton className=\"h-4 w-14\" />\n </div>\n <Skeleton className=\"mt-2 h-5 w-3/5\" />\n <Skeleton className=\"mt-2 h-3.5 w-full\" />\n <Skeleton className=\"mt-1.5 h-3.5 w-4/5\" />\n <div className=\"mt-3 flex flex-col gap-2\">\n <Skeleton className=\"h-4 w-40\" />\n <Skeleton className=\"h-4 w-32\" />\n </div>\n <Skeleton className=\"mt-3 h-1 w-full rounded-full\" />\n <div className=\"mt-4 flex items-center justify-end gap-2 border-t border-border-seam pt-3\">\n <Skeleton className=\"h-8 w-20 rounded-md\" />\n <Skeleton className=\"h-8 w-24 rounded-md\" />\n </div>\n </GlassCard>\n );\n}\n\n/** Skeleton grid mirroring the live `md:grid-cols-2` EventCard layout. */\nfunction EventsSkeletonGrid() {\n return (\n <div className=\"grid gap-4 md:grid-cols-2\" aria-hidden=\"true\">\n {Array.from({ length: 4 }, (_, i) => (\n <EventCardSkeleton key={i} />\n ))}\n </div>\n );\n}\n\nexport function EventsPage() {\n const { navigateTo } = useComradeCircle();\n const pager = useCursorPager();\n const [status, setStatus] = useState<StatusFilter>('ALL');\n const [createOpen, setCreateOpen] = useState(false);\n\n const { data, isLoading, isError, refetch } = useComEvents({\n status: status === 'ALL' ? undefined : status,\n pagination: { limit: PAGE_SIZE, cursor: pager.cursor },\n });\n\n const events = data?.items ?? [];\n const hasMore = data?.pageInfo.hasMore ?? false;\n\n const changeStatus = (next: StatusFilter) => {\n setStatus(next);\n pager.reset();\n };\n\n const filterLabel = status === 'ALL' ? '' : ` ${status.toLowerCase()}`;\n const resultCaption =\n `${formatNumber(events.length)}${filterLabel} ` +\n `${events.length === 1 ? 'event' : 'events'}` +\n (pager.page > 0 ? ` · page ${pager.page + 1}` : hasMore ? ' · more available' : '');\n\n return (\n <PageLayout\n title=\"Events\"\n description=\"Upcoming and past gatherings across all the circles you belong to.\"\n actions={\n <Button onClick={() => setCreateOpen(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" /> New event\n </Button>\n }\n >\n <FilterTabs\n options={STATUS_FILTERS}\n value={status}\n onChange={changeStatus}\n className=\"mb-5\"\n />\n\n {isLoading ? (\n <EventsSkeletonGrid />\n ) : isError ? (\n <ErrorView message=\"We couldn't load events.\" onRetry={() => refetch()} />\n ) : events.length === 0 && pager.page === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<CalendarDays className=\"h-10 w-10\" />}\n title={status === 'ALL' ? 'No events yet' : 'No events match this filter'}\n description={\n status === 'ALL'\n ? 'Schedule a gathering for one of your circles — online, in person, or hybrid.'\n : 'Try a different status, or schedule a new gathering for one of your circles.'\n }\n action={\n <Button onClick={() => setCreateOpen(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" /> New event\n </Button>\n }\n />\n ) : (\n <div className=\"flex flex-col gap-4\">\n <p className=\"text-xs font-medium text-text-tertiary\">{resultCaption}</p>\n <div className=\"grid gap-4 md:grid-cols-2\">\n {events.map((event) => (\n <EventCard\n key={event.id}\n event={event}\n onOpen={() => navigateTo('events/' + event.id)}\n />\n ))}\n </div>\n <Pagination\n page={pager.page}\n pageSize={PAGE_SIZE}\n itemCount={events.length}\n hasMore={data?.pageInfo.hasMore ?? false}\n onPageChange={(target) => pager.onPageChange(target, data?.pageInfo.cursor)}\n />\n </div>\n )}\n\n <CreateEventDialog open={createOpen} onOpenChange={setCreateOpen} />\n </PageLayout>\n );\n}\n"],"mappings":"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"}
@@ -1,138 +1,210 @@
1
1
  import { useComradeCircle as e } from "../../context/ComradeCircleContext.js";
2
- import { PageLayout as t } from "../../components/PageLayout.js";
2
+ import { cn as t } from "../../utils/cn.js";
3
+ import { PageLayout as n } from "../../components/PageLayout.js";
3
4
  import "../../context/index.js";
4
- import { useComFollow as n, useComMyFollows as r, useComProfile as i, useComUnfollow as a } from "../../hooks/useComradeCircleApi.js";
5
+ import { useComFollow as r, useComMyFollows as i, useComProfile as a, useComUnfollow as o } from "../../hooks/useComradeCircleApi.js";
5
6
  import "../../hooks/index.js";
6
- import { Avatar as o } from "../../components/Avatar.js";
7
- import { describeError as s, notify as c } from "../../lib/toast.js";
8
- import { EmptyState as l } from "../../components/EmptyState.js";
9
- import { ErrorView as u, LoadingView as d, Section as f } from "../../components/StateViews.js";
10
- import { StatusBadge as p } from "../../components/StatusBadge.js";
11
- import { ArrowLeft as m, Pencil as h, UserCheck as g, UserPlus as _, UserX as v } from "lucide-react";
7
+ import { Avatar as s } from "../../components/Avatar.js";
8
+ import { describeError as c, notify as l } from "../../lib/toast.js";
9
+ import { EmptyState as u } from "../../components/EmptyState.js";
10
+ import { ErrorView as d } from "../../components/StateViews.js";
11
+ import { StatusBadge as f } from "../../components/StatusBadge.js";
12
+ import { ArrowLeft as p, Pencil as m, UserCheck as h, UserMinus as g, UserPlus as _, UserX as v } from "lucide-react";
12
13
  import { useParams as y } from "react-router-dom";
13
14
  import { jsx as b, jsxs as x } from "react/jsx-runtime";
14
- import { Button as S } from "@burdenoff/fe-libs/ui";
15
+ import { AuroraBackground as S, Button as C, GlassCard as w, GradientText as T, Skeleton as E } from "@burdenoff/fe-libs/ui";
15
16
  //#region src/comradecircle/pages/members/MemberProfilePage.tsx
16
- function C({ items: e }) {
17
- return /* @__PURE__ */ b("div", {
18
- className: "flex flex-wrap gap-1.5",
19
- children: e.map((e) => /* @__PURE__ */ b("span", {
20
- className: "rounded-full bg-bg-sunken px-2.5 py-0.5 text-xs font-medium text-text-secondary",
17
+ function D({ items: e, variant: n }) {
18
+ return /* @__PURE__ */ b("ul", {
19
+ className: "flex flex-wrap gap-2",
20
+ children: e.map((e) => /* @__PURE__ */ b("li", {
21
+ className: t("rounded-full px-3 py-1 text-xs font-medium motion-safe:transition-transform motion-safe:duration-150 motion-safe:hover:-translate-y-0.5", n === "interest" ? "bg-[var(--color-accent-soft)] text-accent" : "border border-border-seam text-text-primary hover:border-border-strong"),
21
22
  children: e
22
23
  }, e))
23
24
  });
24
25
  }
25
- function w() {
26
- let { memberId: w } = y(), { navigateTo: T, currentUser: E } = e(), { data: D, isLoading: O, isError: k, refetch: A } = i(w), j = r("MEMBER"), M = n(), N = a(), P = /* @__PURE__ */ x(S, {
26
+ function O() {
27
+ return /* @__PURE__ */ x("div", {
28
+ className: "mx-auto flex max-w-2xl flex-col gap-6",
29
+ children: [/* @__PURE__ */ x(w, {
30
+ treatment: "plain",
31
+ className: "overflow-hidden p-0",
32
+ children: [/* @__PURE__ */ b(E, { className: "h-24 w-full rounded-none sm:h-28" }), /* @__PURE__ */ x("div", {
33
+ className: "px-5 pb-5 sm:px-6 sm:pb-6",
34
+ children: [/* @__PURE__ */ x("div", {
35
+ className: "flex flex-col items-center gap-4 sm:flex-row sm:items-end",
36
+ children: [/* @__PURE__ */ b(E, { className: "-mt-16 h-28 w-28 rounded-full sm:-mt-20" }), /* @__PURE__ */ x("div", {
37
+ className: "w-full space-y-2 pb-1 text-center sm:text-left",
38
+ children: [
39
+ /* @__PURE__ */ b(E, { className: "mx-auto h-7 w-44 sm:mx-0" }),
40
+ /* @__PURE__ */ b(E, { className: "mx-auto h-4 w-56 sm:mx-0" }),
41
+ /* @__PURE__ */ b(E, { className: "mx-auto h-5 w-20 rounded-full sm:mx-0" })
42
+ ]
43
+ })]
44
+ }), /* @__PURE__ */ x("div", {
45
+ className: "mt-5 space-y-2",
46
+ children: [/* @__PURE__ */ b(E, { className: "h-4 w-full" }), /* @__PURE__ */ b(E, { className: "h-4 w-3/4" })]
47
+ })]
48
+ })]
49
+ }), /* @__PURE__ */ b(w, {
50
+ treatment: "plain",
51
+ className: "flex flex-col gap-6 p-5 sm:p-6",
52
+ children: [0, 1].map((e) => /* @__PURE__ */ x("div", {
53
+ className: "space-y-3",
54
+ children: [/* @__PURE__ */ b(E, { className: "h-4 w-24" }), /* @__PURE__ */ b("div", {
55
+ className: "flex flex-wrap gap-2",
56
+ children: [
57
+ 0,
58
+ 1,
59
+ 2,
60
+ 3
61
+ ].map((e) => /* @__PURE__ */ b(E, { className: "h-6 w-20 rounded-full" }, e))
62
+ })]
63
+ }, e))
64
+ })]
65
+ });
66
+ }
67
+ function k() {
68
+ let { memberId: t } = y(), { navigateTo: E, currentUser: k } = e(), { data: A, isLoading: j, isError: M, refetch: N } = a(t), P = i("MEMBER"), F = r(), I = o(), L = /* @__PURE__ */ x(C, {
27
69
  variant: "ghost",
28
70
  size: "sm",
29
- onClick: () => T("members"),
30
- children: [/* @__PURE__ */ b(m, { className: "mr-1.5 h-4 w-4" }), " Back"]
71
+ onClick: () => E("members"),
72
+ children: [/* @__PURE__ */ b(p, { className: "mr-1.5 h-4 w-4" }), " Back"]
31
73
  });
32
- if (O) return /* @__PURE__ */ b(t, {
74
+ if (j) return /* @__PURE__ */ b(n, {
33
75
  title: "Profile",
34
- actions: P,
35
- children: /* @__PURE__ */ b(d, { label: "Loading profile…" })
76
+ actions: L,
77
+ children: /* @__PURE__ */ b(O, {})
36
78
  });
37
- if (k) return /* @__PURE__ */ b(t, {
79
+ if (M) return /* @__PURE__ */ b(n, {
38
80
  title: "Profile",
39
- actions: P,
40
- children: /* @__PURE__ */ b(u, {
81
+ actions: L,
82
+ children: /* @__PURE__ */ b(d, {
41
83
  message: "We couldn't load this member's profile.",
42
- onRetry: () => A()
84
+ onRetry: () => N()
43
85
  })
44
86
  });
45
- if (!D) return /* @__PURE__ */ b(t, {
87
+ if (!A) return /* @__PURE__ */ b(n, {
46
88
  title: "Profile",
47
- actions: P,
48
- children: /* @__PURE__ */ b(l, {
89
+ actions: L,
90
+ children: /* @__PURE__ */ b(u, {
49
91
  icon: /* @__PURE__ */ b(v, { className: "h-10 w-10" }),
50
92
  title: "No profile",
51
93
  description: "This member hasn't set up a ComradeCircle profile yet."
52
94
  })
53
95
  });
54
- let F = !!(w && E?.id === w), I = (j.data ?? []).some((e) => e.targetId === w && e.targetType === "MEMBER"), L = M.isPending || N.isPending, R = async () => {
55
- if (w) try {
56
- I ? (await N.mutateAsync({
57
- targetId: w,
96
+ let R = !!(t && k?.id === t), z = (P.data ?? []).some((e) => e.targetId === t && e.targetType === "MEMBER"), B = F.isPending || I.isPending, V = async () => {
97
+ if (t) try {
98
+ z ? (await I.mutateAsync({
99
+ targetId: t,
58
100
  targetType: "MEMBER"
59
- }), c.success("Unfollowed", D.displayName)) : (await M.mutateAsync({
60
- targetId: w,
101
+ }), l.success("Unfollowed", A.displayName)) : (await F.mutateAsync({
102
+ targetId: t,
61
103
  targetType: "MEMBER"
62
- }), c.success("Following", D.displayName));
104
+ }), l.success("Following", A.displayName));
63
105
  } catch (e) {
64
- c.error("Could not update follow", s(e));
106
+ l.error("Could not update follow", c(e));
65
107
  }
66
- }, z = F ? /* @__PURE__ */ x(S, {
108
+ }, H = R ? /* @__PURE__ */ x(C, {
67
109
  variant: "outline",
68
- onClick: () => T("profile"),
69
- children: [/* @__PURE__ */ b(h, { className: "mr-1.5 h-4 w-4" }), " Edit profile"]
70
- }) : I ? /* @__PURE__ */ x(S, {
110
+ onClick: () => E("profile"),
111
+ children: [/* @__PURE__ */ b(m, { className: "mr-1.5 h-4 w-4" }), " Edit profile"]
112
+ }) : z ? /* @__PURE__ */ x(C, {
71
113
  variant: "outline",
72
- onClick: R,
73
- disabled: L,
74
- children: [/* @__PURE__ */ b(g, { className: "mr-1.5 h-4 w-4" }), " Following"]
75
- }) : /* @__PURE__ */ x(S, {
76
- onClick: R,
77
- disabled: L,
114
+ onClick: V,
115
+ disabled: B,
116
+ "aria-label": `Following ${A.displayName}. Activate to unfollow.`,
117
+ className: "group/follow min-w-[8rem] justify-center motion-safe:transition-colors hover:border-status-error-border hover:bg-status-error-subtle hover:text-status-error-text",
118
+ children: [
119
+ /* @__PURE__ */ b(h, { className: "mr-1.5 h-4 w-4 group-hover/follow:hidden" }),
120
+ /* @__PURE__ */ b(g, { className: "mr-1.5 hidden h-4 w-4 group-hover/follow:inline" }),
121
+ /* @__PURE__ */ b("span", {
122
+ className: "group-hover/follow:hidden",
123
+ children: "Following"
124
+ }),
125
+ /* @__PURE__ */ b("span", {
126
+ className: "hidden group-hover/follow:inline",
127
+ children: "Unfollow"
128
+ })
129
+ ]
130
+ }) : /* @__PURE__ */ x(C, {
131
+ onClick: V,
132
+ disabled: B,
78
133
  children: [/* @__PURE__ */ b(_, { className: "mr-1.5 h-4 w-4" }), " Follow"]
79
- });
80
- return /* @__PURE__ */ b(t, {
134
+ }), U = A.interests.length > 0 || A.skills.length > 0;
135
+ return /* @__PURE__ */ b(n, {
81
136
  title: "Profile",
82
- actions: P,
137
+ actions: L,
83
138
  children: /* @__PURE__ */ x("div", {
84
139
  className: "mx-auto flex max-w-2xl flex-col gap-6",
85
- children: [
86
- /* @__PURE__ */ x("div", {
87
- className: "rounded-2xl border border-border-seam bg-bg-surface p-6",
140
+ children: [/* @__PURE__ */ x(w, {
141
+ treatment: "plain",
142
+ className: "overflow-hidden p-0",
143
+ children: [/* @__PURE__ */ b("div", {
144
+ className: "relative h-24 overflow-hidden bg-gloss-card sm:h-28",
145
+ children: /* @__PURE__ */ b(S, { intensity: "subtle" })
146
+ }), /* @__PURE__ */ x("div", {
147
+ className: "px-5 pb-5 sm:px-6 sm:pb-6",
88
148
  children: [/* @__PURE__ */ x("div", {
89
- className: "flex flex-col gap-5 sm:flex-row sm:items-start sm:justify-between",
149
+ className: "flex flex-col gap-4 sm:flex-row sm:items-end sm:justify-between",
90
150
  children: [/* @__PURE__ */ x("div", {
91
- className: "flex flex-col items-center gap-4 sm:flex-row sm:items-start",
92
- children: [/* @__PURE__ */ b(o, {
93
- name: D.displayName,
94
- presence: D.presence,
95
- size: "xl",
96
- fileId: D.avatar?.id
151
+ className: "flex flex-col items-center gap-4 sm:flex-row sm:items-end",
152
+ children: [/* @__PURE__ */ b(s, {
153
+ name: A.displayName,
154
+ presence: A.presence,
155
+ size: "2xl",
156
+ seed: A.memberId,
157
+ fileId: A.avatar?.id,
158
+ ring: !0,
159
+ className: "-mt-16 sm:-mt-20"
97
160
  }), /* @__PURE__ */ x("div", {
98
- className: "min-w-0 text-center sm:text-left",
161
+ className: "min-w-0 pb-1 text-center sm:text-left",
99
162
  children: [
100
- /* @__PURE__ */ b("h2", {
101
- className: "text-2xl font-semibold text-text-primary",
102
- children: D.displayName
163
+ /* @__PURE__ */ b(T, {
164
+ as: "h2",
165
+ className: "text-2xl font-semibold sm:text-[1.75rem]",
166
+ children: A.displayName
103
167
  }),
104
- D.headline && /* @__PURE__ */ b("p", {
168
+ A.headline && /* @__PURE__ */ b("p", {
105
169
  className: "mt-1 text-sm text-text-secondary",
106
- children: D.headline
170
+ children: A.headline
107
171
  }),
108
172
  /* @__PURE__ */ b("div", {
109
173
  className: "mt-3 flex justify-center sm:justify-start",
110
- children: /* @__PURE__ */ b(p, { status: D.presence })
174
+ children: /* @__PURE__ */ b(f, { status: A.presence })
111
175
  })
112
176
  ]
113
177
  })]
114
178
  }), /* @__PURE__ */ b("div", {
115
- className: "flex shrink-0 justify-center sm:justify-end",
116
- children: z
179
+ className: "flex shrink-0 justify-center pb-1 sm:justify-end",
180
+ children: H
117
181
  })]
118
- }), D.bio && /* @__PURE__ */ b("p", {
119
- className: "mt-5 whitespace-pre-wrap text-sm text-text-secondary",
120
- children: D.bio
182
+ }), A.bio && /* @__PURE__ */ b("p", {
183
+ className: "mt-5 whitespace-pre-wrap text-sm leading-relaxed text-text-secondary",
184
+ children: A.bio
121
185
  })]
122
- }),
123
- D.interests.length > 0 && /* @__PURE__ */ b(f, {
124
- title: "Interests",
125
- children: /* @__PURE__ */ b(C, { items: D.interests })
126
- }),
127
- D.skills.length > 0 && /* @__PURE__ */ b(f, {
128
- title: "Skills",
129
- children: /* @__PURE__ */ b(C, { items: D.skills })
130
- })
131
- ]
186
+ })]
187
+ }), U && /* @__PURE__ */ x(w, {
188
+ treatment: "plain",
189
+ className: "flex flex-col gap-6 p-5 sm:p-6",
190
+ children: [A.interests.length > 0 && /* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("h3", {
191
+ className: "mb-3 text-base font-semibold text-text-primary",
192
+ children: "Interests"
193
+ }), /* @__PURE__ */ b(D, {
194
+ items: A.interests,
195
+ variant: "interest"
196
+ })] }), A.skills.length > 0 && /* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("h3", {
197
+ className: "mb-3 text-base font-semibold text-text-primary",
198
+ children: "Skills"
199
+ }), /* @__PURE__ */ b(D, {
200
+ items: A.skills,
201
+ variant: "skill"
202
+ })] })]
203
+ })]
132
204
  })
133
205
  });
134
206
  }
135
207
  //#endregion
136
- export { w as MemberProfilePage };
208
+ export { k as MemberProfilePage };
137
209
 
138
210
  //# sourceMappingURL=MemberProfilePage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MemberProfilePage.js","names":[],"sources":["../../../../src/comradecircle/pages/members/MemberProfilePage.tsx"],"sourcesContent":["/**\n * MemberProfilePage — a single member's public social profile.\n * @module comradecircle/pages/members\n *\n * Reads `comProfile(memberId)` (the social-identity layer). The visitor can\n * follow / unfollow the member (state derived from `comMyFollows('MEMBER')`);\n * on their own profile the action becomes an \"Edit profile\" shortcut. Interests\n * and skills render as token-only chips and hide when empty.\n */\n\nimport { ArrowLeft, UserX, UserPlus, UserCheck, Pencil } from 'lucide-react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { Avatar } from '../../components/Avatar';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { EmptyState } from '../../components/EmptyState';\nimport { LoadingView, ErrorView, Section } from '../../components/StateViews';\nimport { useComProfile, useComMyFollows, useComFollow, useComUnfollow } from '../../hooks';\nimport { useComradeCircle } from '../../context';\nimport { notify, describeError } from '../../lib/toast';\nimport { useParams } from 'react-router-dom';\n\nfunction ChipList({ items }: { items: string[] }) {\n return (\n <div className=\"flex flex-wrap gap-1.5\">\n {items.map((item) => (\n <span\n key={item}\n className=\"rounded-full bg-bg-sunken px-2.5 py-0.5 text-xs font-medium text-text-secondary\"\n >\n {item}\n </span>\n ))}\n </div>\n );\n}\n\nexport function MemberProfilePage() {\n const { memberId } = useParams<{ memberId: string }>();\n const { navigateTo, currentUser } = useComradeCircle();\n const { data: profile, isLoading, isError, refetch } = useComProfile(memberId);\n\n const follows = useComMyFollows('MEMBER');\n const follow = useComFollow();\n const unfollow = useComUnfollow();\n\n const back = (\n <Button variant=\"ghost\" size=\"sm\" onClick={() => navigateTo('members')}>\n <ArrowLeft className=\"mr-1.5 h-4 w-4\" /> Back\n </Button>\n );\n\n if (isLoading) {\n return (\n <PageLayout title=\"Profile\" actions={back}>\n <LoadingView label=\"Loading profile…\" />\n </PageLayout>\n );\n }\n\n if (isError) {\n return (\n <PageLayout title=\"Profile\" actions={back}>\n <ErrorView message=\"We couldn't load this member's profile.\" onRetry={() => refetch()} />\n </PageLayout>\n );\n }\n\n if (!profile) {\n return (\n <PageLayout title=\"Profile\" actions={back}>\n <EmptyState\n icon={<UserX className=\"h-10 w-10\" />}\n title=\"No profile\"\n description=\"This member hasn't set up a ComradeCircle profile yet.\"\n />\n </PageLayout>\n );\n }\n\n const isSelf = Boolean(memberId && currentUser?.id === memberId);\n const isFollowing = (follows.data ?? []).some(\n (f) => f.targetId === memberId && f.targetType === 'MEMBER'\n );\n const followPending = follow.isPending || unfollow.isPending;\n\n const toggleFollow = async () => {\n if (!memberId) return;\n try {\n if (isFollowing) {\n await unfollow.mutateAsync({ targetId: memberId, targetType: 'MEMBER' });\n notify.success('Unfollowed', profile.displayName);\n } else {\n await follow.mutateAsync({ targetId: memberId, targetType: 'MEMBER' });\n notify.success('Following', profile.displayName);\n }\n } catch (err) {\n notify.error('Could not update follow', describeError(err));\n }\n };\n\n const action = isSelf ? (\n <Button variant=\"outline\" onClick={() => navigateTo('profile')}>\n <Pencil className=\"mr-1.5 h-4 w-4\" /> Edit profile\n </Button>\n ) : isFollowing ? (\n <Button variant=\"outline\" onClick={toggleFollow} disabled={followPending}>\n <UserCheck className=\"mr-1.5 h-4 w-4\" /> Following\n </Button>\n ) : (\n <Button onClick={toggleFollow} disabled={followPending}>\n <UserPlus className=\"mr-1.5 h-4 w-4\" /> Follow\n </Button>\n );\n\n return (\n <PageLayout title=\"Profile\" actions={back}>\n <div className=\"mx-auto flex max-w-2xl flex-col gap-6\">\n {/* Identity header */}\n <div className=\"rounded-2xl border border-border-seam bg-bg-surface p-6\">\n <div className=\"flex flex-col gap-5 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"flex flex-col items-center gap-4 sm:flex-row sm:items-start\">\n <Avatar\n name={profile.displayName}\n presence={profile.presence}\n size=\"xl\"\n fileId={profile.avatar?.id}\n />\n <div className=\"min-w-0 text-center sm:text-left\">\n <h2 className=\"text-2xl font-semibold text-text-primary\">{profile.displayName}</h2>\n {profile.headline && (\n <p className=\"mt-1 text-sm text-text-secondary\">{profile.headline}</p>\n )}\n <div className=\"mt-3 flex justify-center sm:justify-start\">\n <StatusBadge status={profile.presence} />\n </div>\n </div>\n </div>\n <div className=\"flex shrink-0 justify-center sm:justify-end\">{action}</div>\n </div>\n\n {profile.bio && (\n <p className=\"mt-5 whitespace-pre-wrap text-sm text-text-secondary\">{profile.bio}</p>\n )}\n </div>\n\n {profile.interests.length > 0 && (\n <Section title=\"Interests\">\n <ChipList items={profile.interests} />\n </Section>\n )}\n\n {profile.skills.length > 0 && (\n <Section title=\"Skills\">\n <ChipList items={profile.skills} />\n </Section>\n )}\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"MemberProfilePage.js","names":[],"sources":["../../../../src/comradecircle/pages/members/MemberProfilePage.tsx"],"sourcesContent":["/**\n * MemberProfilePage — a single member's public social profile.\n * @module comradecircle/pages/members\n *\n * Reads `comProfile(memberId)` (the social-identity layer). The visitor can\n * follow / unfollow the member (state derived from `comMyFollows('MEMBER')`);\n * on their own profile the action becomes an \"Edit profile\" shortcut. Interests\n * and skills render as differentiated chips (accent-tinted vs. outlined) and\n * hide when empty. The identity card gets a social-hero treatment: a living\n * gloss/aurora cover strip with the avatar overlapping upward onto it.\n */\n\nimport { ArrowLeft, UserX, UserMinus, UserPlus, UserCheck, Pencil } from 'lucide-react';\nimport { Button, GlassCard, GradientText, AuroraBackground, Skeleton } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { Avatar } from '../../components/Avatar';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { EmptyState } from '../../components/EmptyState';\nimport { ErrorView } from '../../components/StateViews';\nimport { useComProfile, useComMyFollows, useComFollow, useComUnfollow } from '../../hooks';\nimport { useComradeCircle } from '../../context';\nimport { notify, describeError } from '../../lib/toast';\nimport { cn } from '../../utils/cn';\nimport { useParams } from 'react-router-dom';\n\n/**\n * A wrap of tag chips. `interest` chips read as accent-tinted affinities;\n * `skill` chips read as outlined competencies — a quiet visual grammar that\n * lets the two sets be told apart at a glance. Hover gives a tasteful lift.\n */\nfunction ChipList({ items, variant }: { items: string[]; variant: 'interest' | 'skill' }) {\n return (\n <ul className=\"flex flex-wrap gap-2\">\n {items.map((item) => (\n <li\n key={item}\n className={cn(\n 'rounded-full px-3 py-1 text-xs font-medium motion-safe:transition-transform motion-safe:duration-150 motion-safe:hover:-translate-y-0.5',\n variant === 'interest'\n ? 'bg-[var(--color-accent-soft)] text-accent'\n : 'border border-border-seam text-text-primary hover:border-border-strong'\n )}\n >\n {item}\n </li>\n ))}\n </ul>\n );\n}\n\n/** Profile-shaped skeleton — mirrors the hero cover strip, overlapping avatar,\n * identity block and the two chip sections so the layout doesn't jump. */\nfunction ProfileSkeleton() {\n return (\n <div className=\"mx-auto flex max-w-2xl flex-col gap-6\">\n <GlassCard treatment=\"plain\" className=\"overflow-hidden p-0\">\n <Skeleton className=\"h-24 w-full rounded-none sm:h-28\" />\n <div className=\"px-5 pb-5 sm:px-6 sm:pb-6\">\n <div className=\"flex flex-col items-center gap-4 sm:flex-row sm:items-end\">\n <Skeleton className=\"-mt-16 h-28 w-28 rounded-full sm:-mt-20\" />\n <div className=\"w-full space-y-2 pb-1 text-center sm:text-left\">\n <Skeleton className=\"mx-auto h-7 w-44 sm:mx-0\" />\n <Skeleton className=\"mx-auto h-4 w-56 sm:mx-0\" />\n <Skeleton className=\"mx-auto h-5 w-20 rounded-full sm:mx-0\" />\n </div>\n </div>\n <div className=\"mt-5 space-y-2\">\n <Skeleton className=\"h-4 w-full\" />\n <Skeleton className=\"h-4 w-3/4\" />\n </div>\n </div>\n </GlassCard>\n <GlassCard treatment=\"plain\" className=\"flex flex-col gap-6 p-5 sm:p-6\">\n {[0, 1].map((s) => (\n <div key={s} className=\"space-y-3\">\n <Skeleton className=\"h-4 w-24\" />\n <div className=\"flex flex-wrap gap-2\">\n {[0, 1, 2, 3].map((c) => (\n <Skeleton key={c} className=\"h-6 w-20 rounded-full\" />\n ))}\n </div>\n </div>\n ))}\n </GlassCard>\n </div>\n );\n}\n\nexport function MemberProfilePage() {\n const { memberId } = useParams<{ memberId: string }>();\n const { navigateTo, currentUser } = useComradeCircle();\n const { data: profile, isLoading, isError, refetch } = useComProfile(memberId);\n\n const follows = useComMyFollows('MEMBER');\n const follow = useComFollow();\n const unfollow = useComUnfollow();\n\n const back = (\n <Button variant=\"ghost\" size=\"sm\" onClick={() => navigateTo('members')}>\n <ArrowLeft className=\"mr-1.5 h-4 w-4\" /> Back\n </Button>\n );\n\n if (isLoading) {\n return (\n <PageLayout title=\"Profile\" actions={back}>\n <ProfileSkeleton />\n </PageLayout>\n );\n }\n\n if (isError) {\n return (\n <PageLayout title=\"Profile\" actions={back}>\n <ErrorView message=\"We couldn't load this member's profile.\" onRetry={() => refetch()} />\n </PageLayout>\n );\n }\n\n if (!profile) {\n return (\n <PageLayout title=\"Profile\" actions={back}>\n <EmptyState\n icon={<UserX className=\"h-10 w-10\" />}\n title=\"No profile\"\n description=\"This member hasn't set up a ComradeCircle profile yet.\"\n />\n </PageLayout>\n );\n }\n\n const isSelf = Boolean(memberId && currentUser?.id === memberId);\n const isFollowing = (follows.data ?? []).some(\n (f) => f.targetId === memberId && f.targetType === 'MEMBER'\n );\n const followPending = follow.isPending || unfollow.isPending;\n\n const toggleFollow = async () => {\n if (!memberId) return;\n try {\n if (isFollowing) {\n await unfollow.mutateAsync({ targetId: memberId, targetType: 'MEMBER' });\n notify.success('Unfollowed', profile.displayName);\n } else {\n await follow.mutateAsync({ targetId: memberId, targetType: 'MEMBER' });\n notify.success('Following', profile.displayName);\n }\n } catch (err) {\n notify.error('Could not update follow', describeError(err));\n }\n };\n\n const action = isSelf ? (\n <Button variant=\"outline\" onClick={() => navigateTo('profile')}>\n <Pencil className=\"mr-1.5 h-4 w-4\" /> Edit profile\n </Button>\n ) : isFollowing ? (\n <Button\n variant=\"outline\"\n onClick={toggleFollow}\n disabled={followPending}\n aria-label={`Following ${profile.displayName}. Activate to unfollow.`}\n className=\"group/follow min-w-[8rem] justify-center motion-safe:transition-colors hover:border-status-error-border hover:bg-status-error-subtle hover:text-status-error-text\"\n >\n <UserCheck className=\"mr-1.5 h-4 w-4 group-hover/follow:hidden\" />\n <UserMinus className=\"mr-1.5 hidden h-4 w-4 group-hover/follow:inline\" />\n <span className=\"group-hover/follow:hidden\">Following</span>\n <span className=\"hidden group-hover/follow:inline\">Unfollow</span>\n </Button>\n ) : (\n <Button onClick={toggleFollow} disabled={followPending}>\n <UserPlus className=\"mr-1.5 h-4 w-4\" /> Follow\n </Button>\n );\n\n const hasTags = profile.interests.length > 0 || profile.skills.length > 0;\n\n return (\n <PageLayout title=\"Profile\" actions={back}>\n <div className=\"mx-auto flex max-w-2xl flex-col gap-6\">\n {/* Identity hero */}\n <GlassCard treatment=\"plain\" className=\"overflow-hidden p-0\">\n {/* Living cover strip — gloss + drifting aurora, reduced-motion safe */}\n <div className=\"relative h-24 overflow-hidden bg-gloss-card sm:h-28\">\n <AuroraBackground intensity=\"subtle\" />\n </div>\n\n <div className=\"px-5 pb-5 sm:px-6 sm:pb-6\">\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-end sm:justify-between\">\n <div className=\"flex flex-col items-center gap-4 sm:flex-row sm:items-end\">\n <Avatar\n name={profile.displayName}\n presence={profile.presence}\n size=\"2xl\"\n seed={profile.memberId}\n fileId={profile.avatar?.id}\n ring\n className=\"-mt-16 sm:-mt-20\"\n />\n <div className=\"min-w-0 pb-1 text-center sm:text-left\">\n <GradientText as=\"h2\" className=\"text-2xl font-semibold sm:text-[1.75rem]\">\n {profile.displayName}\n </GradientText>\n {profile.headline && (\n <p className=\"mt-1 text-sm text-text-secondary\">{profile.headline}</p>\n )}\n <div className=\"mt-3 flex justify-center sm:justify-start\">\n <StatusBadge status={profile.presence} />\n </div>\n </div>\n </div>\n <div className=\"flex shrink-0 justify-center pb-1 sm:justify-end\">{action}</div>\n </div>\n\n {profile.bio && (\n <p className=\"mt-5 whitespace-pre-wrap text-sm leading-relaxed text-text-secondary\">\n {profile.bio}\n </p>\n )}\n </div>\n </GlassCard>\n\n {/* Interests & skills — differentiated chip grammar */}\n {hasTags && (\n <GlassCard treatment=\"plain\" className=\"flex flex-col gap-6 p-5 sm:p-6\">\n {profile.interests.length > 0 && (\n <div>\n <h3 className=\"mb-3 text-base font-semibold text-text-primary\">Interests</h3>\n <ChipList items={profile.interests} variant=\"interest\" />\n </div>\n )}\n {profile.skills.length > 0 && (\n <div>\n <h3 className=\"mb-3 text-base font-semibold text-text-primary\">Skills</h3>\n <ChipList items={profile.skills} variant=\"skill\" />\n </div>\n )}\n </GlassCard>\n )}\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}