import {Link} from 'react-router-dom'; import {useTranslation} from 'react-i18next'; import {Trophy} from 'lucide-react'; import {Card} from '@/components/ui/card'; import GameCover from './GameCover.jsx'; import FitText from './FitText.jsx'; import {StatCount} from './stats/StatDrill.jsx'; import StatMeter from './stats/StatMeter.jsx'; /** * @param summary the answer of GET /api/library/achievements/summary */ export default function AchievementsCard({summary}) { const {t, i18n} = useTranslation(); const closest = summary.closest ?? []; const started = summary.startedGames ?? 0; const pending = summary.pendingGames ?? 0; const hidden = summary.hiddenGames ?? 0; const perfect = summary.perfectGames ?? 0; // A private profile keeps games pending; the privacy hint explains that better than the pending count. const steamHidesAll = hidden > 0 && started === 0; const average = summary.averageCompletion != null ? `${summary.averageCompletion.toLocaleString(i18n.language)} %` : '–'; const stats = [ [(summary.unlocked ?? 0).toLocaleString(i18n.language), t('DASHBOARD.ACHIEVEMENTS.UNLOCKED')], [perfect.toLocaleString(i18n.language), t('DASHBOARD.ACHIEVEMENTS.PERFECT'), {params: {key: 'PERFECT'}, count: perfect}], [average, t('DASHBOARD.ACHIEVEMENTS.AVERAGE'), undefined, summary.averageCompletion != null ? {percent: summary.averageCompletion, valueText: average} : null], ]; return (

{t('DASHBOARD.ACHIEVEMENTS.TITLE')}

{stats.map(([value, label, drill, meter]) => (
{value}
{meter && }
{label}
))}
{started === 0 && pending === 0 && hidden === 0 && (

{t('DASHBOARD.ACHIEVEMENTS.NONE')}

)} {closest.length > 0 && (

{t('DASHBOARD.ACHIEVEMENTS.CLOSEST')}

)} {pending > 0 && !steamHidesAll && (

{t('DASHBOARD.ACHIEVEMENTS.PENDING', {count: pending})}

)} {steamHidesAll && (

{t('DASHBOARD.ACHIEVEMENTS.HIDDEN')}

)}
); }