import { useEffect, useRef } from 'react' import { BookOpen } from 'lucide-react' import type { Chapter } from '../types' import { activeChapterIndex, chapterKindLabel, chapterLapRange, chapterStartScrub, } from '../lib/chapters' import { EmptyStateCard } from './EmptyStateCard' import '../styles/chapters.css' interface Props { chapters: Chapter[] scrubTime: number | null tMin: number tRange: number tourActive: boolean tourChapterIndex: number | null /** Explicit selection from a chapter click; wins over scrub-derived active. */ selectedChapterIndex?: number | null onChapterClick: (index: number, scrub: number) => void onTourToggle: () => void } export function ChapterStrip({ chapters, scrubTime, tMin, tRange, tourActive, tourChapterIndex, selectedChapterIndex = null, onChapterClick, onTourToggle, }: Props) { const scrollRef = useRef(null) const activeIndex = activeChapterIndex(chapters, scrubTime, tMin, tRange) const highlightedIndex = tourActive ? tourChapterIndex : (selectedChapterIndex ?? activeIndex) useEffect(() => { if (highlightedIndex === null || !scrollRef.current) return const card = scrollRef.current.querySelector( `[data-testid="chapter-card-${highlightedIndex}"]`, ) card?.scrollIntoView?.({ behavior: 'smooth', inline: 'center', block: 'nearest' }) }, [highlightedIndex]) if (chapters.length === 0) { return (
) } return (
Race chapters
{chapters.map((chapter, index) => { const scrub = chapterStartScrub(chapter, tMin, tRange) ?? index / Math.max(chapters.length - 1, 1) const isActive = highlightedIndex === index const headline = chapter.headline || chapter.title return ( ) })}
) }