fix: robustez nos IDs (trim) e substituição de ícone Loader2 por RefreshCw para compatibilidade
This commit is contained in:
parent
26dc4210eb
commit
e2cb0376cf
|
|
@ -144,15 +144,15 @@ const ReportCard: React.FC<ReportCardProps> = ({ data, updateData }) => {
|
|||
initialGrades[subject.id] = {};
|
||||
periods.forEach(period => {
|
||||
const periodGrades: any = {};
|
||||
const linkedExams = (data.exams || []).filter(e => String(e.subjectId) === String(subject.id) && String(e.periodId) === String(period.id) && e.status === 'published');
|
||||
const linkedExams = (data.exams || []).filter(e => String(e.subjectId).trim() === String(subject.id).trim() && String(e.periodId).trim() === String(period.id).trim() && e.status === 'published');
|
||||
|
||||
if (linkedExams.length > 0) {
|
||||
linkedExams.forEach(exam => {
|
||||
const existingGrade = dbNotas.find(g => String(g.disciplina_id) === String(subject.id) && String(g.periodo_id) === String(period.id) && String(g.prova_id) === String(exam.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.prova_id).trim() === String(exam.id).trim());
|
||||
periodGrades[exam.id] = existingGrade ? Number(existingGrade.valor) : '';
|
||||
});
|
||||
} else {
|
||||
const existingGrade = dbNotas.find(g => String(g.disciplina_id) === String(subject.id) && String(g.periodo_id) === String(period.id) && !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() && !g.prova_id);
|
||||
periodGrades['direct'] = existingGrade ? Number(existingGrade.valor) : '';
|
||||
}
|
||||
initialGrades[subject.id][period.id] = periodGrades;
|
||||
|
|
@ -518,7 +518,7 @@ const ReportCard: React.FC<ReportCardProps> = ({ data, updateData }) => {
|
|||
<div className="space-y-6">
|
||||
{subjects.map(subject => {
|
||||
// Encontrar provas vinculadas a esta disciplina
|
||||
const linkedExams = (data.exams || []).filter(e => String(e.subjectId) === String(subject.id) && e.status === 'published');
|
||||
const linkedExams = (data.exams || []).filter(e => String(e.subjectId).trim() === String(subject.id).trim() && e.status === 'published');
|
||||
|
||||
return (
|
||||
<div key={subject.id} className="bg-slate-50 rounded-2xl p-6 border border-slate-100 space-y-4">
|
||||
|
|
@ -529,7 +529,7 @@ const ReportCard: React.FC<ReportCardProps> = ({ data, updateData }) => {
|
|||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
{(() => {
|
||||
const linkedExams = (data.exams || []).filter(e => String(e.subjectId) === String(subject.id) && e.status === 'published');
|
||||
const linkedExams = (data.exams || []).filter(e => String(e.subjectId).trim() === String(subject.id).trim() && e.status === 'published');
|
||||
const provasCount = linkedExams.filter(e => (e as any).evaluationType !== 'activity').length;
|
||||
const atividadesCount = linkedExams.filter(e => (e as any).evaluationType === 'activity').length;
|
||||
return (
|
||||
|
|
@ -561,7 +561,7 @@ const ReportCard: React.FC<ReportCardProps> = ({ data, updateData }) => {
|
|||
</div>
|
||||
<div className="flex flex-col gap-6">
|
||||
{periods.map(period => {
|
||||
const linkedExams = (data.exams || []).filter(e => String(e.subjectId) === String(subject.id) && String(e.periodId) === String(period.id) && e.status === 'published');
|
||||
const linkedExams = (data.exams || []).filter(e => String(e.subjectId).trim() === String(subject.id).trim() && String(e.periodId).trim() === String(period.id).trim() && e.status === 'published');
|
||||
const periodGrades = studentGrades[subject.id]?.[period.id] || {};
|
||||
const periodSum: number = Object.values(periodGrades).reduce<number>((a, b: any) => a + (b !== '' ? Number(b) : 0), 0);
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
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 check() {
|
||||
try {
|
||||
const { rows } = await pool.query(\"SELECT (data->'grades') as grades FROM school_data WHERE id = 1\");
|
||||
console.log('GRADES_JSON_COUNT:' + (rows[0]?.grades?.length || 0));
|
||||
const { rows: n } = await pool.query(\"SELECT count(*) FROM notas_boletim\");
|
||||
console.log('NOTAS_TABLE_COUNT:' + n[0].count);
|
||||
} catch (err) { console.log('ERROR:' + err.message); }
|
||||
finally { await pool.end(); }
|
||||
}
|
||||
check();
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
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() {
|
||||
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(JSON.stringify(subs, null, 2));
|
||||
} catch (err) { console.log('ERROR:' + err.message); }
|
||||
finally { await pool.end(); }
|
||||
}
|
||||
listAll();
|
||||
|
|
@ -306,8 +306,8 @@ app.get('/api/student-submissions/:studentId', async (req, res) => {
|
|||
try {
|
||||
const { studentId } = req.params;
|
||||
const { rows } = await pool.query(
|
||||
'SELECT prova_id as "prova_id", acertos, erros FROM provas_submissoes WHERE aluno_id = $1',
|
||||
[String(studentId)]
|
||||
'SELECT prova_id as "prova_id", acertos, erros FROM provas_submissoes WHERE TRIM(aluno_id) = TRIM($1)',
|
||||
[String(studentId).trim()]
|
||||
);
|
||||
res.json({ submissions: rows });
|
||||
} catch (err) {
|
||||
|
|
@ -322,8 +322,8 @@ app.get('/api/student-submissions/:studentId', async (req, res) => {
|
|||
app.get('/api/notas/:alunoId', async (req, res) => {
|
||||
try {
|
||||
const { rows: dbNotas } = await pool.query(
|
||||
'SELECT id, aluno_id as "aluno_id", disciplina_id as "disciplina_id", periodo_id as "periodo_id", prova_id as "prova_id", valor as "valor" FROM notas_boletim WHERE aluno_id = $1',
|
||||
[req.params.alunoId]
|
||||
'SELECT id, aluno_id as "aluno_id", disciplina_id as "disciplina_id", periodo_id as "periodo_id", prova_id as "prova_id", valor as "valor" FROM notas_boletim WHERE TRIM(aluno_id) = TRIM($1)',
|
||||
[String(req.params.alunoId).trim()]
|
||||
);
|
||||
// Garantir cast numérico para evitar erro de .toFixed no frontend
|
||||
const notas = dbNotas.map(n => ({ ...n, valor: Number(n.valor) }));
|
||||
|
|
|
|||
|
|
@ -264,9 +264,9 @@ app.get('/api/portal/notas', authMiddleware, async (req, res) => {
|
|||
);
|
||||
|
||||
const enrichedGrades = grades.map((g) => {
|
||||
const subject = subjects.find((s) => String(s.id) === String(g.subjectId));
|
||||
const exam = g.examId ? (schoolData.exams || []).find(e => String(e.id) === String(g.examId)) : null;
|
||||
const periodObj = (schoolData.periods || []).find(p => String(p.id) === String(g.period));
|
||||
const subject = subjects.find((s) => String(s.id).trim() === String(g.subjectId).trim());
|
||||
const exam = g.examId ? (schoolData.exams || []).find(e => String(e.id).trim() === String(g.examId).trim()) : null;
|
||||
const periodObj = (schoolData.periods || []).find(p => String(p.id).trim() === String(g.period).trim());
|
||||
|
||||
const submission = g.examId ? submissions.find(s => String(s.prova_id) === String(g.examId)) : null;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { useAuth } from '../context/AuthContext';
|
|||
import type { Exam, ExamSubmission } from '../types';
|
||||
import {
|
||||
ClipboardList, Clock, ChevronLeft, ChevronRight, Send, CheckCircle2,
|
||||
XCircle, Award, AlertTriangle, Timer, ArrowLeft, Loader2
|
||||
XCircle, Award, AlertTriangle, Timer, ArrowLeft, RefreshCw
|
||||
} from 'lucide-react';
|
||||
import { normalizePhotoUrl } from '../helpers';
|
||||
|
||||
|
|
@ -465,7 +465,7 @@ export default function Avaliacoes() {
|
|||
: modalType === 'confirm'
|
||||
? <AlertTriangle size={28} color="var(--color-warning)" />
|
||||
: modalType === 'loading'
|
||||
? <Loader2 size={28} color="var(--color-primary)" className="animate-spin" />
|
||||
? <RefreshCw size={28} color="var(--color-primary)" className="animate-spin" />
|
||||
: <CheckCircle2 size={28} color="var(--color-primary)" />
|
||||
}
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in New Issue