Files
ToBePlayed-Frontend/src/components/SteamGameCount.jsx
T
lobo f9f0d94e2c feat(onboarding): remove dead ends for new users (#55)
Registration shows the address used and can start over.
Confirm page says an admin approves; no login link.
Welcome puts next steps first; Steam link returns to the dashboard.
Dashboard and library explain an empty or private library.
First sync shows queued, polls slower up to 10 min, then a calm text.
Login: simple checks, resend offer after 401, password toggles.
Only a real expired link counts as invalid; typed passwords stay.
Default language follows the browser; texts are platform-neutral.
2026-10-21 09:37:17 +02:00

56 lines
2.1 KiB
React

import {useEffect, useState} from 'react';
import {Link} from 'react-router-dom';
import {useTranslation} from 'react-i18next';
import {ArrowRight, Gamepad2} from 'lucide-react';
import {Card} from '@/components/ui/card';
import useReducedMotion from '../hooks/useReducedMotion.js';
const DURATION_MS = 1000;
const COUNT_CLASS = 'block text-5xl font-bold tracking-tight tabular-nums';
const SteamGameCount = ({targetCount}) => {
const {t} = useTranslation();
const reduce = useReducedMotion();
const [count, setCount] = useState(0);
useEffect(() => {
if (reduce) {
setCount(targetCount);
return undefined;
}
let frame;
let startTime;
const animate = (timestamp) => {
startTime ??= timestamp;
const progress = Math.min((timestamp - startTime) / DURATION_MS, 1);
setCount(Math.floor(progress * targetCount));
if (progress < 1) {
frame = requestAnimationFrame(animate);
}
};
frame = requestAnimationFrame(animate);
return () => cancelAnimationFrame(frame);
}, [targetCount, reduce]);
return (
<Card className="relative justify-between overflow-hidden p-6">
<div className="absolute -right-6 -top-6 size-32 rounded-full bg-primary/10"/>
<div className="flex size-10 items-center justify-center rounded-lg bg-primary/10 text-primary">
<Gamepad2 className="size-5"/>
</div>
<div>
{targetCount > 0
? <Link to="/library" className={`${COUNT_CLASS} hover:text-primary`}>{count}</Link>
: <span className={COUNT_CLASS}>{count}</span>}
<div className="mt-1 text-sm text-muted-foreground">{t('DASHBOARD.GAMES')}</div>
</div>
<Link to="/library" className="inline-flex items-center gap-1 text-sm font-medium text-primary hover:underline">
{t('DASHBOARD.TO_LIBRARY')} <ArrowRight className="size-4"/>
</Link>
</Card>
);
};
export default SteamGameCount;