92 lines
2.8 KiB
TypeScript
92 lines
2.8 KiB
TypeScript
import { useMemo } from 'react'
|
|
import dayjs from 'dayjs'
|
|
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 now = dayjs()
|
|
// Фильтруем лекции, оставляя только те, которые уже прошли (исключаем будущие)
|
|
const pastLessons = data.attendance.filter(lesson => dayjs(lesson.date).isBefore(now))
|
|
|
|
const totalLessons = pastLessons.length
|
|
|
|
// Рассчитываем посещаемость для каждого студента
|
|
const studentAttendance = data.students.map(student => {
|
|
let attended = 0
|
|
|
|
pastLessons.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 = pastLessons.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])
|
|
}
|