import {useState} from 'react'; import {useTranslation} from 'react-i18next'; import {Link} from 'react-router-dom'; import { Archive, ArrowRight, Blocks, Clock, Gamepad2, Library, Link2, Sparkles, Trophy, Users, } from 'lucide-react'; import {Badge} from '@/components/ui/badge'; import {Button} from '@/components/ui/button'; import {Card} from '@/components/ui/card'; import {Skeleton} from '@/components/ui/skeleton'; import GameCover from '../components/GameCover.jsx'; import FitText from '../components/FitText.jsx'; import Logo from '../components/Logo.jsx'; import StatCard from '../components/StatCard.jsx'; import PeopleDialog from '../components/people/PeopleDialog.jsx'; import {YearBars} from '../components/stats/FinishedStats.jsx'; import {TagBars} from '../components/stats/TasteStats.jsx'; import {StatDrillProvider, useStatDrill, useTagDrill} from '../components/stats/StatDrill.jsx'; import useSession from '../hooks/useSession.js'; import {fetchUsers} from '../utils/people.js'; import {genreKey} from '../utils/stats.js'; import usePublicStats from '../hooks/usePublicStats.js'; function RankedGames({title, games, formatValue, drillKey}) { const {t} = useTranslation(); const drill = useStatDrill(); return (

{title}

    {games.map((g, idx) => (
  1. {idx + 1} {formatValue(g.value ?? 0)}
  2. ))}
{drill && ( )}
); } function GameName({game}) { return ( ); } function CommunityBars({core}) { const {t} = useTranslation(); const drill = useStatDrill(); const select = useTagDrill(); const genreLabel = (name) => t(`STATS.GENRE.${genreKey(name)}`, {defaultValue: name}); return (
{core?.gamesPerPlatform?.length > 0 && ( )} {core?.topGenres?.length > 0 && ( )} {core?.finishedPerYear?.length > 0 && ( drill.open(`${t('LANDING.FINISHED_PER_YEAR')}: ${year}`, {key: 'FINISHED_YEAR', arg: year}))}/> )}
); } function BarsCard({title, children}) { return (

{title}

{children}
); } export default function LandingPage() { const {t, i18n} = useTranslation(); const {data, isLoading} = usePublicStats(); const {active} = useSession(); const [people, setPeople] = useState(null); const auth = data.auth; const core = data.core; const stats = [ [t('LANDING.TOTAL_USERS'), auth?.totalUsers, Users, undefined, undefined, 'TOTAL_USERS'], [t('LANDING.STEAM_LINKED'), auth?.usersWithSteamLinked, Link2, undefined, undefined, 'STEAM_LINKED'], [t('LANDING.TOTAL_GAMES'), core?.totalLibraryEntries, Gamepad2, undefined, 'ENTRIES'], [t('LANDING.GAMES_PLAYED'), core?.totalGamesPlayed, Sparkles, undefined, 'PLAYED'], [t('LANDING.DISTINCT_GAMES'), core?.totalDistinctGames, Blocks, undefined, 'OWNED'], [t('LANDING.TOTAL_PLAYTIME_DAYS'), core?.totalPlaytimeDays, Clock, ` ${t('LANDING.DAYS_SUFFIX')}`], [t('LANDING.BIGGEST_LIBRARY'), core?.biggestLibrary, Library], [t('LANDING.BIGGEST_BACKLOG'), core?.biggestBacklog, Archive], ]; return (
ToBePlayed

{t('MAIN.WELCOME')}

{t('MAIN.DESCRIPTION')}

{t('LANDING.STATS_TITLE')}

{isLoading ? stats.map(([label]) => ) : stats.map(([label, value, icon, suffix, key, usersKey]) => ( 0 ? () => setPeople({title: label, key: usersKey}) : undefined}/> ))}
{core?.topPlayedGames?.length > 0 && ( `${Math.round(minutes / 60).toLocaleString(i18n.language)}h`} drillKey="MOST_PLAYED" /> )} {core?.topOwnedGames?.length > 0 && ( count.toLocaleString(i18n.language)} drillKey="OWNED" /> )}
{people && ( setPeople(null)} load={(page) => fetchUsers({key: people.key, page})}/> )}
); }