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)} + /> + )}
); });