@burdenoff/microfe-theculturepost 2026.705.2 → 2026.709.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/dev/main.d.ts +2 -0
- package/dist/dev/main.d.ts.map +1 -0
- package/dist/generated/global-operations.d.ts +2 -0
- package/dist/generated/global-operations.d.ts.map +1 -0
- package/dist/generated/global-types.d.ts +18199 -0
- package/dist/generated/global-types.d.ts.map +1 -0
- package/dist/generated/wspace-operations.d.ts +2 -0
- package/dist/generated/wspace-operations.d.ts.map +1 -0
- package/dist/generated/wspace-types.d.ts +43046 -0
- package/dist/generated/wspace-types.d.ts.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -1
- package/dist/services/assistantApi.d.ts +15 -0
- package/dist/services/assistantApi.d.ts.map +1 -0
- package/dist/services/assistantApi.js +204 -0
- package/dist/services/assistantApi.js.map +1 -0
- package/dist/services/createSandboxAssistantTransport.d.ts +26 -0
- package/dist/services/createSandboxAssistantTransport.d.ts.map +1 -0
- package/dist/services/createSandboxAssistantTransport.js +126 -0
- package/dist/services/createSandboxAssistantTransport.js.map +1 -0
- package/dist/theculturepost/TheCulturePostRoot.d.ts +5 -0
- package/dist/theculturepost/TheCulturePostRoot.d.ts.map +1 -0
- package/dist/theculturepost/TheCulturePostRoutes.d.ts +4 -0
- package/dist/theculturepost/TheCulturePostRoutes.d.ts.map +1 -0
- package/dist/theculturepost/TheCulturePostRoutes.js +73 -40
- package/dist/theculturepost/TheCulturePostRoutes.js.map +1 -1
- package/dist/theculturepost/components/AddCitationDialog.d.ts +11 -0
- package/dist/theculturepost/components/AddCitationDialog.d.ts.map +1 -0
- package/dist/theculturepost/components/ArchiveItemCard.d.ts +9 -0
- package/dist/theculturepost/components/ArchiveItemCard.d.ts.map +1 -0
- package/dist/theculturepost/components/AudioPlayer.d.ts +22 -0
- package/dist/theculturepost/components/AudioPlayer.d.ts.map +1 -0
- package/dist/theculturepost/components/AuthorLabel.d.ts +16 -0
- package/dist/theculturepost/components/AuthorLabel.d.ts.map +1 -0
- package/dist/theculturepost/components/AuthorLabel.js +1 -1
- package/dist/theculturepost/components/CitationList.d.ts +27 -0
- package/dist/theculturepost/components/CitationList.d.ts.map +1 -0
- package/dist/theculturepost/components/CollectionCard.d.ts +9 -0
- package/dist/theculturepost/components/CollectionCard.d.ts.map +1 -0
- package/dist/theculturepost/components/CoverImage.d.ts +13 -0
- package/dist/theculturepost/components/CoverImage.d.ts.map +1 -0
- package/dist/theculturepost/components/CreateArchiveItemDialog.d.ts +12 -0
- package/dist/theculturepost/components/CreateArchiveItemDialog.d.ts.map +1 -0
- package/dist/theculturepost/components/CreateCollectionDialog.d.ts +10 -0
- package/dist/theculturepost/components/CreateCollectionDialog.d.ts.map +1 -0
- package/dist/theculturepost/components/CreateStoryDialog.d.ts +12 -0
- package/dist/theculturepost/components/CreateStoryDialog.d.ts.map +1 -0
- package/dist/theculturepost/components/CreateTopicDialog.d.ts +10 -0
- package/dist/theculturepost/components/CreateTopicDialog.d.ts.map +1 -0
- package/dist/theculturepost/components/DecorativeCover.d.ts +17 -0
- package/dist/theculturepost/components/DecorativeCover.d.ts.map +1 -0
- package/dist/theculturepost/components/DecorativeDivider.d.ts +14 -0
- package/dist/theculturepost/components/DecorativeDivider.d.ts.map +1 -0
- package/dist/theculturepost/components/DiscussionCard.d.ts +9 -0
- package/dist/theculturepost/components/DiscussionCard.d.ts.map +1 -0
- package/dist/theculturepost/components/EmptyState.d.ts +18 -0
- package/dist/theculturepost/components/EmptyState.d.ts.map +1 -0
- package/dist/theculturepost/components/FileImage.d.ts +18 -0
- package/dist/theculturepost/components/FileImage.d.ts.map +1 -0
- package/dist/theculturepost/components/FileUploadField.d.ts +29 -0
- package/dist/theculturepost/components/FileUploadField.d.ts.map +1 -0
- package/dist/theculturepost/components/FilterTabs.d.ts +18 -0
- package/dist/theculturepost/components/FilterTabs.d.ts.map +1 -0
- package/dist/theculturepost/components/HistoryTimeline.d.ts +20 -0
- package/dist/theculturepost/components/HistoryTimeline.d.ts.map +1 -0
- package/dist/theculturepost/components/LifecycleStepper.d.ts +11 -0
- package/dist/theculturepost/components/LifecycleStepper.d.ts.map +1 -0
- package/dist/theculturepost/components/OpenDiscussionDialog.d.ts +12 -0
- package/dist/theculturepost/components/OpenDiscussionDialog.d.ts.map +1 -0
- package/dist/theculturepost/components/OralHistoryCard.d.ts +8 -0
- package/dist/theculturepost/components/OralHistoryCard.d.ts.map +1 -0
- package/dist/theculturepost/components/OverlayBadge.d.ts +15 -0
- package/dist/theculturepost/components/OverlayBadge.d.ts.map +1 -0
- package/dist/theculturepost/components/PageHero.d.ts +26 -0
- package/dist/theculturepost/components/PageHero.d.ts.map +1 -0
- package/dist/theculturepost/components/PageLayout.d.ts +16 -0
- package/dist/theculturepost/components/PageLayout.d.ts.map +1 -0
- package/dist/theculturepost/components/Pagination.d.ts +22 -0
- package/dist/theculturepost/components/Pagination.d.ts.map +1 -0
- package/dist/theculturepost/components/RecordOralHistoryDialog.d.ts +47 -0
- package/dist/theculturepost/components/RecordOralHistoryDialog.d.ts.map +1 -0
- package/dist/theculturepost/components/ReplyThread.d.ts +20 -0
- package/dist/theculturepost/components/ReplyThread.d.ts.map +1 -0
- package/dist/theculturepost/components/ReplyThread.js +1 -1
- package/dist/theculturepost/components/StateViews.d.ts +24 -0
- package/dist/theculturepost/components/StateViews.d.ts.map +1 -0
- package/dist/theculturepost/components/StatusBadge.d.ts +11 -0
- package/dist/theculturepost/components/StatusBadge.d.ts.map +1 -0
- package/dist/theculturepost/components/StoryCard.d.ts +11 -0
- package/dist/theculturepost/components/StoryCard.d.ts.map +1 -0
- package/dist/theculturepost/components/Tabs.d.ts +17 -0
- package/dist/theculturepost/components/Tabs.d.ts.map +1 -0
- package/dist/theculturepost/components/TagInput.d.ts +20 -0
- package/dist/theculturepost/components/TagInput.d.ts.map +1 -0
- package/dist/theculturepost/components/TopicCard.d.ts +9 -0
- package/dist/theculturepost/components/TopicCard.d.ts.map +1 -0
- package/dist/theculturepost/components/Waveform.d.ts +23 -0
- package/dist/theculturepost/components/Waveform.d.ts.map +1 -0
- package/dist/theculturepost/components/categoryMeta.d.ts +14 -0
- package/dist/theculturepost/components/categoryMeta.d.ts.map +1 -0
- package/dist/theculturepost/components/index.d.ts +43 -0
- package/dist/theculturepost/components/index.d.ts.map +1 -0
- package/dist/theculturepost/components/kindIcon.d.ts +7 -0
- package/dist/theculturepost/components/kindIcon.d.ts.map +1 -0
- package/dist/theculturepost/components/viz/BarChart.d.ts +23 -0
- package/dist/theculturepost/components/viz/BarChart.d.ts.map +1 -0
- package/dist/theculturepost/components/viz/Donut.d.ts +25 -0
- package/dist/theculturepost/components/viz/Donut.d.ts.map +1 -0
- package/dist/theculturepost/components/viz/StatTile.d.ts +14 -0
- package/dist/theculturepost/components/viz/StatTile.d.ts.map +1 -0
- package/dist/theculturepost/components/viz/index.d.ts +11 -0
- package/dist/theculturepost/components/viz/index.d.ts.map +1 -0
- package/dist/theculturepost/context/TheCulturePostContext.d.ts +16 -0
- package/dist/theculturepost/context/TheCulturePostContext.d.ts.map +1 -0
- package/dist/theculturepost/context/index.d.ts +6 -0
- package/dist/theculturepost/context/index.d.ts.map +1 -0
- package/dist/theculturepost/hooks/index.d.ts +10 -0
- package/dist/theculturepost/hooks/index.d.ts.map +1 -0
- package/dist/theculturepost/hooks/index.js +2 -0
- package/dist/theculturepost/hooks/useCursorPager.d.ts +32 -0
- package/dist/theculturepost/hooks/useCursorPager.d.ts.map +1 -0
- package/dist/theculturepost/hooks/useFiles.d.ts +31 -0
- package/dist/theculturepost/hooks/useFiles.d.ts.map +1 -0
- package/dist/theculturepost/hooks/usePageAnalytics.d.ts +9 -0
- package/dist/theculturepost/hooks/usePageAnalytics.d.ts.map +1 -0
- package/dist/theculturepost/hooks/usePageAnalytics.js +34 -0
- package/dist/theculturepost/hooks/usePageAnalytics.js.map +1 -0
- package/dist/theculturepost/hooks/useTcpApi.d.ts +74 -0
- package/dist/theculturepost/hooks/useTcpApi.d.ts.map +1 -0
- package/dist/theculturepost/hooks/useTr.d.ts +8 -0
- package/dist/theculturepost/hooks/useTr.d.ts.map +1 -0
- package/dist/theculturepost/hooks/useTr.js +14 -0
- package/dist/theculturepost/hooks/useTr.js.map +1 -0
- package/dist/theculturepost/index.d.ts +9 -0
- package/dist/theculturepost/index.d.ts.map +1 -0
- package/dist/theculturepost/index.js +2 -1
- package/dist/theculturepost/lib/graphql-cache.d.ts +26 -0
- package/dist/theculturepost/lib/graphql-cache.d.ts.map +1 -0
- package/dist/theculturepost/lib/toast.d.ts +23 -0
- package/dist/theculturepost/lib/toast.d.ts.map +1 -0
- package/dist/theculturepost/pages/HomePage.d.ts +16 -0
- package/dist/theculturepost/pages/HomePage.d.ts.map +1 -0
- package/dist/theculturepost/pages/HomePage.js +83 -68
- package/dist/theculturepost/pages/HomePage.js.map +1 -1
- package/dist/theculturepost/pages/archive/ArchiveItemDetailPage.d.ts +12 -0
- package/dist/theculturepost/pages/archive/ArchiveItemDetailPage.d.ts.map +1 -0
- package/dist/theculturepost/pages/archive/ArchiveItemDetailPage.js +21 -21
- package/dist/theculturepost/pages/archive/ArchivePage.d.ts +7 -0
- package/dist/theculturepost/pages/archive/ArchivePage.d.ts.map +1 -0
- package/dist/theculturepost/pages/archive/ArchivePage.js +144 -125
- package/dist/theculturepost/pages/archive/ArchivePage.js.map +1 -1
- package/dist/theculturepost/pages/archive/CollectionDetailPage.d.ts +12 -0
- package/dist/theculturepost/pages/archive/CollectionDetailPage.d.ts.map +1 -0
- package/dist/theculturepost/pages/discussions/DiscussionDetailPage.d.ts +12 -0
- package/dist/theculturepost/pages/discussions/DiscussionDetailPage.d.ts.map +1 -0
- package/dist/theculturepost/pages/discussions/DiscussionDetailPage.js +78 -70
- package/dist/theculturepost/pages/discussions/DiscussionDetailPage.js.map +1 -1
- package/dist/theculturepost/pages/discussions/DiscussionsPage.d.ts +10 -0
- package/dist/theculturepost/pages/discussions/DiscussionsPage.d.ts.map +1 -0
- package/dist/theculturepost/pages/discussions/DiscussionsPage.js +63 -56
- package/dist/theculturepost/pages/discussions/DiscussionsPage.js.map +1 -1
- package/dist/theculturepost/pages/governance/GovernancePage.d.ts +20 -0
- package/dist/theculturepost/pages/governance/GovernancePage.d.ts.map +1 -0
- package/dist/theculturepost/pages/stories/StoriesPage.d.ts +9 -0
- package/dist/theculturepost/pages/stories/StoriesPage.d.ts.map +1 -0
- package/dist/theculturepost/pages/stories/StoriesPage.js +65 -58
- package/dist/theculturepost/pages/stories/StoriesPage.js.map +1 -1
- package/dist/theculturepost/pages/stories/StoryDetailPage.d.ts +18 -0
- package/dist/theculturepost/pages/stories/StoryDetailPage.d.ts.map +1 -0
- package/dist/theculturepost/pages/stories/StoryDetailPage.js +249 -229
- package/dist/theculturepost/pages/stories/StoryDetailPage.js.map +1 -1
- package/dist/theculturepost/pages/timeline/TimelinePage.d.ts +17 -0
- package/dist/theculturepost/pages/timeline/TimelinePage.d.ts.map +1 -0
- package/dist/theculturepost/pages/topics/TopicDetailPage.d.ts +12 -0
- package/dist/theculturepost/pages/topics/TopicDetailPage.d.ts.map +1 -0
- package/dist/theculturepost/pages/topics/TopicsPage.d.ts +12 -0
- package/dist/theculturepost/pages/topics/TopicsPage.d.ts.map +1 -0
- package/dist/theculturepost/pages/topics/TopicsPage.js +61 -52
- package/dist/theculturepost/pages/topics/TopicsPage.js.map +1 -1
- package/dist/theculturepost/styles/injectDisplayFont.d.ts +14 -0
- package/dist/theculturepost/styles/injectDisplayFont.d.ts.map +1 -0
- package/dist/theculturepost/translations/ar.d.ts +50 -0
- package/dist/theculturepost/translations/ar.d.ts.map +1 -0
- package/dist/theculturepost/translations/ar.js +54 -0
- package/dist/theculturepost/translations/ar.js.map +1 -0
- package/dist/theculturepost/translations/en.d.ts +50 -0
- package/dist/theculturepost/translations/en.d.ts.map +1 -0
- package/dist/theculturepost/translations/en.js +54 -0
- package/dist/theculturepost/translations/en.js.map +1 -0
- package/dist/theculturepost/translations/es.d.ts +50 -0
- package/dist/theculturepost/translations/es.d.ts.map +1 -0
- package/dist/theculturepost/translations/es.js +54 -0
- package/dist/theculturepost/translations/es.js.map +1 -0
- package/dist/theculturepost/translations/hi.d.ts +50 -0
- package/dist/theculturepost/translations/hi.d.ts.map +1 -0
- package/dist/theculturepost/translations/hi.js +54 -0
- package/dist/theculturepost/translations/hi.js.map +1 -0
- package/dist/theculturepost/translations/index.d.ts +7 -0
- package/dist/theculturepost/translations/index.d.ts.map +1 -0
- package/dist/theculturepost/translations/ta.d.ts +50 -0
- package/dist/theculturepost/translations/ta.d.ts.map +1 -0
- package/dist/theculturepost/translations/ta.js +54 -0
- package/dist/theculturepost/translations/ta.js.map +1 -0
- package/dist/theculturepost/translations/zh.d.ts +50 -0
- package/dist/theculturepost/translations/zh.d.ts.map +1 -0
- package/dist/theculturepost/translations/zh.js +54 -0
- package/dist/theculturepost/translations/zh.js.map +1 -0
- package/dist/theculturepost/types/index.d.ts +333 -0
- package/dist/theculturepost/types/index.d.ts.map +1 -0
- package/dist/theculturepost/utils/cn.d.ts +4 -0
- package/dist/theculturepost/utils/cn.d.ts.map +1 -0
- package/dist/theculturepost/utils/formatters.d.ts +19 -0
- package/dist/theculturepost/utils/formatters.d.ts.map +1 -0
- package/dist/theculturepost/utils/i18n.d.ts +6 -0
- package/dist/theculturepost/utils/i18n.d.ts.map +1 -0
- package/dist/theculturepost/utils/index.d.ts +11 -0
- package/dist/theculturepost/utils/index.d.ts.map +1 -0
- package/dist/theculturepost/utils/index.js +6 -0
- package/dist/theculturepost/utils/nativeBridge.d.ts +47 -0
- package/dist/theculturepost/utils/nativeBridge.d.ts.map +1 -0
- package/dist/theculturepost/utils/nativeBridge.js +60 -0
- package/dist/theculturepost/utils/nativeBridge.js.map +1 -0
- package/dist/theculturepost/utils/navigation.d.ts +14 -0
- package/dist/theculturepost/utils/navigation.d.ts.map +1 -0
- package/dist/theculturepost/utils/slug.d.ts +6 -0
- package/dist/theculturepost/utils/slug.d.ts.map +1 -0
- package/dist/types/assistant.d.ts +56 -0
- package/dist/types/assistant.d.ts.map +1 -0
- package/dist/utils/pageContext.d.ts +27 -0
- package/dist/utils/pageContext.d.ts.map +1 -0
- package/dist/utils/pageContext.js +47 -0
- package/dist/utils/pageContext.js.map +1 -0
- package/package.json +29 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useTheCulturePost as e } from "../../context/TheCulturePostContext.js";
|
|
2
|
-
import { cn as t } from "../../utils/cn.js";
|
|
3
2
|
import "../../context/index.js";
|
|
3
|
+
import { cn as t } from "../../utils/cn.js";
|
|
4
4
|
import { useFileUrl as n } from "../../hooks/useFiles.js";
|
|
5
5
|
import { PageHero as r } from "../../components/PageHero.js";
|
|
6
6
|
import { ErrorView as i, LoadingView as a } from "../../components/StateViews.js";
|
|
@@ -9,310 +9,329 @@ import { StatusBadge as c } from "../../components/StatusBadge.js";
|
|
|
9
9
|
import { EmptyState as l } from "../../components/EmptyState.js";
|
|
10
10
|
import { useTcpArchiveItems as u, useTcpCollections as d, useTcpOralHistories as f } from "../../hooks/useTcpApi.js";
|
|
11
11
|
import { useCursorPager as p } from "../../hooks/useCursorPager.js";
|
|
12
|
+
import { useTr as m } from "../../hooks/useTr.js";
|
|
12
13
|
import "../../hooks/index.js";
|
|
13
|
-
import { KIND_ICON as
|
|
14
|
-
import { Tabs as
|
|
15
|
-
import { AudioPlayer as
|
|
16
|
-
import { CollectionCard as
|
|
17
|
-
import { ArchiveItemCard as
|
|
18
|
-
import { RecordOralHistoryDialog as
|
|
19
|
-
import { CreateCollectionDialog as
|
|
20
|
-
import { CreateArchiveItemDialog as
|
|
21
|
-
import { Pagination as
|
|
22
|
-
import { createElement as
|
|
23
|
-
import { AudioLines as
|
|
24
|
-
import { Fragment as
|
|
25
|
-
import { Button as
|
|
14
|
+
import { KIND_ICON as h } from "../../components/kindIcon.js";
|
|
15
|
+
import { Tabs as g } from "../../components/Tabs.js";
|
|
16
|
+
import { AudioPlayer as _ } from "../../components/AudioPlayer.js";
|
|
17
|
+
import { CollectionCard as v } from "../../components/CollectionCard.js";
|
|
18
|
+
import { ArchiveItemCard as y } from "../../components/ArchiveItemCard.js";
|
|
19
|
+
import { RecordOralHistoryDialog as b } from "../../components/RecordOralHistoryDialog.js";
|
|
20
|
+
import { CreateCollectionDialog as x } from "../../components/CreateCollectionDialog.js";
|
|
21
|
+
import { CreateArchiveItemDialog as S } from "../../components/CreateArchiveItemDialog.js";
|
|
22
|
+
import { Pagination as C } from "../../components/Pagination.js";
|
|
23
|
+
import { createElement as w, useState as T } from "react";
|
|
24
|
+
import { AudioLines as E, Boxes as D, Globe as O, Layers as k, Library as A, Mic as j, Plus as M } from "lucide-react";
|
|
25
|
+
import { Fragment as N, jsx as P, jsxs as F } from "react/jsx-runtime";
|
|
26
|
+
import { Button as I, GlassCard as L, Select as R, SelectContent as z, SelectItem as B, SelectTrigger as V, SelectValue as H } from "@burdenoff/fe-libs/ui";
|
|
26
27
|
//#region src/theculturepost/pages/archive/ArchivePage.tsx
|
|
27
|
-
var
|
|
28
|
+
var U = [
|
|
28
29
|
{
|
|
29
30
|
value: "collections",
|
|
30
31
|
label: "Collections",
|
|
31
|
-
icon: /* @__PURE__ */
|
|
32
|
+
icon: /* @__PURE__ */ P(A, { className: "h-4 w-4" })
|
|
32
33
|
},
|
|
33
34
|
{
|
|
34
35
|
value: "artifacts",
|
|
35
36
|
label: "Artifacts",
|
|
36
|
-
icon: /* @__PURE__ */
|
|
37
|
+
icon: /* @__PURE__ */ P(D, { className: "h-4 w-4" })
|
|
37
38
|
},
|
|
38
39
|
{
|
|
39
40
|
value: "oral-histories",
|
|
40
41
|
label: "Oral Histories",
|
|
41
|
-
icon: /* @__PURE__ */
|
|
42
|
+
icon: /* @__PURE__ */ P(E, { className: "h-4 w-4" })
|
|
42
43
|
}
|
|
43
44
|
];
|
|
44
|
-
function
|
|
45
|
-
let { navigateTo: t } = e(),
|
|
46
|
-
|
|
45
|
+
function W() {
|
|
46
|
+
let { navigateTo: t } = e(), n = m(), [i, a] = T("collections"), [o, s] = T(!1), [c, l] = T(!1), [u, d] = T(!1), f = i === "collections" ? /* @__PURE__ */ F(I, {
|
|
47
|
+
onClick: () => s(!0),
|
|
48
|
+
"data-tour": "theculturepost-archive-new-collection",
|
|
49
|
+
children: [
|
|
50
|
+
/* @__PURE__ */ P(M, { className: "mr-1.5 h-4 w-4" }),
|
|
51
|
+
" ",
|
|
52
|
+
n("archive.newCollection", "New collection")
|
|
53
|
+
]
|
|
54
|
+
}) : i === "artifacts" ? /* @__PURE__ */ F(I, {
|
|
55
|
+
onClick: () => l(!0),
|
|
56
|
+
"data-tour": "theculturepost-archive-new-artifact",
|
|
57
|
+
children: [
|
|
58
|
+
/* @__PURE__ */ P(M, { className: "mr-1.5 h-4 w-4" }),
|
|
59
|
+
" ",
|
|
60
|
+
n("archive.newArtifact", "Add artifact")
|
|
61
|
+
]
|
|
62
|
+
}) : /* @__PURE__ */ F(I, {
|
|
63
|
+
onClick: () => d(!0),
|
|
64
|
+
"data-tour": "theculturepost-archive-new-recording",
|
|
65
|
+
children: [
|
|
66
|
+
/* @__PURE__ */ P(j, { className: "mr-1.5 h-4 w-4" }),
|
|
67
|
+
" ",
|
|
68
|
+
n("archive.newRecording", "Record")
|
|
69
|
+
]
|
|
70
|
+
});
|
|
71
|
+
return /* @__PURE__ */ F("div", {
|
|
47
72
|
className: "flex h-full flex-col",
|
|
48
73
|
children: [
|
|
49
|
-
/* @__PURE__ */
|
|
74
|
+
/* @__PURE__ */ P("div", {
|
|
50
75
|
className: "flex-1 overflow-auto",
|
|
51
|
-
children: /* @__PURE__ */
|
|
76
|
+
children: /* @__PURE__ */ F("div", {
|
|
52
77
|
className: "mx-auto flex w-full max-w-6xl flex-col gap-6 p-4 sm:p-6",
|
|
53
|
-
children: [/* @__PURE__ */
|
|
78
|
+
children: [/* @__PURE__ */ P(r, {
|
|
54
79
|
eyebrow: "Cultural archive",
|
|
55
|
-
title: "Archive",
|
|
56
|
-
description: "A living archive of manuscripts, photographs, recordings, maps and objects — grouped into collections.",
|
|
57
|
-
actions:
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
className: "mb-6"
|
|
73
|
-
}),
|
|
74
|
-
n === "collections" && /* @__PURE__ */ N(W, { onNew: () => o(!0) }),
|
|
75
|
-
n === "artifacts" && /* @__PURE__ */ N(J, { onNew: () => c(!0) }),
|
|
76
|
-
n === "oral-histories" && /* @__PURE__ */ N(Y, { onNew: () => u(!0) })
|
|
77
|
-
] })]
|
|
80
|
+
title: n("archive.title", "Archive"),
|
|
81
|
+
description: n("archive.description", "A living archive of manuscripts, photographs, recordings, maps and objects — grouped into collections."),
|
|
82
|
+
actions: f
|
|
83
|
+
}), /* @__PURE__ */ F("div", {
|
|
84
|
+
"data-tour": "theculturepost-archive-tabs",
|
|
85
|
+
children: [
|
|
86
|
+
/* @__PURE__ */ P(g, {
|
|
87
|
+
items: U,
|
|
88
|
+
value: i,
|
|
89
|
+
onChange: a,
|
|
90
|
+
className: "mb-6"
|
|
91
|
+
}),
|
|
92
|
+
i === "collections" && /* @__PURE__ */ P(G, { onNew: () => s(!0) }),
|
|
93
|
+
i === "artifacts" && /* @__PURE__ */ P(Y, { onNew: () => l(!0) }),
|
|
94
|
+
i === "oral-histories" && /* @__PURE__ */ P(X, { onNew: () => d(!0) })
|
|
95
|
+
]
|
|
96
|
+
})]
|
|
78
97
|
})
|
|
79
98
|
}),
|
|
80
|
-
/* @__PURE__ */
|
|
81
|
-
open:
|
|
82
|
-
onOpenChange:
|
|
99
|
+
/* @__PURE__ */ P(x, {
|
|
100
|
+
open: o,
|
|
101
|
+
onOpenChange: s,
|
|
83
102
|
onCreated: (e) => t(`archive/collections/${e.id}`)
|
|
84
103
|
}),
|
|
85
|
-
/* @__PURE__ */
|
|
86
|
-
open:
|
|
87
|
-
onOpenChange:
|
|
104
|
+
/* @__PURE__ */ P(S, {
|
|
105
|
+
open: c,
|
|
106
|
+
onOpenChange: l,
|
|
88
107
|
onCreated: (e) => t(`archive/items/${e.id}`)
|
|
89
108
|
}),
|
|
90
|
-
/* @__PURE__ */
|
|
91
|
-
open:
|
|
92
|
-
onOpenChange:
|
|
109
|
+
/* @__PURE__ */ P(b, {
|
|
110
|
+
open: u,
|
|
111
|
+
onOpenChange: d
|
|
93
112
|
})
|
|
94
113
|
]
|
|
95
114
|
});
|
|
96
115
|
}
|
|
97
|
-
function
|
|
116
|
+
function G({ onNew: t }) {
|
|
98
117
|
let { navigateTo: n } = e(), { data: r, isLoading: o, isError: s, refetch: c } = d({ limit: 60 }), u = r ?? [];
|
|
99
|
-
return o ? /* @__PURE__ */
|
|
118
|
+
return o ? /* @__PURE__ */ P(a, { label: "Loading collections…" }) : s ? /* @__PURE__ */ P(i, {
|
|
100
119
|
message: "We couldn't load collections.",
|
|
101
120
|
onRetry: () => c()
|
|
102
|
-
}) : u.length === 0 ? /* @__PURE__ */
|
|
121
|
+
}) : u.length === 0 ? /* @__PURE__ */ P(l, {
|
|
103
122
|
illustration: "empty-files",
|
|
104
|
-
icon: /* @__PURE__ */
|
|
123
|
+
icon: /* @__PURE__ */ P(A, { className: "h-10 w-10" }),
|
|
105
124
|
title: "No collections yet",
|
|
106
125
|
description: "Create a collection to begin grouping artifacts and oral histories.",
|
|
107
|
-
action: /* @__PURE__ */
|
|
126
|
+
action: /* @__PURE__ */ F(I, {
|
|
108
127
|
onClick: t,
|
|
109
|
-
children: [/* @__PURE__ */
|
|
128
|
+
children: [/* @__PURE__ */ P(M, { className: "mr-1.5 h-4 w-4" }), " New collection"]
|
|
110
129
|
})
|
|
111
|
-
}) : /* @__PURE__ */
|
|
130
|
+
}) : /* @__PURE__ */ P("div", {
|
|
112
131
|
className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4",
|
|
113
|
-
children: u.map((e) => /* @__PURE__ */
|
|
132
|
+
children: u.map((e) => /* @__PURE__ */ P(v, {
|
|
114
133
|
collection: e,
|
|
115
134
|
onOpen: () => n(`archive/collections/${e.id}`)
|
|
116
135
|
}, e.id))
|
|
117
136
|
});
|
|
118
137
|
}
|
|
119
|
-
var
|
|
138
|
+
var K = 16, q = [
|
|
120
139
|
{
|
|
121
140
|
value: "ALL",
|
|
122
141
|
label: "All kinds",
|
|
123
|
-
icon:
|
|
142
|
+
icon: k
|
|
124
143
|
},
|
|
125
144
|
{
|
|
126
145
|
value: "MANUSCRIPT",
|
|
127
146
|
label: "Manuscripts",
|
|
128
|
-
icon:
|
|
147
|
+
icon: h.MANUSCRIPT
|
|
129
148
|
},
|
|
130
149
|
{
|
|
131
150
|
value: "PHOTOGRAPH",
|
|
132
151
|
label: "Photographs",
|
|
133
|
-
icon:
|
|
152
|
+
icon: h.PHOTOGRAPH
|
|
134
153
|
},
|
|
135
154
|
{
|
|
136
155
|
value: "AUDIO",
|
|
137
156
|
label: "Audio",
|
|
138
|
-
icon:
|
|
157
|
+
icon: h.AUDIO
|
|
139
158
|
},
|
|
140
159
|
{
|
|
141
160
|
value: "VIDEO",
|
|
142
161
|
label: "Video",
|
|
143
|
-
icon:
|
|
162
|
+
icon: h.VIDEO
|
|
144
163
|
},
|
|
145
164
|
{
|
|
146
165
|
value: "MAP",
|
|
147
166
|
label: "Maps",
|
|
148
|
-
icon:
|
|
167
|
+
icon: h.MAP
|
|
149
168
|
},
|
|
150
169
|
{
|
|
151
170
|
value: "OBJECT",
|
|
152
171
|
label: "Objects",
|
|
153
|
-
icon:
|
|
172
|
+
icon: h.OBJECT
|
|
154
173
|
},
|
|
155
174
|
{
|
|
156
175
|
value: "DOCUMENT",
|
|
157
176
|
label: "Documents",
|
|
158
|
-
icon:
|
|
177
|
+
icon: h.DOCUMENT
|
|
159
178
|
}
|
|
160
|
-
],
|
|
179
|
+
], J = [
|
|
161
180
|
"PUBLIC",
|
|
162
181
|
"COMMUNITY",
|
|
163
182
|
"RESTRICTED",
|
|
164
183
|
"EMBARGOED"
|
|
165
184
|
];
|
|
166
|
-
function
|
|
167
|
-
let { navigateTo: r } = e(), s = p(), [c, d] =
|
|
185
|
+
function Y({ onNew: n }) {
|
|
186
|
+
let { navigateTo: r } = e(), s = p(), [c, d] = T("ALL"), [f, m] = T("ALL"), { data: h, isLoading: g, isError: _, refetch: v } = u({
|
|
168
187
|
kind: c === "ALL" ? void 0 : c,
|
|
169
188
|
accessLevel: f === "ALL" ? void 0 : f,
|
|
170
189
|
pagination: {
|
|
171
|
-
limit:
|
|
190
|
+
limit: K,
|
|
172
191
|
cursor: s.cursor
|
|
173
192
|
}
|
|
174
193
|
}), b = h?.items ?? [], x = (e) => {
|
|
175
194
|
d(e), s.reset();
|
|
176
195
|
};
|
|
177
|
-
return /* @__PURE__ */
|
|
196
|
+
return /* @__PURE__ */ F("div", { children: [/* @__PURE__ */ F("div", {
|
|
178
197
|
className: "mb-6 flex flex-col gap-4 lg:flex-row lg:items-end lg:justify-between",
|
|
179
|
-
children: [/* @__PURE__ */
|
|
198
|
+
children: [/* @__PURE__ */ F("div", {
|
|
180
199
|
className: "flex flex-col gap-2",
|
|
181
|
-
children: [/* @__PURE__ */
|
|
200
|
+
children: [/* @__PURE__ */ P("span", {
|
|
182
201
|
id: "kind-filter-label",
|
|
183
202
|
className: "text-sm font-medium text-text-secondary",
|
|
184
203
|
children: "Kind"
|
|
185
|
-
}), /* @__PURE__ */
|
|
204
|
+
}), /* @__PURE__ */ P("div", {
|
|
186
205
|
role: "tablist",
|
|
187
206
|
"aria-labelledby": "kind-filter-label",
|
|
188
207
|
className: "flex flex-wrap gap-2",
|
|
189
|
-
children:
|
|
208
|
+
children: q.map((e) => {
|
|
190
209
|
let n = e.value === c;
|
|
191
|
-
return /* @__PURE__ */
|
|
210
|
+
return /* @__PURE__ */ F("button", {
|
|
192
211
|
type: "button",
|
|
193
212
|
role: "tab",
|
|
194
213
|
"aria-selected": n,
|
|
195
214
|
onClick: () => x(e.value),
|
|
196
215
|
className: t("inline-flex items-center gap-2 rounded-xl border px-3 py-2 text-sm font-medium transition-colors", n ? "border-transparent bg-action-primary-bg text-action-primary-text" : "border-border-seam bg-bg-surface text-text-secondary hover:bg-bg-sunken hover:text-text-primary"),
|
|
197
|
-
children: [
|
|
216
|
+
children: [w(e.icon, { className: "h-4 w-4" }), e.label]
|
|
198
217
|
}, e.value);
|
|
199
218
|
})
|
|
200
219
|
})]
|
|
201
|
-
}), /* @__PURE__ */
|
|
220
|
+
}), /* @__PURE__ */ F("div", {
|
|
202
221
|
className: "flex flex-col gap-2 lg:items-end",
|
|
203
|
-
children: [/* @__PURE__ */
|
|
222
|
+
children: [/* @__PURE__ */ P("label", {
|
|
204
223
|
htmlFor: "access-filter",
|
|
205
224
|
className: "text-sm font-medium text-text-secondary",
|
|
206
225
|
children: "Access level"
|
|
207
|
-
}), /* @__PURE__ */
|
|
226
|
+
}), /* @__PURE__ */ F(R, {
|
|
208
227
|
value: f,
|
|
209
228
|
onValueChange: (e) => {
|
|
210
229
|
m(e), s.reset();
|
|
211
230
|
},
|
|
212
|
-
children: [/* @__PURE__ */
|
|
231
|
+
children: [/* @__PURE__ */ P(V, {
|
|
213
232
|
id: "access-filter",
|
|
214
233
|
className: "w-full lg:w-[12rem]",
|
|
215
234
|
"aria-label": "Filter by access level",
|
|
216
|
-
children: /* @__PURE__ */
|
|
217
|
-
}), /* @__PURE__ */
|
|
235
|
+
children: /* @__PURE__ */ P(H, { placeholder: "All levels" })
|
|
236
|
+
}), /* @__PURE__ */ F(z, { children: [/* @__PURE__ */ P(B, {
|
|
218
237
|
value: "ALL",
|
|
219
238
|
children: "All levels"
|
|
220
|
-
}),
|
|
239
|
+
}), J.map((e) => /* @__PURE__ */ P(B, {
|
|
221
240
|
value: e,
|
|
222
241
|
children: o(e)
|
|
223
242
|
}, e))] })]
|
|
224
243
|
})]
|
|
225
244
|
})]
|
|
226
|
-
}), g ? /* @__PURE__ */
|
|
245
|
+
}), g ? /* @__PURE__ */ P(a, { label: "Loading artifacts…" }) : _ ? /* @__PURE__ */ P(i, {
|
|
227
246
|
message: "We couldn't load artifacts.",
|
|
228
|
-
onRetry: () =>
|
|
229
|
-
}) : b.length === 0 && s.page === 0 ? /* @__PURE__ */
|
|
247
|
+
onRetry: () => v()
|
|
248
|
+
}) : b.length === 0 && s.page === 0 ? /* @__PURE__ */ P(l, {
|
|
230
249
|
illustration: "empty-files",
|
|
231
|
-
icon: /* @__PURE__ */
|
|
250
|
+
icon: /* @__PURE__ */ P(D, { className: "h-10 w-10" }),
|
|
232
251
|
title: c === "ALL" && f === "ALL" ? "No artifacts yet" : "No artifacts match these filters",
|
|
233
252
|
description: c === "ALL" && f === "ALL" ? "Add the first artifact to the archive." : "Try widening the filters, or add a new artifact.",
|
|
234
|
-
action: /* @__PURE__ */
|
|
253
|
+
action: /* @__PURE__ */ F(I, {
|
|
235
254
|
onClick: n,
|
|
236
|
-
children: [/* @__PURE__ */
|
|
255
|
+
children: [/* @__PURE__ */ P(M, { className: "mr-1.5 h-4 w-4" }), " Add artifact"]
|
|
237
256
|
})
|
|
238
|
-
}) : /* @__PURE__ */
|
|
257
|
+
}) : /* @__PURE__ */ F(N, { children: [/* @__PURE__ */ P("div", {
|
|
239
258
|
className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4",
|
|
240
|
-
children: b.map((e) => /* @__PURE__ */
|
|
259
|
+
children: b.map((e) => /* @__PURE__ */ P(y, {
|
|
241
260
|
item: e,
|
|
242
261
|
onOpen: () => r(`archive/items/${e.id}`)
|
|
243
262
|
}, e.id))
|
|
244
|
-
}), /* @__PURE__ */
|
|
263
|
+
}), /* @__PURE__ */ P(C, {
|
|
245
264
|
page: s.page,
|
|
246
|
-
pageSize:
|
|
265
|
+
pageSize: K,
|
|
247
266
|
itemCount: b.length,
|
|
248
267
|
hasMore: h?.pageInfo.hasMore ?? !1,
|
|
249
268
|
onPageChange: (e) => s.onPageChange(e, h?.pageInfo.cursor)
|
|
250
269
|
})] })] });
|
|
251
270
|
}
|
|
252
|
-
function
|
|
271
|
+
function X({ onNew: e }) {
|
|
253
272
|
let { data: t, isLoading: n, isError: r, refetch: o } = f(), s = t ?? [];
|
|
254
|
-
return n ? /* @__PURE__ */
|
|
273
|
+
return n ? /* @__PURE__ */ P(a, { label: "Loading oral histories…" }) : r ? /* @__PURE__ */ P(i, {
|
|
255
274
|
message: "We couldn't load oral histories.",
|
|
256
275
|
onRetry: () => o()
|
|
257
|
-
}) : s.length === 0 ? /* @__PURE__ */
|
|
276
|
+
}) : s.length === 0 ? /* @__PURE__ */ P(l, {
|
|
258
277
|
illustration: "empty-data",
|
|
259
|
-
icon: /* @__PURE__ */
|
|
278
|
+
icon: /* @__PURE__ */ P(E, { className: "h-10 w-10" }),
|
|
260
279
|
title: "No oral histories yet",
|
|
261
280
|
description: "Record a first-person account to preserve it for the archive.",
|
|
262
|
-
action: /* @__PURE__ */
|
|
281
|
+
action: /* @__PURE__ */ F(I, {
|
|
263
282
|
onClick: e,
|
|
264
|
-
children: [/* @__PURE__ */
|
|
283
|
+
children: [/* @__PURE__ */ P(j, { className: "mr-1.5 h-4 w-4" }), " Record oral history"]
|
|
265
284
|
})
|
|
266
|
-
}) : /* @__PURE__ */
|
|
285
|
+
}) : /* @__PURE__ */ P("div", {
|
|
267
286
|
className: "flex flex-col gap-4",
|
|
268
|
-
children: s.map((e) => /* @__PURE__ */
|
|
287
|
+
children: s.map((e) => /* @__PURE__ */ P(Z, { oralHistory: e }, e.id))
|
|
269
288
|
});
|
|
270
289
|
}
|
|
271
|
-
function
|
|
290
|
+
function Z({ oralHistory: e }) {
|
|
272
291
|
let { data: t } = n(e.recording?.id), r = e.narratorName?.trim(), i = e.summary?.trim() || e.transcript?.trim();
|
|
273
|
-
return /* @__PURE__ */
|
|
292
|
+
return /* @__PURE__ */ F(L, {
|
|
274
293
|
treatment: "plain",
|
|
275
294
|
className: "flex flex-col gap-4 p-4 sm:flex-row sm:items-start",
|
|
276
|
-
children: [/* @__PURE__ */
|
|
295
|
+
children: [/* @__PURE__ */ P("div", {
|
|
277
296
|
className: "flex h-14 w-14 shrink-0 items-center justify-center rounded-full bg-gradient-to-br from-[var(--color-accent-soft)] to-bg-sunken text-sm font-semibold text-text-primary",
|
|
278
297
|
"aria-hidden": "true",
|
|
279
|
-
children: r ? s(r) : /* @__PURE__ */
|
|
280
|
-
}), /* @__PURE__ */
|
|
298
|
+
children: r ? s(r) : /* @__PURE__ */ P(j, { className: "h-5 w-5" })
|
|
299
|
+
}), /* @__PURE__ */ F("div", {
|
|
281
300
|
className: "min-w-0 flex-1",
|
|
282
301
|
children: [
|
|
283
|
-
/* @__PURE__ */
|
|
302
|
+
/* @__PURE__ */ F("div", {
|
|
284
303
|
className: "flex flex-wrap items-start justify-between gap-2",
|
|
285
|
-
children: [/* @__PURE__ */
|
|
304
|
+
children: [/* @__PURE__ */ F("div", {
|
|
286
305
|
className: "min-w-0",
|
|
287
|
-
children: [/* @__PURE__ */
|
|
306
|
+
children: [/* @__PURE__ */ P("h3", {
|
|
288
307
|
className: "font-display text-lg font-semibold leading-snug text-text-primary",
|
|
289
308
|
children: e.title
|
|
290
|
-
}), r && /* @__PURE__ */
|
|
309
|
+
}), r && /* @__PURE__ */ P("p", {
|
|
291
310
|
className: "mt-0.5 text-sm text-text-secondary",
|
|
292
311
|
children: r
|
|
293
312
|
})]
|
|
294
|
-
}), /* @__PURE__ */
|
|
313
|
+
}), /* @__PURE__ */ F("div", {
|
|
295
314
|
className: "flex flex-wrap items-center gap-1.5",
|
|
296
|
-
children: [e.language && /* @__PURE__ */
|
|
315
|
+
children: [e.language && /* @__PURE__ */ F("span", {
|
|
297
316
|
className: "inline-flex items-center gap-1 rounded-full bg-bg-sunken px-2.5 py-0.5 text-xs font-medium text-text-secondary",
|
|
298
317
|
children: [
|
|
299
|
-
/* @__PURE__ */
|
|
318
|
+
/* @__PURE__ */ P(O, {
|
|
300
319
|
className: "h-3 w-3",
|
|
301
320
|
"aria-hidden": "true"
|
|
302
321
|
}),
|
|
303
322
|
" ",
|
|
304
323
|
o(e.language)
|
|
305
324
|
]
|
|
306
|
-
}), /* @__PURE__ */
|
|
325
|
+
}), /* @__PURE__ */ P(c, { status: e.accessLevel })]
|
|
307
326
|
})]
|
|
308
327
|
}),
|
|
309
|
-
/* @__PURE__ */
|
|
328
|
+
/* @__PURE__ */ P(_, {
|
|
310
329
|
className: "mt-3",
|
|
311
330
|
src: t,
|
|
312
331
|
seed: e.id || e.title,
|
|
313
332
|
durationSecs: e.durationSecs
|
|
314
333
|
}),
|
|
315
|
-
i && /* @__PURE__ */
|
|
334
|
+
i && /* @__PURE__ */ F("p", {
|
|
316
335
|
className: "mt-3 border-l-2 border-[var(--color-accent-soft)] pl-3 text-sm italic leading-relaxed text-text-secondary line-clamp-2",
|
|
317
336
|
children: [
|
|
318
337
|
"“",
|
|
@@ -325,6 +344,6 @@ function X({ oralHistory: e }) {
|
|
|
325
344
|
});
|
|
326
345
|
}
|
|
327
346
|
//#endregion
|
|
328
|
-
export {
|
|
347
|
+
export { W as ArchivePage, Z as OralHistoryPlayerRow };
|
|
329
348
|
|
|
330
349
|
//# sourceMappingURL=ArchivePage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ArchivePage.js","names":[],"sources":["../../../../src/theculturepost/pages/archive/ArchivePage.tsx"],"sourcesContent":["/**\n * ArchivePage — the cultural archive: collections, artifacts and oral histories.\n * @module theculturepost/pages/archive\n *\n * Three tabs, each backed by a real list field: `tcpListCollections`,\n * `tcpListArchiveItems` (filtered by kind + access level) and\n * `tcpListOralHistories`. The primary action lives in the editorial {@link PageHero}\n * and switches with the active tab; creation opens the matching dialog.\n */\n\nimport { createElement, useState } from 'react';\nimport {\n Library,\n Boxes,\n AudioLines,\n Plus,\n Mic,\n Layers,\n Globe,\n type LucideIcon,\n} from 'lucide-react';\nimport {\n Button,\n GlassCard,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@burdenoff/fe-libs/ui';\nimport { PageHero } from '../../components/PageHero';\nimport { Tabs, type TabItem } from '../../components/Tabs';\nimport { AudioPlayer } from '../../components/AudioPlayer';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { CollectionCard } from '../../components/CollectionCard';\nimport { ArchiveItemCard } from '../../components/ArchiveItemCard';\nimport { CreateCollectionDialog } from '../../components/CreateCollectionDialog';\nimport { CreateArchiveItemDialog } from '../../components/CreateArchiveItemDialog';\nimport { RecordOralHistoryDialog } from '../../components/RecordOralHistoryDialog';\nimport { KIND_ICON } from '../../components/kindIcon';\nimport { EmptyState } from '../../components/EmptyState';\nimport { LoadingView, ErrorView } from '../../components/StateViews';\nimport { Pagination } from '../../components/Pagination';\nimport {\n useTcpCollections,\n useTcpArchiveItems,\n useTcpOralHistories,\n useCursorPager,\n useFileUrl,\n} from '../../hooks';\nimport { useTheCulturePost } from '../../context';\nimport { cn } from '../../utils/cn';\nimport { formatEnumLabel, initialsOf } from '../../utils/formatters';\nimport type { TcpArchiveItemKind, TcpAccessLevel, TcpOralHistory } from '../../types';\n\ntype TabKey = 'collections' | 'artifacts' | 'oral-histories';\n\nconst TABS: TabItem<TabKey>[] = [\n { value: 'collections', label: 'Collections', icon: <Library className=\"h-4 w-4\" /> },\n { value: 'artifacts', label: 'Artifacts', icon: <Boxes className=\"h-4 w-4\" /> },\n { value: 'oral-histories', label: 'Oral Histories', icon: <AudioLines className=\"h-4 w-4\" /> },\n];\n\nexport function ArchivePage() {\n const { navigateTo } = useTheCulturePost();\n const [tab, setTab] = useState<TabKey>('collections');\n const [collectionOpen, setCollectionOpen] = useState(false);\n const [artifactOpen, setArtifactOpen] = useState(false);\n const [recordOpen, setRecordOpen] = useState(false);\n\n const heroAction =\n tab === 'collections' ? (\n <Button onClick={() => setCollectionOpen(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" /> New collection\n </Button>\n ) : tab === 'artifacts' ? (\n <Button onClick={() => setArtifactOpen(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" /> Add artifact\n </Button>\n ) : (\n <Button onClick={() => setRecordOpen(true)}>\n <Mic className=\"mr-1.5 h-4 w-4\" /> Record\n </Button>\n );\n\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\">\n <PageHero\n eyebrow=\"Cultural archive\"\n title=\"Archive\"\n description=\"A living archive of manuscripts, photographs, recordings, maps and objects — grouped into collections.\"\n actions={heroAction}\n />\n\n <div>\n <Tabs items={TABS} value={tab} onChange={setTab} className=\"mb-6\" />\n {tab === 'collections' && <CollectionsTab onNew={() => setCollectionOpen(true)} />}\n {tab === 'artifacts' && <ArtifactsTab onNew={() => setArtifactOpen(true)} />}\n {tab === 'oral-histories' && <OralHistoriesTab onNew={() => setRecordOpen(true)} />}\n </div>\n </div>\n </div>\n\n <CreateCollectionDialog\n open={collectionOpen}\n onOpenChange={setCollectionOpen}\n onCreated={(collection) => navigateTo(`archive/collections/${collection.id}`)}\n />\n <CreateArchiveItemDialog\n open={artifactOpen}\n onOpenChange={setArtifactOpen}\n onCreated={(item) => navigateTo(`archive/items/${item.id}`)}\n />\n <RecordOralHistoryDialog open={recordOpen} onOpenChange={setRecordOpen} />\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Collections\n// ---------------------------------------------------------------------------\n\nfunction CollectionsTab({ onNew }: { onNew: () => void }) {\n const { navigateTo } = useTheCulturePost();\n const { data, isLoading, isError, refetch } = useTcpCollections({ limit: 60 });\n const collections = data ?? [];\n\n if (isLoading) return <LoadingView label=\"Loading collections…\" />;\n if (isError)\n return <ErrorView message=\"We couldn't load collections.\" onRetry={() => refetch()} />;\n if (collections.length === 0) {\n return (\n <EmptyState\n illustration=\"empty-files\"\n icon={<Library className=\"h-10 w-10\" />}\n title=\"No collections yet\"\n description=\"Create a collection to begin grouping artifacts and oral histories.\"\n action={\n <Button onClick={onNew}>\n <Plus className=\"mr-1.5 h-4 w-4\" /> New collection\n </Button>\n }\n />\n );\n }\n\n return (\n <div className=\"grid gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4\">\n {collections.map((collection) => (\n <CollectionCard\n key={collection.id}\n collection={collection}\n onOpen={() => navigateTo(`archive/collections/${collection.id}`)}\n />\n ))}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Artifacts\n// ---------------------------------------------------------------------------\n\nconst PAGE_SIZE = 16;\n\ntype KindFilter = 'ALL' | TcpArchiveItemKind;\ntype AccessFilter = 'ALL' | TcpAccessLevel;\n\nconst KIND_FILTERS: { value: KindFilter; label: string; icon: LucideIcon }[] = [\n { value: 'ALL', label: 'All kinds', icon: Layers },\n { value: 'MANUSCRIPT', label: 'Manuscripts', icon: KIND_ICON.MANUSCRIPT },\n { value: 'PHOTOGRAPH', label: 'Photographs', icon: KIND_ICON.PHOTOGRAPH },\n { value: 'AUDIO', label: 'Audio', icon: KIND_ICON.AUDIO },\n { value: 'VIDEO', label: 'Video', icon: KIND_ICON.VIDEO },\n { value: 'MAP', label: 'Maps', icon: KIND_ICON.MAP },\n { value: 'OBJECT', label: 'Objects', icon: KIND_ICON.OBJECT },\n { value: 'DOCUMENT', label: 'Documents', icon: KIND_ICON.DOCUMENT },\n];\n\nconst ACCESS_LEVELS: TcpAccessLevel[] = ['PUBLIC', 'COMMUNITY', 'RESTRICTED', 'EMBARGOED'];\n\nfunction ArtifactsTab({ onNew }: { onNew: () => void }) {\n const { navigateTo } = useTheCulturePost();\n const pager = useCursorPager();\n const [kind, setKind] = useState<KindFilter>('ALL');\n const [accessLevel, setAccessLevel] = useState<AccessFilter>('ALL');\n\n const { data, isLoading, isError, refetch } = useTcpArchiveItems({\n kind: kind === 'ALL' ? undefined : kind,\n accessLevel: accessLevel === 'ALL' ? undefined : accessLevel,\n pagination: { limit: PAGE_SIZE, cursor: pager.cursor },\n });\n\n const items = data?.items ?? [];\n\n const changeKind = (next: KindFilter) => {\n setKind(next);\n pager.reset();\n };\n\n const changeAccess = (next: string) => {\n setAccessLevel(next as AccessFilter);\n pager.reset();\n };\n\n return (\n <div>\n <div className=\"mb-6 flex flex-col gap-4 lg:flex-row lg:items-end lg:justify-between\">\n <div className=\"flex flex-col gap-2\">\n <span id=\"kind-filter-label\" className=\"text-sm font-medium text-text-secondary\">\n Kind\n </span>\n <div role=\"tablist\" aria-labelledby=\"kind-filter-label\" className=\"flex flex-wrap gap-2\">\n {KIND_FILTERS.map((opt) => {\n const active = opt.value === kind;\n return (\n <button\n key={opt.value}\n type=\"button\"\n role=\"tab\"\n aria-selected={active}\n onClick={() => changeKind(opt.value)}\n className={cn(\n 'inline-flex items-center gap-2 rounded-xl border px-3 py-2 text-sm font-medium transition-colors',\n active\n ? 'border-transparent bg-action-primary-bg text-action-primary-text'\n : 'border-border-seam bg-bg-surface text-text-secondary hover:bg-bg-sunken hover:text-text-primary'\n )}\n >\n {createElement(opt.icon, { className: 'h-4 w-4' })}\n {opt.label}\n </button>\n );\n })}\n </div>\n </div>\n\n <div className=\"flex flex-col gap-2 lg:items-end\">\n <label htmlFor=\"access-filter\" className=\"text-sm font-medium text-text-secondary\">\n Access level\n </label>\n <Select value={accessLevel} onValueChange={changeAccess}>\n <SelectTrigger\n id=\"access-filter\"\n className=\"w-full lg:w-[12rem]\"\n aria-label=\"Filter by access level\"\n >\n <SelectValue placeholder=\"All levels\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"ALL\">All levels</SelectItem>\n {ACCESS_LEVELS.map((a) => (\n <SelectItem key={a} value={a}>\n {formatEnumLabel(a)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n\n {isLoading ? (\n <LoadingView label=\"Loading artifacts…\" />\n ) : isError ? (\n <ErrorView message=\"We couldn't load artifacts.\" onRetry={() => refetch()} />\n ) : items.length === 0 && pager.page === 0 ? (\n <EmptyState\n illustration=\"empty-files\"\n icon={<Boxes className=\"h-10 w-10\" />}\n title={\n kind === 'ALL' && accessLevel === 'ALL'\n ? 'No artifacts yet'\n : 'No artifacts match these filters'\n }\n description={\n kind === 'ALL' && accessLevel === 'ALL'\n ? 'Add the first artifact to the archive.'\n : 'Try widening the filters, or add a new artifact.'\n }\n action={\n <Button onClick={onNew}>\n <Plus className=\"mr-1.5 h-4 w-4\" /> Add artifact\n </Button>\n }\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 <Pagination\n page={pager.page}\n pageSize={PAGE_SIZE}\n itemCount={items.length}\n hasMore={data?.pageInfo.hasMore ?? false}\n onPageChange={(target) => pager.onPageChange(target, data?.pageInfo.cursor)}\n />\n </>\n )}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Oral histories\n// ---------------------------------------------------------------------------\n\nfunction OralHistoriesTab({ onNew }: { onNew: () => void }) {\n const { data, isLoading, isError, refetch } = useTcpOralHistories();\n const oralHistories = data ?? [];\n\n if (isLoading) return <LoadingView label=\"Loading oral histories…\" />;\n if (isError)\n return <ErrorView message=\"We couldn't load oral histories.\" onRetry={() => refetch()} />;\n if (oralHistories.length === 0) {\n return (\n <EmptyState\n illustration=\"empty-data\"\n icon={<AudioLines className=\"h-10 w-10\" />}\n title=\"No oral histories yet\"\n description=\"Record a first-person account to preserve it for the archive.\"\n action={\n <Button onClick={onNew}>\n <Mic className=\"mr-1.5 h-4 w-4\" /> Record oral history\n </Button>\n }\n />\n );\n }\n\n return (\n <div className=\"flex flex-col gap-4\">\n {oralHistories.map((oralHistory) => (\n <OralHistoryPlayerRow key={oralHistory.id} oralHistory={oralHistory} />\n ))}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// OralHistoryPlayerRow — an inline listenable oral-history row (reused by the\n// collection detail page). Uses the foundation AudioPlayer for play/seek. Real\n// fields only: narrator is a plain string, there is NO portrait or age.\n// ---------------------------------------------------------------------------\n\nexport function OralHistoryPlayerRow({ oralHistory }: { oralHistory: TcpOralHistory }) {\n const { data: recordingUrl } = useFileUrl(oralHistory.recording?.id);\n const narrator = oralHistory.narratorName?.trim();\n const excerpt = oralHistory.summary?.trim() || oralHistory.transcript?.trim();\n\n return (\n <GlassCard treatment=\"plain\" className=\"flex flex-col gap-4 p-4 sm:flex-row sm:items-start\">\n <div\n className=\"flex h-14 w-14 shrink-0 items-center justify-center rounded-full bg-gradient-to-br from-[var(--color-accent-soft)] to-bg-sunken text-sm font-semibold text-text-primary\"\n aria-hidden=\"true\"\n >\n {narrator ? initialsOf(narrator) : <Mic className=\"h-5 w-5\" />}\n </div>\n\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-start justify-between gap-2\">\n <div className=\"min-w-0\">\n <h3 className=\"font-display text-lg font-semibold leading-snug text-text-primary\">\n {oralHistory.title}\n </h3>\n {narrator && <p className=\"mt-0.5 text-sm text-text-secondary\">{narrator}</p>}\n </div>\n <div className=\"flex flex-wrap items-center gap-1.5\">\n {oralHistory.language && (\n <span className=\"inline-flex items-center gap-1 rounded-full bg-bg-sunken px-2.5 py-0.5 text-xs font-medium text-text-secondary\">\n <Globe className=\"h-3 w-3\" aria-hidden=\"true\" />{' '}\n {formatEnumLabel(oralHistory.language)}\n </span>\n )}\n <StatusBadge status={oralHistory.accessLevel} />\n </div>\n </div>\n\n <AudioPlayer\n className=\"mt-3\"\n src={recordingUrl}\n seed={oralHistory.id || oralHistory.title}\n durationSecs={oralHistory.durationSecs}\n />\n\n {excerpt && (\n <p className=\"mt-3 border-l-2 border-[var(--color-accent-soft)] pl-3 text-sm italic leading-relaxed text-text-secondary line-clamp-2\">\n “{excerpt}”\n </p>\n )}\n </div>\n </GlassCard>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ArchivePage.js","names":[],"sources":["../../../../src/theculturepost/pages/archive/ArchivePage.tsx"],"sourcesContent":["/**\n * ArchivePage — the cultural archive: collections, artifacts and oral histories.\n * @module theculturepost/pages/archive\n *\n * Three tabs, each backed by a real list field: `tcpListCollections`,\n * `tcpListArchiveItems` (filtered by kind + access level) and\n * `tcpListOralHistories`. The primary action lives in the editorial {@link PageHero}\n * and switches with the active tab; creation opens the matching dialog.\n */\n\nimport { createElement, useState } from 'react';\nimport {\n Library,\n Boxes,\n AudioLines,\n Plus,\n Mic,\n Layers,\n Globe,\n type LucideIcon,\n} from 'lucide-react';\nimport {\n Button,\n GlassCard,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@burdenoff/fe-libs/ui';\nimport { PageHero } from '../../components/PageHero';\nimport { Tabs, type TabItem } from '../../components/Tabs';\nimport { AudioPlayer } from '../../components/AudioPlayer';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { CollectionCard } from '../../components/CollectionCard';\nimport { ArchiveItemCard } from '../../components/ArchiveItemCard';\nimport { CreateCollectionDialog } from '../../components/CreateCollectionDialog';\nimport { CreateArchiveItemDialog } from '../../components/CreateArchiveItemDialog';\nimport { RecordOralHistoryDialog } from '../../components/RecordOralHistoryDialog';\nimport { KIND_ICON } from '../../components/kindIcon';\nimport { EmptyState } from '../../components/EmptyState';\nimport { LoadingView, ErrorView } from '../../components/StateViews';\nimport { Pagination } from '../../components/Pagination';\nimport {\n useTcpCollections,\n useTcpArchiveItems,\n useTcpOralHistories,\n useCursorPager,\n useFileUrl,\n useTr,\n} from '../../hooks';\nimport { useTheCulturePost } from '../../context';\nimport { cn } from '../../utils/cn';\nimport { formatEnumLabel, initialsOf } from '../../utils/formatters';\nimport type { TcpArchiveItemKind, TcpAccessLevel, TcpOralHistory } from '../../types';\n\ntype TabKey = 'collections' | 'artifacts' | 'oral-histories';\n\nconst TABS: TabItem<TabKey>[] = [\n { value: 'collections', label: 'Collections', icon: <Library className=\"h-4 w-4\" /> },\n { value: 'artifacts', label: 'Artifacts', icon: <Boxes className=\"h-4 w-4\" /> },\n { value: 'oral-histories', label: 'Oral Histories', icon: <AudioLines className=\"h-4 w-4\" /> },\n];\n\nexport function ArchivePage() {\n const { navigateTo } = useTheCulturePost();\n const tr = useTr();\n const [tab, setTab] = useState<TabKey>('collections');\n const [collectionOpen, setCollectionOpen] = useState(false);\n const [artifactOpen, setArtifactOpen] = useState(false);\n const [recordOpen, setRecordOpen] = useState(false);\n\n const heroAction =\n tab === 'collections' ? (\n <Button\n onClick={() => setCollectionOpen(true)}\n data-tour=\"theculturepost-archive-new-collection\"\n >\n <Plus className=\"mr-1.5 h-4 w-4\" /> {tr('archive.newCollection', 'New collection')}\n </Button>\n ) : tab === 'artifacts' ? (\n <Button onClick={() => setArtifactOpen(true)} data-tour=\"theculturepost-archive-new-artifact\">\n <Plus className=\"mr-1.5 h-4 w-4\" /> {tr('archive.newArtifact', 'Add artifact')}\n </Button>\n ) : (\n <Button onClick={() => setRecordOpen(true)} data-tour=\"theculturepost-archive-new-recording\">\n <Mic className=\"mr-1.5 h-4 w-4\" /> {tr('archive.newRecording', 'Record')}\n </Button>\n );\n\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\">\n <PageHero\n eyebrow=\"Cultural archive\"\n title={tr('archive.title', 'Archive')}\n description={tr(\n 'archive.description',\n 'A living archive of manuscripts, photographs, recordings, maps and objects — grouped into collections.'\n )}\n actions={heroAction}\n />\n\n <div data-tour=\"theculturepost-archive-tabs\">\n <Tabs items={TABS} value={tab} onChange={setTab} className=\"mb-6\" />\n {tab === 'collections' && <CollectionsTab onNew={() => setCollectionOpen(true)} />}\n {tab === 'artifacts' && <ArtifactsTab onNew={() => setArtifactOpen(true)} />}\n {tab === 'oral-histories' && <OralHistoriesTab onNew={() => setRecordOpen(true)} />}\n </div>\n </div>\n </div>\n\n <CreateCollectionDialog\n open={collectionOpen}\n onOpenChange={setCollectionOpen}\n onCreated={(collection) => navigateTo(`archive/collections/${collection.id}`)}\n />\n <CreateArchiveItemDialog\n open={artifactOpen}\n onOpenChange={setArtifactOpen}\n onCreated={(item) => navigateTo(`archive/items/${item.id}`)}\n />\n <RecordOralHistoryDialog open={recordOpen} onOpenChange={setRecordOpen} />\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Collections\n// ---------------------------------------------------------------------------\n\nfunction CollectionsTab({ onNew }: { onNew: () => void }) {\n const { navigateTo } = useTheCulturePost();\n const { data, isLoading, isError, refetch } = useTcpCollections({ limit: 60 });\n const collections = data ?? [];\n\n if (isLoading) return <LoadingView label=\"Loading collections…\" />;\n if (isError)\n return <ErrorView message=\"We couldn't load collections.\" onRetry={() => refetch()} />;\n if (collections.length === 0) {\n return (\n <EmptyState\n illustration=\"empty-files\"\n icon={<Library className=\"h-10 w-10\" />}\n title=\"No collections yet\"\n description=\"Create a collection to begin grouping artifacts and oral histories.\"\n action={\n <Button onClick={onNew}>\n <Plus className=\"mr-1.5 h-4 w-4\" /> New collection\n </Button>\n }\n />\n );\n }\n\n return (\n <div className=\"grid gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4\">\n {collections.map((collection) => (\n <CollectionCard\n key={collection.id}\n collection={collection}\n onOpen={() => navigateTo(`archive/collections/${collection.id}`)}\n />\n ))}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Artifacts\n// ---------------------------------------------------------------------------\n\nconst PAGE_SIZE = 16;\n\ntype KindFilter = 'ALL' | TcpArchiveItemKind;\ntype AccessFilter = 'ALL' | TcpAccessLevel;\n\nconst KIND_FILTERS: { value: KindFilter; label: string; icon: LucideIcon }[] = [\n { value: 'ALL', label: 'All kinds', icon: Layers },\n { value: 'MANUSCRIPT', label: 'Manuscripts', icon: KIND_ICON.MANUSCRIPT },\n { value: 'PHOTOGRAPH', label: 'Photographs', icon: KIND_ICON.PHOTOGRAPH },\n { value: 'AUDIO', label: 'Audio', icon: KIND_ICON.AUDIO },\n { value: 'VIDEO', label: 'Video', icon: KIND_ICON.VIDEO },\n { value: 'MAP', label: 'Maps', icon: KIND_ICON.MAP },\n { value: 'OBJECT', label: 'Objects', icon: KIND_ICON.OBJECT },\n { value: 'DOCUMENT', label: 'Documents', icon: KIND_ICON.DOCUMENT },\n];\n\nconst ACCESS_LEVELS: TcpAccessLevel[] = ['PUBLIC', 'COMMUNITY', 'RESTRICTED', 'EMBARGOED'];\n\nfunction ArtifactsTab({ onNew }: { onNew: () => void }) {\n const { navigateTo } = useTheCulturePost();\n const pager = useCursorPager();\n const [kind, setKind] = useState<KindFilter>('ALL');\n const [accessLevel, setAccessLevel] = useState<AccessFilter>('ALL');\n\n const { data, isLoading, isError, refetch } = useTcpArchiveItems({\n kind: kind === 'ALL' ? undefined : kind,\n accessLevel: accessLevel === 'ALL' ? undefined : accessLevel,\n pagination: { limit: PAGE_SIZE, cursor: pager.cursor },\n });\n\n const items = data?.items ?? [];\n\n const changeKind = (next: KindFilter) => {\n setKind(next);\n pager.reset();\n };\n\n const changeAccess = (next: string) => {\n setAccessLevel(next as AccessFilter);\n pager.reset();\n };\n\n return (\n <div>\n <div className=\"mb-6 flex flex-col gap-4 lg:flex-row lg:items-end lg:justify-between\">\n <div className=\"flex flex-col gap-2\">\n <span id=\"kind-filter-label\" className=\"text-sm font-medium text-text-secondary\">\n Kind\n </span>\n <div role=\"tablist\" aria-labelledby=\"kind-filter-label\" className=\"flex flex-wrap gap-2\">\n {KIND_FILTERS.map((opt) => {\n const active = opt.value === kind;\n return (\n <button\n key={opt.value}\n type=\"button\"\n role=\"tab\"\n aria-selected={active}\n onClick={() => changeKind(opt.value)}\n className={cn(\n 'inline-flex items-center gap-2 rounded-xl border px-3 py-2 text-sm font-medium transition-colors',\n active\n ? 'border-transparent bg-action-primary-bg text-action-primary-text'\n : 'border-border-seam bg-bg-surface text-text-secondary hover:bg-bg-sunken hover:text-text-primary'\n )}\n >\n {createElement(opt.icon, { className: 'h-4 w-4' })}\n {opt.label}\n </button>\n );\n })}\n </div>\n </div>\n\n <div className=\"flex flex-col gap-2 lg:items-end\">\n <label htmlFor=\"access-filter\" className=\"text-sm font-medium text-text-secondary\">\n Access level\n </label>\n <Select value={accessLevel} onValueChange={changeAccess}>\n <SelectTrigger\n id=\"access-filter\"\n className=\"w-full lg:w-[12rem]\"\n aria-label=\"Filter by access level\"\n >\n <SelectValue placeholder=\"All levels\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"ALL\">All levels</SelectItem>\n {ACCESS_LEVELS.map((a) => (\n <SelectItem key={a} value={a}>\n {formatEnumLabel(a)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n\n {isLoading ? (\n <LoadingView label=\"Loading artifacts…\" />\n ) : isError ? (\n <ErrorView message=\"We couldn't load artifacts.\" onRetry={() => refetch()} />\n ) : items.length === 0 && pager.page === 0 ? (\n <EmptyState\n illustration=\"empty-files\"\n icon={<Boxes className=\"h-10 w-10\" />}\n title={\n kind === 'ALL' && accessLevel === 'ALL'\n ? 'No artifacts yet'\n : 'No artifacts match these filters'\n }\n description={\n kind === 'ALL' && accessLevel === 'ALL'\n ? 'Add the first artifact to the archive.'\n : 'Try widening the filters, or add a new artifact.'\n }\n action={\n <Button onClick={onNew}>\n <Plus className=\"mr-1.5 h-4 w-4\" /> Add artifact\n </Button>\n }\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 <Pagination\n page={pager.page}\n pageSize={PAGE_SIZE}\n itemCount={items.length}\n hasMore={data?.pageInfo.hasMore ?? false}\n onPageChange={(target) => pager.onPageChange(target, data?.pageInfo.cursor)}\n />\n </>\n )}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Oral histories\n// ---------------------------------------------------------------------------\n\nfunction OralHistoriesTab({ onNew }: { onNew: () => void }) {\n const { data, isLoading, isError, refetch } = useTcpOralHistories();\n const oralHistories = data ?? [];\n\n if (isLoading) return <LoadingView label=\"Loading oral histories…\" />;\n if (isError)\n return <ErrorView message=\"We couldn't load oral histories.\" onRetry={() => refetch()} />;\n if (oralHistories.length === 0) {\n return (\n <EmptyState\n illustration=\"empty-data\"\n icon={<AudioLines className=\"h-10 w-10\" />}\n title=\"No oral histories yet\"\n description=\"Record a first-person account to preserve it for the archive.\"\n action={\n <Button onClick={onNew}>\n <Mic className=\"mr-1.5 h-4 w-4\" /> Record oral history\n </Button>\n }\n />\n );\n }\n\n return (\n <div className=\"flex flex-col gap-4\">\n {oralHistories.map((oralHistory) => (\n <OralHistoryPlayerRow key={oralHistory.id} oralHistory={oralHistory} />\n ))}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// OralHistoryPlayerRow — an inline listenable oral-history row (reused by the\n// collection detail page). Uses the foundation AudioPlayer for play/seek. Real\n// fields only: narrator is a plain string, there is NO portrait or age.\n// ---------------------------------------------------------------------------\n\nexport function OralHistoryPlayerRow({ oralHistory }: { oralHistory: TcpOralHistory }) {\n const { data: recordingUrl } = useFileUrl(oralHistory.recording?.id);\n const narrator = oralHistory.narratorName?.trim();\n const excerpt = oralHistory.summary?.trim() || oralHistory.transcript?.trim();\n\n return (\n <GlassCard treatment=\"plain\" className=\"flex flex-col gap-4 p-4 sm:flex-row sm:items-start\">\n <div\n className=\"flex h-14 w-14 shrink-0 items-center justify-center rounded-full bg-gradient-to-br from-[var(--color-accent-soft)] to-bg-sunken text-sm font-semibold text-text-primary\"\n aria-hidden=\"true\"\n >\n {narrator ? initialsOf(narrator) : <Mic className=\"h-5 w-5\" />}\n </div>\n\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-start justify-between gap-2\">\n <div className=\"min-w-0\">\n <h3 className=\"font-display text-lg font-semibold leading-snug text-text-primary\">\n {oralHistory.title}\n </h3>\n {narrator && <p className=\"mt-0.5 text-sm text-text-secondary\">{narrator}</p>}\n </div>\n <div className=\"flex flex-wrap items-center gap-1.5\">\n {oralHistory.language && (\n <span className=\"inline-flex items-center gap-1 rounded-full bg-bg-sunken px-2.5 py-0.5 text-xs font-medium text-text-secondary\">\n <Globe className=\"h-3 w-3\" aria-hidden=\"true\" />{' '}\n {formatEnumLabel(oralHistory.language)}\n </span>\n )}\n <StatusBadge status={oralHistory.accessLevel} />\n </div>\n </div>\n\n <AudioPlayer\n className=\"mt-3\"\n src={recordingUrl}\n seed={oralHistory.id || oralHistory.title}\n durationSecs={oralHistory.durationSecs}\n />\n\n {excerpt && (\n <p className=\"mt-3 border-l-2 border-[var(--color-accent-soft)] pl-3 text-sm italic leading-relaxed text-text-secondary line-clamp-2\">\n “{excerpt}”\n </p>\n )}\n </div>\n </GlassCard>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CollectionDetailPage — a single archive collection.
|
|
3
|
+
* @module theculturepost/pages/archive
|
|
4
|
+
*
|
|
5
|
+
* Reads `tcpCollection` (with its items + oral histories). An editorial
|
|
6
|
+
* {@link PageHero} shows the real cover (collections DO carry a cover file), with
|
|
7
|
+
* real counts (itemCount, oralHistories.length). Two panels below list the
|
|
8
|
+
* artifacts and the listenable oral histories. Adding an artifact or recording an
|
|
9
|
+
* oral history is pre-scoped to this collection.
|
|
10
|
+
*/
|
|
11
|
+
export declare function CollectionDetailPage(): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
//# sourceMappingURL=CollectionDetailPage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CollectionDetailPage.d.ts","sourceRoot":"","sources":["../../../../src/theculturepost/pages/archive/CollectionDetailPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AA4BH,wBAAgB,oBAAoB,4CAsJnC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DiscussionDetailPage — a single discussion and its moderated replies.
|
|
3
|
+
* @module theculturepost/pages/discussions
|
|
4
|
+
*
|
|
5
|
+
* Reads `tcpDiscussion`. Writes `tcpLockDiscussion` and, via {@link ReplyThread},
|
|
6
|
+
* `tcpPostReply` / `tcpModerateReply`. When anchored to a story, a link back to
|
|
7
|
+
* the story is shown. The header is an editorial card: display-serif title, a
|
|
8
|
+
* moderation-status + interfaith badge row, tag chips, an "opened by" byline and
|
|
9
|
+
* a framed prompt callout.
|
|
10
|
+
*/
|
|
11
|
+
export declare function DiscussionDetailPage(): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
//# sourceMappingURL=DiscussionDetailPage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DiscussionDetailPage.d.ts","sourceRoot":"","sources":["../../../../src/theculturepost/pages/discussions/DiscussionDetailPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AA8CH,wBAAgB,oBAAoB,4CA4JnC"}
|