tahamajs's picture
download
raw
2.85 kB
/**
* react/components/modals/CatalogModal.jsx
* ========================================
* Searchable modal listing all 252 architectural research modules with category filters.
*/
import React, { useState } from 'react';
import { useModuleStore } from '../../store/useModuleStore.js';
import { ROUTING_MATRIX } from '../visualization/routing_matrix.js';
export default function CatalogModal({ isOpen, onClose }) {
const [searchTerm, setSearchTerm] = useState('');
const [categoryFilter, setCategoryFilter] = useState('ALL');
const { setActiveModule } = useModuleStore();
if (!isOpen) return null;
const entries = Object.entries(ROUTING_MATRIX).filter(([id, config]) => {
const matchesSearch = id.toLowerCase().includes(searchTerm.toLowerCase()) ||
(config.name && config.name.toLowerCase().includes(searchTerm.toLowerCase()));
const matchesCat = categoryFilter === 'ALL' || config.category === categoryFilter;
return matchesSearch && matchesCat;
});
const handleSelect = (modId) => {
setActiveModule(modId, ROUTING_MATRIX);
onClose();
};
return (
<div className="modal-backdrop react-modal" data-testid="catalog-modal" role="dialog" aria-modal="true">
<div className="modal-container">
<div className="modal-header">
<h3>Architecture Catalog (252 Modules)</h3>
<button type="button" className="btn-close-modal" onClick={onClose} aria-label="Close modal">✕</button>
</div>
<div className="catalog-filters">
<input
type="text"
className="input-search-catalog"
placeholder="Search module name, author, or keyword..."
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
/>
<select
value={categoryFilter}
onChange={(e) => setCategoryFilter(e.target.value)}
className="filter-category-select"
>
<option value="ALL">All Categories (A–I)</option>
{['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'].map(c => (
<option key={c} value={c}>Category {c}</option>
))}
</select>
</div>
<div className="catalog-grid-scroll">
{entries.map(([id, config]) => (
<div
key={id}
className="catalog-card-item"
onClick={() => handleSelect(id)}
tabIndex={0}
role="button"
>
<div className="item-header">
<span className="item-badge">Cat {config.category}</span>
<span className="item-id">{id}</span>
</div>
<p className="item-desc">{config.name || id}</p>
</div>
))}
</div>
</div>
</div>
);
}

Xet Storage Details

Size:
2.85 kB
·
Xet hash:
f70380cf74e02fbf3b906fc99503b22e58d5c9f9972d0be9c29c0368f2e2092f

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.