Files
journal.pl/src/pages/attendance/hooks/useAttendanceStats.ts

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])
}