|
@@ -0,0 +1,128 @@
|
|
|
|
|
+import { NextRequest, NextResponse } from 'next/server'
|
|
|
|
|
+import { getServerSession } from 'next-auth/next'
|
|
|
|
|
+import { authOptions } from '@/lib/auth'
|
|
|
|
|
+import { db } from '@/lib/db'
|
|
|
|
|
+import {
|
|
|
|
|
+ users,
|
|
|
|
|
+ studentEnrollments,
|
|
|
|
|
+ sections,
|
|
|
|
|
+ classes,
|
|
|
|
|
+ periods,
|
|
|
|
|
+ teacherAssignments,
|
|
|
|
|
+ attendance,
|
|
|
|
|
+ eq,
|
|
|
|
|
+ and
|
|
|
|
|
+} from '@/lib/db/schema'
|
|
|
|
|
+import { count } from 'drizzle-orm'
|
|
|
|
|
+
|
|
|
|
|
+export async function GET(request: NextRequest) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const session = await getServerSession(authOptions)
|
|
|
|
|
+
|
|
|
|
|
+ if (!session || session.user.role !== 'student') {
|
|
|
|
|
+ return NextResponse.json(
|
|
|
|
|
+ { error: 'No autorizado' },
|
|
|
|
|
+ { status: 401 }
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const studentId = session.user.id
|
|
|
|
|
+
|
|
|
|
|
+ // Get enrolled sections with class and period information
|
|
|
|
|
+ const enrolledSections = await db
|
|
|
|
|
+ .select({
|
|
|
|
|
+ sectionId: sections.id,
|
|
|
|
|
+ sectionName: sections.name,
|
|
|
|
|
+ className: classes.name,
|
|
|
|
|
+ classId: classes.id,
|
|
|
|
|
+ classCode: classes.code,
|
|
|
|
|
+ credits: classes.credits,
|
|
|
|
|
+ periodName: periods.name,
|
|
|
|
|
+ periodId: periods.id,
|
|
|
|
|
+ maxStudents: sections.maxStudents,
|
|
|
|
|
+ isActive: sections.isActive,
|
|
|
|
|
+ enrollmentDate: studentEnrollments.createdAt
|
|
|
|
|
+ })
|
|
|
|
|
+ .from(studentEnrollments)
|
|
|
|
|
+ .innerJoin(sections, eq(studentEnrollments.sectionId, sections.id))
|
|
|
|
|
+ .innerJoin(classes, eq(studentEnrollments.classId, classes.id))
|
|
|
|
|
+ .innerJoin(periods, eq(classes.periodId, periods.id))
|
|
|
|
|
+ .where(
|
|
|
|
|
+ and(
|
|
|
|
|
+ eq(studentEnrollments.studentId, studentId),
|
|
|
|
|
+ eq(studentEnrollments.isActive, true)
|
|
|
|
|
+ )
|
|
|
|
|
+ )
|
|
|
|
|
+ .orderBy(classes.code, sections.name)
|
|
|
|
|
+
|
|
|
|
|
+ // Get teacher information for each section
|
|
|
|
|
+ const sectionsWithTeachers = await Promise.all(
|
|
|
|
|
+ enrolledSections.map(async (section) => {
|
|
|
|
|
+ // Get teacher assigned to this section
|
|
|
|
|
+ const teacherQuery = await db
|
|
|
|
|
+ .select({
|
|
|
|
|
+ teacherId: users.id,
|
|
|
|
|
+ teacherFirstName: users.firstName,
|
|
|
|
|
+ teacherLastName: users.lastName
|
|
|
|
|
+ })
|
|
|
|
|
+ .from(teacherAssignments)
|
|
|
|
|
+ .innerJoin(users, eq(teacherAssignments.teacherId, users.id))
|
|
|
|
|
+ .where(
|
|
|
|
|
+ and(
|
|
|
|
|
+ eq(teacherAssignments.sectionId, section.sectionId),
|
|
|
|
|
+ eq(teacherAssignments.isActive, true)
|
|
|
|
|
+ )
|
|
|
|
|
+ )
|
|
|
|
|
+ .limit(1)
|
|
|
|
|
+
|
|
|
|
|
+ const teacher = teacherQuery[0]
|
|
|
|
|
+ const teacherName = teacher
|
|
|
|
|
+ ? `${teacher.teacherFirstName} ${teacher.teacherLastName}`
|
|
|
|
|
+ : 'Sin asignar'
|
|
|
|
|
+
|
|
|
|
|
+ return {
|
|
|
|
|
+ id: section.sectionId,
|
|
|
|
|
+ name: section.sectionName,
|
|
|
|
|
+ className: section.className,
|
|
|
|
|
+ classCode: section.classCode,
|
|
|
|
|
+ credits: section.credits,
|
|
|
|
|
+ teacherName,
|
|
|
|
|
+ isActive: section.isActive
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ // Calculate attendance summary
|
|
|
|
|
+ const attendanceRecords = await db
|
|
|
|
|
+ .select({
|
|
|
|
|
+ status: attendance.status
|
|
|
|
|
+ })
|
|
|
|
|
+ .from(attendance)
|
|
|
|
|
+ .where(eq(attendance.studentId, studentId))
|
|
|
|
|
+
|
|
|
|
|
+ const totalClasses = attendanceRecords.length
|
|
|
|
|
+ const present = attendanceRecords.filter(record => record.status === 'present').length
|
|
|
|
|
+ const absent = attendanceRecords.filter(record => record.status === 'absent').length
|
|
|
|
|
+ const tardy = attendanceRecords.filter(record => record.status === 'late').length
|
|
|
|
|
+ const attendanceRate = totalClasses > 0 ? Math.round((present / totalClasses) * 100 * 10) / 10 : 0
|
|
|
|
|
+
|
|
|
|
|
+ const attendanceSummary = {
|
|
|
|
|
+ totalClasses,
|
|
|
|
|
+ present,
|
|
|
|
|
+ absent,
|
|
|
|
|
+ tardy,
|
|
|
|
|
+ attendanceRate
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return NextResponse.json({
|
|
|
|
|
+ sections: sectionsWithTeachers,
|
|
|
|
|
+ attendanceSummary
|
|
|
|
|
+ })
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('Error fetching student dashboard data:', error)
|
|
|
|
|
+ return NextResponse.json(
|
|
|
|
|
+ { error: 'Error interno del servidor' },
|
|
|
|
|
+ { status: 500 }
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
|
|
+}
|