Public Access
Add perfect games click-through on the dashboard. Remove Steam store links from game lists. Stat numbers with count 0 are not clickable. Tests cover the perfect-games click, zero guards, and owner versus visitor behavior.
49 lines
2.4 KiB
React
49 lines
2.4 KiB
React
import {useTranslation} from 'react-i18next';
|
|
import {Inbox} from 'lucide-react';
|
|
|
|
import StatsSection from './StatsSection.jsx';
|
|
import StatTile from './StatTile.jsx';
|
|
import GameRow from './GameRow.jsx';
|
|
import {formatPlaytime} from '../../utils/games.js';
|
|
import {libraryLink} from '../../utils/statGames.js';
|
|
import {formatDecimal} from '../../utils/stats.js';
|
|
import {formatDate} from '../../utils/format.js';
|
|
|
|
export default function PileStats({pile, linked = true}) {
|
|
const {t, i18n} = useTranslation();
|
|
const since = pile.oldestUnplayed
|
|
? formatDate(pile.oldestUnplayed.inLibrarySince, i18n.language, {dateStyle: 'medium'})
|
|
: null;
|
|
return (
|
|
<StatsSection title={t('STATS.PILE.TITLE')} icon={Inbox}>
|
|
<div className="grid grid-cols-2 gap-3 sm:grid-cols-3">
|
|
<StatTile label={t('STATS.PILE.GAMES')} value={pile.backlogGames.toLocaleString(i18n.language)}
|
|
drill={{to: libraryLink('BACKLOG'), params: {key: 'PILE'}, count: pile.backlogGames}}/>
|
|
<StatTile label={t('STATS.PILE.NORMAL')} value={formatPlaytime(pile.normalMinutes)}
|
|
hint={t('STATS.PILE.KNOWN', {count: pile.gamesWithTimeToBeat})}
|
|
drill={{params: {key: 'PILE_TIME_TO_BEAT'}, count: pile.gamesWithTimeToBeat}}/>
|
|
<StatTile label={t('STATS.PILE.COMPLETIONIST')} value={formatPlaytime(pile.completionistMinutes)}/>
|
|
</div>
|
|
{pile.normalMinutes > 0 && (
|
|
<ul className="space-y-1 text-sm">
|
|
<li>
|
|
{pile.paceWeeks == null
|
|
? t('STATS.PILE.PACE_NONE')
|
|
: t('STATS.PILE.PACE', {
|
|
weeks: formatDecimal(pile.paceWeeks, i18n.language),
|
|
perWeek: formatPlaytime(pile.minutesPerWeek),
|
|
})}
|
|
</li>
|
|
<li>{t('STATS.PILE.WORK_YEARS', {years: formatDecimal(pile.workYears, i18n.language, 2)})}</li>
|
|
</ul>
|
|
)}
|
|
{pile.oldestUnplayed && (
|
|
<div className="space-y-2">
|
|
<span className="text-sm font-medium">{t('STATS.PILE.OLDEST')}</span>
|
|
<GameRow game={pile.oldestUnplayed} value={t('STATS.PILE.SINCE', {date: since})} linked={linked}/>
|
|
</div>
|
|
)}
|
|
</StatsSection>
|
|
);
|
|
}
|