@burdenoff/microfe-theculturepost 2026.704.2 → 2026.705.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/theculturepost/TheCulturePostRoot.js +63 -45
- package/dist/theculturepost/TheCulturePostRoot.js.map +1 -1
- package/dist/theculturepost/TheCulturePostRoutes.js +17 -9
- package/dist/theculturepost/TheCulturePostRoutes.js.map +1 -1
- package/dist/theculturepost/components/AddCitationDialog.js +131 -102
- package/dist/theculturepost/components/AddCitationDialog.js.map +1 -1
- package/dist/theculturepost/components/ArchiveItemCard.js +56 -43
- package/dist/theculturepost/components/ArchiveItemCard.js.map +1 -1
- package/dist/theculturepost/components/AudioPlayer.js +74 -0
- package/dist/theculturepost/components/AudioPlayer.js.map +1 -0
- package/dist/theculturepost/components/CitationList.js +215 -105
- package/dist/theculturepost/components/CitationList.js.map +1 -1
- package/dist/theculturepost/components/CollectionCard.js +32 -32
- package/dist/theculturepost/components/CollectionCard.js.map +1 -1
- package/dist/theculturepost/components/CreateArchiveItemDialog.js +133 -93
- package/dist/theculturepost/components/CreateArchiveItemDialog.js.map +1 -1
- package/dist/theculturepost/components/CreateCollectionDialog.js +91 -70
- package/dist/theculturepost/components/CreateCollectionDialog.js.map +1 -1
- package/dist/theculturepost/components/CreateStoryDialog.js +311 -132
- package/dist/theculturepost/components/CreateStoryDialog.js.map +1 -1
- package/dist/theculturepost/components/DecorativeCover.js +78 -0
- package/dist/theculturepost/components/DecorativeCover.js.map +1 -0
- package/dist/theculturepost/components/DecorativeDivider.js +45 -0
- package/dist/theculturepost/components/DecorativeDivider.js.map +1 -0
- package/dist/theculturepost/components/DiscussionCard.js +75 -60
- package/dist/theculturepost/components/DiscussionCard.js.map +1 -1
- package/dist/theculturepost/components/HistoryTimeline.js +115 -0
- package/dist/theculturepost/components/HistoryTimeline.js.map +1 -0
- package/dist/theculturepost/components/LifecycleStepper.js +33 -0
- package/dist/theculturepost/components/LifecycleStepper.js.map +1 -0
- package/dist/theculturepost/components/OpenDiscussionDialog.js +66 -56
- package/dist/theculturepost/components/OpenDiscussionDialog.js.map +1 -1
- package/dist/theculturepost/components/OralHistoryCard.js +6 -73
- package/dist/theculturepost/components/OverlayBadge.js +22 -0
- package/dist/theculturepost/components/OverlayBadge.js.map +1 -0
- package/dist/theculturepost/components/PageHero.js +62 -0
- package/dist/theculturepost/components/PageHero.js.map +1 -0
- package/dist/theculturepost/components/RecordOralHistoryDialog.js +306 -131
- package/dist/theculturepost/components/RecordOralHistoryDialog.js.map +1 -1
- package/dist/theculturepost/components/ReplyThread.js +268 -139
- package/dist/theculturepost/components/ReplyThread.js.map +1 -1
- package/dist/theculturepost/components/StatusBadge.js +9 -9
- package/dist/theculturepost/components/StatusBadge.js.map +1 -1
- package/dist/theculturepost/components/StoryCard.js +54 -49
- package/dist/theculturepost/components/StoryCard.js.map +1 -1
- package/dist/theculturepost/components/TopicCard.js +60 -41
- package/dist/theculturepost/components/TopicCard.js.map +1 -1
- package/dist/theculturepost/components/Waveform.js +31 -0
- package/dist/theculturepost/components/Waveform.js.map +1 -0
- package/dist/theculturepost/components/categoryMeta.js +20 -0
- package/dist/theculturepost/components/categoryMeta.js.map +1 -0
- package/dist/theculturepost/components/index.js +41 -0
- package/dist/theculturepost/components/viz/BarChart.js +53 -0
- package/dist/theculturepost/components/viz/BarChart.js.map +1 -0
- package/dist/theculturepost/components/viz/Donut.js +58 -0
- package/dist/theculturepost/components/viz/Donut.js.map +1 -0
- package/dist/theculturepost/components/viz/StatTile.js +35 -0
- package/dist/theculturepost/components/viz/StatTile.js.map +1 -0
- package/dist/theculturepost/components/viz/index.js +3 -0
- package/dist/theculturepost/hooks/useFiles.js +1 -1
- package/dist/theculturepost/hooks/useFiles.js.map +1 -1
- package/dist/theculturepost/pages/HomePage.js +247 -124
- package/dist/theculturepost/pages/HomePage.js.map +1 -1
- package/dist/theculturepost/pages/archive/ArchiveItemDetailPage.js +319 -127
- package/dist/theculturepost/pages/archive/ArchiveItemDetailPage.js.map +1 -1
- package/dist/theculturepost/pages/archive/ArchivePage.js +265 -180
- package/dist/theculturepost/pages/archive/ArchivePage.js.map +1 -1
- package/dist/theculturepost/pages/archive/CollectionDetailPage.js +158 -143
- package/dist/theculturepost/pages/archive/CollectionDetailPage.js.map +1 -1
- package/dist/theculturepost/pages/discussions/DiscussionDetailPage.js +155 -93
- package/dist/theculturepost/pages/discussions/DiscussionDetailPage.js.map +1 -1
- package/dist/theculturepost/pages/discussions/DiscussionsPage.js +16 -16
- package/dist/theculturepost/pages/discussions/DiscussionsPage.js.map +1 -1
- package/dist/theculturepost/pages/governance/GovernancePage.js +293 -0
- package/dist/theculturepost/pages/governance/GovernancePage.js.map +1 -0
- package/dist/theculturepost/pages/stories/StoriesPage.js +18 -18
- package/dist/theculturepost/pages/stories/StoriesPage.js.map +1 -1
- package/dist/theculturepost/pages/stories/StoryDetailPage.js +603 -285
- package/dist/theculturepost/pages/stories/StoryDetailPage.js.map +1 -1
- package/dist/theculturepost/pages/timeline/TimelinePage.js +162 -0
- package/dist/theculturepost/pages/timeline/TimelinePage.js.map +1 -0
- package/dist/theculturepost/pages/topics/TopicDetailPage.js +239 -163
- package/dist/theculturepost/pages/topics/TopicDetailPage.js.map +1 -1
- package/dist/theculturepost/pages/topics/TopicsPage.js +76 -74
- package/dist/theculturepost/pages/topics/TopicsPage.js.map +1 -1
- package/dist/theculturepost/styles/injectDisplayFont.js +11 -0
- package/dist/theculturepost/styles/injectDisplayFont.js.map +1 -0
- package/dist/theculturepost/utils/formatters.js +6 -1
- package/dist/theculturepost/utils/formatters.js.map +1 -1
- package/package.json +1 -1
- package/dist/theculturepost/components/OralHistoryCard.js.map +0 -1
|
@@ -1,156 +1,171 @@
|
|
|
1
1
|
import { useTheCulturePost as e } from "../../context/TheCulturePostContext.js";
|
|
2
|
-
import { PageLayout as t } from "../../components/PageLayout.js";
|
|
3
|
-
import { ErrorView as n, LoadingView as r, Section as i } from "../../components/StateViews.js";
|
|
4
2
|
import "../../context/index.js";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
3
|
+
import { PageHero as t } from "../../components/PageHero.js";
|
|
4
|
+
import { ErrorView as n, LoadingView as r } from "../../components/StateViews.js";
|
|
5
|
+
import { formatNumber as i } from "../../utils/formatters.js";
|
|
6
|
+
import { EmptyState as a } from "../../components/EmptyState.js";
|
|
7
|
+
import { useTcpCollection as o } from "../../hooks/useTcpApi.js";
|
|
9
8
|
import "../../hooks/index.js";
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
9
|
+
import { DecorativeDivider as s } from "../../components/DecorativeDivider.js";
|
|
10
|
+
import { ArchiveItemCard as c } from "../../components/ArchiveItemCard.js";
|
|
11
|
+
import { RecordOralHistoryDialog as l } from "../../components/RecordOralHistoryDialog.js";
|
|
12
|
+
import { CreateArchiveItemDialog as u } from "../../components/CreateArchiveItemDialog.js";
|
|
13
|
+
import { OralHistoryPlayerRow as d } from "./ArchivePage.js";
|
|
14
|
+
import { useState as f } from "react";
|
|
15
|
+
import { AudioLines as p, Boxes as m, Mic as h, Plus as g } from "lucide-react";
|
|
16
|
+
import { useParams as _ } from "react-router-dom";
|
|
17
|
+
import { Fragment as v, jsx as y, jsxs as b } from "react/jsx-runtime";
|
|
18
|
+
import { Button as x, GlassCard as S } from "@burdenoff/fe-libs/ui";
|
|
19
19
|
//#region src/theculturepost/pages/archive/CollectionDetailPage.tsx
|
|
20
|
-
function
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
actions: P,
|
|
30
|
-
children: /* @__PURE__ */ b(r, { label: "Loading collection…" })
|
|
31
|
-
});
|
|
32
|
-
if (O || !E) return /* @__PURE__ */ b(t, {
|
|
33
|
-
title: "Collection",
|
|
34
|
-
actions: P,
|
|
35
|
-
children: /* @__PURE__ */ b(n, {
|
|
36
|
-
title: "Collection not found",
|
|
37
|
-
message: "This collection may have been removed, or you may not have access.",
|
|
38
|
-
onRetry: () => k()
|
|
20
|
+
function C({ children: e }) {
|
|
21
|
+
return /* @__PURE__ */ y("div", {
|
|
22
|
+
className: "flex h-full flex-col",
|
|
23
|
+
children: /* @__PURE__ */ y("div", {
|
|
24
|
+
className: "flex-1 overflow-auto",
|
|
25
|
+
children: /* @__PURE__ */ y("div", {
|
|
26
|
+
className: "mx-auto flex w-full max-w-6xl flex-col gap-6 p-4 sm:p-6",
|
|
27
|
+
children: e
|
|
28
|
+
})
|
|
39
29
|
})
|
|
40
30
|
});
|
|
31
|
+
}
|
|
32
|
+
function w() {
|
|
33
|
+
let { id: w } = _(), { navigateTo: T } = e(), { data: E, isLoading: D, isError: O, refetch: k } = o(w), [A, j] = f(!1), [M, N] = f(!1), P = () => T("archive");
|
|
34
|
+
if (D) return /* @__PURE__ */ y(C, { children: /* @__PURE__ */ y(r, { label: "Loading collection…" }) });
|
|
35
|
+
if (O || !E) return /* @__PURE__ */ y(C, { children: /* @__PURE__ */ y(n, {
|
|
36
|
+
title: "Collection not found",
|
|
37
|
+
message: "This collection may have been removed, or you may not have access.",
|
|
38
|
+
onRetry: () => k()
|
|
39
|
+
}) });
|
|
41
40
|
let F = E.items ?? [], I = E.oralHistories ?? [];
|
|
42
|
-
return /* @__PURE__ */
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
children: [
|
|
64
|
-
E.tradition && /* @__PURE__ */ b("span", {
|
|
65
|
-
className: "text-sm font-medium text-text-secondary",
|
|
66
|
-
children: E.tradition
|
|
67
|
-
}),
|
|
68
|
-
E.description && /* @__PURE__ */ b("p", {
|
|
69
|
-
className: "whitespace-pre-wrap text-sm leading-relaxed text-text-secondary",
|
|
70
|
-
children: E.description
|
|
71
|
-
}),
|
|
72
|
-
/* @__PURE__ */ x("div", {
|
|
73
|
-
className: "mt-auto flex flex-wrap items-center gap-4 pt-2 text-sm text-text-tertiary",
|
|
74
|
-
children: [/* @__PURE__ */ x("span", {
|
|
75
|
-
className: "inline-flex items-center gap-1.5",
|
|
76
|
-
children: [
|
|
77
|
-
/* @__PURE__ */ b(g, { className: "h-4 w-4" }),
|
|
78
|
-
" ",
|
|
79
|
-
o(E.itemCount),
|
|
80
|
-
" artifacts"
|
|
81
|
-
]
|
|
82
|
-
}), /* @__PURE__ */ x("span", {
|
|
83
|
-
className: "inline-flex items-center gap-1.5",
|
|
84
|
-
children: [
|
|
85
|
-
/* @__PURE__ */ b(h, { className: "h-4 w-4" }),
|
|
86
|
-
" ",
|
|
87
|
-
o(I.length),
|
|
88
|
-
" oral histories"
|
|
89
|
-
]
|
|
90
|
-
})]
|
|
91
|
-
})
|
|
92
|
-
]
|
|
93
|
-
})]
|
|
94
|
-
}),
|
|
95
|
-
/* @__PURE__ */ b(i, {
|
|
96
|
-
title: "Artifacts",
|
|
97
|
-
action: /* @__PURE__ */ x(S, {
|
|
98
|
-
size: "sm",
|
|
99
|
-
variant: "outline",
|
|
100
|
-
onClick: () => j(!0),
|
|
101
|
-
children: [/* @__PURE__ */ b(v, { className: "mr-1.5 h-4 w-4" }), " Add artifact"]
|
|
41
|
+
return /* @__PURE__ */ b(C, { children: [
|
|
42
|
+
/* @__PURE__ */ y(t, {
|
|
43
|
+
eyebrow: "Collection",
|
|
44
|
+
title: E.name,
|
|
45
|
+
description: E.description ?? void 0,
|
|
46
|
+
coverFileId: E.cover?.id,
|
|
47
|
+
backAction: {
|
|
48
|
+
label: "Archive",
|
|
49
|
+
onClick: P
|
|
50
|
+
},
|
|
51
|
+
meta: /* @__PURE__ */ b(v, { children: [
|
|
52
|
+
E.tradition && /* @__PURE__ */ y("span", {
|
|
53
|
+
className: "inline-flex items-center gap-1.5 rounded-full bg-bg-sunken px-2.5 py-0.5 text-xs font-medium text-text-secondary",
|
|
54
|
+
children: E.tradition
|
|
55
|
+
}),
|
|
56
|
+
/* @__PURE__ */ b("span", {
|
|
57
|
+
className: "inline-flex items-center gap-1.5 text-sm text-text-tertiary",
|
|
58
|
+
children: [
|
|
59
|
+
/* @__PURE__ */ y(m, {
|
|
60
|
+
className: "h-4 w-4",
|
|
61
|
+
"aria-hidden": "true"
|
|
102
62
|
}),
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
onOpen: () => T(`archive/items/${e.id}`)
|
|
116
|
-
}, e.id))
|
|
117
|
-
})
|
|
118
|
-
}),
|
|
119
|
-
/* @__PURE__ */ b(i, {
|
|
120
|
-
title: "Oral histories",
|
|
121
|
-
action: /* @__PURE__ */ x(S, {
|
|
122
|
-
size: "sm",
|
|
123
|
-
variant: "outline",
|
|
124
|
-
onClick: () => N(!0),
|
|
125
|
-
children: [/* @__PURE__ */ b(v, { className: "mr-1.5 h-4 w-4" }), " Record"]
|
|
63
|
+
" ",
|
|
64
|
+
i(E.itemCount),
|
|
65
|
+
" ",
|
|
66
|
+
E.itemCount === 1 ? "item" : "items"
|
|
67
|
+
]
|
|
68
|
+
}),
|
|
69
|
+
/* @__PURE__ */ b("span", {
|
|
70
|
+
className: "inline-flex items-center gap-1.5 text-sm text-text-tertiary",
|
|
71
|
+
children: [
|
|
72
|
+
/* @__PURE__ */ y(p, {
|
|
73
|
+
className: "h-4 w-4",
|
|
74
|
+
"aria-hidden": "true"
|
|
126
75
|
}),
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
76
|
+
" ",
|
|
77
|
+
i(I.length),
|
|
78
|
+
" ",
|
|
79
|
+
I.length === 1 ? "oral history" : "oral histories"
|
|
80
|
+
]
|
|
81
|
+
})
|
|
82
|
+
] }),
|
|
83
|
+
actions: /* @__PURE__ */ b(v, { children: [/* @__PURE__ */ b(x, {
|
|
84
|
+
onClick: () => j(!0),
|
|
85
|
+
children: [/* @__PURE__ */ y(g, { className: "mr-1.5 h-4 w-4" }), " Add artifact"]
|
|
86
|
+
}), /* @__PURE__ */ b(x, {
|
|
87
|
+
variant: "outline",
|
|
88
|
+
onClick: () => N(!0),
|
|
89
|
+
children: [/* @__PURE__ */ y(h, { className: "mr-1.5 h-4 w-4" }), " Record"]
|
|
90
|
+
})] })
|
|
91
|
+
}),
|
|
92
|
+
/* @__PURE__ */ y(s, { className: "py-2" }),
|
|
93
|
+
/* @__PURE__ */ b("div", {
|
|
94
|
+
className: "grid gap-6 lg:grid-cols-2",
|
|
95
|
+
children: [/* @__PURE__ */ b(S, {
|
|
96
|
+
treatment: "plain",
|
|
97
|
+
className: "flex flex-col gap-4 p-5",
|
|
98
|
+
children: [/* @__PURE__ */ b("div", {
|
|
99
|
+
className: "flex items-center justify-between gap-3",
|
|
100
|
+
children: [/* @__PURE__ */ b("h2", {
|
|
101
|
+
className: "flex items-center gap-2 font-display text-lg font-semibold text-text-primary",
|
|
102
|
+
children: [/* @__PURE__ */ y(m, {
|
|
103
|
+
className: "h-5 w-5 text-accent",
|
|
104
|
+
"aria-hidden": "true"
|
|
105
|
+
}), " Items"]
|
|
106
|
+
}), /* @__PURE__ */ b(x, {
|
|
107
|
+
size: "sm",
|
|
108
|
+
variant: "outline",
|
|
109
|
+
onClick: () => j(!0),
|
|
110
|
+
children: [/* @__PURE__ */ y(g, { className: "mr-1.5 h-4 w-4" }), " Add"]
|
|
111
|
+
})]
|
|
112
|
+
}), F.length === 0 ? /* @__PURE__ */ y(a, {
|
|
113
|
+
icon: /* @__PURE__ */ y(m, { className: "h-9 w-9" }),
|
|
114
|
+
title: "No artifacts in this collection",
|
|
115
|
+
description: "Add the first artifact to this collection.",
|
|
116
|
+
action: /* @__PURE__ */ b(x, {
|
|
117
|
+
onClick: () => j(!0),
|
|
118
|
+
children: [/* @__PURE__ */ y(g, { className: "mr-1.5 h-4 w-4" }), " Add artifact"]
|
|
139
119
|
})
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
/* @__PURE__ */ b(
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
120
|
+
}) : /* @__PURE__ */ y("div", {
|
|
121
|
+
className: "grid gap-4 sm:grid-cols-2",
|
|
122
|
+
children: F.map((e) => /* @__PURE__ */ y(c, {
|
|
123
|
+
item: e,
|
|
124
|
+
onOpen: () => T(`archive/items/${e.id}`)
|
|
125
|
+
}, e.id))
|
|
126
|
+
})]
|
|
127
|
+
}), /* @__PURE__ */ b(S, {
|
|
128
|
+
treatment: "plain",
|
|
129
|
+
className: "flex flex-col gap-4 p-5",
|
|
130
|
+
children: [/* @__PURE__ */ b("div", {
|
|
131
|
+
className: "flex items-center justify-between gap-3",
|
|
132
|
+
children: [/* @__PURE__ */ b("h2", {
|
|
133
|
+
className: "flex items-center gap-2 font-display text-lg font-semibold text-text-primary",
|
|
134
|
+
children: [/* @__PURE__ */ y(p, {
|
|
135
|
+
className: "h-5 w-5 text-accent",
|
|
136
|
+
"aria-hidden": "true"
|
|
137
|
+
}), " Oral histories"]
|
|
138
|
+
}), /* @__PURE__ */ b(x, {
|
|
139
|
+
size: "sm",
|
|
140
|
+
variant: "outline",
|
|
141
|
+
onClick: () => N(!0),
|
|
142
|
+
children: [/* @__PURE__ */ y(h, { className: "mr-1.5 h-4 w-4" }), " Record"]
|
|
143
|
+
})]
|
|
144
|
+
}), I.length === 0 ? /* @__PURE__ */ y(a, {
|
|
145
|
+
icon: /* @__PURE__ */ y(p, { className: "h-9 w-9" }),
|
|
146
|
+
title: "No oral histories yet",
|
|
147
|
+
description: "Record a first-person account for this collection.",
|
|
148
|
+
action: /* @__PURE__ */ b(x, {
|
|
149
|
+
onClick: () => N(!0),
|
|
150
|
+
children: [/* @__PURE__ */ y(h, { className: "mr-1.5 h-4 w-4" }), " Record"]
|
|
151
|
+
})
|
|
152
|
+
}) : /* @__PURE__ */ y("div", {
|
|
153
|
+
className: "flex flex-col gap-4",
|
|
154
|
+
children: I.map((e) => /* @__PURE__ */ y(d, { oralHistory: e }, e.id))
|
|
155
|
+
})]
|
|
156
|
+
})]
|
|
157
|
+
}),
|
|
158
|
+
/* @__PURE__ */ y(u, {
|
|
159
|
+
open: A,
|
|
160
|
+
onOpenChange: j,
|
|
161
|
+
collectionId: E.id
|
|
162
|
+
}),
|
|
163
|
+
/* @__PURE__ */ y(l, {
|
|
164
|
+
open: M,
|
|
165
|
+
onOpenChange: N,
|
|
166
|
+
collectionId: E.id
|
|
167
|
+
})
|
|
168
|
+
] });
|
|
154
169
|
}
|
|
155
170
|
//#endregion
|
|
156
171
|
export { w as CollectionDetailPage };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CollectionDetailPage.js","names":[],"sources":["../../../../src/theculturepost/pages/archive/CollectionDetailPage.tsx"],"sourcesContent":["/**\n * CollectionDetailPage — a single archive collection.\n * @module theculturepost/pages/archive\n *\n * Reads `tcpCollection` (with its items + oral histories). Adding an artifact or\n * recording an oral history is pre-scoped to this collection.\n */\n\nimport { useState } from 'react';\nimport { ArrowLeft, Library, Boxes, AudioLines, Plus } from 'lucide-react';\nimport { Button, GlassCard } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { CoverImage } from '../../components/CoverImage';\nimport { ArchiveItemCard } from '../../components/ArchiveItemCard';\nimport { OralHistoryCard } from '../../components/OralHistoryCard';\nimport { CreateArchiveItemDialog } from '../../components/CreateArchiveItemDialog';\nimport { RecordOralHistoryDialog } from '../../components/RecordOralHistoryDialog';\nimport { EmptyState } from '../../components/EmptyState';\nimport { LoadingView, ErrorView, Section } from '../../components/StateViews';\nimport { useTcpCollection } from '../../hooks';\nimport { useTheCulturePost } from '../../context';\nimport { formatNumber } from '../../utils/formatters';\nimport { useParams } from 'react-router-dom';\n\nexport function CollectionDetailPage() {\n const { id } = useParams<{ id: string }>();\n const { navigateTo } = useTheCulturePost();\n const { data: collection, isLoading, isError, refetch } = useTcpCollection(id);\n const [addItemOpen, setAddItemOpen] = useState(false);\n const [recordOpen, setRecordOpen] = useState(false);\n\n const backButton = (\n <Button variant=\"ghost\" size=\"sm\" onClick={() => navigateTo('archive')}>\n <ArrowLeft className=\"mr-1.5 h-4 w-4\" /> Back\n </Button>\n );\n\n if (isLoading) {\n return (\n <PageLayout title=\"Collection\" actions={backButton}>\n <LoadingView label=\"Loading collection…\" />\n </PageLayout>\n );\n }\n\n if (isError || !collection) {\n return (\n <PageLayout title=\"Collection\" actions={backButton}>\n <ErrorView\n title=\"Collection not found\"\n message=\"This collection may have been removed, or you may not have access.\"\n onRetry={() => refetch()}\n />\n </PageLayout>\n );\n }\n\n const items = collection.items ?? [];\n const oralHistories = collection.oralHistories ?? [];\n\n return (\n <PageLayout title={collection.name} actions={backButton}>\n <div className=\"mx-auto flex max-w-6xl flex-col gap-6\">\n <GlassCard\n treatment=\"plain\"\n className=\"flex flex-col gap-4 overflow-hidden p-0 sm:flex-row\"\n >\n <div className=\"sm:w-64 sm:shrink-0\">\n <CoverImage\n fileId={collection.cover?.id}\n alt={collection.name}\n rounded=\"rounded-none\"\n className=\"aspect-[3/2] w-full sm:h-full\"\n icon={<Library className=\"h-10 w-10\" />}\n />\n </div>\n <div className=\"flex flex-1 flex-col gap-2 p-5 sm:p-6\">\n {collection.tradition && (\n <span className=\"text-sm font-medium text-text-secondary\">\n {collection.tradition}\n </span>\n )}\n {collection.description && (\n <p className=\"whitespace-pre-wrap text-sm leading-relaxed text-text-secondary\">\n {collection.description}\n </p>\n )}\n <div className=\"mt-auto flex flex-wrap items-center gap-4 pt-2 text-sm text-text-tertiary\">\n <span className=\"inline-flex items-center gap-1.5\">\n <Boxes className=\"h-4 w-4\" /> {formatNumber(collection.itemCount)} artifacts\n </span>\n <span className=\"inline-flex items-center gap-1.5\">\n <AudioLines className=\"h-4 w-4\" /> {formatNumber(oralHistories.length)} oral\n histories\n </span>\n </div>\n </div>\n </GlassCard>\n\n <Section\n title=\"Artifacts\"\n action={\n <Button size=\"sm\" variant=\"outline\" onClick={() => setAddItemOpen(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" /> Add artifact\n </Button>\n }\n >\n {items.length === 0 ? (\n <EmptyState\n icon={<Boxes className=\"h-9 w-9\" />}\n title=\"No artifacts in this collection\"\n description=\"Add the first artifact to this collection.\"\n action={\n <Button onClick={() => setAddItemOpen(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" /> Add artifact\n </Button>\n }\n />\n ) : (\n <div className=\"grid gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4\">\n {items.map((item) => (\n <ArchiveItemCard\n key={item.id}\n item={item}\n onOpen={() => navigateTo(`archive/items/${item.id}`)}\n />\n ))}\n </div>\n )}\n </Section>\n\n <Section\n title=\"Oral histories\"\n action={\n <Button size=\"sm\" variant=\"outline\" onClick={() => setRecordOpen(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" /> Record\n </Button>\n }\n >\n {oralHistories.length === 0 ? (\n <EmptyState\n icon={<AudioLines className=\"h-9 w-9\" />}\n title=\"No oral histories yet\"\n description=\"Record a first-person account for this collection.\"\n action={\n <Button onClick={() => setRecordOpen(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" /> Record\n </Button>\n }\n />\n ) : (\n <div className=\"grid gap-4 lg:grid-cols-2\">\n {oralHistories.map((oralHistory) => (\n <OralHistoryCard key={oralHistory.id} oralHistory={oralHistory} />\n ))}\n </div>\n )}\n </Section>\n </div>\n\n <CreateArchiveItemDialog\n open={addItemOpen}\n onOpenChange={setAddItemOpen}\n collectionId={collection.id}\n />\n <RecordOralHistoryDialog\n open={recordOpen}\n onOpenChange={setRecordOpen}\n collectionId={collection.id}\n />\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CollectionDetailPage.js","names":[],"sources":["../../../../src/theculturepost/pages/archive/CollectionDetailPage.tsx"],"sourcesContent":["/**\n * CollectionDetailPage — a single archive collection.\n * @module theculturepost/pages/archive\n *\n * Reads `tcpCollection` (with its items + oral histories). An editorial\n * {@link PageHero} shows the real cover (collections DO carry a cover file), with\n * real counts (itemCount, oralHistories.length). Two panels below list the\n * artifacts and the listenable oral histories. Adding an artifact or recording an\n * oral history is pre-scoped to this collection.\n */\n\nimport { useState } from 'react';\nimport { Boxes, AudioLines, Plus, Mic } from 'lucide-react';\nimport { Button, GlassCard } from '@burdenoff/fe-libs/ui';\nimport { useParams } from 'react-router-dom';\nimport { PageHero } from '../../components/PageHero';\nimport { DecorativeDivider } from '../../components/DecorativeDivider';\nimport { ArchiveItemCard } from '../../components/ArchiveItemCard';\nimport { CreateArchiveItemDialog } from '../../components/CreateArchiveItemDialog';\nimport { RecordOralHistoryDialog } from '../../components/RecordOralHistoryDialog';\nimport { EmptyState } from '../../components/EmptyState';\nimport { LoadingView, ErrorView } from '../../components/StateViews';\nimport { OralHistoryPlayerRow } from './ArchivePage';\nimport { useTcpCollection } from '../../hooks';\nimport { useTheCulturePost } from '../../context';\nimport { formatNumber } from '../../utils/formatters';\n\nfunction Shell({ children }: { children: React.ReactNode }) {\n return (\n <div className=\"flex h-full flex-col\">\n <div className=\"flex-1 overflow-auto\">\n <div className=\"mx-auto flex w-full max-w-6xl flex-col gap-6 p-4 sm:p-6\">{children}</div>\n </div>\n </div>\n );\n}\n\nexport function CollectionDetailPage() {\n const { id } = useParams<{ id: string }>();\n const { navigateTo } = useTheCulturePost();\n const { data: collection, isLoading, isError, refetch } = useTcpCollection(id);\n const [addItemOpen, setAddItemOpen] = useState(false);\n const [recordOpen, setRecordOpen] = useState(false);\n\n const goBack = () => navigateTo('archive');\n\n if (isLoading) {\n return (\n <Shell>\n <LoadingView label=\"Loading collection…\" />\n </Shell>\n );\n }\n\n if (isError || !collection) {\n return (\n <Shell>\n <ErrorView\n title=\"Collection not found\"\n message=\"This collection may have been removed, or you may not have access.\"\n onRetry={() => refetch()}\n />\n </Shell>\n );\n }\n\n const items = collection.items ?? [];\n const oralHistories = collection.oralHistories ?? [];\n\n return (\n <Shell>\n <PageHero\n eyebrow=\"Collection\"\n title={collection.name}\n description={collection.description ?? undefined}\n coverFileId={collection.cover?.id}\n backAction={{ label: 'Archive', onClick: goBack }}\n meta={\n <>\n {collection.tradition && (\n <span className=\"inline-flex items-center gap-1.5 rounded-full bg-bg-sunken px-2.5 py-0.5 text-xs font-medium text-text-secondary\">\n {collection.tradition}\n </span>\n )}\n <span className=\"inline-flex items-center gap-1.5 text-sm text-text-tertiary\">\n <Boxes className=\"h-4 w-4\" aria-hidden=\"true\" /> {formatNumber(collection.itemCount)}{' '}\n {collection.itemCount === 1 ? 'item' : 'items'}\n </span>\n <span className=\"inline-flex items-center gap-1.5 text-sm text-text-tertiary\">\n <AudioLines className=\"h-4 w-4\" aria-hidden=\"true\" />{' '}\n {formatNumber(oralHistories.length)}{' '}\n {oralHistories.length === 1 ? 'oral history' : 'oral histories'}\n </span>\n </>\n }\n actions={\n <>\n <Button onClick={() => setAddItemOpen(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" /> Add artifact\n </Button>\n <Button variant=\"outline\" onClick={() => setRecordOpen(true)}>\n <Mic className=\"mr-1.5 h-4 w-4\" /> Record\n </Button>\n </>\n }\n />\n\n <DecorativeDivider className=\"py-2\" />\n\n <div className=\"grid gap-6 lg:grid-cols-2\">\n {/* Items */}\n <GlassCard treatment=\"plain\" className=\"flex flex-col gap-4 p-5\">\n <div className=\"flex items-center justify-between gap-3\">\n <h2 className=\"flex items-center gap-2 font-display text-lg font-semibold text-text-primary\">\n <Boxes className=\"h-5 w-5 text-accent\" aria-hidden=\"true\" /> Items\n </h2>\n <Button size=\"sm\" variant=\"outline\" onClick={() => setAddItemOpen(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" /> Add\n </Button>\n </div>\n {items.length === 0 ? (\n <EmptyState\n icon={<Boxes className=\"h-9 w-9\" />}\n title=\"No artifacts in this collection\"\n description=\"Add the first artifact to this collection.\"\n action={\n <Button onClick={() => setAddItemOpen(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" /> Add artifact\n </Button>\n }\n />\n ) : (\n <div className=\"grid gap-4 sm:grid-cols-2\">\n {items.map((item) => (\n <ArchiveItemCard\n key={item.id}\n item={item}\n onOpen={() => navigateTo(`archive/items/${item.id}`)}\n />\n ))}\n </div>\n )}\n </GlassCard>\n\n {/* Oral histories */}\n <GlassCard treatment=\"plain\" className=\"flex flex-col gap-4 p-5\">\n <div className=\"flex items-center justify-between gap-3\">\n <h2 className=\"flex items-center gap-2 font-display text-lg font-semibold text-text-primary\">\n <AudioLines className=\"h-5 w-5 text-accent\" aria-hidden=\"true\" /> Oral histories\n </h2>\n <Button size=\"sm\" variant=\"outline\" onClick={() => setRecordOpen(true)}>\n <Mic className=\"mr-1.5 h-4 w-4\" /> Record\n </Button>\n </div>\n {oralHistories.length === 0 ? (\n <EmptyState\n icon={<AudioLines className=\"h-9 w-9\" />}\n title=\"No oral histories yet\"\n description=\"Record a first-person account for this collection.\"\n action={\n <Button onClick={() => setRecordOpen(true)}>\n <Mic className=\"mr-1.5 h-4 w-4\" /> Record\n </Button>\n }\n />\n ) : (\n <div className=\"flex flex-col gap-4\">\n {oralHistories.map((oralHistory) => (\n <OralHistoryPlayerRow key={oralHistory.id} oralHistory={oralHistory} />\n ))}\n </div>\n )}\n </GlassCard>\n </div>\n\n <CreateArchiveItemDialog\n open={addItemOpen}\n onOpenChange={setAddItemOpen}\n collectionId={collection.id}\n />\n <RecordOralHistoryDialog\n open={recordOpen}\n onOpenChange={setRecordOpen}\n collectionId={collection.id}\n />\n </Shell>\n );\n}\n"],"mappings":"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"}
|