feat(frontend): adicionar modais detalhados para cada bloco de criterios
- Criar BlocoCriteriosModal com dados completos da planilha oficial - Incluir formula, base, teto, tempo, bonus e recorrencias por bloco - Tornar blocos clicaveis para abrir modal com informacoes detalhadas - Bloco A: Coordenacao CAPES com bonus atualidade/retorno - Bloco B: Consultoria com bonus continuidade/retorno - Bloco C: Premiacoes, Comissoes, Inscricoes com recorrencias - Bloco D: Indicadores e selos (idioma, titulacao) - Bloco E: Explicacao do indicador PPG_COORD
This commit is contained in:
476
frontend/src/components/BlocoCriteriosModal.css
Normal file
476
frontend/src/components/BlocoCriteriosModal.css
Normal file
@@ -0,0 +1,476 @@
|
|||||||
|
.bloco-modal-overlay {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
background: rgba(0, 0, 0, 0.75);
|
||||||
|
backdrop-filter: blur(4px);
|
||||||
|
-webkit-backdrop-filter: blur(4px);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
z-index: 9999;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-modal {
|
||||||
|
background: linear-gradient(145deg, rgba(30, 30, 46, 0.98), rgba(24, 24, 36, 0.98));
|
||||||
|
border-radius: 16px;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 680px;
|
||||||
|
max-height: 85vh;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-modal-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 1rem 1.25rem;
|
||||||
|
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-modal-header::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-modal.bloco-a .bloco-modal-header::before {
|
||||||
|
background: linear-gradient(90deg, #6366f1, #818cf8, #6366f1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-modal.bloco-b .bloco-modal-header::before {
|
||||||
|
background: linear-gradient(90deg, #eab308, #fbbf24, #eab308);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-modal.bloco-c .bloco-modal-header::before {
|
||||||
|
background: linear-gradient(90deg, #10b981, #34d399, #10b981);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-modal.bloco-d .bloco-modal-header::before {
|
||||||
|
background: linear-gradient(90deg, #d97706, #f59e0b, #d97706);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-modal.bloco-e .bloco-modal-header::before {
|
||||||
|
background: linear-gradient(90deg, #8b5cf6, #a78bfa, #8b5cf6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-modal-titulo {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-letra {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
border-radius: 8px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-modal.bloco-a .bloco-letra {
|
||||||
|
background: rgba(99, 102, 241, 0.25);
|
||||||
|
color: #a5b4fc;
|
||||||
|
border: 1px solid rgba(99, 102, 241, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-modal.bloco-b .bloco-letra {
|
||||||
|
background: rgba(234, 179, 8, 0.25);
|
||||||
|
color: #fcd34d;
|
||||||
|
border: 1px solid rgba(234, 179, 8, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-modal.bloco-c .bloco-letra {
|
||||||
|
background: rgba(16, 185, 129, 0.25);
|
||||||
|
color: #6ee7b7;
|
||||||
|
border: 1px solid rgba(16, 185, 129, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-modal.bloco-d .bloco-letra {
|
||||||
|
background: rgba(217, 119, 6, 0.25);
|
||||||
|
color: #fbbf24;
|
||||||
|
border: 1px solid rgba(217, 119, 6, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-modal.bloco-e .bloco-letra {
|
||||||
|
background: rgba(139, 92, 246, 0.25);
|
||||||
|
color: #c4b5fd;
|
||||||
|
border: 1px solid rgba(139, 92, 246, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-nome {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-modal-close {
|
||||||
|
background: rgba(255, 255, 255, 0.1);
|
||||||
|
border: none;
|
||||||
|
color: var(--silver);
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
border-radius: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 1rem;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-modal-close:hover {
|
||||||
|
background: rgba(239, 68, 68, 0.3);
|
||||||
|
color: #fca5a5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-modal-body {
|
||||||
|
padding: 1.25rem;
|
||||||
|
overflow-y: auto;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-descricao {
|
||||||
|
color: var(--silver);
|
||||||
|
font-size: 0.9rem;
|
||||||
|
margin: 0 0 1rem 0;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-formula {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
padding: 0.75rem 1rem;
|
||||||
|
background: rgba(255, 255, 255, 0.05);
|
||||||
|
border-radius: 8px;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.formula-label {
|
||||||
|
color: var(--muted);
|
||||||
|
font-size: 0.8rem;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-formula code {
|
||||||
|
color: #60a5fa;
|
||||||
|
font-family: 'JetBrains Mono', 'Fira Code', monospace;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
background: rgba(96, 165, 250, 0.1);
|
||||||
|
padding: 0.2rem 0.5rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-nota-destaque {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
padding: 0.75rem 1rem;
|
||||||
|
background: rgba(234, 179, 8, 0.15);
|
||||||
|
border: 1px solid rgba(234, 179, 8, 0.3);
|
||||||
|
border-radius: 8px;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
color: #fcd34d;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nota-icon {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-secao {
|
||||||
|
margin-bottom: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-secao h4 {
|
||||||
|
color: var(--accent-2);
|
||||||
|
font-size: 0.85rem;
|
||||||
|
font-weight: 600;
|
||||||
|
margin: 0 0 0.75rem 0;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-secao h4::before {
|
||||||
|
content: "";
|
||||||
|
width: 3px;
|
||||||
|
height: 14px;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-modal.bloco-a .bloco-secao h4::before {
|
||||||
|
background: #6366f1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-modal.bloco-b .bloco-secao h4::before {
|
||||||
|
background: #eab308;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-modal.bloco-c .bloco-secao h4::before {
|
||||||
|
background: #10b981;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-modal.bloco-d .bloco-secao h4::before {
|
||||||
|
background: #d97706;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-modal.bloco-e .bloco-secao h4::before {
|
||||||
|
background: #8b5cf6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-tabela {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-tabela th {
|
||||||
|
text-align: left;
|
||||||
|
padding: 0.5rem 0.75rem;
|
||||||
|
background: rgba(255, 255, 255, 0.05);
|
||||||
|
color: var(--silver);
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.3px;
|
||||||
|
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-tabela td {
|
||||||
|
padding: 0.5rem 0.75rem;
|
||||||
|
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
|
||||||
|
color: var(--muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-tabela tr:last-child td {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-tabela td.cod {
|
||||||
|
color: var(--silver);
|
||||||
|
font-weight: 600;
|
||||||
|
font-family: 'JetBrains Mono', monospace;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-tabela td.num {
|
||||||
|
text-align: center;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-modal.bloco-a .bloco-tabela td.num {
|
||||||
|
color: #a5b4fc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-modal.bloco-b .bloco-tabela td.num {
|
||||||
|
color: #fcd34d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-modal.bloco-c .bloco-tabela td.num {
|
||||||
|
color: #6ee7b7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-modal.bloco-d .bloco-tabela td.num {
|
||||||
|
color: #fbbf24;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-modal.bloco-e .bloco-tabela td.num {
|
||||||
|
color: #c4b5fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-tabela td.tempo,
|
||||||
|
.bloco-tabela td.rec {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
color: var(--silver);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonus-lista {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.75rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonus-item {
|
||||||
|
padding: 0.75rem;
|
||||||
|
background: rgba(255, 255, 255, 0.03);
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonus-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonus-tipo {
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--accent-2);
|
||||||
|
font-size: 0.85rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonus-valor {
|
||||||
|
background: rgba(16, 185, 129, 0.2);
|
||||||
|
color: #6ee7b7;
|
||||||
|
padding: 0.15rem 0.5rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonus-descricao {
|
||||||
|
color: var(--silver);
|
||||||
|
font-size: 0.8rem;
|
||||||
|
margin: 0 0 0.35rem 0;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonus-condicao {
|
||||||
|
color: var(--muted);
|
||||||
|
font-size: 0.75rem;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonus-condicao strong {
|
||||||
|
color: var(--silver);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonus-valores {
|
||||||
|
margin-top: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selos-grid {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selo-grupo {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
padding: 0.5rem 0.75rem;
|
||||||
|
background: rgba(255, 255, 255, 0.03);
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selo-grupo-nome {
|
||||||
|
color: var(--silver);
|
||||||
|
font-size: 0.8rem;
|
||||||
|
font-weight: 500;
|
||||||
|
min-width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selo-itens {
|
||||||
|
color: var(--muted);
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selo-item-detalhe {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.75rem;
|
||||||
|
padding: 0.4rem 0.75rem;
|
||||||
|
background: rgba(255, 255, 255, 0.03);
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selo-cod {
|
||||||
|
font-family: 'JetBrains Mono', monospace;
|
||||||
|
font-size: 0.7rem;
|
||||||
|
color: var(--silver);
|
||||||
|
background: rgba(255, 255, 255, 0.08);
|
||||||
|
padding: 0.15rem 0.4rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selo-nome {
|
||||||
|
color: var(--silver);
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selo-obs {
|
||||||
|
color: var(--muted);
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detalhes-lista {
|
||||||
|
margin: 0;
|
||||||
|
padding-left: 1.25rem;
|
||||||
|
color: var(--muted);
|
||||||
|
font-size: 0.85rem;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detalhes-lista li {
|
||||||
|
margin-bottom: 0.35rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-observacoes {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 0.5rem;
|
||||||
|
padding: 0.75rem 1rem;
|
||||||
|
background: rgba(96, 165, 250, 0.1);
|
||||||
|
border: 1px solid rgba(96, 165, 250, 0.2);
|
||||||
|
border-radius: 8px;
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.obs-icon {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-observacoes span:last-child {
|
||||||
|
color: var(--silver);
|
||||||
|
font-size: 0.8rem;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-modal-footer {
|
||||||
|
padding: 0.75rem 1.25rem;
|
||||||
|
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-modal-footer small {
|
||||||
|
color: var(--muted);
|
||||||
|
font-size: 0.7rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
.bloco-modal {
|
||||||
|
max-height: 90vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-modal-body {
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-tabela {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bloco-tabela th,
|
||||||
|
.bloco-tabela td {
|
||||||
|
padding: 0.4rem 0.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
289
frontend/src/components/BlocoCriteriosModal.jsx
Normal file
289
frontend/src/components/BlocoCriteriosModal.jsx
Normal file
@@ -0,0 +1,289 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { createPortal } from 'react-dom';
|
||||||
|
import './BlocoCriteriosModal.css';
|
||||||
|
|
||||||
|
const DADOS_BLOCOS = {
|
||||||
|
A: {
|
||||||
|
titulo: 'Coordenação CAPES',
|
||||||
|
cor: 'bloco-a',
|
||||||
|
descricao: 'Funções de coordenação institucional no âmbito da CAPES',
|
||||||
|
formula: 'Score = min(Base + Tempo + Bônus, Teto)',
|
||||||
|
atuacoes: [
|
||||||
|
{ cod: 'CA', nome: 'Coordenador de Área', base: 200, teto: 450, tempo: '10 pts/ano', tetoTempo: 100, atualidade: 30, retorno: 20 },
|
||||||
|
{ cod: 'CAJ', nome: 'Coordenador Adjunto', base: 150, teto: 370, tempo: '8 pts/ano', tetoTempo: 80, atualidade: 20, retorno: 15 },
|
||||||
|
{ cod: 'CAJ_MP', nome: 'Coord. Adjunto MP', base: 120, teto: 315, tempo: '6 pts/ano', tetoTempo: 60, atualidade: 15, retorno: 10 },
|
||||||
|
{ cod: 'CAM', nome: 'Câmara Temática', base: 100, teto: 280, tempo: '5 pts/ano', tetoTempo: 50, atualidade: 20, retorno: 10 },
|
||||||
|
],
|
||||||
|
bonus: [
|
||||||
|
{ tipo: 'Atualidade', descricao: 'Mandato vigente no momento da apuração', condicao: 'Coordenação ativa (sem data fim)' },
|
||||||
|
{ tipo: 'Retorno', descricao: 'Novo mandato após período anterior concluído', condicao: 'Hiato entre mandatos' },
|
||||||
|
],
|
||||||
|
observacoes: 'Anos completos de atuação institucional. Mandatos fragmentados da mesma função são somados.',
|
||||||
|
},
|
||||||
|
B: {
|
||||||
|
titulo: 'Consultoria',
|
||||||
|
cor: 'bloco-b',
|
||||||
|
descricao: 'Atuação como consultor institucional da CAPES',
|
||||||
|
formula: 'Score = min(Base + Tempo + Bônus, Teto)',
|
||||||
|
atuacoes: [
|
||||||
|
{ cod: 'ATIVO', nome: 'Consultor Ativo', base: 150, teto: 230, tempo: '5 pts/ano', tetoTempo: 50, atualidade: 20, continuidade: 20, retorno: 15 },
|
||||||
|
{ cod: 'HIST', nome: 'Consultor Histórico', base: 100, teto: 230, tempo: '5 pts/ano', tetoTempo: 50, continuidade: 20, retorno: 20 },
|
||||||
|
{ cod: 'FALEC', nome: 'Consultor Falecido', base: 100, teto: 230, tempo: '5 pts/ano', tetoTempo: 50, continuidade: 20 },
|
||||||
|
],
|
||||||
|
bonus: [
|
||||||
|
{ tipo: 'Atualidade', descricao: 'Consultoria vigente (vínculo ativo)', condicao: 'Apenas CONS_ATIVO', valor: 20 },
|
||||||
|
{ tipo: 'Continuidade', descricao: 'Atuação contínua ≥ 8 anos consecutivos', condicao: 'Sem hiato significativo', valor: 20 },
|
||||||
|
{ tipo: 'Retorno', descricao: 'Reativação da consultoria após inatividade', condicao: 'ATIVO: +15 | HIST: +20' },
|
||||||
|
],
|
||||||
|
observacoes: 'Teto de tempo: 50 pts. Bônus de continuidade aplica-se apenas ao maior patamar atingido (≥8 anos).',
|
||||||
|
},
|
||||||
|
C: {
|
||||||
|
titulo: 'Premiações, Avaliações, Inscrições',
|
||||||
|
cor: 'bloco-c',
|
||||||
|
descricao: 'Participação em premiações, comissões avaliadoras e inscrições',
|
||||||
|
formula: 'Score = Base + Bônus Recorrência (respeitando teto)',
|
||||||
|
secoes: [
|
||||||
|
{
|
||||||
|
nome: 'Premiações (Autor)',
|
||||||
|
itens: [
|
||||||
|
{ cod: 'GP', nome: 'Grande Prêmio', base: 100, teto: 300 },
|
||||||
|
{ cod: 'PREMIO', nome: 'Prêmio', base: 50, teto: 150 },
|
||||||
|
{ cod: 'MENCAO', nome: 'Menção Honrosa', base: 30, teto: 90 },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nome: 'Comissões',
|
||||||
|
itens: [
|
||||||
|
{ cod: 'COORD_GP', nome: 'Coord. Comissão GP', base: 50, teto: 120, recorrencia: '+6 pts/ano', maxRec: 20 },
|
||||||
|
{ cod: 'COORD', nome: 'Coord. Comissão', base: 40, teto: 100, recorrencia: '+4 pts/ano', maxRec: 20 },
|
||||||
|
{ cod: 'AVAL_GP', nome: 'Avaliador GP', base: 40, teto: 80, recorrencia: '+3 pts/ano', maxRec: 20 },
|
||||||
|
{ cod: 'AVAL', nome: 'Avaliador', base: 30, teto: 60, recorrencia: '+2 pts/ano', maxRec: 15 },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nome: 'Inscrições',
|
||||||
|
itens: [
|
||||||
|
{ cod: 'INSC_INST', nome: 'Institucional (PPG)', base: 20, teto: 50, recorrencia: '+5 pts/part.', maxRec: 10 },
|
||||||
|
{ cod: 'INSC_AUTOR', nome: 'Autoinscrição', base: 10, teto: 20, recorrencia: '+2 pts/part.', maxRec: 10 },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
selos: [
|
||||||
|
{ grupo: 'Orientações', itens: ['POS_DOC', 'TESE', 'DISS'] },
|
||||||
|
{ grupo: 'Co-Orientações', itens: ['POS_DOC', 'TESE', 'DISS'] },
|
||||||
|
{ grupo: 'Bancas', itens: ['MB_POS_DOC', 'MB_TESE', 'MB_DISS'] },
|
||||||
|
],
|
||||||
|
observacoes: 'Orientações, co-orientações e bancas geram apenas selos (sem pontuação base no V1).',
|
||||||
|
},
|
||||||
|
D: {
|
||||||
|
titulo: 'Indicadores',
|
||||||
|
cor: 'bloco-d',
|
||||||
|
descricao: 'Indicadores de perfil e participações',
|
||||||
|
formula: 'Score = Base + Bônus Recorrência (respeitando teto)',
|
||||||
|
atuacoes: [
|
||||||
|
{ cod: 'BOL_BPQ', nome: 'Bolsa PQ CNPq', base: 30, teto: 60, obs: 'Reconhecimento externo' },
|
||||||
|
{ cod: 'PROJ', nome: 'Participação Projeto', base: 10, teto: 30, recorrencia: '+2 pts/part.', maxRec: 10 },
|
||||||
|
{ cod: 'EVENTO', nome: 'Participação Evento', base: 1, teto: 5, recorrencia: '+1 pt/part.', maxRec: 10 },
|
||||||
|
],
|
||||||
|
selos: [
|
||||||
|
{ cod: 'PPG_COORD', nome: 'Coordenador PPG', obs: 'Indicador (sem pontuação V1)' },
|
||||||
|
{ cod: 'IDIOMA_BILINGUE', nome: 'Bilíngue', obs: '2+ idiomas' },
|
||||||
|
{ cod: 'IDIOMA_MULTILINGUE', nome: 'Multilíngue', obs: '3+ idiomas' },
|
||||||
|
{ cod: 'TITULACAO_MESTRE', nome: 'Mestre', obs: 'Maior titulação' },
|
||||||
|
{ cod: 'TITULACAO_DOUTOR', nome: 'Doutor', obs: 'Maior titulação' },
|
||||||
|
{ cod: 'TITULACAO_POS_DOC', nome: 'Pós-Doutor', obs: 'Maior titulação' },
|
||||||
|
],
|
||||||
|
observacoes: 'Idiomas e titulações geram apenas selos de perfil, sem pontuação.',
|
||||||
|
},
|
||||||
|
E: {
|
||||||
|
titulo: 'Coordenação PPG',
|
||||||
|
cor: 'bloco-e',
|
||||||
|
descricao: 'Coordenação de Programa de Pós-Graduação',
|
||||||
|
nota: 'Não ativo no Ranking V1',
|
||||||
|
detalhes: [
|
||||||
|
'Dados incompletos no ATUACAPES para pontuação como função institucional',
|
||||||
|
'Ausência de vigência (início/fim) nos dados',
|
||||||
|
'Tratado como indicador de perfil (selo)',
|
||||||
|
'Pode ser ativado em versões futuras com dados completos',
|
||||||
|
],
|
||||||
|
observacoes: 'A pontuação depende de carga futura com datas de início e fim de gestão.',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const BlocoCriteriosModal = ({ bloco, onClose }) => {
|
||||||
|
const dados = DADOS_BLOCOS[bloco];
|
||||||
|
if (!dados) return null;
|
||||||
|
|
||||||
|
return createPortal(
|
||||||
|
<div className="bloco-modal-overlay" onClick={onClose}>
|
||||||
|
<div className={`bloco-modal ${dados.cor}`} onClick={(e) => e.stopPropagation()}>
|
||||||
|
<div className="bloco-modal-header">
|
||||||
|
<div className="bloco-modal-titulo">
|
||||||
|
<span className="bloco-letra">{bloco}</span>
|
||||||
|
<span className="bloco-nome">{dados.titulo}</span>
|
||||||
|
</div>
|
||||||
|
<button className="bloco-modal-close" onClick={onClose}>✕</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="bloco-modal-body">
|
||||||
|
<p className="bloco-descricao">{dados.descricao}</p>
|
||||||
|
|
||||||
|
{dados.formula && (
|
||||||
|
<div className="bloco-formula">
|
||||||
|
<span className="formula-label">Fórmula:</span>
|
||||||
|
<code>{dados.formula}</code>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{dados.nota && (
|
||||||
|
<div className="bloco-nota-destaque">
|
||||||
|
<span className="nota-icon">⚠️</span>
|
||||||
|
<span>{dados.nota}</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{dados.atuacoes && (
|
||||||
|
<div className="bloco-secao">
|
||||||
|
<h4>Atuações</h4>
|
||||||
|
<table className="bloco-tabela">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Código</th>
|
||||||
|
<th>Nome</th>
|
||||||
|
<th>Base</th>
|
||||||
|
<th>Teto</th>
|
||||||
|
{dados.atuacoes[0]?.tempo && <th>Tempo</th>}
|
||||||
|
{dados.atuacoes[0]?.recorrencia && <th>Recorrência</th>}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{dados.atuacoes.map((a) => (
|
||||||
|
<tr key={a.cod}>
|
||||||
|
<td className="cod">{a.cod}</td>
|
||||||
|
<td>{a.nome}</td>
|
||||||
|
<td className="num">{a.base}</td>
|
||||||
|
<td className="num">{a.teto}</td>
|
||||||
|
{a.tempo && <td className="tempo">{a.tempo} (max {a.tetoTempo})</td>}
|
||||||
|
{a.recorrencia && <td className="rec">{a.recorrencia} (max {a.maxRec})</td>}
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{dados.bonus && (
|
||||||
|
<div className="bloco-secao">
|
||||||
|
<h4>Bônus</h4>
|
||||||
|
<div className="bonus-lista">
|
||||||
|
{dados.bonus.map((b, idx) => (
|
||||||
|
<div key={idx} className="bonus-item">
|
||||||
|
<div className="bonus-header">
|
||||||
|
<span className="bonus-tipo">{b.tipo}</span>
|
||||||
|
{b.valor && <span className="bonus-valor">+{b.valor} pts</span>}
|
||||||
|
</div>
|
||||||
|
<p className="bonus-descricao">{b.descricao}</p>
|
||||||
|
<p className="bonus-condicao"><strong>Condição:</strong> {b.condicao}</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
{bloco === 'A' && (
|
||||||
|
<table className="bloco-tabela bonus-valores">
|
||||||
|
<thead>
|
||||||
|
<tr><th>Código</th><th>Atualidade</th><th>Retorno</th></tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{dados.atuacoes.map((a) => (
|
||||||
|
<tr key={a.cod}>
|
||||||
|
<td className="cod">{a.cod}</td>
|
||||||
|
<td className="num">+{a.atualidade}</td>
|
||||||
|
<td className="num">+{a.retorno}</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{dados.secoes && dados.secoes.map((secao, idx) => (
|
||||||
|
<div key={idx} className="bloco-secao">
|
||||||
|
<h4>{secao.nome}</h4>
|
||||||
|
<table className="bloco-tabela">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Código</th>
|
||||||
|
<th>Nome</th>
|
||||||
|
<th>Base</th>
|
||||||
|
<th>Teto</th>
|
||||||
|
{secao.itens[0]?.recorrencia && <th>Recorrência</th>}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{secao.itens.map((item) => (
|
||||||
|
<tr key={item.cod}>
|
||||||
|
<td className="cod">{item.cod}</td>
|
||||||
|
<td>{item.nome}</td>
|
||||||
|
<td className="num">{item.base}</td>
|
||||||
|
<td className="num">{item.teto}</td>
|
||||||
|
{item.recorrencia && <td className="rec">{item.recorrencia} (max {item.maxRec})</td>}
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
|
||||||
|
{dados.selos && (
|
||||||
|
<div className="bloco-secao">
|
||||||
|
<h4>Selos (sem pontuação)</h4>
|
||||||
|
<div className="selos-grid">
|
||||||
|
{Array.isArray(dados.selos) && dados.selos[0]?.grupo ? (
|
||||||
|
dados.selos.map((grupo, idx) => (
|
||||||
|
<div key={idx} className="selo-grupo">
|
||||||
|
<span className="selo-grupo-nome">{grupo.grupo}:</span>
|
||||||
|
<span className="selo-itens">{grupo.itens.join(', ')}</span>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
dados.selos.map((selo, idx) => (
|
||||||
|
<div key={idx} className="selo-item-detalhe">
|
||||||
|
<span className="selo-cod">{selo.cod}</span>
|
||||||
|
<span className="selo-nome">{selo.nome}</span>
|
||||||
|
{selo.obs && <span className="selo-obs">({selo.obs})</span>}
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{dados.detalhes && (
|
||||||
|
<div className="bloco-secao">
|
||||||
|
<h4>Detalhes</h4>
|
||||||
|
<ul className="detalhes-lista">
|
||||||
|
{dados.detalhes.map((d, idx) => (
|
||||||
|
<li key={idx}>{d}</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{dados.observacoes && (
|
||||||
|
<div className="bloco-observacoes">
|
||||||
|
<span className="obs-icon">ℹ️</span>
|
||||||
|
<span>{dados.observacoes}</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="bloco-modal-footer">
|
||||||
|
<small>Fonte: Ranking ATUACAPES V1.0 - Planilha Oficial de Critérios</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>,
|
||||||
|
document.body
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default BlocoCriteriosModal;
|
||||||
@@ -154,6 +154,21 @@
|
|||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.criteria-section.clickable {
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.criteria-section.clickable * {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.criteria-section.clickable:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.06);
|
||||||
|
border-color: rgba(255, 255, 255, 0.2);
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
.criteria-section h4 {
|
.criteria-section h4 {
|
||||||
color: var(--accent-2);
|
color: var(--accent-2);
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import React from 'react';
|
import React, { useState } from 'react';
|
||||||
import './Header.css';
|
import './Header.css';
|
||||||
|
import BlocoCriteriosModal from './BlocoCriteriosModal';
|
||||||
|
|
||||||
const Header = ({ total }) => {
|
const Header = ({ total }) => {
|
||||||
|
const [modalBloco, setModalBloco] = useState(null);
|
||||||
const dataGeracao = new Date().toLocaleDateString('pt-BR');
|
const dataGeracao = new Date().toLocaleDateString('pt-BR');
|
||||||
const totalFormatado = new Intl.NumberFormat('pt-BR', {
|
const totalFormatado = new Intl.NumberFormat('pt-BR', {
|
||||||
maximumFractionDigits: 0,
|
maximumFractionDigits: 0,
|
||||||
@@ -25,7 +27,7 @@ const Header = ({ total }) => {
|
|||||||
<h3>Criterios de Pontuacao</h3>
|
<h3>Criterios de Pontuacao</h3>
|
||||||
|
|
||||||
<div className="criteria-row">
|
<div className="criteria-row">
|
||||||
<div className="criteria-section bloco-a">
|
<div className="criteria-section bloco-a clickable" onClick={() => setModalBloco('A')}>
|
||||||
<div className="section-header">
|
<div className="section-header">
|
||||||
<h4>A - Coordenacao CAPES</h4>
|
<h4>A - Coordenacao CAPES</h4>
|
||||||
<span className="max-pts">max 450</span>
|
<span className="max-pts">max 450</span>
|
||||||
@@ -43,7 +45,7 @@ const Header = ({ total }) => {
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="criteria-section bloco-b">
|
<div className="criteria-section bloco-b clickable" onClick={() => setModalBloco('B')}>
|
||||||
<div className="section-header">
|
<div className="section-header">
|
||||||
<h4>B - Consultoria</h4>
|
<h4>B - Consultoria</h4>
|
||||||
<span className="max-pts">max 230</span>
|
<span className="max-pts">max 230</span>
|
||||||
@@ -61,7 +63,7 @@ const Header = ({ total }) => {
|
|||||||
<div className="criteria-note">At=20 Ct=20 Rt=15-20 | Teto tempo: 50</div>
|
<div className="criteria-note">At=20 Ct=20 Rt=15-20 | Teto tempo: 50</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="criteria-section bloco-e">
|
<div className="criteria-section bloco-e clickable" onClick={() => setModalBloco('E')}>
|
||||||
<div className="section-header">
|
<div className="section-header">
|
||||||
<h4>E - Coord. PPG</h4>
|
<h4>E - Coord. PPG</h4>
|
||||||
<span className="max-pts">indicador</span>
|
<span className="max-pts">indicador</span>
|
||||||
@@ -71,7 +73,7 @@ const Header = ({ total }) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="criteria-row">
|
<div className="criteria-row">
|
||||||
<div className="criteria-section bloco-c wide">
|
<div className="criteria-section bloco-c wide clickable" onClick={() => setModalBloco('C')}>
|
||||||
<div className="section-header">
|
<div className="section-header">
|
||||||
<h4>C - Premiacoes, Avaliacoes, Inscricoes</h4>
|
<h4>C - Premiacoes, Avaliacoes, Inscricoes</h4>
|
||||||
</div>
|
</div>
|
||||||
@@ -126,7 +128,7 @@ const Header = ({ total }) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="criteria-row">
|
<div className="criteria-row">
|
||||||
<div className="criteria-section bloco-c selos-section">
|
<div className="criteria-section bloco-c selos-section clickable" onClick={() => setModalBloco('C')}>
|
||||||
<div className="section-header">
|
<div className="section-header">
|
||||||
<h4>C - Orientacoes</h4>
|
<h4>C - Orientacoes</h4>
|
||||||
<span className="max-pts">selos</span>
|
<span className="max-pts">selos</span>
|
||||||
@@ -151,7 +153,7 @@ const Header = ({ total }) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="criteria-section bloco-c selos-section">
|
<div className="criteria-section bloco-c selos-section clickable" onClick={() => setModalBloco('C')}>
|
||||||
<div className="section-header">
|
<div className="section-header">
|
||||||
<h4>C - Bancas</h4>
|
<h4>C - Bancas</h4>
|
||||||
<span className="max-pts">selos</span>
|
<span className="max-pts">selos</span>
|
||||||
@@ -166,7 +168,7 @@ const Header = ({ total }) => {
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="criteria-section bloco-d selos-section">
|
<div className="criteria-section bloco-d selos-section clickable" onClick={() => setModalBloco('D')}>
|
||||||
<div className="section-header">
|
<div className="section-header">
|
||||||
<h4>D - Indicadores</h4>
|
<h4>D - Indicadores</h4>
|
||||||
<span className="max-pts">selos</span>
|
<span className="max-pts">selos</span>
|
||||||
@@ -184,6 +186,13 @@ const Header = ({ total }) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{modalBloco && (
|
||||||
|
<BlocoCriteriosModal
|
||||||
|
bloco={modalBloco}
|
||||||
|
onClose={() => setModalBloco(null)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</header>
|
</header>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user