feat(stats): use generic title wording for mixed-source library

The stats dashboard now supports both anime series and YouTube videos
in the same library, so the anime-only copy no longer fits. Rename
user-visible labels ("Active Anime", "Search anime…", "Anime — Per
Day", "Episodes per Anime", "Words In Multiple Anime", etc.) to use
"Title"/"Library" wording that covers either source.

Data-model names (animeId, animeCount, useAnimeLibrary) stay as-is;
this pass only touches strings the user actually reads.
This commit is contained in:
2026-04-09 01:55:49 -07:00
parent b1acbae580
commit c5e778d7d2
6 changed files with 20 additions and 20 deletions

View File

@@ -93,7 +93,7 @@ export function AnimeTab({
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<input <input
type="text" type="text"
placeholder="Search anime..." placeholder="Search library..."
value={search} value={search}
onChange={(e) => setSearch(e.target.value)} onChange={(e) => setSearch(e.target.value)}
className="flex-1 bg-ctp-surface0 border border-ctp-surface1 rounded-lg px-3 py-2 text-sm text-ctp-text placeholder:text-ctp-overlay2 focus:outline-none focus:border-ctp-blue" className="flex-1 bg-ctp-surface0 border border-ctp-surface1 rounded-lg px-3 py-2 text-sm text-ctp-text placeholder:text-ctp-overlay2 focus:outline-none focus:border-ctp-blue"
@@ -125,12 +125,12 @@ export function AnimeTab({
))} ))}
</div> </div>
<div className="text-xs text-ctp-overlay2 shrink-0"> <div className="text-xs text-ctp-overlay2 shrink-0">
{filtered.length} anime · {formatDuration(totalMs)} {filtered.length} titles · {formatDuration(totalMs)}
</div> </div>
</div> </div>
{filtered.length === 0 ? ( {filtered.length === 0 ? (
<div className="text-sm text-ctp-overlay2 p-4">No anime found</div> <div className="text-sm text-ctp-overlay2 p-4">No titles found</div>
) : ( ) : (
<div className={`grid ${GRID_CLASSES[cardSize]} gap-4`}> <div className={`grid ${GRID_CLASSES[cardSize]} gap-4`}>
{filtered.map((item) => ( {filtered.map((item) => (

View File

@@ -36,7 +36,7 @@ export function HeroStats({ summary, sessions }: HeroStatsProps) {
/> />
<StatCard label="Current Streak" value={`${summary.streakDays}d`} color="text-ctp-peach" /> <StatCard label="Current Streak" value={`${summary.streakDays}d`} color="text-ctp-peach" />
<StatCard <StatCard
label="Active Anime" label="Active Titles"
value={formatNumber(summary.activeAnimeCount)} value={formatNumber(summary.activeAnimeCount)}
color="text-ctp-mauve" color="text-ctp-mauve"
/> />

View File

@@ -71,7 +71,7 @@ export function TrackingSnapshot({
</div> </div>
</div> </div>
</Tooltip> </Tooltip>
<Tooltip text="Total unique episodes (videos) watched across all anime"> <Tooltip text="Total unique videos watched across all titles in your library">
<div className="rounded-lg bg-ctp-surface1/60 p-3"> <div className="rounded-lg bg-ctp-surface1/60 p-3">
<div className="text-xs uppercase tracking-wide text-ctp-overlay2">Episodes</div> <div className="text-xs uppercase tracking-wide text-ctp-overlay2">Episodes</div>
<div className="mt-1 text-xl font-semibold font-mono tabular-nums text-ctp-blue"> <div className="mt-1 text-xl font-semibold font-mono tabular-nums text-ctp-blue">
@@ -79,9 +79,9 @@ export function TrackingSnapshot({
</div> </div>
</div> </div>
</Tooltip> </Tooltip>
<Tooltip text="Number of anime series fully completed"> <Tooltip text="Number of titles fully completed">
<div className="rounded-lg bg-ctp-surface1/60 p-3"> <div className="rounded-lg bg-ctp-surface1/60 p-3">
<div className="text-xs uppercase tracking-wide text-ctp-overlay2">Anime</div> <div className="text-xs uppercase tracking-wide text-ctp-overlay2">Titles</div>
<div className="mt-1 text-xl font-semibold font-mono tabular-nums text-ctp-sapphire"> <div className="mt-1 text-xl font-semibold font-mono tabular-nums text-ctp-sapphire">
{formatNumber(summary.totalAnimeCompleted)} {formatNumber(summary.totalAnimeCompleted)}
</div> </div>

View File

@@ -120,7 +120,7 @@ export function SessionRow({
}} }}
aria-label={`View overview for ${session.canonicalTitle ?? 'Unknown Media'}`} aria-label={`View overview for ${session.canonicalTitle ?? 'Unknown Media'}`}
className="absolute right-10 top-1/2 -translate-y-1/2 w-5 h-5 rounded border border-ctp-surface2 text-transparent hover:border-ctp-blue/50 hover:text-ctp-blue hover:bg-ctp-blue/10 transition-colors opacity-0 group-hover:opacity-100 focus:opacity-100 flex items-center justify-center" className="absolute right-10 top-1/2 -translate-y-1/2 w-5 h-5 rounded border border-ctp-surface2 text-transparent hover:border-ctp-blue/50 hover:text-ctp-blue hover:bg-ctp-blue/10 transition-colors opacity-0 group-hover:opacity-100 focus:opacity-100 flex items-center justify-center"
title="View anime overview" title="View in Library"
> >
{'\u2197'} {'\u2197'}
</button> </button>

View File

@@ -221,7 +221,7 @@ export function TrendsTab() {
type="line" type="line"
/> />
<SectionHeader>Anime Per Day</SectionHeader> <SectionHeader>Library Per Day</SectionHeader>
<AnimeVisibilityFilter <AnimeVisibilityFilter
animeTitles={animeTitles} animeTitles={animeTitles}
hiddenAnime={activeHiddenAnime} hiddenAnime={activeHiddenAnime}
@@ -239,21 +239,21 @@ export function TrendsTab() {
}) })
} }
/> />
<StackedTrendChart title="Episodes per Anime" data={filteredEpisodesPerAnime} /> <StackedTrendChart title="Videos per Title" data={filteredEpisodesPerAnime} />
<StackedTrendChart title="Watch Time per Anime (min)" data={filteredWatchTimePerAnime} /> <StackedTrendChart title="Watch Time per Title (min)" data={filteredWatchTimePerAnime} />
<StackedTrendChart <StackedTrendChart
title="Cards Mined per Anime" title="Cards Mined per Title"
data={filteredCardsPerAnime} data={filteredCardsPerAnime}
colorPalette={cardsMinedStackedColors} colorPalette={cardsMinedStackedColors}
/> />
<StackedTrendChart title="Words Seen per Anime" data={filteredWordsPerAnime} /> <StackedTrendChart title="Words Seen per Title" data={filteredWordsPerAnime} />
<StackedTrendChart title="Lookups per Anime" data={filteredLookupsPerAnime} /> <StackedTrendChart title="Lookups per Title" data={filteredLookupsPerAnime} />
<StackedTrendChart <StackedTrendChart
title="Lookups/100w per Anime" title="Lookups/100w per Title"
data={filteredLookupsPerHundredPerAnime} data={filteredLookupsPerHundredPerAnime}
/> />
<SectionHeader>Anime Cumulative</SectionHeader> <SectionHeader>Library Cumulative</SectionHeader>
<StackedTrendChart title="Watch Time Progress (min)" data={filteredWatchTimeProgress} /> <StackedTrendChart title="Watch Time Progress (min)" data={filteredWatchTimeProgress} />
<StackedTrendChart title="Episodes Progress" data={filteredAnimeProgress} /> <StackedTrendChart title="Episodes Progress" data={filteredAnimeProgress} />
<StackedTrendChart <StackedTrendChart

View File

@@ -72,7 +72,7 @@ export function CrossAnimeWordsTable({
> >
{'\u25B6'} {'\u25B6'}
</span> </span>
Words In Multiple Anime Words Across Multiple Titles
</button> </button>
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
{hasKnownData && ( {hasKnownData && (
@@ -97,8 +97,8 @@ export function CrossAnimeWordsTable({
{collapsed ? null : ranked.length === 0 ? ( {collapsed ? null : ranked.length === 0 ? (
<div className="text-xs text-ctp-overlay2 mt-3"> <div className="text-xs text-ctp-overlay2 mt-3">
{hideKnown {hideKnown
? 'All multi-anime words are already known!' ? 'All words that span multiple titles are already known!'
: 'No words found across multiple anime.'} : 'No words found across multiple titles.'}
</div> </div>
) : ( ) : (
<> <>
@@ -109,7 +109,7 @@ export function CrossAnimeWordsTable({
<th className="text-left py-2 pr-3 font-medium">Word</th> <th className="text-left py-2 pr-3 font-medium">Word</th>
<th className="text-left py-2 pr-3 font-medium">Reading</th> <th className="text-left py-2 pr-3 font-medium">Reading</th>
<th className="text-left py-2 pr-3 font-medium w-20">POS</th> <th className="text-left py-2 pr-3 font-medium w-20">POS</th>
<th className="text-right py-2 pr-3 font-medium w-16">Anime</th> <th className="text-right py-2 pr-3 font-medium w-16">Titles</th>
<th className="text-right py-2 font-medium w-16">Seen</th> <th className="text-right py-2 font-medium w-16">Seen</th>
</tr> </tr>
</thead> </thead>