Files
ToBePlayed-Frontend/src/components/MostPlayedCard.jsx
T
lobo d7810fbf94
Build, Test & Push Frontend / quality-check (push) Successful in 31s
Build, Test & Push Frontend / docker (push) Successful in 24s
fix(layout): fit names on phones without sideways scroll
Display and game names shrink to 0.875rem, then end with an ellipsis
(FitText + fit-text utility, CSS container units, full text in title).
Rows and buttons wrap at large fonts, header points chip can shrink.
Guard: scripts/check-overflow.js.
2026-10-03 12:18:31 +02:00

66 lines
3.2 KiB
React

import {Link} from 'react-router-dom';
import {useTranslation} from 'react-i18next';
import {ArrowRight, Trophy} from 'lucide-react';
import {Button} from '@/components/ui/button';
import {Card} from '@/components/ui/card';
import GameCover from './GameCover.jsx';
import FitText from './FitText.jsx';
import {formatPlaytime} from '../utils/games.js';
import {coverEffect} from '../utils/rewards.js';
export default function MostPlayedCard({games, syncing, equipped}) {
const {t} = useTranslation();
const maxMinutes = games[0]?.playtimeMinutes || 1;
return (
<Card className="gap-0 py-0">
<div className="flex flex-wrap items-center justify-between gap-x-3 px-5 py-4 border-b">
<h2 className="flex items-center gap-2 font-semibold">
<Trophy className="size-4 text-amber-500"/>
{t('DASHBOARD.MOST_PLAYED')}
</h2>
<Button asChild variant="ghost" size="sm">
<Link to="/library">{t('DASHBOARD.SHOW_ALL')}<ArrowRight/></Link>
</Button>
</div>
{games.length === 0 ? (
<p className="px-5 py-10 text-center text-sm text-muted-foreground">
{syncing ? t('LIBRARY.SYNCING_FIRST_TIME') : t('LIBRARY.EMPTY')}
</p>
) : (
<ol className="divide-y">
{games.map((g, index) => (
<li key={g.appid}>
<Link
to={`/library/${g.appid}`}
className="group flex items-center gap-3 sm:gap-4 px-4 sm:px-5 py-3 transition-colors hover:bg-muted/50"
>
<span className="w-4 text-right text-sm font-semibold text-muted-foreground tabular-nums">
{index + 1}
</span>
<GameCover appid={g.appid} imageUrl={g.imageUrl} fx={coverEffect(equipped, g.status)}
className="w-16 sm:w-24 shrink-0"/>
<div className="@container min-w-0 flex-1">
<div className="font-medium group-hover:text-primary transition-colors">
<FitText text={g.name ?? `App ${g.appid}`}/>
</div>
<div className="mt-2 h-1.5 rounded-full bg-muted">
<div
className="h-full rounded-full bg-primary"
style={{width: `${Math.max(2, (g.playtimeMinutes / maxMinutes) * 100)}%`}}
/>
</div>
</div>
<span className="w-12 sm:w-14 text-right text-sm font-medium text-muted-foreground tabular-nums">
{formatPlaytime(g.playtimeMinutes)}
</span>
</Link>
</li>
))}
</ol>
)}
</Card>
);
}