fix: vinculo robusto por ID/Nome no Boletim e exibição de acertos/erros

This commit is contained in:
Sidney 2026-05-01 11:36:34 -03:00
parent 5adb683d4e
commit 10431ab9e8
2 changed files with 57 additions and 35 deletions

View File

@ -132,7 +132,11 @@ const ReportCard: React.FC<ReportCardProps> = ({ data, updateData }) => {
const { submissions } = await res.json();
const subsMap: Record<string, {acertos: number, erros: number}> = {};
(submissions || []).forEach((s: any) => {
subsMap[s.prova_id] = { acertos: s.acertos, erros: s.erros };
// Normalização agressiva para garantir o vínculo
const pId = String(s.prova_id || '').trim();
if (pId) {
subsMap[pId] = { acertos: s.acertos, erros: s.erros };
}
});
setStudentSubmissions(subsMap);
}
@ -148,11 +152,19 @@ const ReportCard: React.FC<ReportCardProps> = ({ data, updateData }) => {
if (linkedExams.length > 0) {
linkedExams.forEach(exam => {
const existingGrade = dbNotas.find(g => String(g.disciplina_id).trim() === String(subject.id).trim() && String(g.periodo_id).trim() === String(period.id).trim() && String(g.prova_id).trim() === String(exam.id).trim());
const existingGrade = dbNotas.find(g =>
String(g.disciplina_id).trim() === String(subject.id).trim() &&
(String(g.periodo_id).trim() === String(period.id).trim() || String(g.periodo_id).trim() === String(period.name).trim()) &&
String(g.prova_id).trim() === String(exam.id).trim()
);
periodGrades[exam.id] = existingGrade ? Number(existingGrade.valor) : '';
});
} else {
const existingGrade = dbNotas.find(g => String(g.disciplina_id).trim() === String(subject.id).trim() && String(g.periodo_id).trim() === String(period.id).trim() && !g.prova_id);
const existingGrade = dbNotas.find(g =>
String(g.disciplina_id).trim() === String(subject.id).trim() &&
(String(g.periodo_id).trim() === String(period.id).trim() || String(g.periodo_id).trim() === String(period.name).trim()) &&
!g.prova_id
);
periodGrades['direct'] = existingGrade ? Number(existingGrade.valor) : '';
}
initialGrades[subject.id][period.id] = periodGrades;
@ -579,7 +591,6 @@ const ReportCard: React.FC<ReportCardProps> = ({ data, updateData }) => {
const maxScore = (exam as any).maxScore ?? 10;
return (
<div key={exam.id} className={`p-4 rounded-xl border flex flex-col md:flex-row md:items-center justify-between gap-4 ${isActivity ? 'bg-sky-50/50 border-sky-100' : 'bg-violet-50/50 border-violet-100'}`}>
<div className="flex-1">
<div className="flex flex-col">
<div className="text-sm font-bold text-slate-800 leading-tight mb-1 flex items-center gap-2">
<span className={`px-2 py-0.5 rounded text-[9px] uppercase tracking-wider font-black shrink-0 ${isActivity ? 'bg-sky-200 text-sky-800' : 'bg-violet-200 text-violet-800'}`}>
@ -591,17 +602,20 @@ const ReportCard: React.FC<ReportCardProps> = ({ data, updateData }) => {
{exam.description && (
<p className="text-xs text-slate-500 leading-snug pr-2">{exam.description}</p>
)}
{studentSubmissions[String(exam.id).trim()] && (
{(() => {
const stats = studentSubmissions[String(exam.id).trim()];
if (!stats) return null;
return (
<div className="flex gap-2 mt-2">
<span className="text-[10px] font-bold px-2 py-0.5 rounded-full bg-emerald-100 text-emerald-700 border border-emerald-200">
{studentSubmissions[String(exam.id).trim()].acertos} Acertos
<span className="text-[10px] font-bold px-2 py-0.5 rounded-full bg-emerald-100 text-emerald-700 border border-emerald-200 flex items-center gap-1">
<CheckCircle2 size={10} /> {stats.acertos} Acertos
</span>
<span className="text-[10px] font-bold px-2 py-0.5 rounded-full bg-rose-100 text-rose-700 border border-rose-200">
{studentSubmissions[String(exam.id).trim()].erros} Erros
<span className="text-[10px] font-bold px-2 py-0.5 rounded-full bg-rose-100 text-rose-700 border border-rose-200 flex items-center gap-1">
<X size={10} /> {stats.erros} Erros
</span>
</div>
)}
</div>
);
})()}
</div>
</div>

View File

@ -1,17 +1,25 @@
import pg from 'pg';
const DATABASE_URL = 'postgresql://edumanager:EduManager2026!Seguro@127.0.0.1:5432/edumanager';
const pool = new pg.Pool({ connectionString: DATABASE_URL });
async function listAll() {
import pkg from 'pg';
const { Pool } = pkg;
const pool = new Pool({
connectionString: 'postgresql://postgres:postgres@localhost:5432/edumanager'
});
async function check() {
try {
const { rows: notas } = await pool.query('SELECT * FROM notas_boletim LIMIT 20');
console.log('--- NOTAS NA TABELA ---');
console.log(JSON.stringify(notas, null, 2));
const { rows: subs } = await pool.query('SELECT * FROM provas_submissoes LIMIT 10');
console.log('--- SUBMISSÕES NA TABELA ---');
console.log('--- SUBMISSÕES NO BANCO ---');
const { rows: subs } = await pool.query('SELECT aluno_id, prova_id, acertos, erros FROM provas_submissoes');
console.log(JSON.stringify(subs, null, 2));
} catch (err) { console.log('ERROR:' + err.message); }
finally { await pool.end(); }
console.log('\n--- NOTAS NO BOLETIM ---');
const { rows: notas } = await pool.query('SELECT aluno_id, disciplina_id, periodo_id, prova_id, valor FROM notas_boletim');
console.log(JSON.stringify(notas, null, 2));
} catch (err) {
console.error(err);
} finally {
await pool.end();
}
listAll();
}
check();