diff --git a/frontend/src/components/ConsultorCard.css b/frontend/src/components/ConsultorCard.css
index 53c3e96..5d0713e 100644
--- a/frontend/src/components/ConsultorCard.css
+++ b/frontend/src/components/ConsultorCard.css
@@ -205,6 +205,14 @@
color: #0f172a;
}
+.badge-premiado {
+ background: linear-gradient(120deg, #fbbf24, #f59e0b);
+ color: #0f172a;
+ font-size: 0.85rem;
+ padding: 0.15rem 0.35rem;
+ border: none;
+}
+
.card-stats {
display: flex;
align-items: center;
@@ -580,36 +588,36 @@
.selos-container.selos-compacto {
display: inline-flex;
- margin-left: 0.25rem;
- gap: 0.2rem;
+ margin-left: 0.5rem;
+ gap: 0.4rem;
}
.selos-compacto .selo {
- background: rgba(148, 163, 184, 0.12);
- border-color: rgba(148, 163, 184, 0.25);
+ background: rgba(148, 163, 184, 0.15);
+ border-color: rgba(148, 163, 184, 0.3);
color: #94a3b8;
- padding: 0.1rem 0.25rem;
- gap: 0.15rem;
- font-size: 0.6rem;
+ padding: 0.25rem 0.45rem;
+ gap: 0.25rem;
+ font-size: 0.7rem;
}
.selos-compacto .selo:hover {
- background: rgba(148, 163, 184, 0.2);
- border-color: rgba(148, 163, 184, 0.4);
+ background: rgba(148, 163, 184, 0.25);
+ border-color: rgba(148, 163, 184, 0.5);
color: #cbd5e1;
}
.selos-compacto .selo-icone {
filter: grayscale(100%) brightness(1.2);
- opacity: 0.85;
- font-size: 0.65rem;
+ opacity: 0.9;
+ font-size: 0.9rem;
}
.selos-compacto .selo-qtd {
- background: rgba(148, 163, 184, 0.25);
+ background: rgba(148, 163, 184, 0.3);
color: #cbd5e1;
- font-size: 0.5rem;
- padding: 0.05rem 0.2rem;
+ font-size: 0.6rem;
+ padding: 0.1rem 0.25rem;
}
.selo {
@@ -927,3 +935,140 @@
font-size: 0.55rem;
}
}
+
+.tipo-clicavel,
+.selo-clicavel {
+ cursor: pointer;
+}
+
+.tipo-clicavel:hover,
+.selo-clicavel:hover {
+ transform: translateY(-2px) scale(1.05);
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
+}
+
+.tipo-modal-overlay {
+ position: fixed;
+ inset: 0;
+ background: rgba(0, 0, 0, 0.75);
+ backdrop-filter: blur(4px);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ z-index: 1000;
+ padding: 1rem;
+}
+
+.tipo-modal {
+ background: linear-gradient(155deg, rgba(30, 41, 59, 0.98), rgba(15, 23, 42, 0.98));
+ border: 1px solid var(--stroke);
+ border-radius: 16px;
+ box-shadow: 0 25px 50px rgba(0, 0, 0, 0.5);
+ max-width: 600px;
+ width: 100%;
+ max-height: 80vh;
+ overflow: hidden;
+ display: flex;
+ flex-direction: column;
+}
+
+.tipo-modal-header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 1rem 1.25rem;
+ border-bottom: 1px solid var(--stroke);
+ background: rgba(255, 255, 255, 0.03);
+}
+
+.tipo-modal-header .tipo-atuacao {
+ font-size: 0.85rem;
+ padding: 0.35rem 0.7rem;
+}
+
+.tipo-modal-header .tipo-icone {
+ font-size: 1rem;
+}
+
+.tipo-modal-close {
+ background: rgba(255, 255, 255, 0.06);
+ border: 1px solid var(--stroke);
+ border-radius: 8px;
+ color: var(--muted);
+ font-size: 1rem;
+ width: 32px;
+ height: 32px;
+ cursor: pointer;
+ transition: all 200ms ease;
+}
+
+.tipo-modal-close:hover {
+ background: rgba(239, 68, 68, 0.2);
+ border-color: rgba(239, 68, 68, 0.4);
+ color: #fca5a5;
+}
+
+.tipo-modal-body {
+ padding: 1rem 1.25rem;
+ overflow-y: auto;
+ flex: 1;
+}
+
+.modal-list {
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+}
+
+.modal-item {
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+ padding: 0.6rem 0.8rem;
+ background: rgba(255, 255, 255, 0.03);
+ border-radius: 8px;
+ border: 1px solid var(--stroke);
+ font-size: 0.85rem;
+}
+
+.modal-item:hover {
+ background: rgba(255, 255, 255, 0.06);
+ border-color: rgba(255, 255, 255, 0.15);
+}
+
+.modal-item-main {
+ flex: 1;
+ color: var(--text);
+ font-weight: 500;
+}
+
+.modal-summary {
+ display: flex;
+ gap: 1.5rem;
+ padding: 0.75rem 1rem;
+ background: rgba(79, 70, 229, 0.1);
+ border: 1px solid rgba(79, 70, 229, 0.25);
+ border-radius: 8px;
+ margin-bottom: 0.75rem;
+ font-size: 0.85rem;
+ color: var(--muted);
+}
+
+.modal-summary strong {
+ color: var(--accent-2);
+}
+
+.modal-empty {
+ text-align: center;
+ color: var(--muted);
+ padding: 2rem;
+ font-size: 0.9rem;
+}
+
+.tipo-modal-body h5 {
+ color: var(--accent-2);
+ font-size: 0.75rem;
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+ margin: 1rem 0 0.5rem;
+}
diff --git a/frontend/src/components/ConsultorCard.jsx b/frontend/src/components/ConsultorCard.jsx
index 5864d23..7cd6e9c 100644
--- a/frontend/src/components/ConsultorCard.jsx
+++ b/frontend/src/components/ConsultorCard.jsx
@@ -1,27 +1,28 @@
import React, { useState, useRef, useEffect, useMemo, memo } from 'react';
+import { createPortal } from 'react-dom';
import './ConsultorCard.css';
import RawDataModal from './RawDataModal';
import { rankingService } from '../services/api';
const SELOS = {
- PRESID_CAMARA: { label: 'Presidente Camara', cor: 'selo-camara', icone: '👑' },
- COORD_PPG: { label: 'Coord. PPG', cor: 'selo-coord', icone: '🎓' },
- BPQ: { label: 'BPQ', cor: 'selo-bpq', icone: '🏅' },
- AUTOR_GP: { label: 'Autor GP', cor: 'selo-gp', icone: '🏆' },
- AUTOR_PREMIO: { label: 'Autor Premio', cor: 'selo-premio', icone: '🥇' },
- AUTOR_MENCAO: { label: 'Autor Mencao', cor: 'selo-mencao', icone: '🥈' },
- ORIENT_GP: { label: 'Orient. GP', cor: 'selo-gp', icone: '🏆' },
- ORIENT_PREMIO: { label: 'Orient. Premio', cor: 'selo-orient-premio', icone: '🎖️' },
- ORIENT_MENCAO: { label: 'Orient. Mencao', cor: 'selo-orient-mencao', icone: '📜' },
- COORIENT_GP: { label: 'Coorient. GP', cor: 'selo-gp', icone: '🏆' },
- COORIENT_PREMIO: { label: 'Coorient. Premio', cor: 'selo-coorient-premio', icone: '🎖️' },
- COORIENT_MENCAO: { label: 'Coorient. Mencao', cor: 'selo-coorient-mencao', icone: '📜' },
- ORIENT_TESE: { label: 'Orient. Tese', cor: 'selo-orient', icone: '📚' },
- ORIENT_DISS: { label: 'Orient. Diss.', cor: 'selo-orient', icone: '📄' },
- ORIENT_POS_DOC: { label: 'Orient. Pos-Doc', cor: 'selo-orient', icone: '🔬' },
- CO_ORIENT_TESE: { label: 'Coorient. Tese', cor: 'selo-coorient', icone: '📚' },
- CO_ORIENT_DISS: { label: 'Coorient. Diss.', cor: 'selo-coorient', icone: '📄' },
- CO_ORIENT_POS_DOC: { label: 'Coorient. Pos-Doc', cor: 'selo-coorient', icone: '🔬' },
+ PRESID_CAMARA: { codigo: 'PRESID_CAMARA', label: 'Presidente Camara', cor: 'selo-camara', icone: '👑' },
+ COORD_PPG: { codigo: 'COORD_PPG', label: 'Coord. PPG', cor: 'selo-coord', icone: '🎓' },
+ BPQ: { codigo: 'BPQ', label: 'BPQ', cor: 'selo-bpq', icone: '🏅' },
+ AUTOR_GP: { codigo: 'AUTOR_GP', label: 'Autor GP', cor: 'selo-gp', icone: '🏆' },
+ AUTOR_PREMIO: { codigo: 'AUTOR_PREMIO', label: 'Autor Premio', cor: 'selo-premio', icone: '🥇' },
+ AUTOR_MENCAO: { codigo: 'AUTOR_MENCAO', label: 'Autor Mencao', cor: 'selo-mencao', icone: '🥈' },
+ ORIENT_GP: { codigo: 'ORIENT_GP', label: 'Orient. GP', cor: 'selo-gp', icone: '🏆' },
+ ORIENT_PREMIO: { codigo: 'ORIENT_PREMIO', label: 'Orient. Premio', cor: 'selo-orient-premio', icone: '🎖️' },
+ ORIENT_MENCAO: { codigo: 'ORIENT_MENCAO', label: 'Orient. Mencao', cor: 'selo-orient-mencao', icone: '📜' },
+ COORIENT_GP: { codigo: 'COORIENT_GP', label: 'Coorient. GP', cor: 'selo-gp', icone: '🏆' },
+ COORIENT_PREMIO: { codigo: 'COORIENT_PREMIO', label: 'Coorient. Premio', cor: 'selo-coorient-premio', icone: '🎖️' },
+ COORIENT_MENCAO: { codigo: 'COORIENT_MENCAO', label: 'Coorient. Mencao', cor: 'selo-coorient-mencao', icone: '📜' },
+ ORIENT_TESE: { codigo: 'ORIENT_TESE', label: 'Orient. Tese', cor: 'selo-orient', icone: '📚' },
+ ORIENT_DISS: { codigo: 'ORIENT_DISS', label: 'Orient. Diss.', cor: 'selo-orient', icone: '📄' },
+ ORIENT_POS_DOC: { codigo: 'ORIENT_POS_DOC', label: 'Orient. Pos-Doc', cor: 'selo-orient', icone: '🔬' },
+ CO_ORIENT_TESE: { codigo: 'CO_ORIENT_TESE', label: 'Coorient. Tese', cor: 'selo-coorient', icone: '📚' },
+ CO_ORIENT_DISS: { codigo: 'CO_ORIENT_DISS', label: 'Coorient. Diss.', cor: 'selo-coorient', icone: '📄' },
+ CO_ORIENT_POS_DOC: { codigo: 'CO_ORIENT_POS_DOC', label: 'Coorient. Pos-Doc', cor: 'selo-coorient', icone: '🔬' },
};
const TIPOS_ATUACAO_CONFIG = {
@@ -100,25 +101,47 @@ const gerarSelos = (consultor) => {
return selos;
};
-const SelosBadges = ({ selos, compacto = false }) => {
+const SELOS_COM_DADOS = [
+ 'PRESID_CAMARA', 'COORD_PPG', 'BPQ',
+ 'AUTOR_GP', 'AUTOR_PREMIO', 'AUTOR_MENCAO',
+ 'ORIENT_GP', 'ORIENT_PREMIO', 'ORIENT_MENCAO',
+ 'COORIENT_GP', 'COORIENT_PREMIO', 'COORIENT_MENCAO',
+ 'ORIENT_TESE', 'ORIENT_DISS', 'ORIENT_POS_DOC',
+ 'CO_ORIENT_TESE', 'CO_ORIENT_DISS', 'CO_ORIENT_POS_DOC'
+];
+
+const SelosBadges = ({ selos, compacto = false, onSeloClick }) => {
if (!selos || selos.length === 0) return null;
const selosExibidos = compacto ? selos.slice(0, 4) : selos;
const selosOcultos = compacto && selos.length > 4 ? selos.length - 4 : 0;
+ const handleClick = (e, selo) => {
+ if (onSeloClick && SELOS_COM_DADOS.includes(selo.codigo)) {
+ e.preventDefault();
+ e.stopPropagation();
+ onSeloClick(selo);
+ }
+ };
+
return (
- {selosExibidos.map((selo, idx) => (
-
1 ? ` (${selo.qtd}x)` : ''}`}
- >
- {selo.icone}
- {!compacto && {selo.label}}
- {!compacto && {selo.qtd || 1}}
-
- ))}
+ {selosExibidos.map((selo, idx) => {
+ const temDados = SELOS_COM_DADOS.includes(selo.codigo);
+ return (
+
1 ? ` (${selo.qtd}x)` : ''}`)}
+ onMouseDown={(e) => onSeloClick && temDados && e.stopPropagation()}
+ onClick={(e) => handleClick(e, selo)}
+ >
+ {selo.icone}
+ {!compacto && {selo.label}}
+ {!compacto && {selo.qtd || 1}}
+
+ );
+ })}
{selosOcultos > 0 && (
+{selosOcultos}
)}
@@ -126,18 +149,32 @@ const SelosBadges = ({ selos, compacto = false }) => {
);
};
-const TiposAtuacaoBadges = ({ tipos, exibirTodos = false }) => {
+const TiposAtuacaoBadges = ({ tipos, exibirTodos = false, onBadgeClick, consultor }) => {
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;
+ const handleClick = (e, tipo) => {
+ if (onBadgeClick) {
+ e.preventDefault();
+ e.stopPropagation();
+ onBadgeClick(tipo);
+ }
+ };
+
return (
{tiposExibidos.map((tipo, idx) => {
const config = TIPOS_ATUACAO_CONFIG[tipo] || { cor: 'tipo-default', icone: '📌' };
return (
-
+ onBadgeClick && e.stopPropagation()}
+ onClick={(e) => handleClick(e, tipo)}
+ >
{config.icone}
{tipo}
@@ -152,6 +189,368 @@ const TiposAtuacaoBadges = ({ tipos, exibirTodos = false }) => {
);
};
+const TipoAtuacaoModal = ({ tipo, consultor, onClose }) => {
+ if (!tipo || !consultor) return null;
+
+ const formatDate = (dateStr) => {
+ if (!dateStr) return 'Atual';
+ return new Date(dateStr).toLocaleDateString('pt-BR');
+ };
+
+ const renderContent = () => {
+ switch (tipo) {
+ case 'Coordenador': {
+ const coords = consultor.coordenacoes_capes || [];
+ if (coords.length === 0) return Sem dados de coordenação
;
+ return (
+
+ {[...coords].sort((a, b) => new Date(b.inicio || 0) - new Date(a.inicio || 0)).map((c, i) => (
+
+ {c.codigo}
+ {c.area_avaliacao}
+ {c.presidente && 👑 Presidente}
+ {formatDate(c.inicio)} - {formatDate(c.fim)}
+
+ ))}
+
+ );
+ }
+ case 'Consultor': {
+ const cons = consultor.consultoria;
+ if (!cons) return Sem dados de consultoria
;
+ const vinculos = cons.vinculos || [];
+ return (
+
+
+ Anos consecutivos: {cons.anos_consecutivos || 0}
+ Início: {formatDate(cons.inicio)}
+
+ {vinculos.length > 0 && (
+ <>
+
Vínculos ({vinculos.length})
+ {[...vinculos].sort((a, b) => new Date(b.periodo?.inicio || 0) - new Date(a.periodo?.inicio || 0)).map((v, i) => {
+ const isAtivo = v.periodo?.ativo ?? !v.periodo?.fim;
+ return (
+
+
+ {isAtivo ? 'ATIVO' : 'ENCERRADO'}
+
+
+ {v.ies ? (v.ies.sigla ? `${v.ies.sigla} - ${v.ies.nome || ''}` : v.ies.nome) : 'IES não informada'}
+
+ {formatDate(v.periodo?.inicio)} - {formatDate(v.periodo?.fim)}
+
+ );
+ })}
+ >
+ )}
+
+ );
+ }
+ case 'Avaliador': {
+ const avals = consultor.avaliacoes_comissao || [];
+ if (avals.length === 0) return Sem avaliações de comissão
;
+ return (
+
+ {[...avals].sort((a, b) => (b.ano || 0) - (a.ano || 0)).map((a, i) => (
+
+ {a.codigo}
+ {a.nome_comissao || a.premio || a.descricao || '-'}
+ {a.ano || '-'}
+
+ ))}
+
+ );
+ }
+ case 'Premiado': {
+ const prems = consultor.premiacoes || [];
+ if (prems.length === 0) return Sem premiações
;
+ return (
+
+ {[...prems].sort((a, b) => (b.ano || 0) - (a.ano || 0)).map((p, i) => (
+
+ {p.codigo}
+ {p.nome_premio || p.premio || '-'}
+ {p.papel || ''}
+ {p.ano || '-'}
+
+ ))}
+
+ );
+ }
+ case 'Orientador': {
+ const orients = consultor.orientacoes || [];
+ if (orients.length === 0) return Sem orientações
;
+ const contagem = {};
+ orients.forEach(o => { contagem[o.codigo] = (contagem[o.codigo] || 0) + 1; });
+ const labels = {
+ ORIENT_POS_DOC: '🔬 Pós-Doutorado',
+ ORIENT_TESE: '📚 Tese (Doutorado)',
+ ORIENT_DISS: '📄 Dissertação (Mestrado)',
+ CO_ORIENT_POS_DOC: '🔬 Coorient. Pós-Doc',
+ CO_ORIENT_TESE: '📚 Coorient. Tese',
+ CO_ORIENT_DISS: '📄 Coorient. Diss.'
+ };
+ return (
+
+
Total: {orients.length} orientações
+ {Object.entries(contagem).map(([cod, qtd]) => (
+
+ {labels[cod] || cod}
+ {qtd}x
+
+ ))}
+
+ );
+ }
+ case 'Bolsista CNPq': {
+ const bolsas = consultor.bolsas_cnpq || [];
+ if (bolsas.length === 0) return Sem bolsas CNPq
;
+ return (
+
+ {bolsas.map((b, i) => (
+
+ BPQ
+ Nível {b.nivel || 'N/A'}
+
+ ))}
+
+ );
+ }
+ case 'Inscrito Premio': {
+ const inscs = consultor.inscricoes || [];
+ if (inscs.length === 0) return Sem inscrições em prêmios
;
+ return (
+
+ {[...inscs].sort((a, b) => (b.ano || 0) - (a.ano || 0)).map((ins, i) => (
+
+ {ins.codigo}
+ {ins.premio || ins.descricao || '-'}
+ {ins.ano || '-'}
+
+ ))}
+
+ );
+ }
+ case 'Projeto': {
+ const parts = (consultor.participacoes || []).filter(p => p.codigo === 'PROJ');
+ if (parts.length === 0) return Sem projetos
;
+ return (
+
+ {[...parts].sort((a, b) => (b.ano || 0) - (a.ano || 0)).slice(0, 20).map((p, i) => (
+
+ PROJ
+ {p.descricao || p.tipo || '-'}
+ {p.ano || '-'}
+
+ ))}
+ {parts.length > 20 &&
... e mais {parts.length - 20} projetos
}
+
+ );
+ }
+ case 'Evento': {
+ const parts = (consultor.participacoes || []).filter(p => p.codigo === 'EVENTO');
+ if (parts.length === 0) return Sem eventos
;
+ return (
+
+ {[...parts].sort((a, b) => (b.ano || 0) - (a.ano || 0)).slice(0, 20).map((p, i) => (
+
+ EVENTO
+ {p.descricao || p.tipo || '-'}
+ {p.ano || '-'}
+
+ ))}
+ {parts.length > 20 &&
... e mais {parts.length - 20} eventos
}
+
+ );
+ }
+ default:
+ return Tipo não reconhecido
;
+ }
+ };
+
+ const config = TIPOS_ATUACAO_CONFIG[tipo] || { cor: 'tipo-default', icone: '📌' };
+
+ return createPortal(
+
+
e.stopPropagation()}>
+
+
+ {config.icone}
+ {tipo}
+
+
+
+
+ {renderContent()}
+
+
+
,
+ document.body
+ );
+};
+
+const SeloModal = ({ selo, consultor, onClose }) => {
+ if (!selo || !consultor) return null;
+
+ const formatDate = (dateStr) => {
+ if (!dateStr) return 'Atual';
+ return new Date(dateStr).toLocaleDateString('pt-BR');
+ };
+
+ const renderContent = () => {
+ switch (selo.codigo) {
+ case 'PRESID_CAMARA': {
+ const coords = (consultor.coordenacoes_capes || []).filter(c => c.presidente);
+ if (coords.length === 0) return Sem dados
;
+ return (
+
+ {coords.map((c, i) => (
+
+ {c.codigo}
+ {c.area_avaliacao}
+ {formatDate(c.inicio)} - {formatDate(c.fim)}
+
+ ))}
+
+ );
+ }
+ case 'COORD_PPG':
+ return Coordenador de Programa de Pós-Graduação
;
+ case 'BPQ': {
+ const bolsas = consultor.bolsas_cnpq || [];
+ if (bolsas.length === 0) return Sem bolsas
;
+ return (
+
+
Total: {bolsas.length} bolsa(s) BPQ
+ {bolsas.map((b, i) => (
+
+ BPQ
+ Nível {b.nivel || 'N/A'}
+
+ ))}
+
+ );
+ }
+ case 'AUTOR_GP':
+ case 'AUTOR_PREMIO':
+ case 'AUTOR_MENCAO': {
+ const codMap = { AUTOR_GP: 'PREMIACAO_GP_AUTOR', AUTOR_PREMIO: 'PREMIACAO_AUTOR', AUTOR_MENCAO: 'MENCAO_AUTOR' };
+ const prems = (consultor.premiacoes || []).filter(p => p.codigo === codMap[selo.codigo] && (p.papel || '').toLowerCase() === 'autor');
+ if (prems.length === 0) return Sem premiações
;
+ return (
+
+ {prems.sort((a, b) => (b.ano || 0) - (a.ano || 0)).map((p, i) => (
+
+ {p.codigo}
+ {p.nome_premio || p.premio || '-'}
+ {p.ano || '-'}
+
+ ))}
+
+ );
+ }
+ case 'ORIENT_GP':
+ case 'ORIENT_PREMIO':
+ case 'ORIENT_MENCAO': {
+ const codMap = { ORIENT_GP: 'PREMIACAO_GP_AUTOR', ORIENT_PREMIO: 'PREMIACAO_AUTOR', ORIENT_MENCAO: 'MENCAO_AUTOR' };
+ const prems = (consultor.premiacoes || []).filter(p => p.codigo === codMap[selo.codigo] && (p.papel || '').toLowerCase() === 'orientador');
+ if (prems.length === 0) return Sem premiações como orientador
;
+ return (
+
+ {prems.sort((a, b) => (b.ano || 0) - (a.ano || 0)).map((p, i) => (
+
+ {p.codigo}
+ {p.nome_premio || p.premio || '-'}
+ {p.ano || '-'}
+
+ ))}
+
+ );
+ }
+ case 'COORIENT_GP':
+ case 'COORIENT_PREMIO':
+ case 'COORIENT_MENCAO': {
+ const codMap = { COORIENT_GP: 'PREMIACAO_GP_AUTOR', COORIENT_PREMIO: 'PREMIACAO_AUTOR', COORIENT_MENCAO: 'MENCAO_AUTOR' };
+ const prems = (consultor.premiacoes || []).filter(p => p.codigo === codMap[selo.codigo] && (p.papel || '').toLowerCase() === 'coorientador');
+ if (prems.length === 0) return Sem premiações como coorientador
;
+ return (
+
+ {prems.sort((a, b) => (b.ano || 0) - (a.ano || 0)).map((p, i) => (
+
+ {p.codigo}
+ {p.nome_premio || p.premio || '-'}
+ {p.ano || '-'}
+
+ ))}
+
+ );
+ }
+ case 'ORIENT_TESE':
+ case 'ORIENT_DISS':
+ case 'ORIENT_POS_DOC':
+ case 'CO_ORIENT_TESE':
+ case 'CO_ORIENT_DISS':
+ case 'CO_ORIENT_POS_DOC': {
+ const orients = consultor.orientacoes || [];
+ const lista = orients.filter(o => o.codigo === selo.codigo);
+ const isCoorient = selo.codigo.startsWith('CO_');
+ const tipoLabel = {
+ ORIENT_TESE: 'Teses de Doutorado',
+ ORIENT_DISS: 'Dissertações de Mestrado',
+ ORIENT_POS_DOC: 'Pós-Doutorados',
+ CO_ORIENT_TESE: 'Coorientações de Tese',
+ CO_ORIENT_DISS: 'Coorientações de Dissertação',
+ CO_ORIENT_POS_DOC: 'Coorientações de Pós-Doc'
+ };
+ const premiadas = lista.filter(o => o.premiada);
+ return (
+
+
+ Total: {lista.length} {tipoLabel[selo.codigo]?.toLowerCase() || 'orientações'}
+ {premiadas.length > 0 && Premiadas: {premiadas.length} 🏆}
+
+
+
+ {isCoorient ? 'Coorientações' : 'Orientações'} de {selo.codigo.includes('TESE') ? 'Doutorado' : selo.codigo.includes('DISS') ? 'Mestrado' : 'Pós-Doutorado'} concluídas.
+
+ {premiadas.length > 0 && (
+
+ 🏆 {premiadas.length} orientação(ões) premiada(s) no Prêmio CAPES de Tese
+
+ )}
+
+ Dados agregados do currículo Lattes via ATUACAPES.
+
+
+
+ );
+ }
+ default:
+ return Sem dados detalhados para este selo
;
+ }
+ };
+
+ return createPortal(
+
+
e.stopPropagation()}>
+
+
+ {selo.icone}
+ {selo.label}
+ {selo.qtd}
+
+
+
+
+ {renderContent()}
+
+
+
,
+ document.body
+ );
+};
+
const FORMULAS = {
bloco_a: {
titulo: 'Coordenacao CAPES',
@@ -222,6 +621,8 @@ const ScoreItemWithTooltip = ({ value, label, formula, style }) => (
const ConsultorCard = memo(({ consultor, highlight, selecionado, onToggleSelecionado }) => {
const [expanded, setExpanded] = useState(false);
const [showRawModal, setShowRawModal] = useState(false);
+ const [tipoAtuacaoModal, setTipoAtuacaoModal] = useState(null);
+ const [seloModal, setSeloModal] = useState(null);
const cardRef = useRef(null);
useEffect(() => {
@@ -354,7 +755,7 @@ const ConsultorCard = memo(({ consultor, highlight, selecionado, onToggleSelecio
{expanded && (
-
+
e.stopPropagation()}>
Pontuacao Total
@@ -413,14 +814,19 @@ const ConsultorCard = memo(({ consultor, highlight, selecionado, onToggleSelecio
{consultor.tipos_atuacao?.length > 0 && (
Tipos de Atuacao
-
+
)}
{selos.length > 0 && (
Selos e Reconhecimentos
-
+
)}
@@ -550,6 +956,49 @@ const ConsultorCard = memo(({ consultor, highlight, selecionado, onToggleSelecio
)}
+
+ {consultor.orientacoes?.length > 0 && (() => {
+ const orientacoes = consultor.orientacoes;
+ const contagem = {};
+ const premiadas = {};
+ orientacoes.forEach(o => {
+ contagem[o.codigo] = (contagem[o.codigo] || 0) + 1;
+ if (o.premiada) premiadas[o.codigo] = (premiadas[o.codigo] || 0) + 1;
+ });
+ const config = {
+ ORIENT_POS_DOC: { label: 'Pós-Doutorado', icone: '🔬', cor: 'tipo-orientador' },
+ ORIENT_TESE: { label: 'Tese (Doutorado)', icone: '📚', cor: 'tipo-orientador' },
+ ORIENT_DISS: { label: 'Dissertação (Mestrado)', icone: '📄', cor: 'tipo-orientador' },
+ CO_ORIENT_POS_DOC: { label: 'Coorient. Pós-Doc', icone: '🔬', cor: 'tipo-avaliador' },
+ CO_ORIENT_TESE: { label: 'Coorient. Tese', icone: '📚', cor: 'tipo-avaliador' },
+ CO_ORIENT_DISS: { label: 'Coorient. Diss.', icone: '📄', cor: 'tipo-avaliador' },
+ };
+ const ordem = ['ORIENT_POS_DOC', 'ORIENT_TESE', 'ORIENT_DISS', 'CO_ORIENT_POS_DOC', 'CO_ORIENT_TESE', 'CO_ORIENT_DISS'];
+ return (
+
+
Orientacoes ({orientacoes.length} total)
+
+ {ordem.filter(cod => contagem[cod] > 0).map(cod => {
+ const cfg = config[cod];
+ const qtd = contagem[cod];
+ const prem = premiadas[cod] || 0;
+ return (
+
+ {cfg.icone}
+ {cfg.label}
+ {qtd}x
+ {prem > 0 && (
+
+ 🏆 {prem}
+
+ )}
+
+ );
+ })}
+
+
+ );
+ })()}
)}
@@ -560,6 +1009,22 @@ const ConsultorCard = memo(({ consultor, highlight, selecionado, onToggleSelecio
onClose={() => setShowRawModal(false)}
/>
)}
+
+ {tipoAtuacaoModal && (
+
setTipoAtuacaoModal(null)}
+ />
+ )}
+
+ {seloModal && (
+ setSeloModal(null)}
+ />
+ )}
);
});