diff --git a/src/app/manufacturers/DirectoryClient.tsx b/src/app/manufacturers/DirectoryClient.tsx index 92fb8dd..b10ff16 100644 --- a/src/app/manufacturers/DirectoryClient.tsx +++ b/src/app/manufacturers/DirectoryClient.tsx @@ -11,22 +11,44 @@ type Manufacturer = { categories: string[] | null; exhibits_nab: boolean; exhibits_ibc: boolean; + shows_attending: string[] | null; mention_count: number; featured: boolean; }; -const SHOW_FILTERS = ["All", "NAB Show", "IBC", "Both shows"] as const; -type ShowFilter = (typeof SHOW_FILTERS)[number]; +type ShowOption = { + slug: string; + short_name: string | null; + name: string; + start_date: string; + end_date: string; + status: string; +}; export default function ManufacturerDirectoryClient({ manufacturers, + shows = [], }: { manufacturers: Manufacturer[]; + shows?: ShowOption[]; }) { const [q, setQ] = useState(""); - const [showFilter, setShowFilter] = useState("All"); + // showFilter is now a show slug from bb.events (e.g. 'nab-show-2026') or + // 'all' / 'both-major' (NAB+IBC overlap). + const [showFilter, setShowFilter] = useState("all"); const [letter, setLetter] = useState("All"); + // Per-show exhibitor counts for badge display + auto-hiding empty shows. + const showCounts = useMemo(() => { + const counts: Record = {}; + for (const m of manufacturers) { + for (const s of m.shows_attending || []) { + counts[s] = (counts[s] || 0) + 1; + } + } + return counts; + }, [manufacturers]); + const filtered = useMemo(() => { const needle = q.trim().toLowerCase(); return manufacturers.filter((m) => { @@ -34,9 +56,11 @@ export default function ManufacturerDirectoryClient({ const hay = `${m.company_name} ${m.bio || ""}`.toLowerCase(); if (!hay.includes(needle)) return false; } - if (showFilter === "NAB Show" && !m.exhibits_nab) return false; - if (showFilter === "IBC" && !m.exhibits_ibc) return false; - if (showFilter === "Both shows" && !(m.exhibits_nab && m.exhibits_ibc)) return false; + if (showFilter === "both-major") { + if (!(m.exhibits_nab && m.exhibits_ibc)) return false; + } else if (showFilter !== "all") { + if (!(m.shows_attending || []).includes(showFilter)) return false; + } if (letter !== "All") { const c = (m.company_name || "").trim().charAt(0).toUpperCase(); if (letter === "#") { @@ -63,20 +87,53 @@ export default function ManufacturerDirectoryClient({ className="w-full bg-[#0d0d0d] border border-[#2a2a2a] rounded-md px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-[#3b82f6]/40" /> -
- {SHOW_FILTERS.map((f) => ( +
+ + {/* Per-show filter chips. Every event from bb.events shows up; ones + without exhibitor mappings yet render a "(soon)" badge so the + admin can see what's still missing data. */} +
+ + + {shows.map((s) => { + const count = showCounts[s.slug] || 0; + const active = showFilter === s.slug; + const label = s.short_name || s.name; + return ( - ))} -
+ ); + })}