diff --git a/frontend/src/components/ConsultorCard.css b/frontend/src/components/ConsultorCard.css index edc38b7..79fa062 100644 --- a/frontend/src/components/ConsultorCard.css +++ b/frontend/src/components/ConsultorCard.css @@ -494,3 +494,146 @@ grid-template-columns: 1fr; } } + +.selos-container { + display: flex; + flex-wrap: wrap; + gap: 0.4rem; + align-items: center; +} + +.selos-container.selos-compacto { + display: inline-flex; + margin-left: 0.3rem; +} + +.selo { + display: inline-flex; + align-items: center; + gap: 0.25rem; + font-size: 0.7rem; + padding: 0.2rem 0.45rem; + border-radius: 6px; + border: 1px solid rgba(255, 255, 255, 0.15); + background: rgba(255, 255, 255, 0.08); + color: var(--text); + font-weight: 500; + transition: transform 150ms ease, box-shadow 150ms ease; +} + +.selo:hover { + transform: translateY(-1px); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); +} + +.selo-icone { + font-size: 0.85rem; + line-height: 1; +} + +.selo-label { + font-size: 0.68rem; + letter-spacing: 0.2px; +} + +.selo-qtd { + font-size: 0.6rem; + font-weight: 700; + background: rgba(255, 255, 255, 0.2); + padding: 0.1rem 0.3rem; + border-radius: 4px; + margin-left: 0.15rem; +} + +.selo-mais { + background: rgba(255, 255, 255, 0.05); + border-style: dashed; + font-size: 0.65rem; + color: var(--muted); +} + +.selo-coord { + background: linear-gradient(135deg, rgba(139, 92, 246, 0.25), rgba(139, 92, 246, 0.1)); + border-color: rgba(139, 92, 246, 0.4); + color: #c4b5fd; +} + +.selo-camara { + background: linear-gradient(135deg, rgba(59, 130, 246, 0.25), rgba(59, 130, 246, 0.1)); + border-color: rgba(59, 130, 246, 0.4); + color: #93c5fd; +} + +.selo-bpq { + background: linear-gradient(135deg, rgba(34, 197, 94, 0.25), rgba(34, 197, 94, 0.1)); + border-color: rgba(34, 197, 94, 0.4); + color: #86efac; +} + +.selo-gp { + background: linear-gradient(135deg, rgba(251, 191, 36, 0.35), rgba(251, 191, 36, 0.15)); + border-color: rgba(251, 191, 36, 0.6); + color: #fcd34d; +} + +.selo-premio { + background: linear-gradient(135deg, rgba(249, 115, 22, 0.25), rgba(249, 115, 22, 0.1)); + border-color: rgba(249, 115, 22, 0.4); + color: #fdba74; +} + +.selo-mencao { + background: linear-gradient(135deg, rgba(203, 213, 225, 0.2), rgba(203, 213, 225, 0.08)); + border-color: rgba(203, 213, 225, 0.35); + color: #e2e8f0; +} + +.selo-orient { + background: linear-gradient(135deg, rgba(14, 165, 233, 0.2), rgba(14, 165, 233, 0.08)); + border-color: rgba(14, 165, 233, 0.35); + 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-coorient { + background: linear-gradient(135deg, rgba(99, 102, 241, 0.2), rgba(99, 102, 241, 0.08)); + border-color: rgba(99, 102, 241, 0.35); + 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; +} + +.selos-section { + grid-column: 1 / -1; +} + +.selos-section .selos-container { + gap: 0.5rem; +} + +.selos-section .selo { + padding: 0.35rem 0.6rem; +} + +.selos-section .selo-icone { + font-size: 1rem; +} + +.selos-section .selo-label { + font-size: 0.72rem; +} + +@media (max-width: 900px) { + .selos-container.selos-compacto { + display: none; + } +} diff --git a/frontend/src/components/ConsultorCard.jsx b/frontend/src/components/ConsultorCard.jsx index 49f149e..de2cc80 100644 --- a/frontend/src/components/ConsultorCard.jsx +++ b/frontend/src/components/ConsultorCard.jsx @@ -1,6 +1,96 @@ import React, { useState, useRef, useEffect } from 'react'; import './ConsultorCard.css'; +const SELOS = { + COORD_PPG: { label: 'Coord. PPG', cor: 'selo-coord', icone: '๐' }, + PRESID_CAMARA: { label: 'Presid. Cรขmara', cor: 'selo-camara', icone: '๐๏ธ' }, + BPQ: { label: 'Bolsista PQ', cor: 'selo-bpq', icone: '๐ฌ' }, + GRANDE_PREMIO: { label: 'Grande Prรชmio', cor: 'selo-gp', icone: '๐' }, + PREMIO: { label: 'Prรชmio', cor: 'selo-premio', icone: '๐ฅ' }, + MENCAO: { label: '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: '๐๐' }, +}; + +const gerarSelos = (consultor) => { + const selos = []; + + if (consultor.coordenacoes_capes?.some(c => c.codigo === 'CAM' && c.presidente)) { + selos.push({ ...SELOS.PRESID_CAMARA, qtd: 1 }); + } + + if (consultor.coordenador_ppg) { + selos.push({ ...SELOS.COORD_PPG, qtd: 1 }); + } + + if (consultor.bolsas_cnpq?.length > 0) { + selos.push({ ...SELOS.BPQ, qtd: consultor.bolsas_cnpq.length }); + } + + const gp = consultor.premiacoes?.filter(p => p.codigo === 'PREMIACAO')?.length || 0; + const premio = consultor.premiacoes?.filter(p => p.codigo === 'PREMIACAO_GP')?.length || 0; + const mencao = consultor.premiacoes?.filter(p => p.codigo === 'MENCAO')?.length || 0; + + if (gp > 0) selos.push({ ...SELOS.GRANDE_PREMIO, qtd: gp }); + if (premio > 0) selos.push({ ...SELOS.PREMIO, qtd: premio }); + if (mencao > 0) selos.push({ ...SELOS.MENCAO, qtd: mencao }); + + const orientPosDoc = consultor.orientacoes?.filter(o => o.codigo === 'ORIENT_POS_DOC')?.length || 0; + const orientTese = consultor.orientacoes?.filter(o => o.codigo === 'ORIENT_TESE')?.length || 0; + const orientDiss = consultor.orientacoes?.filter(o => o.codigo === 'ORIENT_DISS')?.length || 0; + + const orientPosDocPrem = consultor.orientacoes?.filter(o => o.codigo === 'ORIENT_POS_DOC' && o.premiada)?.length || 0; + const orientTesePrem = consultor.orientacoes?.filter(o => o.codigo === 'ORIENT_TESE' && o.premiada)?.length || 0; + const orientDissPrem = consultor.orientacoes?.filter(o => o.codigo === 'ORIENT_DISS' && o.premiada)?.length || 0; + + if (orientPosDocPrem > 0) selos.push({ ...SELOS.ORIENT_POS_DOC_PREM, qtd: orientPosDocPrem }); + else if (orientPosDoc > 0) selos.push({ ...SELOS.ORIENT_POS_DOC, qtd: orientPosDoc }); + + if (orientTesePrem > 0) selos.push({ ...SELOS.ORIENT_TESE_PREM, qtd: orientTesePrem }); + else if (orientTese > 0) selos.push({ ...SELOS.ORIENT_TESE, qtd: orientTese }); + + if (orientDissPrem > 0) selos.push({ ...SELOS.ORIENT_DISS_PREM, qtd: orientDissPrem }); + else if (orientDiss > 0) selos.push({ ...SELOS.ORIENT_DISS, qtd: orientDiss }); + + return selos; +}; + +const SelosBadges = ({ selos, compacto = false }) => { + 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; + + return ( +