Barazo default frontend barazo.forum
at main 53 lines 1.7 kB view raw
1/** 2 * TopicList - Paginated list of TopicCard components. 3 * Renders topics with optional heading and empty state. 4 * Separates pinned topics from regular topics with section headings. 5 * @see specs/prd-web.md Section 4 (Topic Components) 6 */ 7 8import type { Topic } from '@/lib/api/types' 9import { TopicCard } from './topic-card' 10 11interface TopicListProps { 12 topics: Topic[] 13 heading?: string 14} 15 16export function TopicList({ topics, heading }: TopicListProps) { 17 const pinnedTopics = topics.filter((t) => t.isPinned) 18 const regularTopics = topics.filter((t) => !t.isPinned) 19 const hasPinned = pinnedTopics.length > 0 20 21 return ( 22 <section> 23 {heading && <h2 className="mb-4 text-xl font-semibold text-foreground">{heading}</h2>} 24 {topics.length === 0 ? ( 25 <div className="rounded-lg border border-border bg-card p-8 text-center"> 26 <p className="text-muted-foreground"> 27 No topics yet. Be the first to start a discussion! 28 </p> 29 </div> 30 ) : ( 31 <div className="space-y-3"> 32 {hasPinned && ( 33 <> 34 <h3 className="text-xs font-medium uppercase tracking-wide text-muted-foreground"> 35 Pinned 36 </h3> 37 {pinnedTopics.map((topic) => ( 38 <TopicCard key={topic.uri} topic={topic} /> 39 ))} 40 <div className="border-b border-border" role="separator" /> 41 <h3 className="text-xs font-medium uppercase tracking-wide text-muted-foreground"> 42 Topics 43 </h3> 44 </> 45 )} 46 {regularTopics.map((topic) => ( 47 <TopicCard key={topic.uri} topic={topic} /> 48 ))} 49 </div> 50 )} 51 </section> 52 ) 53}