import { useMemo, useState } from 'react'; import { Link } from 'react-router-dom'; import { MOCK_CATEGORIES, MOCK_THREADS } from '../../data/mockData'; import { timeAgo } from '../../utils/format'; import type { ForumCategory, ForumThread } from '../../types'; // ── Sub-components ───────────────────────────────────────────────────────────── function CategoryCard({ category, threads }: { category: ForumCategory; threads: ForumThread[] }) { const pinned = threads.filter((t) => t.isPinned && t.categoryId === category.id); const regular = threads.filter((t) => !t.isPinned && t.categoryId === category.id); const categoryThreads = [...pinned, ...regular]; return (
{/* Category header */}
{category.icon}

{category.name}

{category.description}

{category.threadCount} threads
{/* Threads */}
{categoryThreads.length === 0 ? (
No threads yet. Be the first to post.
) : ( categoryThreads.map((thread, idx) => (
{thread.isPinned && ( Pinned )} {thread.isLocked && ( Locked )} {thread.title}
by {thread.authorName} {' '}— {timeAgo(thread.createdAt)}
{thread.replyCount}
replies
)) )}
); } // ── Forum Page ───────────────────────────────────────────────────────────────── export default function ForumPage() { const [search, setSearch] = useState(''); const filteredCategories = useMemo(() => { if (!search.trim()) return MOCK_CATEGORIES; const q = search.toLowerCase(); return MOCK_CATEGORIES.filter((cat) => cat.name.toLowerCase().includes(q) || MOCK_THREADS.some((t) => t.categoryId === cat.id && t.title.toLowerCase().includes(q)) ); }, [search]); return (
{/* Header */}
Community

FORUM

Read freely. Login to post.

{/* Search */}
setSearch(e.target.value)} style={{ width: '220px' }} aria-label="Search forum threads" />
{/* Categories */} {filteredCategories.length === 0 ? (
No results found for "{search}"
) : ( filteredCategories.map((cat) => ( )) )}
); }