Industry News: remove author search filter
This commit is contained in:
@@ -47,19 +47,6 @@ type FeedMode = "pagination" | "infinite";
|
|||||||
type SortOrder = "recent" | "trending" | "most-commented";
|
type SortOrder = "recent" | "trending" | "most-commented";
|
||||||
const ARTICLES_PER_PAGE = 15;
|
const ARTICLES_PER_PAGE = 15;
|
||||||
|
|
||||||
// Derive unique authors from all articles (static + imported merged at runtime)
|
|
||||||
function getUniqueAuthors(articles: ArticleItem[]): string[] {
|
|
||||||
const seen = new Set<string>();
|
|
||||||
const authors: string[] = [];
|
|
||||||
for (const a of articles) {
|
|
||||||
if (a.author && !seen.has(a.author)) {
|
|
||||||
seen.add(a.author);
|
|
||||||
authors.push(a.author);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return authors.sort();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse "Month DD, YYYY" → Date object for comparison
|
// Parse "Month DD, YYYY" → Date object for comparison
|
||||||
function parseArticleDate(dateStr: string): Date | null {
|
function parseArticleDate(dateStr: string): Date | null {
|
||||||
const d = new Date(dateStr);
|
const d = new Date(dateStr);
|
||||||
@@ -79,7 +66,6 @@ export default function ArticleFeed() {
|
|||||||
const [sortOrder, setSortOrder] = useState<SortOrder>("recent");
|
const [sortOrder, setSortOrder] = useState<SortOrder>("recent");
|
||||||
// Advanced filters
|
// Advanced filters
|
||||||
const [showAdvanced, setShowAdvanced] = useState(false);
|
const [showAdvanced, setShowAdvanced] = useState(false);
|
||||||
const [authorFilter, setAuthorFilter] = useState("All");
|
|
||||||
const [dateFrom, setDateFrom] = useState("");
|
const [dateFrom, setDateFrom] = useState("");
|
||||||
const [dateTo, setDateTo] = useState("");
|
const [dateTo, setDateTo] = useState("");
|
||||||
const searchRef = useRef<HTMLInputElement>(null);
|
const searchRef = useRef<HTMLInputElement>(null);
|
||||||
@@ -138,15 +124,12 @@ export default function ArticleFeed() {
|
|||||||
// Merge: interleave imported posts with static (imported first by recency, then static)
|
// Merge: interleave imported posts with static (imported first by recency, then static)
|
||||||
const allArticles: ArticleItem[] = [...wpPosts];
|
const allArticles: ArticleItem[] = [...wpPosts];
|
||||||
|
|
||||||
const uniqueAuthors = getUniqueAuthors(allArticles);
|
const hasAdvancedActive = dateFrom !== "" || dateTo !== "";
|
||||||
|
|
||||||
const hasAdvancedActive = authorFilter !== "All" || dateFrom !== "" || dateTo !== "";
|
|
||||||
|
|
||||||
const clearAllFilters = () => {
|
const clearAllFilters = () => {
|
||||||
setSearchQuery("");
|
setSearchQuery("");
|
||||||
setActiveCategory("All");
|
setActiveCategory("All");
|
||||||
setSourceFilter("All");
|
setSourceFilter("All");
|
||||||
setAuthorFilter("All");
|
|
||||||
setDateFrom("");
|
setDateFrom("");
|
||||||
setDateTo("");
|
setDateTo("");
|
||||||
setPage(1);
|
setPage(1);
|
||||||
@@ -162,8 +145,7 @@ export default function ArticleFeed() {
|
|||||||
(sourceFilter === "Imported" && a.source === "imported") ||
|
(sourceFilter === "Imported" && a.source === "imported") ||
|
||||||
(sourceFilter === "Live" && a.source === "live");
|
(sourceFilter === "Live" && a.source === "live");
|
||||||
const q = searchQuery.toLowerCase();
|
const q = searchQuery.toLowerCase();
|
||||||
const matchSearch = !q || a.title.toLowerCase().includes(q) || a.excerpt.toLowerCase().includes(q) || a.author.toLowerCase().includes(q);
|
const matchSearch = !q || a.title.toLowerCase().includes(q) || a.excerpt.toLowerCase().includes(q);
|
||||||
const matchAuthor = authorFilter === "All" || a.author === authorFilter;
|
|
||||||
// Date range filtering
|
// Date range filtering
|
||||||
let matchDate = true;
|
let matchDate = true;
|
||||||
if (dateFrom || dateTo) {
|
if (dateFrom || dateTo) {
|
||||||
@@ -180,7 +162,7 @@ export default function ArticleFeed() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return matchCat && matchSource && matchSearch && matchAuthor && matchDate;
|
return matchCat && matchSource && matchSearch && matchDate;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Sort filtered articles based on sortOrder. For every order we honor
|
// Sort filtered articles based on sortOrder. For every order we honor
|
||||||
@@ -244,7 +226,7 @@ export default function ArticleFeed() {
|
|||||||
// Reset infinite count when filters change
|
// Reset infinite count when filters change
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setInfiniteCount(ARTICLES_PER_PAGE);
|
setInfiniteCount(ARTICLES_PER_PAGE);
|
||||||
}, [searchQuery, activeCategory, sourceFilter, authorFilter, dateFrom, dateTo, sortOrder]);
|
}, [searchQuery, activeCategory, sourceFilter, dateFrom, dateTo, sortOrder]);
|
||||||
|
|
||||||
// Arrow key navigation for filter chips
|
// Arrow key navigation for filter chips
|
||||||
const handleFilterKeyDown = (e: React.KeyboardEvent, index: number) => {
|
const handleFilterKeyDown = (e: React.KeyboardEvent, index: number) => {
|
||||||
@@ -363,7 +345,7 @@ 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 — topic chips + date range visible by default, advanced (author + source) behind toggle */}
|
{/* Filters — date range visible by default, advanced (source) behind toggle */}
|
||||||
<div className="mb-4 space-y-3">
|
<div className="mb-4 space-y-3">
|
||||||
{/* Row: date range + advanced toggle */}
|
{/* Row: date range + advanced toggle */}
|
||||||
<div className="flex items-center gap-2 flex-wrap">
|
<div className="flex items-center gap-2 flex-wrap">
|
||||||
@@ -426,31 +408,6 @@ export default function ArticleFeed() {
|
|||||||
className="bg-[#F8FAFC] border border-[#DCE6F2] rounded-sm p-3 space-y-3"
|
className="bg-[#F8FAFC] border border-[#DCE6F2] rounded-sm p-3 space-y-3"
|
||||||
role="group"
|
role="group"
|
||||||
aria-label="Advanced filters">
|
aria-label="Advanced filters">
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
|
|
||||||
{/* Author filter (category + date moved out to the always-visible row) */}
|
|
||||||
<div className="space-y-1">
|
|
||||||
<label htmlFor={`${feedId}-author`} className="font-body text-[10px] text-[#555] uppercase tracking-wide block">
|
|
||||||
Author
|
|
||||||
</label>
|
|
||||||
<div className="relative">
|
|
||||||
<select
|
|
||||||
id={`${feedId}-author`}
|
|
||||||
value={authorFilter}
|
|
||||||
onChange={(e) => { setAuthorFilter(e.target.value); setPage(1); }}
|
|
||||||
className="w-full bg-[#111] border border-[#DCE6F2] text-[#ccc] font-body text-sm rounded-sm px-3 py-1.5 pr-8 appearance-none focus:outline-none focus:border-[#1D4ED8] focus:ring-1 focus:ring-[#1D4ED8]/30 transition-colors [color-scheme:dark]"
|
|
||||||
aria-label="Filter by author">
|
|
||||||
<option value="All">All Authors</option>
|
|
||||||
{uniqueAuthors.map((author) => (
|
|
||||||
<option key={author} value={author}>{author}</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
<svg className="absolute right-2.5 top-1/2 -translate-y-1/2 pointer-events-none text-[#555]" width="10" height="10" viewBox="0 0 10 10" fill="none" aria-hidden="true">
|
|
||||||
<path d="M2 3.5L5 6.5L8 3.5" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Source filter inside advanced panel */}
|
{/* Source filter inside advanced panel */}
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
<span className="font-body text-[10px] text-[#555] uppercase tracking-wide block">Source</span>
|
<span className="font-body text-[10px] text-[#555] uppercase tracking-wide block">Source</span>
|
||||||
@@ -485,7 +442,7 @@ export default function ArticleFeed() {
|
|||||||
<div className="flex justify-end pt-1 border-t border-[#1e1e1e]">
|
<div className="flex justify-end pt-1 border-t border-[#1e1e1e]">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => { setAuthorFilter("All"); setDateFrom(""); setDateTo(""); setPage(1); }}
|
onClick={() => { setDateFrom(""); setDateTo(""); setPage(1); }}
|
||||||
className="font-body text-[11px] text-[#1D4ED8] hover:underline focus:outline-none focus-visible:underline">
|
className="font-body text-[11px] text-[#1D4ED8] hover:underline focus:outline-none focus-visible:underline">
|
||||||
Clear advanced filters
|
Clear advanced filters
|
||||||
</button>
|
</button>
|
||||||
@@ -499,7 +456,7 @@ export default function ArticleFeed() {
|
|||||||
selection now. */}
|
selection now. */}
|
||||||
|
|
||||||
{/* Results count */}
|
{/* Results count */}
|
||||||
{(searchQuery || activeCategory !== "All" || sourceFilter !== "All" || authorFilter !== "All" || dateFrom || dateTo) && (
|
{(searchQuery || activeCategory !== "All" || sourceFilter !== "All" || dateFrom || dateTo) && (
|
||||||
<p
|
<p
|
||||||
id={`${feedId}-results`}
|
id={`${feedId}-results`}
|
||||||
className="font-body text-xs text-[#666]"
|
className="font-body text-xs text-[#666]"
|
||||||
@@ -510,7 +467,6 @@ export default function ArticleFeed() {
|
|||||||
: `${sortedFiltered.length} article${sortedFiltered.length !== 1 ? "s" : ""} found`}
|
: `${sortedFiltered.length} article${sortedFiltered.length !== 1 ? "s" : ""} found`}
|
||||||
{searchQuery ? ` for "${searchQuery}"` : ""}
|
{searchQuery ? ` for "${searchQuery}"` : ""}
|
||||||
{activeCategory !== "All" ? ` in ${activeCategory}` : ""}
|
{activeCategory !== "All" ? ` in ${activeCategory}` : ""}
|
||||||
{authorFilter !== "All" ? ` · by ${authorFilter}` : ""}
|
|
||||||
{sourceFilter !== "All" ? ` · ${sourceFilter} only` : ""}
|
{sourceFilter !== "All" ? ` · ${sourceFilter} only` : ""}
|
||||||
{(dateFrom || dateTo) ? ` · ${dateFrom ? dateFrom : "any"} → ${dateTo ? dateTo : "any"}` : ""}
|
{(dateFrom || dateTo) ? ` · ${dateFrom ? dateFrom : "any"} → ${dateTo ? dateTo : "any"}` : ""}
|
||||||
{sortedFiltered.length === 0 && (
|
{sortedFiltered.length === 0 && (
|
||||||
|
|||||||
Reference in New Issue
Block a user