@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,163 +1,355 @@
|
|
|
1
1
|
import { useTheCulturePost as e } from "../../context/TheCulturePostContext.js";
|
|
2
|
-
import {
|
|
3
|
-
import { ErrorView as n, LoadingView as r } from "../../components/StateViews.js";
|
|
2
|
+
import { cn as t } from "../../utils/cn.js";
|
|
4
3
|
import "../../context/index.js";
|
|
5
|
-
import { useFileUrl as
|
|
6
|
-
import {
|
|
7
|
-
import { formatDate as
|
|
8
|
-
import { StatusBadge as
|
|
9
|
-
import { useTcpArchiveItem as l } from "../../hooks/useTcpApi.js";
|
|
4
|
+
import { useFileUrl as n } from "../../hooks/useFiles.js";
|
|
5
|
+
import { ErrorView as r, LoadingView as i } from "../../components/StateViews.js";
|
|
6
|
+
import { formatDate as a, formatEnumLabel as o } from "../../utils/formatters.js";
|
|
7
|
+
import { StatusBadge as s } from "../../components/StatusBadge.js";
|
|
8
|
+
import { useTcpAddCitation as c, useTcpArchiveItem as l, useTcpStories as u } from "../../hooks/useTcpApi.js";
|
|
10
9
|
import "../../hooks/index.js";
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
10
|
+
import { DecorativeDivider as d } from "../../components/DecorativeDivider.js";
|
|
11
|
+
import { IMAGE_KINDS as f, KIND_ICON as p } from "../../components/kindIcon.js";
|
|
12
|
+
import { describeError as m, notify as h } from "../../lib/toast.js";
|
|
13
|
+
import { createElement as g, useEffect as _, useState as v } from "react";
|
|
14
|
+
import { ArrowLeft as y, CalendarClock as b, Clock as x, Download as S, Globe as C, Landmark as w, Languages as T, Library as E, Loader2 as D, Lock as O, Maximize2 as k, Minus as A, Plus as j, Quote as M, Tag as N, Users as P, X as F } from "lucide-react";
|
|
15
|
+
import { useParams as I } from "react-router-dom";
|
|
16
|
+
import { Fragment as L, jsx as R, jsxs as z } from "react/jsx-runtime";
|
|
17
|
+
import { Button as B, GlassCard as V, Input as H, ResponsiveDialog as U, ResponsiveDialogContent as W, ResponsiveDialogDescription as G, ResponsiveDialogFooter as K, ResponsiveDialogHeader as q, ResponsiveDialogTitle as J } from "@burdenoff/fe-libs/ui";
|
|
16
18
|
//#region src/theculturepost/pages/archive/ArchiveItemDetailPage.tsx
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
19
|
+
var Y = {
|
|
20
|
+
PUBLIC: C,
|
|
21
|
+
COMMUNITY: P,
|
|
22
|
+
RESTRICTED: O,
|
|
23
|
+
EMBARGOED: x
|
|
24
|
+
};
|
|
25
|
+
function X({ onBack: e, children: t }) {
|
|
26
|
+
return /* @__PURE__ */ R("div", {
|
|
27
|
+
className: "flex h-full flex-col",
|
|
28
|
+
children: /* @__PURE__ */ R("div", {
|
|
29
|
+
className: "flex-1 overflow-auto",
|
|
30
|
+
children: /* @__PURE__ */ z("div", {
|
|
31
|
+
className: "mx-auto w-full max-w-6xl p-4 sm:p-6",
|
|
32
|
+
children: [/* @__PURE__ */ z("button", {
|
|
33
|
+
type: "button",
|
|
34
|
+
onClick: e,
|
|
35
|
+
className: "inline-flex items-center gap-1.5 text-sm font-medium text-text-secondary hover:text-text-primary",
|
|
36
|
+
children: [/* @__PURE__ */ R(y, {
|
|
37
|
+
className: "h-4 w-4",
|
|
38
|
+
"aria-hidden": "true"
|
|
39
|
+
}), " Archive"]
|
|
40
|
+
}), /* @__PURE__ */ R("div", {
|
|
41
|
+
className: "mt-4",
|
|
42
|
+
children: t
|
|
43
|
+
})]
|
|
44
|
+
})
|
|
45
|
+
})
|
|
33
46
|
});
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
47
|
+
}
|
|
48
|
+
function Z() {
|
|
49
|
+
let { id: t } = I(), { navigateTo: n } = e(), { data: c, isLoading: u, isError: f, refetch: m } = l(t), [h, _] = v(!1), y = () => n("archive");
|
|
50
|
+
if (u) return /* @__PURE__ */ R(X, {
|
|
51
|
+
onBack: y,
|
|
52
|
+
children: /* @__PURE__ */ R(i, { label: "Loading artifact…" })
|
|
38
53
|
});
|
|
39
|
-
if (
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
children: /* @__PURE__ */ b(n, {
|
|
54
|
+
if (f || !c) return /* @__PURE__ */ R(X, {
|
|
55
|
+
onBack: y,
|
|
56
|
+
children: /* @__PURE__ */ R(r, {
|
|
43
57
|
title: "Artifact not found",
|
|
44
58
|
message: "This artifact may have been archived, or you may not have access.",
|
|
45
|
-
onRetry: () =>
|
|
59
|
+
onRetry: () => m()
|
|
46
60
|
})
|
|
47
61
|
});
|
|
48
|
-
let
|
|
49
|
-
return /* @__PURE__ */
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
className: "flex flex-col gap-4",
|
|
56
|
-
children: [j ? /* @__PURE__ */ b(a, {
|
|
57
|
-
fileId: T.file?.id,
|
|
58
|
-
alt: T.title,
|
|
59
|
-
className: "aspect-[4/3] w-full",
|
|
60
|
-
icon: /* @__PURE__ */ b(A, { className: "h-12 w-12" })
|
|
61
|
-
}) : /* @__PURE__ */ x(C, {
|
|
62
|
-
treatment: "plain",
|
|
63
|
-
className: "flex aspect-[4/3] w-full flex-col items-center justify-center gap-3 text-text-tertiary",
|
|
64
|
-
children: [/* @__PURE__ */ b(A, { className: "h-14 w-14" }), /* @__PURE__ */ b("span", {
|
|
65
|
-
className: "text-sm font-medium",
|
|
66
|
-
children: s(T.kind)
|
|
67
|
-
})]
|
|
68
|
-
}), T.file?.id && /* @__PURE__ */ b(w, { fileId: T.file.id })]
|
|
69
|
-
}), /* @__PURE__ */ x("div", {
|
|
70
|
-
className: "flex flex-col gap-5",
|
|
62
|
+
let x = c.collection, S = Y[c.accessLevel], D = p[c.kind];
|
|
63
|
+
return /* @__PURE__ */ z(X, {
|
|
64
|
+
onBack: y,
|
|
65
|
+
children: [/* @__PURE__ */ z("div", {
|
|
66
|
+
className: "grid gap-6 lg:grid-cols-[1.3fr_1fr]",
|
|
67
|
+
children: [/* @__PURE__ */ R($, { item: c }), /* @__PURE__ */ z("div", {
|
|
68
|
+
className: "flex min-w-0 flex-col gap-5",
|
|
71
69
|
children: [
|
|
72
|
-
/* @__PURE__ */
|
|
70
|
+
/* @__PURE__ */ R("h1", {
|
|
71
|
+
className: "font-display text-3xl font-semibold leading-tight text-text-primary",
|
|
72
|
+
children: c.title
|
|
73
|
+
}),
|
|
74
|
+
/* @__PURE__ */ z("div", {
|
|
73
75
|
className: "flex flex-wrap items-center gap-1.5",
|
|
74
|
-
children: [/* @__PURE__ */
|
|
76
|
+
children: [/* @__PURE__ */ R(s, {
|
|
77
|
+
status: c.kind,
|
|
78
|
+
icon: g(D, { className: "h-3 w-3" })
|
|
79
|
+
}), /* @__PURE__ */ R(s, {
|
|
80
|
+
status: c.accessLevel,
|
|
81
|
+
icon: g(S, { className: "h-3 w-3" })
|
|
82
|
+
})]
|
|
75
83
|
}),
|
|
76
|
-
|
|
84
|
+
c.description && /* @__PURE__ */ R("p", {
|
|
77
85
|
className: "whitespace-pre-wrap text-sm leading-relaxed text-text-secondary",
|
|
78
|
-
children:
|
|
86
|
+
children: c.description
|
|
79
87
|
}),
|
|
80
|
-
/* @__PURE__ */
|
|
81
|
-
|
|
88
|
+
/* @__PURE__ */ R(d, { className: "py-2" }),
|
|
89
|
+
/* @__PURE__ */ z("dl", {
|
|
90
|
+
className: "flex flex-col gap-4",
|
|
82
91
|
children: [
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
+
c.provenance && /* @__PURE__ */ R(Q, {
|
|
93
|
+
icon: w,
|
|
94
|
+
label: "Provenance",
|
|
95
|
+
children: c.provenance
|
|
96
|
+
}),
|
|
97
|
+
c.origin && /* @__PURE__ */ R(Q, {
|
|
98
|
+
icon: C,
|
|
99
|
+
label: "Origin",
|
|
100
|
+
children: c.origin
|
|
92
101
|
}),
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
children: "Dated"
|
|
98
|
-
}), /* @__PURE__ */ b("dd", {
|
|
99
|
-
className: "mt-0.5 text-text-primary",
|
|
100
|
-
children: o(T.datedAt)
|
|
101
|
-
})] })]
|
|
102
|
+
c.datedAt && /* @__PURE__ */ R(Q, {
|
|
103
|
+
icon: b,
|
|
104
|
+
label: "Date",
|
|
105
|
+
children: a(c.datedAt)
|
|
102
106
|
}),
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
children: "Languages"
|
|
108
|
-
}), /* @__PURE__ */ b("dd", {
|
|
109
|
-
className: "mt-0.5 text-text-primary",
|
|
110
|
-
children: T.languages.map(s).join(", ")
|
|
111
|
-
})] })]
|
|
107
|
+
c.languages.length > 0 && /* @__PURE__ */ R(Q, {
|
|
108
|
+
icon: T,
|
|
109
|
+
label: "Languages",
|
|
110
|
+
children: c.languages.map(o).join(", ")
|
|
112
111
|
}),
|
|
113
|
-
/* @__PURE__ */
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
112
|
+
c.tags.length > 0 && /* @__PURE__ */ R(Q, {
|
|
113
|
+
icon: N,
|
|
114
|
+
label: "Tags",
|
|
115
|
+
children: /* @__PURE__ */ R("div", {
|
|
116
|
+
className: "flex flex-wrap gap-1.5",
|
|
117
|
+
children: c.tags.map((e) => /* @__PURE__ */ R("span", {
|
|
118
|
+
className: "rounded-full bg-bg-sunken px-2.5 py-0.5 text-xs font-medium text-text-secondary",
|
|
119
|
+
children: e
|
|
120
|
+
}, e))
|
|
121
|
+
})
|
|
122
122
|
})
|
|
123
123
|
]
|
|
124
124
|
}),
|
|
125
|
-
|
|
126
|
-
className: "rounded-xl border border-border-seam bg-bg-surface p-4",
|
|
127
|
-
children: [/* @__PURE__ */ b("p", {
|
|
128
|
-
className: "text-xs font-semibold uppercase tracking-wide text-text-tertiary",
|
|
129
|
-
children: "Provenance"
|
|
130
|
-
}), /* @__PURE__ */ b("p", {
|
|
131
|
-
className: "mt-1.5 whitespace-pre-wrap text-sm text-text-secondary",
|
|
132
|
-
children: T.provenance
|
|
133
|
-
})]
|
|
134
|
-
}),
|
|
135
|
-
T.tags.length > 0 && /* @__PURE__ */ x("div", {
|
|
136
|
-
className: "flex flex-wrap items-center gap-1.5",
|
|
137
|
-
children: [/* @__PURE__ */ b(v, {
|
|
138
|
-
className: "h-3.5 w-3.5 text-text-tertiary",
|
|
139
|
-
"aria-hidden": "true"
|
|
140
|
-
}), T.tags.map((e) => /* @__PURE__ */ x("span", {
|
|
141
|
-
className: "rounded-full bg-bg-sunken px-2.5 py-0.5 text-xs font-medium text-text-secondary",
|
|
142
|
-
children: ["#", e]
|
|
143
|
-
}, e))]
|
|
144
|
-
}),
|
|
145
|
-
T.collection && /* @__PURE__ */ x("button", {
|
|
125
|
+
x && /* @__PURE__ */ z("button", {
|
|
146
126
|
type: "button",
|
|
147
|
-
onClick: () =>
|
|
127
|
+
onClick: () => n(`archive/collections/${x.id}`),
|
|
148
128
|
className: "inline-flex items-center gap-2 self-start rounded-lg border border-border-seam bg-bg-surface px-3 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken",
|
|
149
129
|
children: [
|
|
150
|
-
/* @__PURE__ */
|
|
130
|
+
/* @__PURE__ */ R(E, {
|
|
131
|
+
className: "h-4 w-4 text-text-tertiary",
|
|
132
|
+
"aria-hidden": "true"
|
|
133
|
+
}),
|
|
151
134
|
" ",
|
|
152
|
-
|
|
135
|
+
x.name
|
|
153
136
|
]
|
|
137
|
+
}),
|
|
138
|
+
/* @__PURE__ */ z(B, {
|
|
139
|
+
className: "w-full sm:w-auto",
|
|
140
|
+
onClick: () => _(!0),
|
|
141
|
+
children: [/* @__PURE__ */ R(M, { className: "mr-1.5 h-4 w-4" }), " Cite in a story"]
|
|
154
142
|
})
|
|
155
143
|
]
|
|
156
144
|
})]
|
|
145
|
+
}), /* @__PURE__ */ R(ee, {
|
|
146
|
+
open: h,
|
|
147
|
+
onOpenChange: _,
|
|
148
|
+
item: c
|
|
149
|
+
})]
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
function Q({ icon: e, label: t, children: n }) {
|
|
153
|
+
return /* @__PURE__ */ z("div", {
|
|
154
|
+
className: "flex items-start gap-3",
|
|
155
|
+
children: [
|
|
156
|
+
/* @__PURE__ */ R(e, {
|
|
157
|
+
className: "mt-0.5 h-4 w-4 shrink-0 text-accent",
|
|
158
|
+
"aria-hidden": "true"
|
|
159
|
+
}),
|
|
160
|
+
/* @__PURE__ */ R("dt", {
|
|
161
|
+
className: "w-24 shrink-0 text-sm text-text-tertiary",
|
|
162
|
+
children: t
|
|
163
|
+
}),
|
|
164
|
+
/* @__PURE__ */ R("dd", {
|
|
165
|
+
className: "min-w-0 flex-1 text-sm text-text-primary",
|
|
166
|
+
children: n
|
|
167
|
+
})
|
|
168
|
+
]
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
function $({ item: e }) {
|
|
172
|
+
let { data: r } = n(e.file?.id), i = p[e.kind], [a, s] = v(1), [c, l] = v(!1), [u, d] = v(!1), m = f.has(e.kind) && !!r && !u;
|
|
173
|
+
return _(() => {
|
|
174
|
+
if (!c) return;
|
|
175
|
+
let e = (e) => {
|
|
176
|
+
e.key === "Escape" && l(!1);
|
|
177
|
+
};
|
|
178
|
+
return window.addEventListener("keydown", e), () => window.removeEventListener("keydown", e);
|
|
179
|
+
}, [c]), /* @__PURE__ */ z("div", {
|
|
180
|
+
className: "flex flex-col gap-4",
|
|
181
|
+
children: [
|
|
182
|
+
/* @__PURE__ */ R(V, {
|
|
183
|
+
treatment: "plain",
|
|
184
|
+
className: "p-3 sm:p-4",
|
|
185
|
+
children: /* @__PURE__ */ z("div", {
|
|
186
|
+
className: t("relative aspect-[4/3] w-full rounded-xl bg-bg-sunken", a > 1 ? "overflow-auto" : "overflow-hidden"),
|
|
187
|
+
children: [m && r ? /* @__PURE__ */ R("img", {
|
|
188
|
+
src: r,
|
|
189
|
+
alt: e.title,
|
|
190
|
+
onError: () => d(!0),
|
|
191
|
+
style: {
|
|
192
|
+
transform: `scale(${a})`,
|
|
193
|
+
transformOrigin: "center center"
|
|
194
|
+
},
|
|
195
|
+
className: "h-full w-full object-contain transition-transform duration-200"
|
|
196
|
+
}) : /* @__PURE__ */ z("div", {
|
|
197
|
+
className: "flex h-full w-full flex-col items-center justify-center gap-3 text-text-tertiary",
|
|
198
|
+
children: [/* @__PURE__ */ R(i, {
|
|
199
|
+
className: "h-16 w-16",
|
|
200
|
+
"aria-hidden": "true"
|
|
201
|
+
}), /* @__PURE__ */ R("span", {
|
|
202
|
+
className: "text-sm font-medium",
|
|
203
|
+
children: o(e.kind)
|
|
204
|
+
})]
|
|
205
|
+
}), m && r && /* @__PURE__ */ z(L, { children: [/* @__PURE__ */ R("button", {
|
|
206
|
+
type: "button",
|
|
207
|
+
onClick: () => l(!0),
|
|
208
|
+
"aria-label": "View full screen",
|
|
209
|
+
className: "absolute right-3 top-3 z-10 flex h-9 w-9 items-center justify-center rounded-lg bg-bg-canvas/85 text-text-primary shadow-sm backdrop-blur-sm hover:bg-bg-canvas",
|
|
210
|
+
children: /* @__PURE__ */ R(k, { className: "h-4 w-4" })
|
|
211
|
+
}), /* @__PURE__ */ z("div", {
|
|
212
|
+
className: "absolute bottom-3 left-3 z-10 flex flex-col overflow-hidden rounded-lg border border-border-seam bg-bg-canvas/85 text-text-primary shadow-sm backdrop-blur-sm",
|
|
213
|
+
children: [
|
|
214
|
+
/* @__PURE__ */ R("button", {
|
|
215
|
+
type: "button",
|
|
216
|
+
onClick: () => s((e) => Math.min(4, Math.round((e + .5) * 10) / 10)),
|
|
217
|
+
disabled: a >= 4,
|
|
218
|
+
"aria-label": "Zoom in",
|
|
219
|
+
className: "flex h-8 w-9 items-center justify-center hover:bg-bg-sunken disabled:opacity-40",
|
|
220
|
+
children: /* @__PURE__ */ R(j, { className: "h-4 w-4" })
|
|
221
|
+
}),
|
|
222
|
+
/* @__PURE__ */ z("button", {
|
|
223
|
+
type: "button",
|
|
224
|
+
onClick: () => s(1),
|
|
225
|
+
"aria-label": "Reset zoom",
|
|
226
|
+
className: "border-y border-border-seam px-1 py-1 text-[10px] font-medium tabular-nums hover:bg-bg-sunken",
|
|
227
|
+
children: [Math.round(a * 100), "%"]
|
|
228
|
+
}),
|
|
229
|
+
/* @__PURE__ */ R("button", {
|
|
230
|
+
type: "button",
|
|
231
|
+
onClick: () => s((e) => Math.max(1, Math.round((e - .5) * 10) / 10)),
|
|
232
|
+
disabled: a <= 1,
|
|
233
|
+
"aria-label": "Zoom out",
|
|
234
|
+
className: "flex h-8 w-9 items-center justify-center hover:bg-bg-sunken disabled:opacity-40",
|
|
235
|
+
children: /* @__PURE__ */ R(A, { className: "h-4 w-4" })
|
|
236
|
+
})
|
|
237
|
+
]
|
|
238
|
+
})] })]
|
|
239
|
+
})
|
|
240
|
+
}),
|
|
241
|
+
r && /* @__PURE__ */ z("a", {
|
|
242
|
+
href: r,
|
|
243
|
+
target: "_blank",
|
|
244
|
+
rel: "noreferrer noopener",
|
|
245
|
+
download: !0,
|
|
246
|
+
className: "inline-flex items-center justify-center gap-2 self-start rounded-lg border border-border-seam bg-bg-surface px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken",
|
|
247
|
+
children: [/* @__PURE__ */ R(S, { className: "h-4 w-4" }), " Download"]
|
|
248
|
+
}),
|
|
249
|
+
c && r && /* @__PURE__ */ z("div", {
|
|
250
|
+
role: "dialog",
|
|
251
|
+
"aria-modal": "true",
|
|
252
|
+
"aria-label": `${e.title} — full view`,
|
|
253
|
+
onClick: () => l(!1),
|
|
254
|
+
className: "fixed inset-0 z-50 flex items-center justify-center bg-bg-canvas/95 p-4 backdrop-blur-sm",
|
|
255
|
+
children: [/* @__PURE__ */ R("button", {
|
|
256
|
+
type: "button",
|
|
257
|
+
onClick: () => l(!1),
|
|
258
|
+
"aria-label": "Close full view",
|
|
259
|
+
className: "absolute right-4 top-4 flex h-10 w-10 items-center justify-center rounded-full bg-bg-surface text-text-primary shadow-sm hover:bg-bg-sunken",
|
|
260
|
+
children: /* @__PURE__ */ R(F, { className: "h-5 w-5" })
|
|
261
|
+
}), /* @__PURE__ */ R("img", {
|
|
262
|
+
src: r,
|
|
263
|
+
alt: e.title,
|
|
264
|
+
onClick: (e) => e.stopPropagation(),
|
|
265
|
+
className: "max-h-full max-w-full rounded-lg object-contain"
|
|
266
|
+
})]
|
|
267
|
+
})
|
|
268
|
+
]
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
function ee({ open: e, onOpenChange: t, item: n }) {
|
|
272
|
+
let r = u({ pagination: { limit: 50 } }), a = c(), [s, l] = v(""), [d, f] = v(null), [p, g] = v(null), _ = r.data?.items ?? [], y = s.trim().toLowerCase(), b = y ? _.filter((e) => e.title.toLowerCase().includes(y)) : _, x = async (e) => {
|
|
273
|
+
f(e.id), g(null);
|
|
274
|
+
try {
|
|
275
|
+
await a.mutateAsync({
|
|
276
|
+
storyId: e.id,
|
|
277
|
+
title: n.title,
|
|
278
|
+
sourceType: "ARCHIVAL_RECORD",
|
|
279
|
+
provenance: n.provenance ?? null,
|
|
280
|
+
excerpt: n.description ?? null,
|
|
281
|
+
sourceFileId: n.file?.id ?? null
|
|
282
|
+
}), h.success("Cited in a story", e.title), t(!1);
|
|
283
|
+
} catch (e) {
|
|
284
|
+
g(m(e));
|
|
285
|
+
} finally {
|
|
286
|
+
f(null);
|
|
287
|
+
}
|
|
288
|
+
};
|
|
289
|
+
return /* @__PURE__ */ R(U, {
|
|
290
|
+
open: e,
|
|
291
|
+
onOpenChange: t,
|
|
292
|
+
children: /* @__PURE__ */ z(W, {
|
|
293
|
+
className: "sm:max-w-lg",
|
|
294
|
+
children: [
|
|
295
|
+
/* @__PURE__ */ z(q, { children: [/* @__PURE__ */ R(J, { children: "Cite in a story" }), /* @__PURE__ */ z(G, { children: [
|
|
296
|
+
"Attach “",
|
|
297
|
+
n.title,
|
|
298
|
+
"” to a story as an archival-record citation."
|
|
299
|
+
] })] }),
|
|
300
|
+
/* @__PURE__ */ z("div", {
|
|
301
|
+
className: "flex flex-col gap-3 py-2",
|
|
302
|
+
children: [
|
|
303
|
+
/* @__PURE__ */ R(H, {
|
|
304
|
+
value: s,
|
|
305
|
+
onChange: (e) => l(e.target.value),
|
|
306
|
+
placeholder: "Search stories…",
|
|
307
|
+
"aria-label": "Search stories"
|
|
308
|
+
}),
|
|
309
|
+
/* @__PURE__ */ R("div", {
|
|
310
|
+
className: "flex max-h-[50vh] flex-col gap-1.5 overflow-y-auto",
|
|
311
|
+
children: r.isLoading ? /* @__PURE__ */ R(i, {
|
|
312
|
+
label: "Loading stories…",
|
|
313
|
+
className: "min-h-[8rem]"
|
|
314
|
+
}) : b.length === 0 ? /* @__PURE__ */ R("p", {
|
|
315
|
+
className: "py-8 text-center text-sm text-text-tertiary",
|
|
316
|
+
children: _.length === 0 ? "No stories yet — draft a story first." : "No stories match your search."
|
|
317
|
+
}) : b.map((e) => /* @__PURE__ */ z("button", {
|
|
318
|
+
type: "button",
|
|
319
|
+
onClick: () => x(e),
|
|
320
|
+
disabled: a.isPending,
|
|
321
|
+
className: "flex items-center justify-between gap-3 rounded-xl border border-border-seam bg-bg-surface px-3 py-2.5 text-left transition-colors hover:bg-bg-sunken disabled:opacity-60",
|
|
322
|
+
children: [/* @__PURE__ */ z("span", {
|
|
323
|
+
className: "min-w-0",
|
|
324
|
+
children: [/* @__PURE__ */ R("span", {
|
|
325
|
+
className: "block truncate text-sm font-medium text-text-primary",
|
|
326
|
+
children: e.title
|
|
327
|
+
}), /* @__PURE__ */ R("span", {
|
|
328
|
+
className: "mt-0.5 block truncate text-xs text-text-tertiary",
|
|
329
|
+
children: e.topic?.name ?? o(e.status)
|
|
330
|
+
})]
|
|
331
|
+
}), d === e.id ? /* @__PURE__ */ R(D, { className: "h-4 w-4 shrink-0 animate-spin text-text-tertiary" }) : /* @__PURE__ */ R(M, {
|
|
332
|
+
className: "h-4 w-4 shrink-0 text-text-tertiary",
|
|
333
|
+
"aria-hidden": "true"
|
|
334
|
+
})]
|
|
335
|
+
}, e.id))
|
|
336
|
+
}),
|
|
337
|
+
p && /* @__PURE__ */ R("p", {
|
|
338
|
+
className: "text-sm text-status-error-text",
|
|
339
|
+
children: p
|
|
340
|
+
})
|
|
341
|
+
]
|
|
342
|
+
}),
|
|
343
|
+
/* @__PURE__ */ R(K, { children: /* @__PURE__ */ R(B, {
|
|
344
|
+
variant: "outline",
|
|
345
|
+
onClick: () => t(!1),
|
|
346
|
+
children: "Close"
|
|
347
|
+
}) })
|
|
348
|
+
]
|
|
157
349
|
})
|
|
158
350
|
});
|
|
159
351
|
}
|
|
160
352
|
//#endregion
|
|
161
|
-
export {
|
|
353
|
+
export { Z as ArchiveItemDetailPage };
|
|
162
354
|
|
|
163
355
|
//# sourceMappingURL=ArchiveItemDetailPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ArchiveItemDetailPage.js","names":[],"sources":["../../../../src/theculturepost/pages/archive/ArchiveItemDetailPage.tsx"],"sourcesContent":["/**\n * ArchiveItemDetailPage — a single archived artifact.\n * @module theculturepost/pages/archive\n *\n * Reads `tcpArchiveItem` (with its parent collection). Image kinds render the\n * file inline; other kinds expose a download link resolved from the file id.\n */\n\nimport { ArrowLeft, MapPin, CalendarClock, Languages, Download, Library, Tag } from 'lucide-react';\nimport { Button, GlassCard } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { CoverImage } from '../../components/CoverImage';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { KIND_ICON, IMAGE_KINDS } from '../../components/kindIcon';\nimport { LoadingView, ErrorView } from '../../components/StateViews';\nimport { useTcpArchiveItem, useFileUrl } from '../../hooks';\nimport { useTheCulturePost } from '../../context';\nimport { formatDate, formatEnumLabel } from '../../utils/formatters';\nimport { useParams } from 'react-router-dom';\n\nfunction DownloadLink({ fileId }: { fileId: string }) {\n const { data: url } = useFileUrl(fileId);\n if (!url) return null;\n return (\n <a\n href={url}\n target=\"_blank\"\n rel=\"noreferrer noopener\"\n className=\"inline-flex items-center gap-1.5 rounded-lg bg-action-primary-bg px-3 py-2 text-sm font-medium text-action-primary-text hover:opacity-90\"\n >\n <Download className=\"h-4 w-4\" /> Download / open file\n </a>\n );\n}\n\nexport function ArchiveItemDetailPage() {\n const { id } = useParams<{ id: string }>();\n const { navigateTo } = useTheCulturePost();\n const { data: item, isLoading, isError, refetch } = useTcpArchiveItem(id);\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=\"Artifact\" actions={backButton}>\n <LoadingView label=\"Loading artifact…\" />\n </PageLayout>\n );\n }\n\n if (isError || !item) {\n return (\n <PageLayout title=\"Artifact\" actions={backButton}>\n <ErrorView\n title=\"Artifact not found\"\n message=\"This artifact may have been archived, or you may not have access.\"\n onRetry={() => refetch()}\n />\n </PageLayout>\n );\n }\n\n const Icon = KIND_ICON[item.kind];\n const isImage = IMAGE_KINDS.has(item.kind);\n\n return (\n <PageLayout title={item.title} actions={backButton}>\n <div className=\"mx-auto grid max-w-5xl gap-6 lg:grid-cols-[1.4fr_1fr]\">\n {/* Media */}\n <div className=\"flex flex-col gap-4\">\n {isImage ? (\n <CoverImage\n fileId={item.file?.id}\n alt={item.title}\n className=\"aspect-[4/3] w-full\"\n icon={<Icon className=\"h-12 w-12\" />}\n />\n ) : (\n <GlassCard\n treatment=\"plain\"\n className=\"flex aspect-[4/3] w-full flex-col items-center justify-center gap-3 text-text-tertiary\"\n >\n <Icon className=\"h-14 w-14\" />\n <span className=\"text-sm font-medium\">{formatEnumLabel(item.kind)}</span>\n </GlassCard>\n )}\n {item.file?.id && <DownloadLink fileId={item.file.id} />}\n </div>\n\n {/* Details */}\n <div className=\"flex flex-col gap-5\">\n <div className=\"flex flex-wrap items-center gap-1.5\">\n <StatusBadge status={item.kind} />\n <StatusBadge status={item.accessLevel} />\n </div>\n\n {item.description && (\n <p className=\"whitespace-pre-wrap text-sm leading-relaxed text-text-secondary\">\n {item.description}\n </p>\n )}\n\n <dl className=\"flex flex-col gap-3 text-sm\">\n {item.origin && (\n <div className=\"flex items-start gap-2.5\">\n <MapPin className=\"mt-0.5 h-4 w-4 shrink-0 text-text-tertiary\" />\n <div>\n <dt className=\"text-text-tertiary\">Origin</dt>\n <dd className=\"mt-0.5 text-text-primary\">{item.origin}</dd>\n </div>\n </div>\n )}\n {item.datedAt && (\n <div className=\"flex items-start gap-2.5\">\n <CalendarClock className=\"mt-0.5 h-4 w-4 shrink-0 text-text-tertiary\" />\n <div>\n <dt className=\"text-text-tertiary\">Dated</dt>\n <dd className=\"mt-0.5 text-text-primary\">{formatDate(item.datedAt)}</dd>\n </div>\n </div>\n )}\n {item.languages.length > 0 && (\n <div className=\"flex items-start gap-2.5\">\n <Languages className=\"mt-0.5 h-4 w-4 shrink-0 text-text-tertiary\" />\n <div>\n <dt className=\"text-text-tertiary\">Languages</dt>\n <dd className=\"mt-0.5 text-text-primary\">\n {item.languages.map(formatEnumLabel).join(', ')}\n </dd>\n </div>\n </div>\n )}\n <div className=\"flex items-start gap-2.5\">\n <CalendarClock className=\"mt-0.5 h-4 w-4 shrink-0 text-text-tertiary\" />\n <div>\n <dt className=\"text-text-tertiary\">Catalogued</dt>\n <dd className=\"mt-0.5 text-text-primary\">{formatDate(item.createdAt)}</dd>\n </div>\n </div>\n </dl>\n\n {item.provenance && (\n <div className=\"rounded-xl border border-border-seam bg-bg-surface p-4\">\n <p className=\"text-xs font-semibold uppercase tracking-wide text-text-tertiary\">\n Provenance\n </p>\n <p className=\"mt-1.5 whitespace-pre-wrap text-sm text-text-secondary\">\n {item.provenance}\n </p>\n </div>\n )}\n\n {item.tags.length > 0 && (\n <div className=\"flex flex-wrap items-center gap-1.5\">\n <Tag className=\"h-3.5 w-3.5 text-text-tertiary\" aria-hidden=\"true\" />\n {item.tags.map((tag) => (\n <span\n key={tag}\n className=\"rounded-full bg-bg-sunken px-2.5 py-0.5 text-xs font-medium text-text-secondary\"\n >\n #{tag}\n </span>\n ))}\n </div>\n )}\n\n {item.collection && (\n <button\n type=\"button\"\n onClick={() => navigateTo(`archive/collections/${item.collection!.id}`)}\n className=\"inline-flex items-center gap-2 self-start rounded-lg border border-border-seam bg-bg-surface px-3 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken\"\n >\n <Library className=\"h-4 w-4 text-text-tertiary\" /> {item.collection.name}\n </button>\n )}\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ArchiveItemDetailPage.js","names":[],"sources":["../../../../src/theculturepost/pages/archive/ArchiveItemDetailPage.tsx"],"sourcesContent":["/**\n * ArchiveItemDetailPage — a single archived artifact.\n * @module theculturepost/pages/archive\n *\n * Reads `tcpArchiveItem` (with its parent collection). Two columns: a media\n * viewer with CSS zoom + a full-screen lightbox (the schema exposes a SINGLE\n * `file` — never a thumbnail-strip gallery) and a details panel. \"Cite in a\n * story\" opens a story picker and writes an `ARCHIVAL_RECORD` citation via\n * `tcpAddCitation`. There is no bookmark/share (the schema has neither).\n */\n\nimport { createElement, useEffect, useState } from 'react';\nimport {\n ArrowLeft,\n Landmark,\n Globe,\n CalendarClock,\n Languages,\n Download,\n Library,\n Tag,\n Quote,\n Maximize2,\n Plus,\n Minus,\n X,\n Loader2,\n Users,\n Lock,\n Clock,\n type LucideIcon,\n} from 'lucide-react';\nimport {\n Button,\n GlassCard,\n Input,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n} from '@burdenoff/fe-libs/ui';\nimport { useParams } from 'react-router-dom';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { DecorativeDivider } from '../../components/DecorativeDivider';\nimport { KIND_ICON, IMAGE_KINDS } from '../../components/kindIcon';\nimport { LoadingView, ErrorView } from '../../components/StateViews';\nimport { useTcpArchiveItem, useFileUrl, useTcpStories, useTcpAddCitation } from '../../hooks';\nimport { useTheCulturePost } from '../../context';\nimport { cn } from '../../utils/cn';\nimport { formatDate, formatEnumLabel } from '../../utils/formatters';\nimport { notify, describeError } from '../../lib/toast';\nimport type { TcpArchiveItem, TcpStory, TcpAccessLevel } from '../../types';\n\nconst ACCESS_ICON: Record<TcpAccessLevel, LucideIcon> = {\n PUBLIC: Globe,\n COMMUNITY: Users,\n RESTRICTED: Lock,\n EMBARGOED: Clock,\n};\n\nfunction Shell({ onBack, children }: { onBack: () => void; 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 w-full max-w-6xl p-4 sm:p-6\">\n <button\n type=\"button\"\n onClick={onBack}\n className=\"inline-flex items-center gap-1.5 text-sm font-medium text-text-secondary hover:text-text-primary\"\n >\n <ArrowLeft className=\"h-4 w-4\" aria-hidden=\"true\" /> Archive\n </button>\n <div className=\"mt-4\">{children}</div>\n </div>\n </div>\n </div>\n );\n}\n\nexport function ArchiveItemDetailPage() {\n const { id } = useParams<{ id: string }>();\n const { navigateTo } = useTheCulturePost();\n const { data: item, isLoading, isError, refetch } = useTcpArchiveItem(id);\n const [citeOpen, setCiteOpen] = useState(false);\n\n const goBack = () => navigateTo('archive');\n\n if (isLoading) {\n return (\n <Shell onBack={goBack}>\n <LoadingView label=\"Loading artifact…\" />\n </Shell>\n );\n }\n\n if (isError || !item) {\n return (\n <Shell onBack={goBack}>\n <ErrorView\n title=\"Artifact not found\"\n message=\"This artifact may have been archived, or you may not have access.\"\n onRetry={() => refetch()}\n />\n </Shell>\n );\n }\n\n const collection = item.collection;\n const AccessIcon = ACCESS_ICON[item.accessLevel];\n const KindIcon = KIND_ICON[item.kind];\n\n return (\n <Shell onBack={goBack}>\n <div className=\"grid gap-6 lg:grid-cols-[1.3fr_1fr]\">\n <MediaViewer item={item} />\n\n <div className=\"flex min-w-0 flex-col gap-5\">\n <h1 className=\"font-display text-3xl font-semibold leading-tight text-text-primary\">\n {item.title}\n </h1>\n\n <div className=\"flex flex-wrap items-center gap-1.5\">\n <StatusBadge\n status={item.kind}\n icon={createElement(KindIcon, { className: 'h-3 w-3' })}\n />\n <StatusBadge\n status={item.accessLevel}\n icon={createElement(AccessIcon, { className: 'h-3 w-3' })}\n />\n </div>\n\n {item.description && (\n <p className=\"whitespace-pre-wrap text-sm leading-relaxed text-text-secondary\">\n {item.description}\n </p>\n )}\n\n <DecorativeDivider className=\"py-2\" />\n\n <dl className=\"flex flex-col gap-4\">\n {item.provenance && (\n <DetailRow icon={Landmark} label=\"Provenance\">\n {item.provenance}\n </DetailRow>\n )}\n {item.origin && (\n <DetailRow icon={Globe} label=\"Origin\">\n {item.origin}\n </DetailRow>\n )}\n {item.datedAt && (\n <DetailRow icon={CalendarClock} label=\"Date\">\n {formatDate(item.datedAt)}\n </DetailRow>\n )}\n {item.languages.length > 0 && (\n <DetailRow icon={Languages} label=\"Languages\">\n {item.languages.map(formatEnumLabel).join(', ')}\n </DetailRow>\n )}\n {item.tags.length > 0 && (\n <DetailRow icon={Tag} label=\"Tags\">\n <div className=\"flex flex-wrap gap-1.5\">\n {item.tags.map((tag) => (\n <span\n key={tag}\n className=\"rounded-full bg-bg-sunken px-2.5 py-0.5 text-xs font-medium text-text-secondary\"\n >\n {tag}\n </span>\n ))}\n </div>\n </DetailRow>\n )}\n </dl>\n\n {collection && (\n <button\n type=\"button\"\n onClick={() => navigateTo(`archive/collections/${collection.id}`)}\n className=\"inline-flex items-center gap-2 self-start rounded-lg border border-border-seam bg-bg-surface px-3 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken\"\n >\n <Library className=\"h-4 w-4 text-text-tertiary\" aria-hidden=\"true\" />{' '}\n {collection.name}\n </button>\n )}\n\n <Button className=\"w-full sm:w-auto\" onClick={() => setCiteOpen(true)}>\n <Quote className=\"mr-1.5 h-4 w-4\" /> Cite in a story\n </Button>\n </div>\n </div>\n\n <CiteInStoryDialog open={citeOpen} onOpenChange={setCiteOpen} item={item} />\n </Shell>\n );\n}\n\n// ---------------------------------------------------------------------------\n// DetailRow\n// ---------------------------------------------------------------------------\n\nfunction DetailRow({\n icon: Icon,\n label,\n children,\n}: {\n icon: LucideIcon;\n label: string;\n children: React.ReactNode;\n}) {\n return (\n <div className=\"flex items-start gap-3\">\n <Icon className=\"mt-0.5 h-4 w-4 shrink-0 text-accent\" aria-hidden=\"true\" />\n <dt className=\"w-24 shrink-0 text-sm text-text-tertiary\">{label}</dt>\n <dd className=\"min-w-0 flex-1 text-sm text-text-primary\">{children}</dd>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// MediaViewer — single file only (no gallery), CSS zoom + a full-screen lightbox.\n// ---------------------------------------------------------------------------\n\nfunction MediaViewer({ item }: { item: TcpArchiveItem }) {\n const { data: url } = useFileUrl(item.file?.id);\n const Icon = KIND_ICON[item.kind];\n const [zoom, setZoom] = useState(1);\n const [lightbox, setLightbox] = useState(false);\n const [imgFailed, setImgFailed] = useState(false);\n const showImage = IMAGE_KINDS.has(item.kind) && Boolean(url) && !imgFailed;\n\n useEffect(() => {\n if (!lightbox) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') setLightbox(false);\n };\n window.addEventListener('keydown', onKey);\n return () => window.removeEventListener('keydown', onKey);\n }, [lightbox]);\n\n const zoomIn = () => setZoom((z) => Math.min(4, Math.round((z + 0.5) * 10) / 10));\n const zoomOut = () => setZoom((z) => Math.max(1, Math.round((z - 0.5) * 10) / 10));\n\n return (\n <div className=\"flex flex-col gap-4\">\n <GlassCard treatment=\"plain\" className=\"p-3 sm:p-4\">\n <div\n className={cn(\n 'relative aspect-[4/3] w-full rounded-xl bg-bg-sunken',\n zoom > 1 ? 'overflow-auto' : 'overflow-hidden'\n )}\n >\n {showImage && url ? (\n <img\n src={url}\n alt={item.title}\n onError={() => setImgFailed(true)}\n style={{ transform: `scale(${zoom})`, transformOrigin: 'center center' }}\n className=\"h-full w-full object-contain transition-transform duration-200\"\n />\n ) : (\n <div className=\"flex h-full w-full flex-col items-center justify-center gap-3 text-text-tertiary\">\n <Icon className=\"h-16 w-16\" aria-hidden=\"true\" />\n <span className=\"text-sm font-medium\">{formatEnumLabel(item.kind)}</span>\n </div>\n )}\n\n {showImage && url && (\n <>\n <button\n type=\"button\"\n onClick={() => setLightbox(true)}\n aria-label=\"View full screen\"\n className=\"absolute right-3 top-3 z-10 flex h-9 w-9 items-center justify-center rounded-lg bg-bg-canvas/85 text-text-primary shadow-sm backdrop-blur-sm hover:bg-bg-canvas\"\n >\n <Maximize2 className=\"h-4 w-4\" />\n </button>\n <div className=\"absolute bottom-3 left-3 z-10 flex flex-col overflow-hidden rounded-lg border border-border-seam bg-bg-canvas/85 text-text-primary shadow-sm backdrop-blur-sm\">\n <button\n type=\"button\"\n onClick={zoomIn}\n disabled={zoom >= 4}\n aria-label=\"Zoom in\"\n className=\"flex h-8 w-9 items-center justify-center hover:bg-bg-sunken disabled:opacity-40\"\n >\n <Plus className=\"h-4 w-4\" />\n </button>\n <button\n type=\"button\"\n onClick={() => setZoom(1)}\n aria-label=\"Reset zoom\"\n className=\"border-y border-border-seam px-1 py-1 text-[10px] font-medium tabular-nums hover:bg-bg-sunken\"\n >\n {Math.round(zoom * 100)}%\n </button>\n <button\n type=\"button\"\n onClick={zoomOut}\n disabled={zoom <= 1}\n aria-label=\"Zoom out\"\n className=\"flex h-8 w-9 items-center justify-center hover:bg-bg-sunken disabled:opacity-40\"\n >\n <Minus className=\"h-4 w-4\" />\n </button>\n </div>\n </>\n )}\n </div>\n </GlassCard>\n\n {url && (\n <a\n href={url}\n target=\"_blank\"\n rel=\"noreferrer noopener\"\n download\n className=\"inline-flex items-center justify-center gap-2 self-start rounded-lg border border-border-seam bg-bg-surface px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken\"\n >\n <Download className=\"h-4 w-4\" /> Download\n </a>\n )}\n\n {lightbox && url && (\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={`${item.title} — full view`}\n onClick={() => setLightbox(false)}\n className=\"fixed inset-0 z-50 flex items-center justify-center bg-bg-canvas/95 p-4 backdrop-blur-sm\"\n >\n <button\n type=\"button\"\n onClick={() => setLightbox(false)}\n aria-label=\"Close full view\"\n className=\"absolute right-4 top-4 flex h-10 w-10 items-center justify-center rounded-full bg-bg-surface text-text-primary shadow-sm hover:bg-bg-sunken\"\n >\n <X className=\"h-5 w-5\" />\n </button>\n <img\n src={url}\n alt={item.title}\n onClick={(e) => e.stopPropagation()}\n className=\"max-h-full max-w-full rounded-lg object-contain\"\n />\n </div>\n )}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// CiteInStoryDialog — pick a story and attach this artifact as a citation.\n// ---------------------------------------------------------------------------\n\nfunction CiteInStoryDialog({\n open,\n onOpenChange,\n item,\n}: {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n item: TcpArchiveItem;\n}) {\n const storiesQuery = useTcpStories({ pagination: { limit: 50 } });\n const addCitation = useTcpAddCitation();\n const [query, setQuery] = useState('');\n const [pendingId, setPendingId] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n const stories = storiesQuery.data?.items ?? [];\n const q = query.trim().toLowerCase();\n const filtered = q ? stories.filter((s) => s.title.toLowerCase().includes(q)) : stories;\n\n const cite = async (story: TcpStory) => {\n setPendingId(story.id);\n setError(null);\n try {\n await addCitation.mutateAsync({\n storyId: story.id,\n title: item.title,\n sourceType: 'ARCHIVAL_RECORD',\n provenance: item.provenance ?? null,\n excerpt: item.description ?? null,\n sourceFileId: item.file?.id ?? null,\n });\n notify.success('Cited in a story', story.title);\n onOpenChange(false);\n } catch (err) {\n setError(describeError(err));\n } finally {\n setPendingId(null);\n }\n };\n\n return (\n <ResponsiveDialog open={open} onOpenChange={onOpenChange}>\n <ResponsiveDialogContent className=\"sm:max-w-lg\">\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Cite in a story</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Attach “{item.title}” to a story as an archival-record citation.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n\n <div className=\"flex flex-col gap-3 py-2\">\n <Input\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder=\"Search stories…\"\n aria-label=\"Search stories\"\n />\n <div className=\"flex max-h-[50vh] flex-col gap-1.5 overflow-y-auto\">\n {storiesQuery.isLoading ? (\n <LoadingView label=\"Loading stories…\" className=\"min-h-[8rem]\" />\n ) : filtered.length === 0 ? (\n <p className=\"py-8 text-center text-sm text-text-tertiary\">\n {stories.length === 0\n ? 'No stories yet — draft a story first.'\n : 'No stories match your search.'}\n </p>\n ) : (\n filtered.map((story) => (\n <button\n key={story.id}\n type=\"button\"\n onClick={() => cite(story)}\n disabled={addCitation.isPending}\n className=\"flex items-center justify-between gap-3 rounded-xl border border-border-seam bg-bg-surface px-3 py-2.5 text-left transition-colors hover:bg-bg-sunken disabled:opacity-60\"\n >\n <span className=\"min-w-0\">\n <span className=\"block truncate text-sm font-medium text-text-primary\">\n {story.title}\n </span>\n <span className=\"mt-0.5 block truncate text-xs text-text-tertiary\">\n {story.topic?.name ?? formatEnumLabel(story.status)}\n </span>\n </span>\n {pendingId === story.id ? (\n <Loader2 className=\"h-4 w-4 shrink-0 animate-spin text-text-tertiary\" />\n ) : (\n <Quote className=\"h-4 w-4 shrink-0 text-text-tertiary\" aria-hidden=\"true\" />\n )}\n </button>\n ))\n )}\n </div>\n {error && <p className=\"text-sm text-status-error-text\">{error}</p>}\n </div>\n\n <ResponsiveDialogFooter>\n <Button variant=\"outline\" onClick={() => onOpenChange(false)}>\n Close\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n );\n}\n"],"mappings":"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"}
|