import { useState } from 'react' import { Link, useSearchParams } from 'react-router-dom' import PublicLayout from '../../components/PublicLayout.jsx' import PageHeader from '../../components/PageHeader.jsx' import { Loading, ErrorState, EmptyState } from '../../components/PageState.jsx' import { useAsync } from '../../lib/useAsync.js' import { api } from '../../api/client.js' function SearchBox({ initial, onSubmit }) { const [term, setTerm] = useState(initial || '') return (
) } // Group published pages under their category, preserving category sort order and // collecting anything uncategorized into a trailing section. function groupByCategory(categories, pages) { const byId = new Map(categories.map((c) => [c.id, { ...c, pages: [] }])) const uncategorized = [] for (const page of pages) { const bucket = page.category_id != null ? byId.get(page.category_id) : null if (bucket) bucket.pages.push(page) else uncategorized.push(page) } const sections = [...byId.values()].filter((c) => c.pages.length > 0) if (uncategorized.length) { sections.push({ id: 'uncategorized', title: 'Other Pages', description: '', pages: uncategorized }) } return sections } function PageCard({ page }) { return ({page.excerpt || 'Open the guide →'}
) } export default function Wiki() { const [searchParams, setSearchParams] = useSearchParams() const activeCategory = searchParams.get('category') const activeTag = searchParams.get('tag') const activeQ = searchParams.get('q') // Search / tag views fetch a filtered page list; otherwise all pages (grouped here). const pageOpts = activeQ ? { q: activeQ } : activeTag ? { tag: activeTag } : {} const { loading, error, data } = useAsync( () => Promise.all([api.wikiCategories(), api.wiki(pageOpts)]).then(([categories, pages]) => ({ categories, pages, })), [activeTag, activeQ], ) const allSections = data ? groupByCategory(data.categories, data.pages) : [] const sections = activeCategory ? allSections.filter((s) => s.slug === activeCategory) : allSections const hasPages = data && data.pages.length > 0 const flat = Boolean(activeTag || activeQ) // flat-list views const filtered = Boolean(activeCategory || activeTag || activeQ) const runSearch = (term) => setSearchParams(term ? { q: term } : {}) return (← All sections {activeTag && · Tagged #{activeTag}} {activeQ && · Results for “{activeQ}”}
)} {/* Flat list: search results or a tag filter (both cross categories). */} {!loading && !error && flat && (data.pages.length === 0 ? ({section.description}
)}