import {Link} from 'react-router-dom'; import {useTranslation} from 'react-i18next'; import {Dices, Inbox, Shuffle} from 'lucide-react'; import {Button} from '@/components/ui/button'; import {Card} from '@/components/ui/card'; import GameCover from './GameCover.jsx'; import {STATUS_META} from './GameStatusBadge.jsx'; import {backlogShare, GAME_STATUSES} from '../utils/backlog.js'; import {formatPlaytime} from '../utils/games.js'; export default function PileOfShameCard({summary, syncing, onShuffle, shuffling}) { const {t, i18n} = useTranslation(); const backlog = summary.byStatus?.BACKLOG ?? 0; const suggestion = summary.suggestion; if (syncing && summary.total === 0) { return ( <p className="py-6 text-center text-sm text-muted-foreground">{t('LIBRARY.SYNCING_FIRST_TIME')}</p> </Card> ); } return ( <Card className="gap-5 p-5"> <Title/> <div> <div className="flex items-baseline gap-2"> <span className="text-4xl font-bold tabular-nums">{backlog.toLocaleString(i18n.language)}</span> <span className="text-sm text-muted-foreground"> {t('DASHBOARD.PILE_SHARE', {percent: backlogShare(summary)})} </span> </div> <p className="mt-1 text-sm text-muted-foreground"> {t('DASHBOARD.NEVER_PLAYED', {count: summary.neverPlayed})} </p> {summary.backlogMinutes > 0 && ( <p className="text-sm text-muted-foreground"> {t('DASHBOARD.BACKLOG_HOURS', {time: formatPlaytime(summary.backlogMinutes)})} </p> )} </div> {summary.total > 0 && ( <div className="space-y-2"> <div className="flex h-2.5 overflow-hidden rounded-full bg-muted"> {GAME_STATUSES.map((s) => ( <div key={s} className={STATUS_META[s].bar} style={{width: `${(summary.byStatus[s] / summary.total) * 100}%`}} /> ))} </div> <ul className="flex flex-wrap gap-x-4 gap-y-1 text-xs text-muted-foreground"> {GAME_STATUSES.map((s) => ( <li key={s} className="flex items-center gap-1.5"> <span className={`size-2 rounded-full ${STATUS_META[s].bar}`}/> {t(`BACKLOG.STATUS.${s}`)} <span className="tabular-nums text-foreground">{summary.byStatus[s]}</span> </li> ))} </ul> </div> )} {suggestion ? ( <div className="space-y-2"> <div className="flex items-center justify-between"> <span className="text-sm font-medium">{t('DASHBOARD.SUGGESTION')}</span> {backlog > 1 && ( <Button variant="ghost" size="sm" onClick={onShuffle} disabled={shuffling}> <Shuffle/>{t('DASHBOARD.OTHER_SUGGESTION')} </Button> )} </div> <Link to={`/library/${suggestion.appid}`} className="group flex items-center gap-3 rounded-lg border p-2 transition-colors hover:bg-muted/50" > <GameCover appid={suggestion.appid} className="w-24 shrink-0"/> <span className="min-w-0 truncate font-medium group-hover:text-primary transition-colors"> {suggestion.name ?? `App ${suggestion.appid}`} </span> </Link> <Button asChild variant="outline" size="sm" className="w-full"> <Link to="/play-next"><Dices/>{t('DASHBOARD.OPEN_PICKER')}</Link> </Button> </div> ) : ( <p className="text-sm text-muted-foreground">{t('DASHBOARD.BACKLOG_EMPTY')}</p> )} </Card> ); } function Title() { const {t} = useTranslation(); return ( <h2 className="flex items-center gap-2 font-semibold"> <Inbox className="size-4 text-rose-500"/> {t('DASHBOARD.PILE_OF_SHAME')} </h2> ); }