fix(selos): corrigir geração de selos e adicionar ícones visuais
- Corrigir extração de orientações (tipo "Orientação de Discentes") - Selos de premiação agora usam campo papel (Autor/Orientador/Coorientador) - Adicionar ícones visuais aos selos (emojis Unicode) - Adicionar estilos CSS para novos tipos de selos - Melhorias no Oracle client e ranking repository
This commit is contained in:
@@ -594,10 +594,17 @@
|
||||
color: #7dd3fc;
|
||||
}
|
||||
|
||||
.selo-orient-prem {
|
||||
background: linear-gradient(135deg, rgba(14, 165, 233, 0.35), rgba(251, 191, 36, 0.2));
|
||||
border-color: rgba(251, 191, 36, 0.5);
|
||||
color: #fcd34d;
|
||||
.selo-orient-prem,
|
||||
.selo-orient-premio {
|
||||
background: linear-gradient(135deg, rgba(14, 165, 233, 0.35), rgba(249, 115, 22, 0.2));
|
||||
border-color: rgba(249, 115, 22, 0.5);
|
||||
color: #fdba74;
|
||||
}
|
||||
|
||||
.selo-orient-mencao {
|
||||
background: linear-gradient(135deg, rgba(14, 165, 233, 0.25), rgba(203, 213, 225, 0.15));
|
||||
border-color: rgba(203, 213, 225, 0.4);
|
||||
color: #e2e8f0;
|
||||
}
|
||||
|
||||
.selo-coorient {
|
||||
@@ -606,10 +613,17 @@
|
||||
color: #a5b4fc;
|
||||
}
|
||||
|
||||
.selo-coorient-prem {
|
||||
background: linear-gradient(135deg, rgba(99, 102, 241, 0.35), rgba(251, 191, 36, 0.2));
|
||||
border-color: rgba(251, 191, 36, 0.5);
|
||||
color: #fcd34d;
|
||||
.selo-coorient-prem,
|
||||
.selo-coorient-premio {
|
||||
background: linear-gradient(135deg, rgba(99, 102, 241, 0.35), rgba(249, 115, 22, 0.2));
|
||||
border-color: rgba(249, 115, 22, 0.5);
|
||||
color: #fdba74;
|
||||
}
|
||||
|
||||
.selo-coorient-mencao {
|
||||
background: linear-gradient(135deg, rgba(99, 102, 241, 0.25), rgba(203, 213, 225, 0.15));
|
||||
border-color: rgba(203, 213, 225, 0.4);
|
||||
color: #e2e8f0;
|
||||
}
|
||||
|
||||
.selos-section {
|
||||
|
||||
@@ -2,24 +2,24 @@ import React, { useState, useRef, useEffect } from 'react';
|
||||
import './ConsultorCard.css';
|
||||
|
||||
const SELOS = {
|
||||
PRESID_CAMARA: { label: 'Presidente Câmara Temática', cor: 'selo-camara', icone: '🏛️' },
|
||||
COORD_PPG: { label: 'Coordenador de PPG', cor: 'selo-coord', icone: '🎓' },
|
||||
BPQ: { label: 'BPQ', cor: 'selo-bpq', icone: '🔬' },
|
||||
AUTOR_GP: { label: 'Autor - Grande Prêmio', cor: 'selo-gp', icone: '🏆' },
|
||||
AUTOR_PREMIO: { label: 'Autor - Prêmio', cor: 'selo-premio', icone: '🥇' },
|
||||
AUTOR_MENCAO: { label: 'Autor - Menção Honrosa', cor: 'selo-mencao', icone: '🎖️' },
|
||||
ORIENT_POS_DOC: { label: 'Orient. Pós-Doc', cor: 'selo-orient', icone: '📚' },
|
||||
ORIENT_POS_DOC_PREM: { label: 'Orient. Pós-Doc Premiada', cor: 'selo-orient-prem', icone: '📚🏆' },
|
||||
ORIENT_TESE: { label: 'Orient. Tese', cor: 'selo-orient', icone: '📖' },
|
||||
ORIENT_TESE_PREM: { label: 'Orient. Tese Premiada', cor: 'selo-orient-prem', icone: '📖🏆' },
|
||||
ORIENT_DISS: { label: 'Orient. Dissertação', cor: 'selo-orient', icone: '📝' },
|
||||
ORIENT_DISS_PREM: { label: 'Orient. Diss. Premiada', cor: 'selo-orient-prem', icone: '📝🏆' },
|
||||
CO_ORIENT_POS_DOC: { label: 'Co-Orient. Pós-Doc', cor: 'selo-coorient', icone: '📚' },
|
||||
CO_ORIENT_POS_DOC_PREM: { label: 'Co-Orient. Pós-Doc Prem.', cor: 'selo-coorient-prem', icone: '📚🏆' },
|
||||
CO_ORIENT_TESE: { label: 'Co-Orient. Tese', cor: 'selo-coorient', icone: '📖' },
|
||||
CO_ORIENT_TESE_PREM: { label: 'Co-Orient. Tese Premiada', cor: 'selo-coorient-prem', icone: '📖🏆' },
|
||||
CO_ORIENT_DISS: { label: 'Co-Orient. Diss.', cor: 'selo-coorient', icone: '📝' },
|
||||
CO_ORIENT_DISS_PREM: { label: 'Co-Orient. Diss. Prem.', cor: 'selo-coorient-prem', icone: '📝🏆' },
|
||||
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: '🔬' },
|
||||
};
|
||||
|
||||
const gerarSelos = (consultor) => {
|
||||
@@ -29,11 +29,11 @@ const gerarSelos = (consultor) => {
|
||||
(c) => c.codigo === 'CAM' && c.presidente && (c.ativo ?? !c.fim)
|
||||
);
|
||||
if (isPresidCamaraVigente) {
|
||||
selos.push({ ...SELOS.PRESID_CAMARA, qtd: 1, hint: 'Presidente Câmara Temática: mandato vigente como presidente.' });
|
||||
selos.push({ ...SELOS.PRESID_CAMARA, qtd: 1, hint: 'Presidente Câmara Temática' });
|
||||
}
|
||||
|
||||
if (consultor.coordenador_ppg) {
|
||||
selos.push({ ...SELOS.COORD_PPG, qtd: 1, hint: 'Coordenador de PPG: possui perfil/atuação de coordenação de programa no ATUACAPES.' });
|
||||
selos.push({ ...SELOS.COORD_PPG, qtd: 1, hint: 'Coordenador de PPG' });
|
||||
}
|
||||
|
||||
const bolsas = Array.isArray(consultor.bolsas_cnpq) ? consultor.bolsas_cnpq : [];
|
||||
@@ -43,68 +43,45 @@ const gerarSelos = (consultor) => {
|
||||
const nivel = (b.nivel || 'N/A').toString().trim();
|
||||
porNivel[nivel] = (porNivel[nivel] || 0) + 1;
|
||||
}
|
||||
const niveis = Object.keys(porNivel);
|
||||
const niveis = Object.keys(porNivel).sort();
|
||||
const label = niveis.length === 1 ? `BPQ ${niveis[0]}` : 'BPQ';
|
||||
const breakdown = niveis
|
||||
.sort()
|
||||
.map((n) => `${n}=${porNivel[n]}`)
|
||||
.join(' | ');
|
||||
selos.push({ ...SELOS.BPQ, label, qtd: bolsas.length, hint: `BPQ NIVEL: ${breakdown}` });
|
||||
const niveisStr = niveis.join(', ');
|
||||
selos.push({ ...SELOS.BPQ, label, qtd: bolsas.length, hint: `BPQ NIVEL ${niveisStr}` });
|
||||
}
|
||||
|
||||
const premiacoes = Array.isArray(consultor.premiacoes) ? consultor.premiacoes : [];
|
||||
const premiacoesAutor = premiacoes.filter((p) => (p.papel || '').toString().toLowerCase() === 'autor');
|
||||
const autorGp = premiacoesAutor.filter((p) => p.codigo === 'PREMIACAO').length;
|
||||
const autorPremio = premiacoesAutor.filter((p) => p.codigo === 'PREMIACAO_GP').length;
|
||||
const autorMencao = premiacoesAutor.filter((p) => p.codigo === 'MENCAO').length;
|
||||
|
||||
if (autorGp > 0) selos.push({ ...SELOS.AUTOR_GP, qtd: autorGp, hint: `Autor - Grande Prêmio: ${autorGp} ocorrência(s).` });
|
||||
if (autorPremio > 0) selos.push({ ...SELOS.AUTOR_PREMIO, qtd: autorPremio, hint: `Autor - Prêmio: ${autorPremio} ocorrência(s).` });
|
||||
if (autorMencao > 0) selos.push({ ...SELOS.AUTOR_MENCAO, qtd: autorMencao, hint: `Autor - Menção Honrosa: ${autorMencao} ocorrência(s).` });
|
||||
const gerarSelosPorPapel = (papel, seloGP, seloPremio, seloMencao, hintPrefix) => {
|
||||
const lista = premiacoes.filter((p) => (p.papel || '').toString().toLowerCase() === papel.toLowerCase());
|
||||
const gp = lista.filter((p) => p.codigo === 'PREMIACAO').length;
|
||||
const premio = lista.filter((p) => p.codigo === 'PREMIACAO_GP').length;
|
||||
const mencao = lista.filter((p) => p.codigo === 'MENCAO').length;
|
||||
|
||||
if (gp > 0) selos.push({ ...seloGP, qtd: gp, hint: `${hintPrefix} - Grande Prêmio` });
|
||||
if (premio > 0) selos.push({ ...seloPremio, qtd: premio, hint: `${hintPrefix} - Prêmio` });
|
||||
if (mencao > 0) selos.push({ ...seloMencao, qtd: mencao, hint: `${hintPrefix} - Menção Honrosa` });
|
||||
};
|
||||
|
||||
gerarSelosPorPapel('autor', SELOS.AUTOR_GP, SELOS.AUTOR_PREMIO, SELOS.AUTOR_MENCAO, 'Autor');
|
||||
gerarSelosPorPapel('orientador', SELOS.ORIENT_GP, SELOS.ORIENT_PREMIO, SELOS.ORIENT_MENCAO, 'Orientador');
|
||||
gerarSelosPorPapel('coorientador', SELOS.COORIENT_GP, SELOS.COORIENT_PREMIO, SELOS.COORIENT_MENCAO, 'Coorientador');
|
||||
|
||||
const orientacoes = Array.isArray(consultor.orientacoes) ? consultor.orientacoes : [];
|
||||
const contarPremiadas = (lista) => {
|
||||
const acc = { GP: 0, PREMIO: 0, MENCAO: 0 };
|
||||
for (const o of lista) {
|
||||
if (!o?.premiada) continue;
|
||||
const t = (o.premiacao_tipo || '').toString().toUpperCase();
|
||||
if (t.includes('GP')) acc.GP += 1;
|
||||
else if (t.includes('MENCAO')) acc.MENCAO += 1;
|
||||
else acc.PREMIO += 1;
|
||||
}
|
||||
return acc;
|
||||
};
|
||||
const hintPremiadas = (labelBase, counts) =>
|
||||
`${labelBase} (GP / Prêmio / Menção): GP=${counts.GP} | Prêmio=${counts.PREMIO} | Menção=${counts.MENCAO}`;
|
||||
|
||||
const selosOrientacao = (codigo, seloNormal, seloPrem) => {
|
||||
const base = orientacoes.filter((o) => o.codigo === codigo && !o.coorientacao);
|
||||
const prem = base.filter((o) => o.premiada);
|
||||
const naoPrem = base.filter((o) => !o.premiada);
|
||||
if (prem.length > 0) {
|
||||
selos.push({ ...seloPrem, qtd: prem.length, hint: hintPremiadas(seloPrem.label, contarPremiadas(prem)) });
|
||||
} else if (naoPrem.length > 0) {
|
||||
selos.push({ ...seloNormal, qtd: naoPrem.length, hint: `${seloNormal.label}: ${naoPrem.length} ocorrência(s).` });
|
||||
const gerarSelosOrientacaoContagem = (codigo, isCoorientacao, seloBase) => {
|
||||
const lista = orientacoes.filter((o) => o.codigo === codigo && (isCoorientacao ? o.coorientacao : !o.coorientacao));
|
||||
if (lista.length > 0) {
|
||||
selos.push({ ...seloBase, qtd: lista.length, hint: `${seloBase.label} (${lista.length}x)` });
|
||||
}
|
||||
};
|
||||
|
||||
const selosCoorientacao = (codigo, seloNormal, seloPrem) => {
|
||||
const base = orientacoes.filter((o) => o.codigo === codigo && o.coorientacao);
|
||||
const prem = base.filter((o) => o.premiada);
|
||||
const naoPrem = base.filter((o) => !o.premiada);
|
||||
if (prem.length > 0) {
|
||||
selos.push({ ...seloPrem, qtd: prem.length, hint: hintPremiadas(seloPrem.label, contarPremiadas(prem)) });
|
||||
} else if (naoPrem.length > 0) {
|
||||
selos.push({ ...seloNormal, qtd: naoPrem.length, hint: `${seloNormal.label}: ${naoPrem.length} ocorrência(s).` });
|
||||
}
|
||||
};
|
||||
gerarSelosOrientacaoContagem('ORIENT_POS_DOC', false, SELOS.ORIENT_POS_DOC);
|
||||
gerarSelosOrientacaoContagem('ORIENT_TESE', false, SELOS.ORIENT_TESE);
|
||||
gerarSelosOrientacaoContagem('ORIENT_DISS', false, SELOS.ORIENT_DISS);
|
||||
|
||||
selosOrientacao('ORIENT_POS_DOC', SELOS.ORIENT_POS_DOC, SELOS.ORIENT_POS_DOC_PREM);
|
||||
selosOrientacao('ORIENT_TESE', SELOS.ORIENT_TESE, SELOS.ORIENT_TESE_PREM);
|
||||
selosOrientacao('ORIENT_DISS', SELOS.ORIENT_DISS, SELOS.ORIENT_DISS_PREM);
|
||||
selosCoorientacao('CO_ORIENT_POS_DOC', SELOS.CO_ORIENT_POS_DOC, SELOS.CO_ORIENT_POS_DOC_PREM);
|
||||
selosCoorientacao('CO_ORIENT_TESE', SELOS.CO_ORIENT_TESE, SELOS.CO_ORIENT_TESE_PREM);
|
||||
selosCoorientacao('CO_ORIENT_DISS', SELOS.CO_ORIENT_DISS, SELOS.CO_ORIENT_DISS_PREM);
|
||||
gerarSelosOrientacaoContagem('CO_ORIENT_POS_DOC', true, SELOS.CO_ORIENT_POS_DOC);
|
||||
gerarSelosOrientacaoContagem('CO_ORIENT_TESE', true, SELOS.CO_ORIENT_TESE);
|
||||
gerarSelosOrientacaoContagem('CO_ORIENT_DISS', true, SELOS.CO_ORIENT_DISS);
|
||||
|
||||
return selos;
|
||||
};
|
||||
@@ -146,11 +123,11 @@ const FORMULAS = {
|
||||
},
|
||||
bloco_c: {
|
||||
titulo: 'Consultoria',
|
||||
descricao: 'CONS_ATIVO=150 | CONS_HIST=100 | CONS_FALECIDO=100\nTempo: 5 pts/ano (max 50)\nContinuidade (escalonado): 3a=+5 | 5a=+10 | 8a+=+15\nRetorno (reativação): +15 (uma vez)',
|
||||
descricao: 'CONS_ATIVO=150 | CONS_HIST=100 | CONS_FALECIDO=100\nTempo: 5 pts/ano (max 50)\nContinuidade 8a+=+20 (escalonado)\nRetorno (reativação): +15 (uma vez)',
|
||||
},
|
||||
bloco_d: {
|
||||
titulo: 'Premiacoes/Avaliacoes',
|
||||
descricao: 'Premiações: GP=150 (teto 180) | Prêmio=30 (teto 60) | Menção=10 (teto 20)\nBolsas: BPQ_SUP=30 (teto 60) | BPQ_INT=50 (teto 100)\nInscrições/Avaliações/Comissões/Participações/Orientações/Bancas (com tetos por código)',
|
||||
descricao: 'Premiações: GP=100 (teto 180) | Prêmio=50 (teto 60) | Menção=30 (teto 30)\nBolsas: BPQ_SUP=30 (teto 60) | BPQ_INT=50 (teto 100)\nInscrições/Avaliações/Comissões/Participações/Orientações/Bancas (com tetos por código)',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -160,7 +137,7 @@ const PONTOS_BASE = {
|
||||
INSC_AUTOR: 10, INSC_INST: 30,
|
||||
AVAL_COMIS_PREMIO: 30, AVAL_COMIS_GP: 50,
|
||||
COORD_COMIS_PREMIO: 50, COORD_COMIS_GP: 60,
|
||||
PREMIACAO: 150, PREMIACAO_GP: 30, MENCAO: 10,
|
||||
PREMIACAO: 100, PREMIACAO_GP: 50, MENCAO: 30,
|
||||
BOL_BPQ_SUP: 30, BOL_BPQ_INT: 50,
|
||||
BOL_BPQ_SUPERIOR: 30, BOL_BPQ_INTERMEDIARIO: 50,
|
||||
EVENTO: 1, PROJ: 10,
|
||||
@@ -173,12 +150,12 @@ const TETOS = {
|
||||
INSC_AUTOR: { teto: 20, doc: '3.3 Inscrições' },
|
||||
INSC_INST: { teto: 60, doc: '3.3 Inscrições' },
|
||||
AVAL_COMIS_PREMIO: { teto: 60, doc: '3.4 Avaliação/Comissão', bonus: '+2/ano (max 15)' },
|
||||
AVAL_COMIS_GP: { teto: 100, doc: '3.4 Avaliação/Comissão', bonus: '+3/ano (max 20)' },
|
||||
AVAL_COMIS_GP: { teto: 80, doc: '3.4 Avaliação/Comissão', bonus: '+3/ano (max 20)' },
|
||||
COORD_COMIS_PREMIO: { teto: 100, doc: '3.4 Avaliação/Comissão', bonus: '+4/ano (max 20)' },
|
||||
COORD_COMIS_GP: { teto: 120, doc: '3.4 Avaliação/Comissão', bonus: '+6/ano (max 20)' },
|
||||
PREMIACAO: { teto: 180, doc: '3.4 Premiações e Bolsas' },
|
||||
PREMIACAO_GP: { teto: 60, doc: '3.4 Premiações e Bolsas' },
|
||||
MENCAO: { teto: 20, doc: '3.4 Premiações e Bolsas' },
|
||||
MENCAO: { teto: 30, doc: '3.4 Premiações e Bolsas' },
|
||||
EVENTO: { teto: 5, doc: '3.5 Participações Acadêmicas' },
|
||||
PROJ: { teto: 40, doc: '3.5 Participações Acadêmicas' },
|
||||
BOL_BPQ_SUP: { teto: 60, doc: '3.4 Premiações e Bolsas' },
|
||||
|
||||
Reference in New Issue
Block a user