fix: match portal attendance stats logic, record selection priority, and UI colors identically with manager
This commit is contained in:
parent
880fffbd85
commit
b850d76ba5
|
|
@ -150,24 +150,31 @@ export default function Frequencia() {
|
||||||
const lessonStartMs = lessonMs;
|
const lessonStartMs = lessonMs;
|
||||||
const lessonEndMs = parseLessonDateTime(lesson.date, lesson.endTime || '00:00:00', lesson.endTime ? 0 : 60);
|
const lessonEndMs = parseLessonDateTime(lesson.date, lesson.endTime || '00:00:00', lesson.endTime ? 0 : 60);
|
||||||
|
|
||||||
// No Manager, ele procura o primeiro registro válido
|
// Pega todos os registros válidos na janela de tempo
|
||||||
const att = attendance.find(a => {
|
const allAtts = attendance.filter(a => {
|
||||||
if (!a.date || typeof a.date !== 'string') return false;
|
if (!a.date || typeof a.date !== 'string') return false;
|
||||||
|
|
||||||
// 1. Exact Match (Including Manager DB fallback format)
|
|
||||||
if (a.date === `${lesson.date}T${lesson.startTime || '00:00'}:00` || a.date === lessonFullISO) return true;
|
if (a.date === `${lesson.date}T${lesson.startTime || '00:00'}:00` || a.date === lessonFullISO) return true;
|
||||||
|
|
||||||
const attMs = new Date(a.date).getTime();
|
const attMs = new Date(a.date).getTime();
|
||||||
const presenceStartWindow = lessonStartMs - 30 * 60000;
|
const presenceStartWindow = lessonStartMs - 30 * 60000;
|
||||||
|
|
||||||
// 2. Window Match (Matches Manager Logic: 30 mins before until end of lesson)
|
|
||||||
return attMs >= presenceStartWindow && attMs <= lessonEndMs;
|
return attMs >= presenceStartWindow && attMs <= lessonEndMs;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Prioridade de seleção para o status da aula:
|
||||||
|
// 1. Presença
|
||||||
|
// 2. Justificativa
|
||||||
|
// 3. Qualquer outro (Falta/Aguardando)
|
||||||
|
let bestRecord = allAtts.find(a => a.type === 'presence' || (!a.type && !a.isVirtual) || a.verified === true);
|
||||||
|
if (!bestRecord) {
|
||||||
|
bestRecord = allAtts.find(a => !!a.justification);
|
||||||
|
}
|
||||||
|
if (!bestRecord && allAtts.length > 0) {
|
||||||
|
bestRecord = allAtts[0];
|
||||||
|
}
|
||||||
|
|
||||||
const { isInProgress, isCompleted } = getLessonTimeStatus(lesson, now);
|
const { isInProgress, isCompleted } = getLessonTimeStatus(lesson, now);
|
||||||
return {
|
return {
|
||||||
lesson,
|
lesson,
|
||||||
attendances: att ? [att] : [], // Simulando o comportamento do manager (apenas 1 registro)
|
attendances: bestRecord ? [bestRecord] : [], // Mantém 1 registro para alinhar com Manager
|
||||||
isInProgress,
|
isInProgress,
|
||||||
isCompleted
|
isCompleted
|
||||||
};
|
};
|
||||||
|
|
@ -179,18 +186,20 @@ export default function Frequencia() {
|
||||||
let justified = 0;
|
let justified = 0;
|
||||||
|
|
||||||
processedItems.forEach(item => {
|
processedItems.forEach(item => {
|
||||||
const { lesson, attendances: atts, isCompleted } = item;
|
const { lesson, attendances: atts } = item;
|
||||||
if (lesson.status === 'cancelled') return; // Apenas canceladas ficam fora
|
if (lesson.status === 'cancelled') return;
|
||||||
|
|
||||||
const isPresent = atts.some(a => a.type === 'presence' || a.verified === true);
|
const record = atts[0];
|
||||||
const activeJustification = atts.find(a => !!a.justification);
|
const lessonEnd = new Date(lesson.date + 'T' + (lesson.endTime || '23:59') + ':00');
|
||||||
const hasJustification = !!activeJustification;
|
|
||||||
|
|
||||||
if (isPresent) {
|
if (record) {
|
||||||
presences++;
|
if (record.type === 'absence') {
|
||||||
} else if (activeJustification?.justificationAccepted) {
|
if (record.justificationAccepted) justified++;
|
||||||
justified++;
|
else absences++;
|
||||||
} else if (isCompleted || parseLessonDateTime(lesson.date || '', '23:59:59') < now.getTime()) {
|
} else if (record.type === 'presence' || (!record.type && !record.isVirtual) || record.verified) {
|
||||||
|
presences++;
|
||||||
|
}
|
||||||
|
} else if (now > lessonEnd) {
|
||||||
absences++;
|
absences++;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -540,11 +549,11 @@ export default function Frequencia() {
|
||||||
<CheckCircle2 size={16} /> Presente
|
<CheckCircle2 size={16} /> Presente
|
||||||
</span>
|
</span>
|
||||||
) : isJustificationAccepted ? (
|
) : isJustificationAccepted ? (
|
||||||
<span style={{ display: 'flex', alignItems: 'center', gap: 6, color: '#f59e0b', fontWeight: 600 }}>
|
<span style={{ display: 'flex', alignItems: 'center', gap: 6, color: 'var(--color-success)', fontWeight: 600 }}>
|
||||||
<AlertTriangle size={16} /> Falta Justificada
|
<CheckCircle2 size={16} /> Falta Justificada
|
||||||
</span>
|
</span>
|
||||||
) : hasJustification ? (
|
) : hasJustification ? (
|
||||||
<span style={{ display: 'flex', alignItems: 'center', gap: 6, color: 'var(--color-info)', fontWeight: 500 }}>
|
<span style={{ display: 'flex', alignItems: 'center', gap: 6, color: '#f59e0b', fontWeight: 500 }}>
|
||||||
<Clock size={16} /> Justificativa Pendente
|
<Clock size={16} /> Justificativa Pendente
|
||||||
</span>
|
</span>
|
||||||
) : (isCompleted || parseLessonDateTime(lesson.date || '', '23:59:59') < now.getTime()) && !isCancelled ? (
|
) : (isCompleted || parseLessonDateTime(lesson.date || '', '23:59:59') < now.getTime()) && !isCancelled ? (
|
||||||
|
|
@ -595,7 +604,7 @@ export default function Frequencia() {
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{justText ? (
|
{justText ? (
|
||||||
<span style={{ display: 'flex', alignItems: 'center', gap: 6, fontSize: '0.8125rem', color: isJustificationAccepted ? 'var(--color-success)' : 'var(--color-text-secondary)' }}>
|
<span style={{ display: 'flex', alignItems: 'center', gap: 6, fontSize: '0.8125rem', color: isJustificationAccepted ? 'var(--color-success)' : '#f59e0b', fontWeight: isJustificationAccepted ? 600 : 500 }}>
|
||||||
<FileText size={14} color="currentColor" />
|
<FileText size={14} color="currentColor" />
|
||||||
{isJustificationAccepted ? 'Justificativa Aceita' : 'Em Análise'}
|
{isJustificationAccepted ? 'Justificativa Aceita' : 'Em Análise'}
|
||||||
</span>
|
</span>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue