'use client'; import { useState, useEffect } from 'react'; import { MainLayout } from '@/components/layout/main-layout'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog'; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from '@/components/ui/alert-dialog'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; import { Switch } from '@/components/ui/switch'; import { toast } from 'sonner'; import { Plus, Search, Edit, Trash2, Users, GraduationCap, BookOpen } from 'lucide-react'; interface Teacher { id: string; firstName: string; lastName: string; cedula: string; email: string; phone: string; } interface Section { id: string; name: string; class: { id: string; name: string; code: string; period: { id: string; name: string; isActive: boolean; }; }; } interface TeacherAssignment { id: string; teacherId: string; sectionId: string; isActive: boolean; createdAt: string; updatedAt: string; teacher: Teacher; section: Section; } interface CreateAssignmentData { teacherId: string; sectionId: string; } export default function TeacherAssignmentsPage() { const [assignments, setAssignments] = useState([]); const [teachers, setTeachers] = useState([]); const [sections, setSections] = useState([]); const [loading, setLoading] = useState(true); const [searchTerm, setSearchTerm] = useState(''); const [isCreateDialogOpen, setIsCreateDialogOpen] = useState(false); const [isEditDialogOpen, setIsEditDialogOpen] = useState(false); const [editingAssignment, setEditingAssignment] = useState(null); const [formData, setFormData] = useState({ teacherId: '', sectionId: '', }); useEffect(() => { fetchAssignments(); fetchTeachers(); fetchSections(); }, []); const fetchAssignments = async () => { try { const response = await fetch('/api/admin/teacher-assignments'); if (response.ok) { const data = await response.json(); setAssignments(data); } else { toast.error('Error al cargar las asignaciones'); } } catch (error) { console.error('Error fetching assignments:', error); toast.error('Error al cargar las asignaciones'); } finally { setLoading(false); } }; const fetchTeachers = async () => { try { const response = await fetch('/api/admin/users'); if (response.ok) { const users = await response.json(); const teacherUsers = users.filter((user: any) => user.role === 'TEACHER' && user.teacher); const teachersData = teacherUsers.map((user: any) => ({ id: user.teacher.id, firstName: user.teacher.firstName, lastName: user.teacher.lastName, cedula: user.teacher.cedula, email: user.teacher.email, phone: user.teacher.phone, })); setTeachers(teachersData); } } catch (error) { console.error('Error fetching teachers:', error); } }; const fetchSections = async () => { try { const response = await fetch('/api/admin/sections'); if (response.ok) { const data = await response.json(); setSections(data); } } catch (error) { console.error('Error fetching sections:', error); } }; const handleCreateAssignment = async () => { if (!validateForm()) return; try { const response = await fetch('/api/admin/teacher-assignments', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(formData), }); const result = await response.json(); if (response.ok) { toast.success('Asignación creada exitosamente'); setIsCreateDialogOpen(false); resetForm(); fetchAssignments(); } else { toast.error(result.message || 'Error al crear la asignación'); } } catch (error) { console.error('Error creating assignment:', error); toast.error('Error al crear la asignación'); } }; const handleUpdateAssignment = async () => { if (!editingAssignment || !validateForm()) return; try { const response = await fetch(`/api/admin/teacher-assignments/${editingAssignment.id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ ...formData, isActive: editingAssignment.isActive, }), }); const result = await response.json(); if (response.ok) { toast.success('Asignación actualizada exitosamente'); setIsEditDialogOpen(false); setEditingAssignment(null); resetForm(); fetchAssignments(); } else { toast.error(result.message || 'Error al actualizar la asignación'); } } catch (error) { console.error('Error updating assignment:', error); toast.error('Error al actualizar la asignación'); } }; const handleDeleteAssignment = async (assignmentId: string) => { try { const response = await fetch(`/api/admin/teacher-assignments/${assignmentId}`, { method: 'DELETE', }); const result = await response.json(); if (response.ok) { toast.success(result.message || 'Asignación eliminada exitosamente'); fetchAssignments(); } else { toast.error(result.message || 'Error al eliminar la asignación'); } } catch (error) { console.error('Error deleting assignment:', error); toast.error('Error al eliminar la asignación'); } }; const handleToggleActive = async (assignment: TeacherAssignment) => { try { const response = await fetch(`/api/admin/teacher-assignments/${assignment.id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ teacherId: assignment.teacherId, sectionId: assignment.sectionId, isActive: !assignment.isActive, }), }); const result = await response.json(); if (response.ok) { toast.success(`Asignación ${!assignment.isActive ? 'activada' : 'desactivada'} exitosamente`); fetchAssignments(); } else { toast.error(result.message || 'Error al cambiar el estado de la asignación'); } } catch (error) { console.error('Error toggling assignment status:', error); toast.error('Error al cambiar el estado de la asignación'); } }; const validateForm = (): boolean => { if (!formData.teacherId) { toast.error('Por favor selecciona un profesor'); return false; } if (!formData.sectionId) { toast.error('Por favor selecciona una sección'); return false; } return true; }; const resetForm = () => { setFormData({ teacherId: '', sectionId: '', }); }; const openEditDialog = (assignment: TeacherAssignment) => { setEditingAssignment(assignment); setFormData({ teacherId: assignment.teacherId, sectionId: assignment.sectionId, }); setIsEditDialogOpen(true); }; const filteredAssignments = assignments.filter(assignment => { const searchLower = searchTerm.toLowerCase(); const teacherName = `${assignment.teacher.firstName} ${assignment.teacher.lastName}`.toLowerCase(); const sectionName = assignment.section.name.toLowerCase(); const className = assignment.section.class.name.toLowerCase(); const classCode = assignment.section.class.code.toLowerCase(); return teacherName.includes(searchLower) || sectionName.includes(searchLower) || className.includes(searchLower) || classCode.includes(searchLower); }); const getStatusBadgeVariant = (isActive: boolean) => { return isActive ? 'default' : 'secondary'; }; const getTeacherName = (teacher: Teacher) => { return `${teacher.firstName} ${teacher.lastName}`; }; const getSectionDisplay = (section: Section) => { return `${section.class.code} - ${section.class.name} (${section.name})`; }; return (

