Barazo default frontend
barazo.forum
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}