feat(comparacao): exibir selos de cada consultor no modal de comparacao

This commit is contained in:
Frederico Castro
2025-12-15 13:13:47 -03:00
parent 3254374486
commit 6034289403
2 changed files with 161 additions and 0 deletions

View File

@@ -121,6 +121,73 @@
border-radius: 8px; border-radius: 8px;
} }
.comparacao-selos {
display: flex;
align-items: center;
gap: 1rem;
margin-bottom: 1.5rem;
padding: 0.75rem 1rem;
background: rgba(255, 255, 255, 0.02);
border: 1px solid var(--stroke);
border-radius: 12px;
}
.selos-lista {
flex: 1;
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}
.selos-1 {
justify-content: flex-end;
}
.selos-2 {
justify-content: flex-start;
}
.selos-label {
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
color: var(--muted);
padding: 0 0.5rem;
}
.selo-badge {
display: inline-flex;
align-items: center;
gap: 0.2rem;
padding: 0.3rem 0.5rem;
background: rgba(255, 255, 255, 0.06);
border: 1px solid var(--stroke);
border-radius: 6px;
font-size: 0.85rem;
}
.selo-badge .selo-icone {
font-size: 1rem;
}
.selo-badge .selo-qtd {
font-size: 0.7rem;
font-weight: 600;
color: var(--accent-2);
background: rgba(79, 70, 229, 0.2);
padding: 0.1rem 0.3rem;
border-radius: 4px;
min-width: 1.2rem;
text-align: center;
}
.sem-selos {
font-size: 0.8rem;
color: var(--muted);
font-style: italic;
}
.comparacao-secao { .comparacao-secao {
margin-bottom: 1.5rem; margin-bottom: 1.5rem;
padding: 1rem; padding: 1rem;

View File

@@ -1,6 +1,78 @@
import React from 'react'; import React from 'react';
import './CompararModal.css'; import './CompararModal.css';
const SELOS = {
PRESID_CAMARA: { label: 'Pres. Câmara', icone: '👑' },
COORD_PPG: { label: 'Coord. PPG', icone: '🎓' },
BPQ: { label: 'BPQ', icone: '🏅' },
AUTOR_GP: { label: 'Autor GP', icone: '🏆' },
AUTOR_PREMIO: { label: 'Autor Prêmio', icone: '🥇' },
AUTOR_MENCAO: { label: 'Autor Menção', icone: '🥈' },
ORIENT_GP: { label: 'Orient. GP', icone: '🏆' },
ORIENT_PREMIO: { label: 'Orient. Prêmio', icone: '🎖️' },
ORIENT_MENCAO: { label: 'Orient. Menção', icone: '📜' },
COORIENT_GP: { label: 'Coorient. GP', icone: '🏆' },
COORIENT_PREMIO: { label: 'Coorient. Prêmio', icone: '🎖️' },
COORIENT_MENCAO: { label: 'Coorient. Menção', icone: '📜' },
ORIENT_POS_DOC: { label: 'Orient. Pós-Doc', icone: '🔬' },
ORIENT_TESE: { label: 'Orient. Tese', icone: '📚' },
ORIENT_DISS: { label: 'Orient. Diss.', icone: '📄' },
CO_ORIENT_POS_DOC: { label: 'Coorient. Pós-Doc', icone: '🔬' },
CO_ORIENT_TESE: { label: 'Coorient. Tese', icone: '📚' },
CO_ORIENT_DISS: { label: 'Coorient. Diss.', icone: '📄' },
};
const gerarSelos = (consultor) => {
const selos = [];
const isPresidCamara = consultor.coordenacoes_capes?.some(
(c) => c.codigo === 'CAM' && c.presidente && (c.ativo ?? !c.fim)
);
if (isPresidCamara) selos.push({ ...SELOS.PRESID_CAMARA, qtd: 1 });
if (consultor.coordenador_ppg) selos.push({ ...SELOS.COORD_PPG, qtd: 1 });
const bolsas = Array.isArray(consultor.bolsas_cnpq) ? consultor.bolsas_cnpq : [];
if (bolsas.length > 0) selos.push({ ...SELOS.BPQ, qtd: bolsas.length });
const premiacoes = Array.isArray(consultor.premiacoes) ? consultor.premiacoes : [];
const contarPrem = (papel, codigo) => premiacoes.filter(
(p) => (p.papel || '').toLowerCase() === papel && p.codigo === codigo
).length;
const addPremSelo = (papel, codBase, seloGP, seloPremio, seloMencao) => {
const gp = contarPrem(papel, 'PREMIACAO');
const premio = contarPrem(papel, 'PREMIACAO_GP');
const mencao = contarPrem(papel, 'MENCAO');
if (gp > 0) selos.push({ ...seloGP, qtd: gp });
if (premio > 0) selos.push({ ...seloPremio, qtd: premio });
if (mencao > 0) selos.push({ ...seloMencao, qtd: mencao });
};
addPremSelo('autor', '', SELOS.AUTOR_GP, SELOS.AUTOR_PREMIO, SELOS.AUTOR_MENCAO);
addPremSelo('orientador', '', SELOS.ORIENT_GP, SELOS.ORIENT_PREMIO, SELOS.ORIENT_MENCAO);
addPremSelo('coorientador', '', SELOS.COORIENT_GP, SELOS.COORIENT_PREMIO, SELOS.COORIENT_MENCAO);
const orientacoes = Array.isArray(consultor.orientacoes) ? consultor.orientacoes : [];
const contarOrient = (codigo, coorient) => orientacoes.filter(
(o) => o.codigo === codigo && (coorient ? o.coorientacao : !o.coorientacao)
).length;
const addOrientSelo = (codigo, coorient, selo) => {
const qtd = contarOrient(codigo, coorient);
if (qtd > 0) selos.push({ ...selo, qtd });
};
addOrientSelo('ORIENT_POS_DOC', false, SELOS.ORIENT_POS_DOC);
addOrientSelo('ORIENT_TESE', false, SELOS.ORIENT_TESE);
addOrientSelo('ORIENT_DISS', false, SELOS.ORIENT_DISS);
addOrientSelo('CO_ORIENT_POS_DOC', true, SELOS.CO_ORIENT_POS_DOC);
addOrientSelo('CO_ORIENT_TESE', true, SELOS.CO_ORIENT_TESE);
addOrientSelo('CO_ORIENT_DISS', true, SELOS.CO_ORIENT_DISS);
return selos;
};
const CompararModal = ({ consultor1, consultor2, onClose }) => { const CompararModal = ({ consultor1, consultor2, onClose }) => {
if (!consultor1 || !consultor2) return null; if (!consultor1 || !consultor2) return null;
@@ -82,6 +154,28 @@ const CompararModal = ({ consultor1, consultor2, onClose }) => {
</div> </div>
</div> </div>
<div className="comparacao-selos">
<div className="selos-lista selos-1">
{gerarSelos(consultor1).map((selo, i) => (
<span key={i} className="selo-badge" title={selo.label}>
<span className="selo-icone">{selo.icone}</span>
{selo.qtd > 1 && <span className="selo-qtd">{selo.qtd}</span>}
</span>
))}
{gerarSelos(consultor1).length === 0 && <span className="sem-selos">Sem selos</span>}
</div>
<div className="selos-label">SELOS</div>
<div className="selos-lista selos-2">
{gerarSelos(consultor2).map((selo, i) => (
<span key={i} className="selo-badge" title={selo.label}>
<span className="selo-icone">{selo.icone}</span>
{selo.qtd > 1 && <span className="selo-qtd">{selo.qtd}</span>}
</span>
))}
{gerarSelos(consultor2).length === 0 && <span className="sem-selos">Sem selos</span>}
</div>
</div>
<div className="comparacao-secao"> <div className="comparacao-secao">
<h3>Pontuacao Total</h3> <h3>Pontuacao Total</h3>
{renderLinhaComparacao('TOTAL', total1, total2, 'var(--accent)')} {renderLinhaComparacao('TOTAL', total1, total2, 'var(--accent)')}