Asignaciones de Profesores

Gestiona las asignaciones de profesores a secciones

Crear Nueva Asignación Asigna un profesor a una sección específica.
Asignaciones del Sistema Lista de todas las asignaciones de profesores a secciones
setSearchTerm(e.target.value)} className="max-w-sm" />
{loading ? (
Cargando asignaciones...
) : ( Profesor Cédula Materia Sección Periodo Estado Fecha Asignación Acciones {filteredAssignments.length === 0 ? ( {searchTerm ? 'No se encontraron asignaciones que coincidan con la búsqueda' : 'No hay asignaciones registradas'} ) : ( filteredAssignments.map((assignment) => ( {getTeacherName(assignment.teacher)} {assignment.teacher.cedula}
{assignment.section.class.name}
{assignment.section.class.code}
{assignment.section.name} {assignment.section.class.period.name}
handleToggleActive(assignment)} /> {assignment.isActive ? 'Activa' : 'Inactiva'}
{new Date(assignment.createdAt).toLocaleDateString('es-ES')}
¿Estás seguro? Esta acción eliminará la asignación de {getTeacherName(assignment.teacher)} a la sección {assignment.section.name}. {assignment.isActive && ' Si existen registros de asistencia, la asignación será desactivada en lugar de eliminada.'} Cancelar handleDeleteAssignment(assignment.id)} className="bg-destructive text-destructive-foreground hover:bg-destructive/90" > Eliminar
)) )}
)}
{/* Edit Dialog */} Editar Asignación Modifica los detalles de la asignación.
); }