Files
ToBePlayed-Frontend/src/components/CurrentlyPlayingCard.jsx
T
lobo aa9e83e0cb
Build, Test & Push Frontend / quality-check (push) Successful in 18s
Build, Test & Push Frontend / docker (push) Successful in 28s
feat(tiles): let users arrange the dashboard and profile tiles
2026-09-28 15:03:16 +02:00

52 lines
2.3 KiB
React

import {Link} from 'react-router-dom';
import {useTranslation} from 'react-i18next';
import {ArrowRight, Gamepad2} from 'lucide-react';
import {Button} from '@/components/ui/button';
import {Card} from '@/components/ui/card';
import {cn} from '@/lib/utils';
import GameCover from './GameCover.jsx';
import {formatPlaytime} from '../utils/games.js';
/**
* @param wide four games per row instead of two, for the large tile
*/
export default function CurrentlyPlayingCard({games, syncing, wide}) {
const {t} = useTranslation();
return (
<Card className="gap-0 py-0">
<div className="flex items-center justify-between px-5 py-4 border-b">
<h2 className="flex items-center gap-2 font-semibold">
<Gamepad2 className="size-4 text-primary"/>
{t('DASHBOARD.CURRENTLY_PLAYING')}
</h2>
<Button asChild variant="ghost" size="sm">
<Link to="/library?status=PLAYING">{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('DASHBOARD.NOTHING_PLAYING')}
</p>
) : (
<ul className={cn('grid grid-cols-2 gap-3 p-4', wide && 'sm:grid-cols-4')}>
{games.map((g) => (
<li key={g.appid}>
<Link to={`/library/${g.appid}`} className="group block space-y-1.5">
<GameCover appid={g.appid} imageUrl={g.imageUrl} className="w-full transition-opacity group-hover:opacity-80"/>
<div className="truncate text-sm font-medium group-hover:text-primary transition-colors">
{g.name ?? `App ${g.appid}`}
</div>
<div className="text-xs text-muted-foreground tabular-nums">
{formatPlaytime(g.playtimeMinutes)}
</div>
</Link>
</li>
))}
</ul>
)}
</Card>
);
}