Files
ranking/frontend/src/App.jsx
2025-12-10 13:52:11 -03:00

99 lines
3.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useState, useEffect } from 'react';
import Header from './components/Header';
import ConsultorCard from './components/ConsultorCard';
import { rankingService } from './services/api';
import './App.css';
function App() {
const [consultores, setConsultores] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const [total, setTotal] = useState(0);
const [page, setPage] = useState(1);
const [pageSize, setPageSize] = useState(50);
const [totalPages, setTotalPages] = useState(0);
useEffect(() => {
loadRanking();
}, [page, pageSize]);
const loadRanking = async () => {
try {
setLoading(true);
setError(null);
const response = await rankingService.getRanking(page, pageSize);
setConsultores(response.consultores);
setTotal(response.total);
setTotalPages(response.total_pages || 0);
setPage(response.page || page);
} catch (err) {
console.error('Erro ao carregar ranking:', err);
setError('Erro ao carregar ranking. Verifique se a API está rodando.');
} finally {
setLoading(false);
}
};
if (loading) {
return (
<div className="container">
<div className="loading">Carregando ranking...</div>
</div>
);
}
if (error) {
return (
<div className="container">
<div className="error">
<h2>Erro</h2>
<p>{error}</p>
<button onClick={loadRanking}>Tentar novamente</button>
</div>
</div>
);
}
return (
<div className="container">
<Header total={total} />
<div className="controls">
<label>
Limite de consultores:
<select value={pageSize} onChange={(e) => { setPageSize(Number(e.target.value)); setPage(1); }}>
<option value={10}>Top 10</option>
<option value={50}>Top 50</option>
<option value={100}>Top 100</option>
<option value={200}>Top 200</option>
<option value={500}>Top 500</option>
</select>
</label>
<div className="pagination">
<button onClick={() => setPage(1)} disabled={page <= 1}>« Primeira</button>
<button onClick={() => setPage((p) => Math.max(1, p - 1))} disabled={page <= 1}> Anterior</button>
<span className="page-info">
Página {page} de {totalPages || '?'}
</span>
<button onClick={() => setPage((p) => (totalPages ? Math.min(totalPages, p + 1) : p + 1))} disabled={totalPages && page >= totalPages}>Próxima </button>
<button onClick={() => totalPages && setPage(totalPages)} disabled={totalPages && page >= totalPages}>Última »</button>
</div>
</div>
<div className="ranking-list">
{consultores.map((consultor) => (
<ConsultorCard key={consultor.id_pessoa} consultor={consultor} />
))}
</div>
<footer>
<p>Dados: ATUACAPES (Elasticsearch) + SUCUPIRA_PAINEL (Oracle)</p>
<p>Critérios: Minuta Técnica - Ranking AtuaCAPES | Clique em qualquer consultor para ver detalhes</p>
</footer>
</div>
);
}
export default App;