// History / Archive view — calendar-style timeline of past briefs
const { useState: useStateH, useMemo: useMemoH, useEffect: useEffectH, useCallback: useCallbackH } = React;
function ArchiveView({ tweaks }) {
const companies = window.DATA?.companies || [];
const initialId = window.DATA.todaysBrief?.entityId || companies[0]?.id;
const [selectedId, setSelectedId] = useStateH(initialId);
const [search, setSearch] = useStateH("");
const [sortMode, setSortMode] = useStateH("recent");
const [expandedRunId, setExpandedRunId] = useStateH(null);
const [historyData, setHistoryData] = useStateH({
entityId: initialId,
entityName: window.DATA.todaysBrief?.entityName || "",
ticker: window.DATA.todaysBrief?.ticker || "",
history: window.DATA.history || [],
pulse: window.DATA.pulse || [],
});
const [loading, setLoading] = useStateH(false);
// Cache runs count per company from companySummaries
const summaries = window.DATA.companySummaries || {};
function loadCompany(id) {
if (id === historyData.entityId && !loading) return;
setSelectedId(id);
setLoading(true);
fetch(`/api/frontend/entity/${id}/history`)
.then(r => r.json())
.then(d => {
setHistoryData({
entityId: d.entityId,
entityName: d.entityName,
ticker: d.ticker,
history: d.history || [],
pulse: d.pulse || [],
});
})
.catch(console.error)
.finally(() => setLoading(false));
}
const filtered = companies.filter(c =>
c.name.toLowerCase().includes(search.toLowerCase()) ||
c.ticker.toLowerCase().includes(search.toLowerCase())
);
const history = sortMode === "activity"
? [...historyData.history].sort((a, b) => b.saved - a.saved)
: historyData.history;
const grouped = useMemoH(() => {
// Group by date first, then by month
const byDate = {};
history.forEach(h => { (byDate[h.date] = byDate[h.date] || []).push(h); });
const out = {};
Object.entries(byDate).forEach(([date, runs]) => {
const d = new Date(date + "T00:00:00Z");
const monthKey = d.toLocaleDateString("en-US", { month: "long", year: "numeric", timeZone: "UTC" });
(out[monthKey] = out[monthKey] || []).push({ date, runs });
});
return out;
}, [history]);
return (
{_tk(historyData.ticker)} · {companies.find(c => c.id === historyData.entityId)?.industry || ""}
{loading ? Loading… : historyData.entityName}
All briefs filed for this entity. {history.length} runs across the last {history.length} days.
{history.length} briefs
·
{history.reduce((s, h) => s + h.saved, 0)} bullets saved
·
{history.reduce((s, h) => s + h.discarded, 0)} discarded
{Object.entries(grouped).map(([month, items]) => (
{month}
{items.length} briefs · {items.reduce((s, i) => s + i.saved, 0)} saved
{items.map(({ date, runs }) => {
const d = new Date(date + "T00:00:00Z");
const day = d.getUTCDate();
const month3 = d.toLocaleDateString("en-US", { month: "short", timeZone: "UTC" });
const wd = d.toLocaleDateString("en-US", { weekday: "short", timeZone: "UTC" });
const isMulti = runs.length > 1;
const totalSaved = runs.reduce((s, r) => s + r.saved, 0);
const totalDiscarded = runs.reduce((s, r) => s + r.discarded, 0);
return (
{String(day).padStart(2, "0")}
{month3}
{wd}
{isMulti && (
{runs.length} runs
·
{totalSaved} saved
·
{totalDiscarded} discarded
)}
{runs.map(entry => (
{entry.narrative || entry.bullets?.[0]?.text || "No material developments"}
run-{entry.runId}
·
{entry.saved} saved
·
{entry.discarded} discarded
{entry.themes?.length > 0 && (
<>
·
{entry.themes.map(t => (
{t}
))}
>
)}
{entry.bullets?.length > 0 && (
)}
{expandedRunId === entry.runId && entry.bullets?.length > 0 && (
{entry.bullets.map((b, i) => (
-
{b.theme && {b.theme}}
{b.text}
))}
)}
))}
);
})}
))}
{history.length === 0 && !loading && (
No briefs found for this entity.
)}
);
}
window.ArchiveView = ArchiveView;