Matthew Trejo 4 månader sedan
förälder
incheckning
57e38f020e

+ 16 - 13
src/app/teacher/attendance-history/page.tsx

@@ -159,14 +159,14 @@ export default function AttendanceHistoryPage() {
             <CardTitle>Filtros</CardTitle>
           </CardHeader>
           <CardContent>
-            <div className="grid grid-cols-1 md:grid-cols-4 gap-4">
-              <div>
+            <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
+              <div className="space-y-2">
                 <Label htmlFor="section">Sección</Label>
                 <Select value={selectedSection} onValueChange={setSelectedSection}>
-                  <SelectTrigger>
+                  <SelectTrigger className="w-full">
                     <SelectValue placeholder="Seleccionar sección" />
                   </SelectTrigger>
-                  <SelectContent>
+                  <SelectContent className="z-50">
                     {sections.map((section) => (
                       <SelectItem key={section.id} value={section.id}>
                         {section.className} - {section.name} ({section.periodName})
@@ -176,27 +176,30 @@ export default function AttendanceHistoryPage() {
                 </Select>
               </div>
               
-              <div>
+              <div className="space-y-2">
                 <Label htmlFor="startDate">Fecha Inicio</Label>
                 <Input
                   id="startDate"
                   type="date"
                   value={startDate}
                   onChange={(e) => setStartDate(e.target.value)}
+                  className="w-full"
                 />
               </div>
               
-              <div>
+              <div className="space-y-2">
                 <Label htmlFor="endDate">Fecha Fin</Label>
                 <Input
                   id="endDate"
                   type="date"
                   value={endDate}
                   onChange={(e) => setEndDate(e.target.value)}
+                  className="w-full"
                 />
               </div>
               
-              <div className="flex items-end">
+              <div className="space-y-2">
+                <Label className="opacity-0">Acción</Label>
                 <Button 
                   onClick={fetchHistory} 
                   disabled={loading || !selectedSection}
@@ -227,25 +230,25 @@ export default function AttendanceHistoryPage() {
                   <div className="text-2xl font-bold text-blue-600">
                     {history.reduce((acc, day) => acc + day.summary.total, 0)}
                   </div>
-                  <div className="text-sm text-gray-600">Total Registros</div>
+                  <div className="text-sm">Total Registros</div>
                 </div>
                 <div className="text-center">
                   <div className="text-2xl font-bold text-green-600">
                     {history.reduce((acc, day) => acc + day.summary.present, 0)}
                   </div>
-                  <div className="text-sm text-gray-600">Presentes</div>
+                  <div className="text-sm">Presentes</div>
                 </div>
                 <div className="text-center">
                   <div className="text-2xl font-bold text-yellow-600">
                     {history.reduce((acc, day) => acc + day.summary.late, 0)}
                   </div>
-                  <div className="text-sm text-gray-600">Tardanzas</div>
+                  <div className="text-sm">Tardanzas</div>
                 </div>
                 <div className="text-center">
                   <div className="text-2xl font-bold text-red-600">
                     {history.reduce((acc, day) => acc + day.summary.absent, 0)}
                   </div>
-                  <div className="text-sm text-gray-600">Ausentes</div>
+                  <div className="text-sm">Ausentes</div>
                 </div>
               </div>
             </CardContent>
@@ -327,8 +330,8 @@ export default function AttendanceHistoryPage() {
         {!selectedSection && (
           <Card>
             <CardContent className="text-center py-8">
-              <Users className="h-12 w-12 mx-auto text-gray-400 mb-4" />
-              <p className="text-gray-500">Selecciona una sección para ver el historial de asistencia.</p>
+              <Users className="h-12 w-12 mx-auto mb-4" />
+              <p className="">Selecciona una sección para ver el historial de asistencia.</p>
             </CardContent>
           </Card>
         )}

+ 71 - 57
src/app/teacher/attendance/page.tsx

@@ -5,6 +5,7 @@ import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
 import { Button } from '@/components/ui/button'
 import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
 import { Badge } from '@/components/ui/badge'
+import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'
 import { CheckCircle, XCircle, Clock, Users } from 'lucide-react'
 import { toast } from 'sonner'
 import { DashboardLayout } from '@/components/dashboard-layout'
@@ -189,8 +190,8 @@ export default function AttendancePage() {
     <DashboardLayout breadcrumbs={breadcrumbs}>
       <div className="space-y-6">
         <div>
-          <h1 className="text-2xl font-bold text-gray-900">Gestión de Asistencia</h1>
-          <p className="text-gray-600">Registra la asistencia de tus estudiantes</p>
+          <h1 className="text-2xl font-bold">Gestión de Asistencia</h1>
+          <p>Registra la asistencia de tus estudiantes</p>
         </div>
 
       {/* Filters */}
@@ -202,14 +203,14 @@ export default function AttendancePage() {
           </CardTitle>
         </CardHeader>
         <CardContent>
-          <div className="grid grid-cols-1 md:grid-cols-4 gap-4">
-            <div>
-              <label className="block text-sm font-medium mb-2">Sección</label>
+          <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
+            <div className="space-y-2">
+              <label className="block text-sm font-medium">Sección</label>
               <Select value={selectedSection} onValueChange={setSelectedSection}>
-                <SelectTrigger>
+                <SelectTrigger className="w-full">
                   <SelectValue placeholder="Seleccionar sección" />
                 </SelectTrigger>
-                <SelectContent>
+                <SelectContent className="z-50">
                   {sections.map((section) => (
                     <SelectItem key={section.id} value={section.id}>
                       {section.className} - {section.name}
@@ -219,13 +220,13 @@ export default function AttendancePage() {
               </Select>
             </div>
 
-            <div>
-              <label className="block text-sm font-medium mb-2">Parcial</label>
+            <div className="space-y-2">
+              <label className="block text-sm font-medium">Parcial</label>
               <Select value={selectedPartial} onValueChange={setSelectedPartial}>
-                <SelectTrigger>
+                <SelectTrigger className="w-full">
                   <SelectValue placeholder="Seleccionar parcial" />
                 </SelectTrigger>
-                <SelectContent>
+                <SelectContent className="z-40">
                   {partials.map((partial) => (
                     <SelectItem key={partial.id} value={partial.id}>
                       {partial.name}
@@ -235,8 +236,8 @@ export default function AttendancePage() {
               </Select>
             </div>
 
-            <div>
-              <label className="block text-sm font-medium mb-2">Fecha</label>
+            <div className="space-y-2">
+              <label className="block text-sm font-medium">Fecha</label>
               <input
                 type="date"
                 value={selectedDate}
@@ -245,7 +246,8 @@ export default function AttendancePage() {
               />
             </div>
 
-            <div className="flex items-end">
+            <div className="space-y-2">
+              <label className="block text-sm font-medium opacity-0">Acción</label>
               <Button 
                 onClick={fetchStudents} 
                 disabled={!selectedSection || !selectedPartial || loading}
@@ -276,49 +278,61 @@ export default function AttendancePage() {
             </div>
           </CardHeader>
           <CardContent>
-            <div className="space-y-4">
-              {students.map((student) => (
-                <div
-                  key={student.id}
-                  className="flex items-center justify-between p-4 border rounded-lg hover:bg-gray-50"
-                >
-                  <div className="flex items-center space-x-3">
-                    {getStatusIcon(student.attendance?.status || 'absent')}
-                    <div>
-                      <h3 className="font-medium">{student.name}</h3>
-                      <p className="text-sm text-gray-600">{student.email}</p>
-                    </div>
-                  </div>
-                  
-                  <div className="flex items-center space-x-4">
-                    {getStatusBadge(student.attendance?.status || 'absent')}
-                    
-                    <div className="flex space-x-2">
-                      <Button
-                        size="sm"
-                        variant={student.attendance?.status === 'present' ? 'default' : 'outline'}
-                        onClick={() => updateAttendance(student.id, 'present')}
-                      >
-                        Presente
-                      </Button>
-                      <Button
-                        size="sm"
-                        variant={student.attendance?.status === 'late' ? 'default' : 'outline'}
-                        onClick={() => updateAttendance(student.id, 'late')}
-                      >
-                        Tardanza
-                      </Button>
-                      <Button
-                        size="sm"
-                        variant={student.attendance?.status === 'absent' ? 'default' : 'outline'}
-                        onClick={() => updateAttendance(student.id, 'absent')}
-                      >
-                        Ausente
-                      </Button>
-                    </div>
-                  </div>
-                </div>
-              ))}
+            <div className="overflow-x-auto">
+              <Table>
+                <TableHeader>
+                  <TableRow>
+                    <TableHead>Estado</TableHead>
+                    <TableHead>Estudiante</TableHead>
+                    <TableHead>Email</TableHead>
+                    <TableHead>Asistencia</TableHead>
+                    <TableHead className="text-right">Acciones</TableHead>
+                  </TableRow>
+                </TableHeader>
+                <TableBody>
+                  {students.map((student) => (
+                    <TableRow key={student.id}>
+                      <TableCell>
+                        {getStatusIcon(student.attendance?.status || 'absent')}
+                      </TableCell>
+                      <TableCell className="font-medium">
+                        {student.name}
+                      </TableCell>
+                      <TableCell>
+                        {student.email}
+                      </TableCell>
+                      <TableCell>
+                        {getStatusBadge(student.attendance?.status || 'absent')}
+                      </TableCell>
+                      <TableCell className="text-right">
+                        <div className="flex justify-end space-x-2">
+                          <Button
+                            size="sm"
+                            variant={student.attendance?.status === 'present' ? 'default' : 'outline'}
+                            onClick={() => updateAttendance(student.id, 'present')}
+                          >
+                            Presente
+                          </Button>
+                          <Button
+                            size="sm"
+                            variant={student.attendance?.status === 'late' ? 'default' : 'outline'}
+                            onClick={() => updateAttendance(student.id, 'late')}
+                          >
+                            Tardanza
+                          </Button>
+                          <Button
+                            size="sm"
+                            variant={student.attendance?.status === 'absent' ? 'default' : 'outline'}
+                            onClick={() => updateAttendance(student.id, 'absent')}
+                          >
+                            Ausente
+                          </Button>
+                        </div>
+                      </TableCell>
+                    </TableRow>
+                  ))}
+                </TableBody>
+              </Table>
             </div>
           </CardContent>
         </Card>

+ 68 - 34
src/app/teacher/dashboard/page.tsx

@@ -4,6 +4,8 @@ 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 { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'
+import { Badge } from '@/components/ui/badge'
 import { BookOpen, Users, ClipboardCheck, Calendar } from 'lucide-react'
 import { DashboardLayout } from '@/components/dashboard-layout'
 
@@ -122,10 +124,10 @@ export default async function TeacherDashboard() {
     <DashboardLayout breadcrumbs={breadcrumbs}>
       <div className="space-y-6">
         <div>
-          <h1 className="text-2xl font-bold text-gray-900">
+          <h1 className="text-2xl font-bold">
             Bienvenido, {session.user.firstName} {session.user.lastName}
           </h1>
-          <p className="text-gray-600">
+          <p>
             Gestiona tus clases y estudiantes desde aquí
           </p>
         </div>
@@ -192,38 +194,70 @@ export default async function TeacherDashboard() {
               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 className="overflow-x-auto">
+              <Table>
+                <TableHeader>
+                  <TableRow>
+                    <TableHead>Sección</TableHead>
+                    <TableHead>Clase</TableHead>
+                    <TableHead>Período</TableHead>
+                    <TableHead>Estudiantes</TableHead>
+                    <TableHead className="text-right">Capacidad</TableHead>
+                  </TableRow>
+                </TableHeader>
+                <TableBody>
+                  {assignedSections.map((section) => (
+                    <TableRow key={section.id}>
+                      <TableCell className="font-medium">
+                        {section.name}
+                      </TableCell>
+                      <TableCell>
+                        {section.className}
+                      </TableCell>
+                      <TableCell>
+                        <Badge variant="default">{section.periodName}</Badge>
+                      </TableCell>
+                      <TableCell>
+                        <Badge 
+                          variant={
+                            section.studentCount >= section.maxStudents 
+                              ? "destructive" 
+                              : section.studentCount >= section.maxStudents * 0.8 
+                                ? "outline" 
+                                : "secondary"
+                          }
+                        >
+                          {section.studentCount} estudiantes
+                        </Badge>
+                      </TableCell>
+                      <TableCell className="text-right">
+                        <div className="flex items-center justify-end gap-2">
+                          <span className="text-sm text-muted-foreground">
+                            {section.studentCount}/{section.maxStudents}
+                          </span>
+                          <div className="w-16 bg-gray-200 rounded-full h-2">
+                            <div
+                              className={`h-2 rounded-full ${
+                                section.studentCount >= section.maxStudents
+                                  ? 'bg-red-500'
+                                  : section.studentCount >= section.maxStudents * 0.8
+                                    ? 'bg-yellow-500'
+                                    : 'bg-green-500'
+                              }`}
+                              style={{
+                                width: `${Math.min(
+                                  (section.studentCount / section.maxStudents) * 100,
+                                  100
+                                )}%`
+                              }}
+                            ></div>
+                          </div>
+                        </div>
+                      </TableCell>
+                    </TableRow>
+                  ))}
+                </TableBody>
+              </Table>
             </div>
           )}
         </CardContent>

+ 2 - 2
src/app/teacher/page.tsx

@@ -122,10 +122,10 @@ export default async function TeacherDashboard() {
     <DashboardLayout breadcrumbs={breadcrumbs}>
       <div className="space-y-6">
         <div>
-          <h1 className="text-2xl font-bold text-gray-900">
+          <h1 className="text-2xl font-bold">
             Bienvenido, {session.user.firstName} {session.user.lastName}
           </h1>
-          <p className="text-gray-600">
+          <p>
             Gestiona tus clases y estudiantes desde aquí
           </p>
         </div>

+ 5 - 5
src/components/app-sidebar.tsx

@@ -145,11 +145,11 @@ const teacherMenuSections = [
         url: "/teacher/attendance-history",
         icon: ClipboardList,
       },
-      {
-        title: "Asistencia por Estudiante",
-        url: "/teacher/student-attendance",
-        icon: Users,
-      },
+      // {
+      //   title: "Asistencia por Estudiante",
+      //   url: "/teacher/student-attendance",
+      //   icon: Users,
+      // },
     ],
   },
   {