fix(lattes): correcoes finais na integracao Lattes

This commit is contained in:
Frederico Castro
2025-12-27 01:06:43 -03:00
parent 1e15ab64ca
commit c78f48c988
3 changed files with 632 additions and 25 deletions

View File

@@ -1607,3 +1607,34 @@
opacity: 1;
transform: translateY(-50%) translateX(3px);
}
.modal-stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
gap: 0.75rem;
margin-bottom: 1rem;
}
.modal-stat-card {
background: rgba(99, 102, 241, 0.1);
border: 1px solid rgba(99, 102, 241, 0.2);
border-radius: 8px;
padding: 0.75rem;
text-align: center;
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.modal-stat-card .stat-number {
font-size: 1.5rem;
font-weight: 700;
color: var(--accent);
}
.modal-stat-card .stat-label {
font-size: 0.7rem;
color: var(--text-secondary);
text-transform: uppercase;
letter-spacing: 0.03em;
}

View File

@@ -719,6 +719,10 @@ const ItemDetalheModal = ({ item, tipo, onClose }) => {
case 'orientacao': return 'Orientação';
case 'orientacao_lattes': return 'Orientação Concluída';
case 'idioma': return 'Idioma';
case 'docencia': return 'Docência em PPG';
case 'emprego': return 'Vínculo Empregatício';
case 'projeto': return 'Projeto de Pesquisa';
case 'premiacao_lattes': return 'Premiação';
default: return 'Detalhes';
}
};
@@ -736,6 +740,10 @@ const ItemDetalheModal = ({ item, tipo, onClose }) => {
case 'orientacao': return '🎓';
case 'orientacao_lattes': return '👨‍🏫';
case 'idioma': return '🌐';
case 'docencia': return '👨‍🏫';
case 'emprego': return '🏢';
case 'projeto': return '📊';
case 'premiacao_lattes': return '🏆';
default: return '📄';
}
};
@@ -792,6 +800,18 @@ const ItemDetalheModal = ({ item, tipo, onClose }) => {
<span className="modal-detalhe-value">{it.codigo_programa}</span>
</div>
)}
{it.programa_modalidade && (
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">Modalidade</span>
<span className="modal-detalhe-value">{it.programa_modalidade}</span>
</div>
)}
{it.programa_situacao && (
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">Situação Programa</span>
<span className="modal-detalhe-value">{it.programa_situacao}</span>
</div>
)}
{it.pais && (
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">País</span>
@@ -900,6 +920,269 @@ const ItemDetalheModal = ({ item, tipo, onClose }) => {
);
}
case 'docencia': {
const d = currentItem;
return (
<div className="modal-detalhe-content">
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">Programa</span>
<span className="modal-detalhe-value">{d.programa || 'N/A'}</span>
</div>
{d.codigo_programa && (
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">Código</span>
<span className="modal-detalhe-value">{d.codigo_programa}</span>
</div>
)}
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">Instituição</span>
<span className="modal-detalhe-value">{d.ies_nome} ({d.ies_sigla})</span>
</div>
{d.modalidade && (
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">Modalidade</span>
<span className="modal-detalhe-value">{d.modalidade}</span>
</div>
)}
{d.situacao_programa && (
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">Situação</span>
<span className="modal-detalhe-value">{d.situacao_programa}</span>
</div>
)}
{d.area && (
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">Área</span>
<span className="modal-detalhe-value">{d.area}</span>
</div>
)}
{d.area_avaliacao && (
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">Área de Avaliação</span>
<span className="modal-detalhe-value">{d.area_avaliacao}</span>
</div>
)}
{d.categoria && (
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">Categoria</span>
<span className="modal-detalhe-value">{d.categoria}</span>
</div>
)}
{d.tipo_vinculo && (
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">Tipo de Vínculo</span>
<span className="modal-detalhe-value">{d.tipo_vinculo}</span>
</div>
)}
{d.regime_trabalho && (
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">Regime de Trabalho</span>
<span className="modal-detalhe-value">{d.regime_trabalho}</span>
</div>
)}
{d.carga_horaria && (
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">Carga Horária</span>
<span className="modal-detalhe-value">{d.carga_horaria}h</span>
</div>
)}
{d.linhas_pesquisa_ativas?.length > 0 && (
<>
<h5 className="modal-section-title">Linhas de Pesquisa Ativas ({d.linhas_pesquisa_ativas.length} de {d.total_linhas_pesquisa})</h5>
<ul className="modal-list">
{d.linhas_pesquisa_ativas.map((linha, idx) => (
<li key={idx} className="modal-item">
<span className="modal-item-main">{linha}</span>
</li>
))}
</ul>
</>
)}
</div>
);
}
case 'emprego': {
const e = currentItem;
return (
<div className="modal-detalhe-content">
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">Empregador</span>
<span className="modal-detalhe-value">{e.empregador || 'N/A'}</span>
</div>
{e.cnpj && (
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">CNPJ</span>
<span className="modal-detalhe-value">{e.cnpj}</span>
</div>
)}
{e.tipo_emprego && (
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">Tipo</span>
<span className="modal-detalhe-value">{e.tipo_emprego}</span>
</div>
)}
{e.atividade && (
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">Atividade</span>
<span className="modal-detalhe-value">{e.atividade}</span>
</div>
)}
{e.vinculo && (
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">Vínculo</span>
<span className="modal-detalhe-value">{e.vinculo}</span>
</div>
)}
{e.profissao && (
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">Profissão</span>
<span className="modal-detalhe-value">{e.profissao}</span>
</div>
)}
{e.periodos?.length > 0 && (
<>
<h5 className="modal-section-title">Períodos ({e.periodos.length})</h5>
<ul className="modal-list">
{e.periodos.map((p, idx) => (
<li key={idx} className="modal-item">
<span className="modal-item-main">
{p.inicio ? formatDate(p.inicio) : 'Sem data'} a {p.fim ? formatDate(p.fim) : 'Atual'}
</span>
</li>
))}
</ul>
</>
)}
</div>
);
}
case 'projeto': {
const p = currentItem;
return (
<div className="modal-detalhe-content">
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">Nome</span>
<span className="modal-detalhe-value">{p.nome || 'N/A'}</span>
</div>
{p.situacao && (
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">Situação</span>
<span className={`badge ${p.situacao === 'EM ANDAMENTO' ? 'badge-ativo' : 'badge-historico'}`}>
{p.situacao}
</span>
</div>
)}
{p.ano_inicio && (
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">Ano de Início</span>
<span className="modal-detalhe-value">{p.ano_inicio}</span>
</div>
)}
{p.ies_sigla && (
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">Instituição</span>
<span className="modal-detalhe-value">{p.ies_sigla}</span>
</div>
)}
{p.programa && (
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">Programa</span>
<span className="modal-detalhe-value">{p.programa}</span>
</div>
)}
{p.area && (
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">Área</span>
<span className="modal-detalhe-value">{p.area}</span>
</div>
)}
{p.linha_pesquisa && (
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">Linha de Pesquisa</span>
<span className="modal-detalhe-value">{p.linha_pesquisa}</span>
</div>
)}
</div>
);
}
case 'premiacao_lattes': {
const pr = currentItem;
return (
<div className="modal-detalhe-content">
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">Evento</span>
<span className="modal-detalhe-value">{pr.evento || pr.premio || 'N/A'}</span>
</div>
{pr.premiacao && (
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">Tipo</span>
<span className="modal-detalhe-value">{pr.premiacao}</span>
</div>
)}
{pr.ano && (
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">Ano</span>
<span className="modal-detalhe-value">{pr.ano}</span>
</div>
)}
{pr.papel && (
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">Papel</span>
<span className="modal-detalhe-value">{pr.papel}</span>
</div>
)}
{pr.situacao && (
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">Situação</span>
<span className="modal-detalhe-value">{pr.situacao}</span>
</div>
)}
{pr.ies_sigla && (
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">Instituição</span>
<span className="modal-detalhe-value">{pr.ies_sigla}</span>
</div>
)}
{pr.programa && (
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">Programa</span>
<span className="modal-detalhe-value">{pr.programa}</span>
</div>
)}
{pr.area && (
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">Área</span>
<span className="modal-detalhe-value">{pr.area}</span>
</div>
)}
{pr.produto_nome && (
<>
<h5 className="modal-section-title">Produto</h5>
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">Título</span>
<span className="modal-detalhe-value">{pr.produto_nome}</span>
</div>
{pr.produto_tipo && (
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">Tipo</span>
<span className="modal-detalhe-value">{pr.produto_tipo}</span>
</div>
)}
{pr.produto_autor && (
<div className="modal-detalhe-row">
<span className="modal-detalhe-label">Autor</span>
<span className="modal-detalhe-value">{pr.produto_autor}</span>
</div>
)}
</>
)}
</div>
);
}
case 'producoes_lattes': {
const titulacoes = item.titulacoes || [];
const idiomas = item.idiomas || [];
@@ -1013,6 +1296,162 @@ const ItemDetalheModal = ({ item, tipo, onClose }) => {
</>
)}
{item.estatisticas_orientacoes && (
<>
<h5 className="modal-section-title">Estatísticas de Orientações</h5>
<div className="modal-stats-grid">
{item.estatisticas_orientacoes.doutorado_finalizado > 0 && (
<div className="modal-stat-card">
<span className="stat-number">{item.estatisticas_orientacoes.doutorado_finalizado}</span>
<span className="stat-label">Doutorados Concluídos</span>
</div>
)}
{item.estatisticas_orientacoes.mestrado_finalizado > 0 && (
<div className="modal-stat-card">
<span className="stat-number">{item.estatisticas_orientacoes.mestrado_finalizado}</span>
<span className="stat-label">Mestrados Concluídos</span>
</div>
)}
{item.estatisticas_orientacoes.doutorado_andamento > 0 && (
<div className="modal-stat-card">
<span className="stat-number">{item.estatisticas_orientacoes.doutorado_andamento}</span>
<span className="stat-label">Doutorados em Andamento</span>
</div>
)}
{item.estatisticas_orientacoes.mestrado_andamento > 0 && (
<div className="modal-stat-card">
<span className="stat-number">{item.estatisticas_orientacoes.mestrado_andamento}</span>
<span className="stat-label">Mestrados em Andamento</span>
</div>
)}
{item.estatisticas_orientacoes.pos_doutorado > 0 && (
<div className="modal-stat-card">
<span className="stat-number">{item.estatisticas_orientacoes.pos_doutorado}</span>
<span className="stat-label">Pós-Doutorados</span>
</div>
)}
</div>
</>
)}
{item.docencias?.length > 0 && (
<>
<h5 className="modal-section-title">Docência em PPG ({item.docencias.length})</h5>
<ul className="modal-list">
{item.docencias.map((d, idx) => (
<li
key={idx}
className="modal-item modal-item-clicavel"
onClick={() => setSubDetalhe({ item: d, tipo: 'docencia' })}
>
<span className="modal-item-main">
<strong>{d.programa || 'Programa não informado'}</strong>
</span>
<span className="modal-item-detail">
{d.ies_sigla} | {d.modalidade} | {d.categoria}
</span>
{d.linhas_pesquisa_ativas?.length > 0 && (
<span className="modal-item-sub muted">
{d.linhas_pesquisa_ativas.length} linhas de pesquisa ativas
</span>
)}
<span className="modal-item-arrow"></span>
</li>
))}
</ul>
</>
)}
{item.empregos?.length > 0 && (
<>
<h5 className="modal-section-title">Vínculos Empregatícios ({item.empregos.length})</h5>
<ul className="modal-list">
{item.empregos.map((e, idx) => (
<li
key={idx}
className="modal-item modal-item-clicavel"
onClick={() => setSubDetalhe({ item: e, tipo: 'emprego' })}
>
<span className="modal-item-main">{e.empregador || 'Empregador não informado'}</span>
<span className="modal-item-detail">
{e.tipo_emprego}
{e.atividade && ` | ${e.atividade}`}
</span>
{e.periodos?.length > 0 && (
<span className="modal-item-sub muted">
{e.periodos.length} período(s) registrado(s)
</span>
)}
<span className="modal-item-arrow"></span>
</li>
))}
</ul>
</>
)}
{item.projetos?.length > 0 && (
<>
<h5 className="modal-section-title">
Projetos de Pesquisa ({item.total_projetos})
</h5>
<ul className="modal-list">
{item.projetos.slice(0, 10).map((p, idx) => (
<li
key={idx}
className="modal-item modal-item-clicavel"
onClick={() => setSubDetalhe({ item: p, tipo: 'projeto' })}
>
<span className="modal-item-main">
{p.nome?.length > 60 ? p.nome.substring(0, 60) + '...' : p.nome}
</span>
<span className="modal-item-detail">
{p.situacao}
{p.ano_inicio && ` | Início: ${p.ano_inicio}`}
{p.ies_sigla && ` | ${p.ies_sigla}`}
</span>
<span className="modal-item-arrow"></span>
</li>
))}
{item.total_projetos > 10 && (
<li className="modal-item muted">
... e mais {item.total_projetos - 10} projetos
</li>
)}
</ul>
</>
)}
{item.premiacoes_detalhadas?.length > 0 && (
<>
<h5 className="modal-section-title">Premiações Detalhadas ({item.premiacoes_detalhadas.length})</h5>
<ul className="modal-list">
{item.premiacoes_detalhadas.map((pr, idx) => (
<li
key={idx}
className="modal-item modal-item-clicavel"
onClick={() => setSubDetalhe({ item: pr, tipo: 'premiacao_lattes' })}
>
<span className="modal-item-main">
<strong>{pr.evento || pr.premio}</strong>
{pr.premiacao && ` - ${pr.premiacao}`}
</span>
<span className="modal-item-detail">
{pr.papel && `${pr.papel} | `}
{pr.ano}
{pr.ies_sigla && ` | ${pr.ies_sigla}`}
</span>
{pr.produto_nome && (
<span className="modal-item-sub muted" style={{ fontSize: '0.75rem' }}>
{pr.produto_nome.length > 60 ? pr.produto_nome.substring(0, 60) + '...' : pr.produto_nome}
</span>
)}
<span className="modal-item-arrow"></span>
</li>
))}
</ul>
</>
)}
{endereco && (
<>
<h5 className="modal-section-title">Endereço Profissional</h5>
@@ -1030,7 +1469,8 @@ const ItemDetalheModal = ({ item, tipo, onClose }) => {
</>
)}
{titulacoes.length === 0 && idiomas.length === 0 && orientacoes.length === 0 && (
{titulacoes.length === 0 && idiomas.length === 0 && orientacoes.length === 0 &&
!item.docencias?.length && !item.projetos?.length && !item.premiacoes_detalhadas?.length && (
<p className="modal-empty">Dados detalhados não disponíveis no ATUACAPES.</p>
)}
</div>
@@ -1953,27 +2393,6 @@ const ConsultorCard = memo(({ consultor, highlight, selecionado, onToggleSelecio
<span className="lattes-external"></span>
</a>
<div className="titulacoes-resumo">
{consultor.lattes.titulacoes
?.sort((a, b) => {
const ordem = { 'Pos-Doutorado': 1, 'Doutorado': 2, 'Mestrado': 3, 'Graduacao': 4 };
return (ordem[a.grau] || 99) - (ordem[b.grau] || 99);
})
.map((t, idx) => (
<span
key={idx}
className="titulacao-badge titulacao-clicavel"
onClick={(e) => {
e.stopPropagation();
setItemDetalhe({
item: t,
tipo: 'titulacao'
});
}}
title={`${t.grau}${t.area ? ` em ${t.area}` : ''}${t.ies_nome ? ` - ${t.ies_nome}` : ''}${t.pais ? ` (${t.pais})` : ''}`}
>
{t.grau}{t.ies_sigla ? ` (${t.ies_sigla})` : ''}{t.ano ? ` - ${t.ano}` : ''}
</span>
))}
<span
className="titulacao-badge titulacao-clicavel lattes-producoes"
title="Ver producoes do Lattes"
@@ -1998,6 +2417,27 @@ const ConsultorCard = memo(({ consultor, highlight, selecionado, onToggleSelecio
>
📚 Producoes
</span>
{consultor.lattes.titulacoes
?.sort((a, b) => {
const ordem = { 'Pos-Doutorado': 1, 'Doutorado': 2, 'Mestrado': 3, 'Graduacao': 4, 'Bacharelado': 5 };
return (ordem[a.grau] || 99) - (ordem[b.grau] || 99);
})
.map((t, idx) => (
<span
key={idx}
className="titulacao-badge titulacao-clicavel"
onClick={(e) => {
e.stopPropagation();
setItemDetalhe({
item: t,
tipo: 'titulacao'
});
}}
title={`Clique para detalhes: ${t.grau}${t.area ? ` em ${t.area}` : ''}${t.programa ? ` (${t.programa})` : ''}${t.ies_nome ? ` - ${t.ies_nome}` : ''}`}
>
{t.grau}{t.ies_sigla ? ` (${t.ies_sigla})` : ''}{t.ano ? ` - ${t.ano}` : ''}
</span>
))}
</div>
</div>
</div>