import type { KanjiEntry, VocabularyEntry, VocabularyOccurrenceEntry } from '../../types/stats'; import { formatNumber } from '../../lib/formatters'; type VocabularyDrawerTarget = | { kind: 'word'; entry: VocabularyEntry; } | { kind: 'kanji'; entry: KanjiEntry; }; interface VocabularyOccurrencesDrawerProps { target: VocabularyDrawerTarget | null; occurrences: VocabularyOccurrenceEntry[]; loading: boolean; loadingMore: boolean; error: string | null; hasMore: boolean; onClose: () => void; onLoadMore: () => void; } function formatSegment(ms: number | null): string { if (ms == null || !Number.isFinite(ms)) return '--:--'; const totalSeconds = Math.max(0, Math.floor(ms / 1000)); const minutes = Math.floor(totalSeconds / 60); const seconds = totalSeconds % 60; return `${minutes}:${String(seconds).padStart(2, '0')}`; } function renderTitle(target: VocabularyDrawerTarget): string { return target.kind === 'word' ? target.entry.headword : target.entry.kanji; } function renderSubtitle(target: VocabularyDrawerTarget): string { if (target.kind === 'word') { return target.entry.reading || target.entry.word; } return `${formatNumber(target.entry.frequency)} seen`; } function renderFrequency(target: VocabularyDrawerTarget): string { return `${formatNumber(target.entry.frequency)} total`; } export function VocabularyOccurrencesDrawer({ target, occurrences, loading, loadingMore, error, hasMore, onClose, onLoadMore, }: VocabularyOccurrencesDrawerProps) { if (!target) return null; return (
{loading ?
Loading occurrences...
: null} {!loading && error ?
Error: {error}
: null} {!loading && !error && occurrences.length === 0 ? (
No occurrences tracked yet.
) : null} {!loading && !error ? (
{occurrences.map((occurrence, index) => (
{occurrence.animeTitle ?? occurrence.videoTitle}
{occurrence.videoTitle} · line {occurrence.lineIndex}
{formatNumber(occurrence.occurrenceCount)} in line
{formatSegment(occurrence.segmentStartMs)}-{formatSegment(occurrence.segmentEndMs)} · session{' '} {occurrence.sessionId}

{occurrence.text}

))}
) : null}
{!loading && !error && hasMore ? (
) : null} ); } export type { VocabularyDrawerTarget };