import {useCallback, useEffect, useState} from 'react'; import {Link} from 'react-router-dom'; import {useTranslation} from 'react-i18next'; import {ChevronLeft, ChevronRight, Link2, Loader2, X} from 'lucide-react'; import {toast} from 'sonner'; import {Badge} from '@/components/ui/badge'; import {Button} from '@/components/ui/button'; import {Card, CardContent, CardHeader, CardTitle} from '@/components/ui/card'; import GameCover from '../components/GameCover.jsx'; import FitText from '../components/FitText.jsx'; import PageContainer from '../components/PageContainer.jsx'; import {dismissPair, fetchLinkQueue, linkGames} from '../utils/links.js'; const PAGE_SIZE = 20; function PairGame({game}) { return ( ); } /** * AUDITOR or higher: the pairs IGDB suggests and users asked for. Core checks the role. */ export default function LinkQueuePage() { const {t} = useTranslation(); const [page, setPage] = useState(0); const [result, setResult] = useState({content: [], totalPages: 0}); const [status, setStatus] = useState('loading'); const [busy, setBusy] = useState(false); const load = useCallback(async () => { try { const response = await fetchLinkQueue({page, size: PAGE_SIZE}); if (response.status === 401) return; if (response.status === 403) { setStatus('forbidden'); return; } if (!response.ok) { setStatus('error'); return; } const data = await response.json(); // The last pair of the last page was decided: show the page before. if (data.content.length === 0 && page > 0) { setPage(page - 1); return; } setResult(data); setStatus('ready'); } catch (err) { console.error('Link queue error:', err); setStatus('error'); } }, [page]); useEffect(() => { load(); }, [load]); const run = async (request, doneKey) => { setBusy(true); try { const response = await request(); if (response.status === 401) return; if (response.ok) { toast.success(t(doneKey)); } else { const data = await response.json().catch(() => ({})); toast.error(t(data.code === 'ALREADY_LINKED' ? 'LINKS.ERROR_CODES.ALREADY_LINKED' : 'LINKS.ERROR')); } await load(); } catch (err) { console.error('Link queue action error:', err); toast.error(t('INFO.ERROR.NETWORK_FAILURE')); } finally { setBusy(false); } }; if (status === 'forbidden') { return (

{t('LINKS.NO_ACCESS')}

); } return ( {t('LINKS.QUEUE_TITLE')} {status === 'loading' && } {status === 'error' &&

{t('LINKS.ERROR')}

} {status === 'ready' && result.content.length === 0 && (

{t('LINKS.QUEUE_EMPTY')}

)} {status === 'ready' && result.content.length > 0 && (
    {result.content.map(({a, b, igdb, requests}) => (
  • {igdb && {t('LINKS.FROM_IGDB')}} {requests > 0 && {t('LINKS.REQUESTED_BY', {count: requests})}}
  • ))}
)} {status === 'ready' && result.totalPages > 1 && (
{t('LINKS.PAGE_OF', {current: page + 1, total: result.totalPages})}
)}
); }