// Medway MSS — Catalogue page // Consumes window.MEDWAY_CATALOGUE from public/catalogue/data.js const ACCENT = '#1ea34d'; // ── Subcategory illustrations (Halo-style geometric specimens) ──────────────── function SubcatIllustration({ sub, accent = ACCENT }) { const ink = '#171717'; const sw = 1.75; const wrap = (children) => ( {children} ); switch (sub) { case 'biochem': return wrap(<> ); case 'hematology': return wrap(<> ); case 'control_calib': return wrap(<> ); case 'hplc_cleaning': return wrap(<> ); case 'gel_cards': return wrap(<> {[0,1,2,3,4,5,6,7].map(i => ( ))} ); case 'rbc': return wrap(<> {[60, 110, 160].map((cx,i) => ( ))} ); case 'diluents': return wrap(<> ); case 'equipment': return wrap(<> ); default: // x-ray subcategories use photos, but keep a default return wrap(<> ); } } // ── Product card ────────────────────────────────────────────────────────────── function ProductCard({ p, accent = ACCENT }) { const hasPhoto = !!p.image; return (
{ e.currentTarget.style.borderColor = 'var(--fg-1)'; }} onMouseLeave={(e) => { e.currentTarget.style.borderColor = 'var(--border)'; }} > {hasPhoto ? (
{p.name}
) : (
)}
{p.name}
{p.method && (
{p.method}
)} {p.refs && p.refs.length > 0 && (
{p.refs.slice(0, 6).map((r) => ( {r} ))} {p.refs.length > 6 && ( +{p.refs.length - 6} )}
)}
); } // ── Subcategory section ─────────────────────────────────────────────────────── function SubcategorySection({ sub, products, t, lang, meta, accent = ACCENT }) { const isMobile = useIsMobile(); const label = meta.subcategories[sub]?.[lang] || meta.subcategories[sub]?.fr || sub; return (

{label}

{products.length} {t('cat.items')}
{products.map((p, i) => )}
); } // ── Category section ────────────────────────────────────────────────────────── function CategorySection({ cat, products, t, lang, meta, n }) { const isMobile = useIsMobile(); const label = meta.labels[cat]?.[lang] || meta.labels[cat]?.fr || cat; // Preserve subcategory order from data (first-occurrence) const subOrder = []; for (const p of products) if (!subOrder.includes(p.sub)) subOrder.push(p.sub); return (
§ 0{n}
{products.length} {t('cat.items')}

{label}

{subOrder.map((sub) => { const list = products.filter((p) => p.sub === sub); if (!list.length) return null; return ( ); })}
); } // ── Top bar (sticky) ────────────────────────────────────────────────────────── function CatalogueTopBar({ t, lang, setLang, query, setQuery, scrollToCat }) { const [scrolled, setScrolled] = React.useState(false); const isMobile = useIsMobile(); React.useEffect(() => { const on = () => setScrolled(window.scrollY > 8); window.addEventListener('scroll', on); return () => window.removeEventListener('scroll', on); }, []); return ( ); } // ── Hero ────────────────────────────────────────────────────────────────────── function CatalogueHero({ t, lang, meta, productsByCat, scrollToCat }) { const isMobile = useIsMobile(); const cats = Object.keys(productsByCat); return (
Medway MSS · Lomé, Togo

{t('cat.title')}

{t('cat.subtitle')}

{cats.map((cat) => { const list = productsByCat[cat] || []; const label = meta.labels[cat]?.[lang] || meta.labels[cat]?.fr || cat; return ( ); })}
); } // ── App ─────────────────────────────────────────────────────────────────────── function CategoryButton({ cat, label, count, onClick }) { return ( ); } function App() { const { lang, setLang, t } = useI18n(); const isMobile = useIsMobile(); const [query, setQuery] = React.useState(''); React.useEffect(() => { document.documentElement.lang = lang; }, [lang]); React.useEffect(() => { if (window.lucide) window.lucide.createIcons(); }); const data = window.MEDWAY_CATALOGUE || { _meta: { labels: {}, subcategories: {} }, products: [] }; const meta = data._meta; const all = data.products; // Apply name overrides per language where present const translated = all.map((p) => { if (lang === 'en' && p.name_en) return { ...p, name: p.name_en }; return p; }); const filtered = React.useMemo(() => { const q = query.trim().toLowerCase(); if (!q) return translated; return translated.filter((p) => { if (p.name.toLowerCase().includes(q)) return true; if (p.method && p.method.toLowerCase().includes(q)) return true; if (p.refs && p.refs.some((r) => r.toLowerCase().includes(q))) return true; const subLabel = meta.subcategories[p.sub]?.[lang] || ''; if (subLabel.toLowerCase().includes(q)) return true; return false; }); }, [query, translated, lang]); // Group by category in fixed order const CAT_ORDER = ['reaktif', 'kan_gruplama', 'radyoloji']; const byCat = {}; for (const c of CAT_ORDER) byCat[c] = filtered.filter((p) => p.category === c); const scrollToCat = (cat) => { const el = document.getElementById(`cat-${cat}`); if (el) { const top = el.getBoundingClientRect().top + window.scrollY - 68; window.scrollTo({ top, behavior: 'smooth' }); } }; return (
{filtered.length === 0 ? (
{t('cat.no_results')}
) : ( CAT_ORDER.map((cat, i) => { const list = byCat[cat]; if (!list || list.length === 0) return null; return ( ); }) )}
Medway MSS

{t('cat.note')}

{isMobile && ( )}
); } const root = ReactDOM.createRoot(document.getElementById('root')); root.render();