homepage: add topic chips + date filters to Industry News section (matches /news page UX)
This commit is contained in:
@@ -26,7 +26,21 @@ interface ArticleItem {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
const ALL_CATEGORIES = ["All", "BROADCAST", "POST PRODUCTION", "ANIMATION"];
|
// Match the topic list on /news for a consistent filter experience sitewide.
|
||||||
|
const ALL_CATEGORIES = [
|
||||||
|
"All",
|
||||||
|
"Cloud",
|
||||||
|
"AI",
|
||||||
|
"IP Workflows",
|
||||||
|
"Live Production",
|
||||||
|
"Streaming",
|
||||||
|
"Audio",
|
||||||
|
"Cameras",
|
||||||
|
"NAB 2026",
|
||||||
|
"EAS",
|
||||||
|
"Sports Broadcasting",
|
||||||
|
"Ad Tech",
|
||||||
|
];
|
||||||
const SOURCE_FILTERS = ["All", "Live", "Imported"] as const;
|
const SOURCE_FILTERS = ["All", "Live", "Imported"] as const;
|
||||||
type SourceFilter = typeof SOURCE_FILTERS[number];
|
type SourceFilter = typeof SOURCE_FILTERS[number];
|
||||||
type FeedMode = "pagination" | "infinite";
|
type FeedMode = "pagination" | "infinite";
|
||||||
@@ -141,7 +155,8 @@ export default function ArticleFeed() {
|
|||||||
|
|
||||||
// Filter articles
|
// Filter articles
|
||||||
const filtered = allArticles.filter((a) => {
|
const filtered = allArticles.filter((a) => {
|
||||||
const matchCat = activeCategory === "All" || a.category === activeCategory;
|
const matchCat = activeCategory === "All"
|
||||||
|
|| (a.category || "").toLowerCase().includes(activeCategory.toLowerCase());
|
||||||
const matchSource =
|
const matchSource =
|
||||||
sourceFilter === "All" ||
|
sourceFilter === "All" ||
|
||||||
(sourceFilter === "Imported" && a.source === "imported") ||
|
(sourceFilter === "Imported" && a.source === "imported") ||
|
||||||
@@ -337,10 +352,39 @@ export default function ArticleFeed() {
|
|||||||
<span className="font-body text-xs text-[#555]">{sortedFiltered.length?.toLocaleString()} article{sortedFiltered.length !== 1 ? "s" : ""}</span>
|
<span className="font-body text-xs text-[#555]">{sortedFiltered.length?.toLocaleString()} article{sortedFiltered.length !== 1 ? "s" : ""}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Filters only — site-wide search lives in the top-right header */}
|
{/* Filters — topic chips + date range visible by default, advanced (author + source) behind toggle */}
|
||||||
<div className="mb-4 space-y-3">
|
<div className="mb-4 space-y-3">
|
||||||
<div className="flex items-center gap-2">
|
{/* Row: date range + advanced toggle */}
|
||||||
{/* Advanced filters toggle button */}
|
<div className="flex items-center gap-2 flex-wrap">
|
||||||
|
<input
|
||||||
|
type="date"
|
||||||
|
value={dateFrom}
|
||||||
|
onChange={(e) => { setDateFrom(e.target.value); setPage(1); }}
|
||||||
|
max={dateTo || undefined}
|
||||||
|
className="bg-[#1a1a1a] border border-[#2a2a2a] text-[#888] text-xs font-body px-3 py-2 rounded-sm focus:outline-none focus:border-[#3b82f6] transition-colors [color-scheme:dark]"
|
||||||
|
title="From date"
|
||||||
|
aria-label="Filter articles from date"
|
||||||
|
/>
|
||||||
|
<span className="text-[#444] text-xs">–</span>
|
||||||
|
<input
|
||||||
|
type="date"
|
||||||
|
value={dateTo}
|
||||||
|
onChange={(e) => { setDateTo(e.target.value); setPage(1); }}
|
||||||
|
min={dateFrom || undefined}
|
||||||
|
className="bg-[#1a1a1a] border border-[#2a2a2a] text-[#888] text-xs font-body px-3 py-2 rounded-sm focus:outline-none focus:border-[#3b82f6] transition-colors [color-scheme:dark]"
|
||||||
|
title="To date"
|
||||||
|
aria-label="Filter articles to date"
|
||||||
|
/>
|
||||||
|
{(dateFrom || dateTo) && (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => { setDateFrom(""); setDateTo(""); setPage(1); }}
|
||||||
|
className="text-[#666] hover:text-[#aaa] text-xs font-body underline"
|
||||||
|
aria-label="Clear date range">
|
||||||
|
clear dates
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
<div className="flex-1" />
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setShowAdvanced((v) => !v)}
|
onClick={() => setShowAdvanced((v) => !v)}
|
||||||
@@ -354,13 +398,37 @@ export default function ArticleFeed() {
|
|||||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" aria-hidden="true">
|
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" aria-hidden="true">
|
||||||
<path d="M1 3h10M3 6h6M5 9h2" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/>
|
<path d="M1 3h10M3 6h6M5 9h2" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/>
|
||||||
</svg>
|
</svg>
|
||||||
Filters
|
More
|
||||||
{hasAdvancedActive && (
|
{hasAdvancedActive && (
|
||||||
<span className="w-1.5 h-1.5 rounded-full bg-[#3b82f6] inline-block ml-0.5" aria-label="Active filters" />
|
<span className="w-1.5 h-1.5 rounded-full bg-[#3b82f6] inline-block ml-0.5" aria-label="Active filters" />
|
||||||
)}
|
)}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Row: topic chips */}
|
||||||
|
<div className="flex items-center gap-2 flex-wrap">
|
||||||
|
<span className="text-[#555] text-[10px] font-body uppercase tracking-wider shrink-0">Topics:</span>
|
||||||
|
<div className="flex gap-1.5 flex-wrap">
|
||||||
|
{ALL_CATEGORIES.map((cat) => {
|
||||||
|
const isActive = activeCategory === cat;
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
key={cat}
|
||||||
|
type="button"
|
||||||
|
onClick={() => { setActiveCategory(cat); setPage(1); }}
|
||||||
|
aria-pressed={isActive}
|
||||||
|
className={`px-3 py-1.5 rounded-sm font-body text-[11px] font-semibold uppercase tracking-wide transition-all duration-150 focus:outline-none focus-visible:ring-2 focus-visible:ring-[#3b82f6] ${
|
||||||
|
isActive
|
||||||
|
? "bg-[#3b82f6]/20 text-[#3b82f6] border border-[#3b82f6]/50"
|
||||||
|
: "bg-[#111] text-[#888] border border-[#2a2a2a] hover:text-[#ccc] hover:border-[#3a3a3a]"
|
||||||
|
}`}>
|
||||||
|
{cat}
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Advanced filters panel */}
|
{/* Advanced filters panel */}
|
||||||
{showAdvanced && (
|
{showAdvanced && (
|
||||||
<div
|
<div
|
||||||
|
|||||||
Reference in New Issue
Block a user