Реализованы компоненты для отображения посещаемости: AttendanceTable, StatsCard и ShortText. Добавлены хуки useAttendanceData и useAttendanceStats для обработки данных. Обновлен компонент Attendance с использованием новых компонентов и хуков.

This commit is contained in:
2025-03-23 09:01:00 +03:00
parent 433e3b87bf
commit 5e32e55ac2
9 changed files with 438 additions and 125 deletions

View File

@@ -0,0 +1,87 @@
import { useMemo } from 'react'
import { AttendanceData } from './useAttendanceData'
export interface AttendanceStats {
totalLessons: number
averageAttendance: number
topStudents: Array<{
name: string
attendance: number
attendancePercent: number
}>
lessonsAttendance: Array<{
name: string
date: string
attendancePercent: number
}>
}
export const useAttendanceStats = (data: AttendanceData): AttendanceStats => {
return useMemo(() => {
if (!data.attendance || !data.students.length) {
return {
totalLessons: 0,
averageAttendance: 0,
topStudents: [],
lessonsAttendance: []
}
}
const totalLessons = data.attendance.length
// Рассчитываем посещаемость для каждого студента
const studentAttendance = data.students.map(student => {
let attended = 0
data.attendance.forEach(lesson => {
if (lesson.students.some(s => s.sub === student.sub)) {
attended++
}
})
return {
student,
name: student.value,
attendance: attended,
attendancePercent: totalLessons > 0 ? (attended / totalLessons) * 100 : 0
}
})
// Рассчитываем статистику посещаемости для каждого урока
const lessonsAttendance = data.attendance.map(lesson => {
const attendedStudents = lesson.students.length
const attendancePercent = data.students.length > 0
? (attendedStudents / data.students.length) * 100
: 0
return {
name: lesson.name,
date: lesson.date,
attendancePercent
}
})
// Выбираем топ-3 студентов по посещаемости
const topStudents = [...studentAttendance]
.sort((a, b) => b.attendance - a.attendance)
.slice(0, 3)
.map(student => ({
name: student.name,
attendance: student.attendance,
attendancePercent: student.attendancePercent
}))
// Считаем среднюю посещаемость
const totalAttendance = studentAttendance.reduce((sum, student) => sum + student.attendance, 0)
const averageAttendance = data.students.length > 0 && totalLessons > 0
? (totalAttendance / (data.students.length * totalLessons)) * 100
: 0
return {
totalLessons,
averageAttendance,
topStudents,
lessonsAttendance
}
}, [data])
}