feat(ranking): adicionar badges de tipos de atuação nos cards

- Adiciona campo tipos_atuacao ao schema e extração no mapper
- Exibe tipos de atuação (Coordenador, Consultor, Avaliador, etc.)
  na seção expandida do card, acima de Selos e Reconhecimentos
- Inclui estilos visuais distintos para cada tipo de atuação
- Melhorias no Header e SugerirConsultores
This commit is contained in:
Frederico Castro
2025-12-21 05:36:26 -03:00
parent bb36961b4c
commit d4aa75ca0b
10 changed files with 424 additions and 40 deletions

View File

@@ -124,6 +124,8 @@
font-size: 1.35rem;
white-space: nowrap;
line-height: 1;
color: #ffffff;
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
}
.rank-number.rank-digits-4 {
@@ -578,13 +580,17 @@
.selos-container.selos-compacto {
display: inline-flex;
margin-left: 0.3rem;
margin-left: 0.25rem;
gap: 0.2rem;
}
.selos-compacto .selo {
background: rgba(148, 163, 184, 0.12);
border-color: rgba(148, 163, 184, 0.25);
color: #94a3b8;
padding: 0.1rem 0.25rem;
gap: 0.15rem;
font-size: 0.6rem;
}
.selos-compacto .selo:hover {
@@ -596,11 +602,14 @@
.selos-compacto .selo-icone {
filter: grayscale(100%) brightness(1.2);
opacity: 0.85;
font-size: 0.65rem;
}
.selos-compacto .selo-qtd {
background: rgba(148, 163, 184, 0.25);
color: #cbd5e1;
font-size: 0.5rem;
padding: 0.05rem 0.2rem;
}
.selo {
@@ -644,8 +653,9 @@
.selo-mais {
background: rgba(255, 255, 255, 0.05);
border-style: dashed;
font-size: 0.65rem;
font-size: 0.55rem;
color: var(--muted);
padding: 0.1rem 0.2rem;
}
.selo-coord {
@@ -722,6 +732,32 @@
color: #e2e8f0;
}
.tipos-section {
grid-column: 1 / -1;
margin-top: 1rem;
}
.tipos-section h4 {
color: var(--accent-2);
}
.tipos-expandido {
gap: 0.5rem;
}
.tipos-expandido .tipo-atuacao {
padding: 0.25rem 0.5rem;
font-size: 0.7rem;
}
.tipos-expandido .tipo-icone {
font-size: 0.8rem;
}
.tipos-expandido .tipo-label {
font-size: 0.65rem;
}
.selos-section {
grid-column: 1 / -1;
margin-top: 1rem;
@@ -771,3 +807,123 @@
border-color: rgba(79, 70, 229, 0.4);
transform: scale(1.1);
}
.tipos-atuacao-container {
display: flex;
flex-wrap: wrap;
gap: 0.35rem;
margin-top: 0.4rem;
}
.tipo-atuacao {
display: inline-flex;
align-items: center;
gap: 0.2rem;
font-size: 0.65rem;
padding: 0.15rem 0.4rem;
border-radius: 4px;
border: 1px solid rgba(255, 255, 255, 0.12);
background: rgba(255, 255, 255, 0.05);
color: var(--muted);
font-weight: 500;
transition: all 150ms ease;
}
.tipo-atuacao:hover {
transform: translateY(-1px);
border-color: rgba(255, 255, 255, 0.25);
}
.tipo-icone {
font-size: 0.7rem;
line-height: 1;
opacity: 0.9;
}
.tipo-label {
font-size: 0.6rem;
letter-spacing: 0.2px;
text-transform: uppercase;
}
.tipo-mais {
background: rgba(255, 255, 255, 0.03);
border-style: dashed;
font-size: 0.55rem;
padding: 0.1rem 0.25rem;
}
.tipo-coordenador {
background: linear-gradient(135deg, rgba(239, 68, 68, 0.2), rgba(239, 68, 68, 0.08));
border-color: rgba(239, 68, 68, 0.35);
color: #fca5a5;
}
.tipo-consultor {
background: linear-gradient(135deg, rgba(59, 130, 246, 0.2), rgba(59, 130, 246, 0.08));
border-color: rgba(59, 130, 246, 0.35);
color: #93c5fd;
}
.tipo-avaliador {
background: linear-gradient(135deg, rgba(168, 85, 247, 0.2), rgba(168, 85, 247, 0.08));
border-color: rgba(168, 85, 247, 0.35);
color: #d8b4fe;
}
.tipo-premiado {
background: linear-gradient(135deg, rgba(251, 191, 36, 0.25), rgba(251, 191, 36, 0.1));
border-color: rgba(251, 191, 36, 0.4);
color: #fcd34d;
}
.tipo-orientador {
background: linear-gradient(135deg, rgba(34, 197, 94, 0.2), rgba(34, 197, 94, 0.08));
border-color: rgba(34, 197, 94, 0.35);
color: #86efac;
}
.tipo-bolsista {
background: linear-gradient(135deg, rgba(14, 165, 233, 0.2), rgba(14, 165, 233, 0.08));
border-color: rgba(14, 165, 233, 0.35);
color: #7dd3fc;
}
.tipo-inscrito {
background: linear-gradient(135deg, rgba(249, 115, 22, 0.2), rgba(249, 115, 22, 0.08));
border-color: rgba(249, 115, 22, 0.35);
color: #fdba74;
}
.tipo-projeto {
background: linear-gradient(135deg, rgba(99, 102, 241, 0.2), rgba(99, 102, 241, 0.08));
border-color: rgba(99, 102, 241, 0.35);
color: #a5b4fc;
}
.tipo-evento {
background: linear-gradient(135deg, rgba(236, 72, 153, 0.2), rgba(236, 72, 153, 0.08));
border-color: rgba(236, 72, 153, 0.35);
color: #f9a8d4;
}
.tipo-default {
background: rgba(148, 163, 184, 0.12);
border-color: rgba(148, 163, 184, 0.25);
color: #94a3b8;
}
@media (max-width: 900px) {
.tipos-atuacao-container {
margin-top: 0.3rem;
}
.tipo-atuacao {
font-size: 0.6rem;
padding: 0.1rem 0.3rem;
}
.tipo-label {
font-size: 0.55rem;
}
}

View File

@@ -24,6 +24,18 @@ const SELOS = {
CO_ORIENT_POS_DOC: { label: 'Coorient. Pos-Doc', cor: 'selo-coorient', icone: '🔬' },
};
const TIPOS_ATUACAO_CONFIG = {
'Coordenador': { cor: 'tipo-coordenador', icone: '🎯' },
'Consultor': { cor: 'tipo-consultor', icone: '💼' },
'Avaliador': { cor: 'tipo-avaliador', icone: '📋' },
'Premiado': { cor: 'tipo-premiado', icone: '🏆' },
'Orientador': { cor: 'tipo-orientador', icone: '🎓' },
'Bolsista CNPq': { cor: 'tipo-bolsista', icone: '🔬' },
'Inscrito Premio': { cor: 'tipo-inscrito', icone: '📝' },
'Projeto': { cor: 'tipo-projeto', icone: '📊' },
'Evento': { cor: 'tipo-evento', icone: '📅' },
};
const gerarSelos = (consultor) => {
const selos = [];
@@ -114,6 +126,32 @@ const SelosBadges = ({ selos, compacto = false }) => {
);
};
const TiposAtuacaoBadges = ({ tipos, exibirTodos = false }) => {
if (!tipos || tipos.length === 0) return null;
const tiposExibidos = exibirTodos ? tipos : tipos.slice(0, 4);
const tiposOcultos = !exibirTodos && tipos.length > 4 ? tipos.length - 4 : 0;
return (
<div className={`tipos-atuacao-container ${exibirTodos ? 'tipos-expandido' : ''}`}>
{tiposExibidos.map((tipo, idx) => {
const config = TIPOS_ATUACAO_CONFIG[tipo] || { cor: 'tipo-default', icone: '📌' };
return (
<span key={idx} className={`tipo-atuacao ${config.cor}`} title={tipo}>
<span className="tipo-icone">{config.icone}</span>
<span className="tipo-label">{tipo}</span>
</span>
);
})}
{tiposOcultos > 0 && (
<span className="tipo-atuacao tipo-mais" title={tipos.slice(4).join(', ')}>
+{tiposOcultos}
</span>
)}
</div>
);
};
const FORMULAS = {
bloco_a: {
titulo: 'Coordenacao CAPES',
@@ -372,6 +410,13 @@ const ConsultorCard = memo(({ consultor, highlight, selecionado, onToggleSelecio
)}
</div>
{consultor.tipos_atuacao?.length > 0 && (
<div className="detail-section tipos-section">
<h4>Tipos de Atuacao</h4>
<TiposAtuacaoBadges tipos={consultor.tipos_atuacao} exibirTodos={true} />
</div>
)}
{selos.length > 0 && (
<div className="detail-section selos-section">
<h4>Selos e Reconhecimentos</h4>

View File

@@ -359,6 +359,96 @@
color: #c4b5fd;
}
/* Selos na Legenda */
.selos-table th:last-child,
.selos-table td:last-child {
text-align: center;
width: 2.5rem;
}
.selo-legenda {
display: inline-block;
font-size: 0.75rem;
padding: 0.1rem 0.3rem;
border-radius: 4px;
line-height: 1;
}
.selo-legenda.selo-orient {
background: rgba(34, 211, 238, 0.2);
border: 1px solid rgba(34, 211, 238, 0.4);
}
.selo-legenda.selo-coorient {
background: rgba(96, 165, 250, 0.2);
border: 1px solid rgba(96, 165, 250, 0.4);
}
.selo-legenda.selo-banca {
background: rgba(167, 139, 250, 0.2);
border: 1px solid rgba(167, 139, 250, 0.4);
}
.selo-legenda.selo-bpq {
background: rgba(59, 130, 246, 0.2);
border: 1px solid rgba(59, 130, 246, 0.4);
}
.selo-legenda.selo-proj {
background: rgba(16, 185, 129, 0.2);
border: 1px solid rgba(16, 185, 129, 0.4);
}
.selo-legenda.selo-evento {
background: rgba(251, 146, 60, 0.2);
border: 1px solid rgba(251, 146, 60, 0.4);
}
.selo-legenda.selo-coord {
background: rgba(139, 92, 246, 0.2);
border: 1px solid rgba(139, 92, 246, 0.4);
}
.selo-legenda.selo-camara {
background: rgba(234, 179, 8, 0.2);
border: 1px solid rgba(234, 179, 8, 0.4);
}
.selo-legenda.selo-gp {
background: rgba(234, 179, 8, 0.25);
border: 1px solid rgba(234, 179, 8, 0.5);
}
.selo-legenda.selo-premio {
background: rgba(16, 185, 129, 0.2);
border: 1px solid rgba(16, 185, 129, 0.4);
}
.selo-legenda.selo-mencao {
background: rgba(156, 163, 175, 0.2);
border: 1px solid rgba(156, 163, 175, 0.4);
}
.selo-legenda.selo-orient-premio {
background: rgba(236, 72, 153, 0.2);
border: 1px solid rgba(236, 72, 153, 0.4);
}
.selo-legenda.selo-orient-mencao {
background: rgba(148, 163, 184, 0.2);
border: 1px solid rgba(148, 163, 184, 0.4);
}
.selo-legenda.selo-coorient-premio {
background: rgba(168, 85, 247, 0.2);
border: 1px solid rgba(168, 85, 247, 0.4);
}
.selo-legenda.selo-coorient-mencao {
background: rgba(107, 114, 128, 0.2);
border: 1px solid rgba(107, 114, 128, 0.4);
}
@media (max-width: 900px) {
.criteria-row {
flex-wrap: wrap;

View File

@@ -85,14 +85,29 @@ const Header = ({ total }) => {
<span className="max-pts">max 300</span>
</div>
<div className="table-columns">
<table className="criteria-table">
<table className="criteria-table selos-table">
<thead>
<tr><th>Premiacoes</th><th>Base</th><th>Teto</th></tr>
<tr><th>Premiacoes</th><th>B</th><th>T</th><th>Autor</th><th>Orient</th><th>Coorient</th></tr>
</thead>
<tbody>
<tr><td>PREMIACAO_GP</td><td>100</td><td>300</td></tr>
<tr><td>PREMIACAO</td><td>50</td><td>150</td></tr>
<tr><td>MENCAO</td><td>30</td><td>90</td></tr>
<tr>
<td>GP</td><td>100</td><td>300</td>
<td><span className="selo-legenda selo-gp">🏆</span></td>
<td><span className="selo-legenda selo-gp">🏆</span></td>
<td><span className="selo-legenda selo-gp">🏆</span></td>
</tr>
<tr>
<td>PREMIO</td><td>50</td><td>150</td>
<td><span className="selo-legenda selo-premio">🥇</span></td>
<td><span className="selo-legenda selo-orient-premio">🎖</span></td>
<td><span className="selo-legenda selo-coorient-premio">🎖</span></td>
</tr>
<tr>
<td>MENCAO</td><td>30</td><td>90</td>
<td><span className="selo-legenda selo-mencao">🥈</span></td>
<td><span className="selo-legenda selo-orient-mencao">📜</span></td>
<td><span className="selo-legenda selo-coorient-mencao">📜</span></td>
</tr>
</tbody>
</table>
<table className="criteria-table">
@@ -120,61 +135,59 @@ const Header = ({ total }) => {
</div>
<div className="criteria-row">
<div className="criteria-section bloco-c">
<div className="criteria-section bloco-c selos-section">
<div className="section-header">
<h4>C - Orientacoes</h4>
<span className="max-pts">selos</span>
</div>
<div className="table-columns">
<table className="criteria-table compact">
<thead><tr><th>Orientacao</th><th>B</th><th>T</th></tr></thead>
<table className="criteria-table compact selos-table">
<thead><tr><th>Orientacao</th><th>Selo</th></tr></thead>
<tbody>
<tr><td>POS_DOC</td><td>0</td><td>0</td></tr>
<tr><td>TESE</td><td>0</td><td>0</td></tr>
<tr><td>DISS</td><td>0</td><td>0</td></tr>
<tr><td>POS_DOC</td><td><span className="selo-legenda selo-orient">🔬</span></td></tr>
<tr><td>TESE</td><td><span className="selo-legenda selo-orient">📚</span></td></tr>
<tr><td>DISS</td><td><span className="selo-legenda selo-orient">📄</span></td></tr>
</tbody>
</table>
<table className="criteria-table compact">
<thead><tr><th>Co-Orient</th><th>B</th><th>T</th></tr></thead>
<table className="criteria-table compact selos-table">
<thead><tr><th>Co-Orient</th><th>Selo</th></tr></thead>
<tbody>
<tr><td>POS_DOC</td><td>0</td><td>0</td></tr>
<tr><td>TESE</td><td>0</td><td>0</td></tr>
<tr><td>DISS</td><td>0</td><td>0</td></tr>
<tr><td>POS_DOC</td><td><span className="selo-legenda selo-coorient">🔬</span></td></tr>
<tr><td>TESE</td><td><span className="selo-legenda selo-coorient">📚</span></td></tr>
<tr><td>DISS</td><td><span className="selo-legenda selo-coorient">📄</span></td></tr>
</tbody>
</table>
</div>
<div className="criteria-note">+versoes _PREM | Selos no V1</div>
</div>
<div className="criteria-section bloco-c">
<div className="criteria-section bloco-c selos-section">
<div className="section-header">
<h4>C - Bancas</h4>
<span className="max-pts">selos</span>
</div>
<table className="criteria-table compact">
<thead><tr><th>Membro Banca</th><th>Base</th><th>Teto</th></tr></thead>
<table className="criteria-table compact selos-table">
<thead><tr><th>Membro Banca</th><th>Selo</th></tr></thead>
<tbody>
<tr><td>MB_POS_DOC</td><td>0</td><td>0</td></tr>
<tr><td>MB_TESE</td><td>0</td><td>0</td></tr>
<tr><td>MB_DISS</td><td>0</td><td>0</td></tr>
<tr><td>MB_POS_DOC</td><td><span className="selo-legenda selo-banca">🔬</span></td></tr>
<tr><td>MB_TESE</td><td><span className="selo-legenda selo-banca">📚</span></td></tr>
<tr><td>MB_DISS</td><td><span className="selo-legenda selo-banca">📄</span></td></tr>
</tbody>
</table>
<div className="criteria-note">+versoes _PREM | Selos no V1</div>
</div>
<div className="criteria-section bloco-d">
<div className="criteria-section bloco-d selos-section">
<div className="section-header">
<h4>D - Indicadores</h4>
<span className="max-pts">selos</span>
</div>
<table className="criteria-table compact">
<thead><tr><th>Codigo</th><th>Base</th><th>Teto</th></tr></thead>
<table className="criteria-table compact selos-table">
<thead><tr><th>Codigo</th><th>B</th><th>T</th><th>Selo</th></tr></thead>
<tbody>
<tr><td>BOL_BPQ</td><td>30</td><td>60</td></tr>
<tr><td>PROJ</td><td>10</td><td>30</td></tr>
<tr><td>EVENTO</td><td>1</td><td>5</td></tr>
<tr><td>IDIOMA</td><td>0</td><td>0</td></tr>
<tr><td>TITULACAO</td><td>0</td><td>0</td></tr>
<tr><td>BOL_BPQ</td><td>30</td><td>60</td><td><span className="selo-legenda selo-bpq">🏅</span></td></tr>
<tr><td>PROJ</td><td>10</td><td>30</td><td><span className="selo-legenda selo-proj">📁</span></td></tr>
<tr><td>EVENTO</td><td>1</td><td>5</td><td><span className="selo-legenda selo-evento">📅</span></td></tr>
<tr><td>PPG_COORD</td><td>-</td><td>-</td><td><span className="selo-legenda selo-coord">🎓</span></td></tr>
<tr><td>PRES_CAM</td><td>-</td><td>-</td><td><span className="selo-legenda selo-camara">👑</span></td></tr>
</tbody>
</table>
</div>

View File

@@ -277,7 +277,7 @@
.sugerir-rank {
font-size: 0.8rem;
font-weight: 700;
color: var(--accent);
color: #ebeaff;
min-width: 2rem;
}
@@ -286,6 +286,31 @@
font-weight: 600;
color: var(--white);
font-size: 0.95rem;
display: flex;
align-items: center;
gap: 0.5rem;
}
.sugerir-nome .link-atuacapes {
display: inline-flex;
align-items: center;
justify-content: center;
width: 22px;
height: 22px;
font-size: 0.8rem;
color: #94a3b8;
background: rgba(255, 255, 255, 0.06);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 5px;
text-decoration: none;
transition: all 200ms ease;
}
.sugerir-nome .link-atuacapes:hover {
color: #a5b4fc;
background: rgba(79, 70, 229, 0.2);
border-color: rgba(165, 180, 252, 0.4);
transform: scale(1.1);
}
.sugerir-badges {
@@ -338,12 +363,12 @@
align-items: center;
gap: 0.3rem;
font-size: 0.8rem;
color: #22d3ee;
color: #67e8f9;
font-weight: 600;
background: rgba(34, 211, 238, 0.15);
background: rgba(34, 211, 238, 0.2);
padding: 0.25rem 0.6rem;
border-radius: 6px;
border: 1px solid rgba(34, 211, 238, 0.3);
border: 1px solid rgba(103, 232, 249, 0.4);
}
.stat-icon {

View File

@@ -245,7 +245,21 @@ const SugerirConsultores = ({ onClose, onSelectConsultor }) => {
/>
</label>
<span className="sugerir-rank">#{index + 1}</span>
<span className="sugerir-nome">{c.nome}</span>
<span className="sugerir-nome">
{c.nome}
{import.meta.env.VITE_HOST_ATUACAPES && c.id_pessoa && (
<a
href={`${import.meta.env.VITE_HOST_ATUACAPES}/perfil/${c.id_pessoa}`}
target="_blank"
rel="noopener noreferrer"
className="link-atuacapes"
onClick={(e) => e.stopPropagation()}
title="Ver perfil no ATUACAPES"
>
</a>
)}
</span>
<div className="sugerir-badges">
{c.foi_coordenador && <span className="badge coordenador" title="Foi coordenador">CA</span>}
{c.foi_premiado && <span className="badge premiado" title="Foi premiado">P</span>}

View File

@@ -53,6 +53,7 @@ export const rankingService = {
ativo: c.ativo,
anos_atuacao: anos,
veterano: anos >= 10,
tipos_atuacao: c.tipos_atuacao || [],
coordenador_ppg: Boolean(c.coordenador_ppg),
pontuacao: c.pontuacao || {
pontuacao_total: c.pontuacao_total,