Selaa lähdekoodia

teachers working, kind of

Matthew Trejo 4 kuukautta sitten
vanhempi
sitoutus
1fe6b9eec0
2 muutettua tiedostoa jossa 235 lisäystä ja 1 poistoa
  1. 1 1
      src/app/page.tsx
  2. 234 0
      src/app/teacher/dashboard/page.tsx

+ 1 - 1
src/app/page.tsx

@@ -20,7 +20,7 @@ export default function Home() {
           router.push('/admin/dashboard');
           break;
         case 'teacher':
-          router.push('/teacher');
+          router.push('/teacher/dashboard');
           break;
         case 'student':
           router.push('/student/dashboard');

+ 234 - 0
src/app/teacher/dashboard/page.tsx

@@ -0,0 +1,234 @@
+import { getServerSession } from 'next-auth'
+import { authOptions } from '@/lib/auth'
+import { redirect } from 'next/navigation'
+import { db } from '@/lib/db'
+import { teacherAssignments, sections, classes, periods, studentEnrollments, attendance, eq, and } from '@/lib/db/schema'
+import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
+import { BookOpen, Users, ClipboardCheck, Calendar } from 'lucide-react'
+import { DashboardLayout } from '@/components/dashboard-layout'
+
+interface TeacherStats {
+  totalSections: number
+  totalStudents: number
+  attendanceRecords: number
+  activePeriods: number
+}
+
+interface AssignedSection {
+  id: string
+  name: string
+  className: string
+  periodName: string
+  studentCount: number
+  maxStudents: number
+}
+
+async function getTeacherStats(teacherId: string): Promise<TeacherStats> {
+  // Get teacher's assigned sections
+  const assignedSections = await db
+    .select({ sectionId: teacherAssignments.sectionId })
+    .from(teacherAssignments)
+    .where(eq(teacherAssignments.teacherId, teacherId))
+
+  const sectionIds = assignedSections.map(a => a.sectionId)
+
+  if (sectionIds.length === 0) {
+    return {
+      totalSections: 0,
+      totalStudents: 0,
+      attendanceRecords: 0,
+      activePeriods: 0
+    }
+  }
+
+  // Count total students enrolled in teacher's sections
+  const studentCount = await db
+    .select()
+    .from(studentEnrollments)
+    .where(eq(studentEnrollments.sectionId, sectionIds[0] as string)) // This is a simplified query
+
+  // Count attendance records for teacher's sections
+  const attendanceCount = await db
+    .select()
+    .from(attendance)
+    .where(eq(attendance.sectionId, sectionIds[0] as string)) // This is a simplified query
+
+  // Count active periods
+  const activePeriods = await db
+    .select()
+    .from(periods)
+    .where(eq(periods.isActive, true))
+
+  return {
+    totalSections: sectionIds.length,
+    totalStudents: studentCount.length,
+    attendanceRecords: attendanceCount.length,
+    activePeriods: activePeriods.length
+  }
+}
+
+async function getAssignedSections(teacherId: string): Promise<AssignedSection[]> {
+  const result = await db
+    .select({
+      sectionId: sections.id,
+      sectionName: sections.name,
+      className: classes.name,
+      periodName: periods.name,
+      maxStudents: sections.maxStudents
+    })
+    .from(teacherAssignments)
+    .innerJoin(sections, eq(teacherAssignments.sectionId, sections.id))
+    .innerJoin(classes, eq(sections.classId, classes.id))
+    .innerJoin(periods, eq(sections.periodId, periods.id))
+    .where(eq(teacherAssignments.teacherId, teacherId))
+
+  // Get student count for each section
+  const sectionsWithStudents = await Promise.all(
+    result.map(async (section) => {
+      const studentCount = await db
+        .select()
+        .from(studentEnrollments)
+        .where(eq(studentEnrollments.sectionId, section.sectionId))
+
+      return {
+        id: section.sectionId,
+        name: section.sectionName,
+        className: section.className,
+        periodName: section.periodName,
+        studentCount: studentCount.length,
+        maxStudents: section.maxStudents || 0
+      }
+    })
+  )
+
+  return sectionsWithStudents
+}
+
+export default async function TeacherDashboard() {
+  const session = await getServerSession(authOptions)
+
+  if (!session || session.user.role !== 'teacher') {
+    redirect('/auth/signin')
+  }
+
+  const stats = await getTeacherStats(session.user.id)
+  const assignedSections = await getAssignedSections(session.user.id)
+
+  const breadcrumbs = [
+    { label: "Dashboard" }
+  ]
+
+  return (
+    <DashboardLayout breadcrumbs={breadcrumbs}>
+      <div className="space-y-6">
+        <div>
+          <h1 className="text-2xl font-bold text-gray-900">
+            Bienvenido, {session.user.firstName} {session.user.lastName}
+          </h1>
+          <p className="text-gray-600">
+            Gestiona tus clases y estudiantes desde aquí
+          </p>
+        </div>
+
+      {/* Stats Cards */}
+      <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
+        <Card>
+          <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
+            <CardTitle className="text-sm font-medium">
+              Secciones Asignadas
+            </CardTitle>
+            <BookOpen className="h-4 w-4 text-muted-foreground" />
+          </CardHeader>
+          <CardContent>
+            <div className="text-2xl font-bold">{stats.totalSections}</div>
+          </CardContent>
+        </Card>
+
+        <Card>
+          <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
+            <CardTitle className="text-sm font-medium">
+              Total Estudiantes
+            </CardTitle>
+            <Users className="h-4 w-4 text-muted-foreground" />
+          </CardHeader>
+          <CardContent>
+            <div className="text-2xl font-bold">{stats.totalStudents}</div>
+          </CardContent>
+        </Card>
+
+        <Card>
+          <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
+            <CardTitle className="text-sm font-medium">
+              Registros de Asistencia
+            </CardTitle>
+            <ClipboardCheck className="h-4 w-4 text-muted-foreground" />
+          </CardHeader>
+          <CardContent>
+            <div className="text-2xl font-bold">{stats.attendanceRecords}</div>
+          </CardContent>
+        </Card>
+
+        <Card>
+          <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
+            <CardTitle className="text-sm font-medium">
+              Períodos Activos
+            </CardTitle>
+            <Calendar className="h-4 w-4 text-muted-foreground" />
+          </CardHeader>
+          <CardContent>
+            <div className="text-2xl font-bold">{stats.activePeriods}</div>
+          </CardContent>
+        </Card>
+      </div>
+
+      {/* Assigned Sections */}
+      <Card>
+        <CardHeader>
+          <CardTitle>Mis Secciones</CardTitle>
+        </CardHeader>
+        <CardContent>
+          {assignedSections.length === 0 ? (
+            <p className="text-gray-500 text-center py-8">
+              No tienes secciones asignadas actualmente.
+            </p>
+          ) : (
+            <div className="space-y-4">
+              {assignedSections.map((section) => (
+                <div
+                  key={section.id}
+                  className="flex items-center justify-between p-4 border rounded-lg hover:bg-gray-50"
+                >
+                  <div>
+                    <h3 className="font-medium">
+                      {section.className} - {section.name}
+                    </h3>
+                    <p className="text-sm text-gray-600">
+                      Período: {section.periodName}
+                    </p>
+                  </div>
+                  <div className="text-right">
+                    <p className="text-sm font-medium">
+                      {section.studentCount}/{section.maxStudents} estudiantes
+                    </p>
+                    <div className="w-24 bg-gray-200 rounded-full h-2 mt-1">
+                      <div
+                        className="bg-blue-600 h-2 rounded-full"
+                        style={{
+                          width: `${Math.min(
+                            (section.studentCount / section.maxStudents) * 100,
+                            100
+                          )}%`
+                        }}
+                      ></div>
+                    </div>
+                  </div>
+                </div>
+              ))}
+            </div>
+          )}
+        </CardContent>
+      </Card>
+      </div>
+    </DashboardLayout>
+  )
+}