|
|
@@ -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>
|