// DirectoryView.jsx - sortable filterable card grid const { useState: useStateD, useMemo: useMemoD } = React; const TYPE_TINT = { 'MDB/ IFI / DFI': 'var(--ocean-blue)', 'Bilateral development agency': 'var(--earth-clay)', 'Intergovernmental organization (IGO)': 'var(--faded-dewberry)', 'Coalition or multi-stakeholder platform': 'var(--verdant-green)', 'NGO': 'var(--solar-yellow)', 'Philanthropic foundation': '#e07b4a', 'Private company (IPP)': '#2a7a5a', 'Private investor': '#7a5da8', 'Commercial system actor': '#b05c7a', 'Research & Academic institution': 'var(--sky-blue)', }; function DirectoryView({ orgs, allOrgs, onPickOrg, filters, setFilters }) { const { facets } = window.INITIATIVES_DATA; const [sort, setSort] = useStateD('name'); const searchActive = !!(filters && filters.search); const sorted = useMemoD(() => { const arr = [...orgs]; // When searching, app.jsx has already ordered by relevance - keep that if (searchActive) return arr; if (sort === 'name') arr.sort((a, b) => a.name.localeCompare(b.name)); else if (sort === 'reach') arr.sort((a, b) => b.regions.length - a.regions.length); return arr; }, [orgs, sort, searchActive]); const toggleFilter = (key, val) => { const cur = filters[key] || []; const next = cur.includes(val) ? cur.filter(x => x !== val) : [...cur, val]; setFilters({ ...filters, [key]: next }); }; const clearFilter = (key) => setFilters({ ...filters, [key]: [] }); const activeTypes = filters.types || []; const activePillar = filters.pillar || []; const activeRegions = filters.regions || []; const presentTypes = useMemoD(() => { const s = new Set((allOrgs || orgs).map(o => o.type).filter(Boolean)); return Object.keys(TYPE_TINT).filter(t => s.has(t)); }, [allOrgs, orgs]); return (