// FilterBar.jsx - view-aware filter rail
// Each view defines its own spec'd filter set per the GEA visual specs:
// Value Chain Map: pillar, barrier, region
// Collaboration Network: pillar, org type
// Directory: all filters
const TYPE_KEY = {
'MDB/ IFI / DFI': 'mdb',
'Bilateral development agency': 'bil',
'Intergovernmental organization (IGO)': 'igo',
'Coalition or multi-stakeholder platform': 'coa',
'NGO': 'ngo',
'Research & Academic institution': 'res',
};
window.TYPE_KEY = TYPE_KEY;
// Per-view filter visibility - controls which filter sections render
const VIEW_FILTERS = {
valuechain: ['pillar', 'barriers', 'regions'],
matrix: ['pillar', 'types', 'regions'],
network: ['pillar', 'types'],
directory: ['pillar', 'regions', 'barriers', 'types'],
};
window.VIEW_FILTERS = VIEW_FILTERS;
function FilterChip({ label, count, active, onClick, sublabel, swatch }) {
return (
);
}
function FilterSection({ title, children, onClear, showClear }) {
return (
{title}
{showClear && clear}
{children}
);
}
const PILLAR_COLORS = {
grids: 'var(--c-mint)',
powering: 'var(--c-yellow)',
both: 'var(--c-leaf)',
};
function FilterBar({ filters, setFilters, allOrgs, filteredOrgs, facets, activeView }) {
const { regions, barriers, types, pillar } = facets;
const visible = VIEW_FILTERS[activeView] || VIEW_FILTERS.directory;
const showSearch = activeView === 'directory';
const countOf = (key, val) => filteredOrgs.filter((o) => {
const v = o[key];
return Array.isArray(v) ? v.includes(val) : v === val;
}).length;
const toggle = (key, val) => {
const cur = filters[key] || [];
const next = cur.includes(val) ? cur.filter((x) => x !== val) : [...cur, val];
setFilters({ ...filters, [key]: next });
};
const clear = (key) => setFilters({ ...filters, [key]: [] });
const resetAll = () => setFilters({ search: '', regions: [], barriers: [], types: [], pillar: [] });
const activeCount = ['regions','barriers','types','pillar']
.reduce((n,k) => n + (filters[k]?.length || 0), 0) + (filters.search ? 1 : 0);
return (
);
}
window.FilterBar = FilterBar;