import {useEffect, useState} from 'react';
import {Link, useParams} from 'react-router-dom';
import {useTranslation} from 'react-i18next';
import {CircleCheck, Clock, Gamepad2, Library, Percent, Star, Trophy, UserRoundX} from 'lucide-react';
import {Card} from '@/components/ui/card';
import {Skeleton} from '@/components/ui/skeleton';
import GameCover from '../components/GameCover.jsx';
import GameStatusBadge, {STATUS_META} from '../components/GameStatusBadge.jsx';
import {GAME_STATUSES} from '../utils/backlog.js';
import {formatPlaytime} from '../utils/games.js';
import PageContainer from '../components/PageContainer.jsx';
import PileStats from '../components/stats/PileStats.jsx';
import TrendStats from '../components/stats/TrendStats.jsx';
import TopGamesStats from '../components/stats/TopGamesStats.jsx';
import TasteStats from '../components/stats/TasteStats.jsx';
import HabitsStats from '../components/stats/HabitsStats.jsx';
import FinishedStats from '../components/stats/FinishedStats.jsx';
/**
* Public, no login. Auth returns a short-lived ticket for a public profile; Core returns the data for it.
*/
export default function PublicProfilePage() {
const {t, i18n} = useTranslation();
const {name} = useParams();
const [profile, setProfile] = useState(null);
const [library, setLibrary] = useState(null);
const [error, setError] = useState(null);
useEffect(() => {
let cancelled = false;
setProfile(null);
setLibrary(null);
setError(null);
(async () => {
try {
const profileResponse = await fetch(
`${import.meta.env.VITE_API_URL}/api/public/profiles/${encodeURIComponent(name)}`);
if (cancelled) return;
if (profileResponse.status === 404) {
setError(t('PROFILE.NOT_FOUND'));
return;
}
if (!profileResponse.ok) {
setError(t('PROFILE.ERROR_LOAD'));
return;
}
const found = await profileResponse.json();
const libraryResponse = await fetch(`${import.meta.env.VITE_CORE_API_URL}/api/public/profiles/library`, {
headers: {'X-Profile-Ticket': found.ticket},
});
if (cancelled) return;
if (!libraryResponse.ok) {
setError(t('PROFILE.ERROR_LOAD'));
return;
}
const data = await libraryResponse.json();
if (!cancelled) {
setProfile(found);
setLibrary(data);
}
} catch (err) {
console.error('Public profile load error:', err);
if (!cancelled) setError(t('INFO.ERROR.NETWORK_FAILURE'));
}
})();
return () => {
cancelled = true;
};
}, [name, t]);
if (error) {
return (
{error} {t('PROFILE.TITLE')} {t('PROFILE.MEMBER_SINCE', {date: memberSince})}{profile.displayName}
{memberSince && (
{GAME_STATUSES.map((s) => (
{library.playing.map((g) => (
{library.finished.map((g) => (