import React, { useEffect, useState } from 'react'; import { Check, Close, FilterList, KeyboardArrowDown, People, PersonAdd, Search } from '@mui/icons-material'; import useTimetableStore from '../../stores/timetableStore'; import Modal from '../../components/common/Modal'; interface RequestFilters { class_id?: string; status: 'pending' | 'approved' | 'rejected' | 'all'; search: string; } const EnrollmentRequestsPage: React.FC = () => { const { myClasses, enrollmentRequests, enrollmentRequestsLoading, enrollmentRequestsError, fetchMyClasses, fetchEnrollmentRequests, respondToEnrollmentRequest, } = useTimetableStore(); const [filters, setFilters] = useState({ status: 'pending', search: '', }); const [selectedRequest, setSelectedRequest] = useState(null); const [actionType, setActionType] = useState<'approve' | 'reject' | null>(null); const [notes, setNotes] = useState(''); const [processing, setProcessing] = useState(false); // Get classes where user is teacher const teachingClasses = myClasses.filter(c => c.role === 'teacher'); useEffect(() => { fetchMyClasses(); fetchEnrollmentRequests({ class_id: filters.class_id, status: filters.status === 'all' ? undefined : filters.status, }); }, [fetchMyClasses, fetchEnrollmentRequests, filters.class_id, filters.status]); const handleRespond = async () => { if (!selectedRequest || !actionType) return; setProcessing(true); try { await respondToEnrollmentRequest(selectedRequest, { status: actionType, notes: notes || undefined, }); setSelectedRequest(null); setActionType(null); setNotes(''); } finally { setProcessing(false); } }; // Filter requests by search const filteredRequests = enrollmentRequests.filter(request => { if (!filters.search) return true; const searchLower = filters.search.toLowerCase(); return ( request.student?.first_name?.toLowerCase().includes(searchLower) || request.student?.last_name?.toLowerCase().includes(searchLower) || request.student?.email?.toLowerCase().includes(searchLower) || request.class?.name?.toLowerCase().includes(searchLower) ); }); const getStatusBadge = (status: string) => { switch (status) { case 'pending': return Pending; case 'approved': return Approved; case 'rejected': return Rejected; default: return {status}; } }; if (enrollmentRequestsLoading && enrollmentRequests.length === 0) { return (
); } return (
{/* Header */}

Enrollment Requests

Manage student enrollment requests for your classes

{/* Filters */}
{/* Class Filter */}
{/* Status Filter */}
{/* Search */}
setFilters(prev => ({ ...prev, search: e.target.value }))} className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-md text-sm focus:ring-blue-500 focus:border-blue-500" />
{/* Error */} {enrollmentRequestsError && (

Error loading requests: {enrollmentRequestsError}

)} {/* Requests Table */} {filteredRequests.length > 0 ? (
{filteredRequests.map((request) => ( ))}
Student Class Requested Status Actions
{request.student?.first_name} {request.student?.last_name}
{request.student?.email}
{request.class?.name}
{request.class?.code && (
{request.class.code}
)}
{new Date(request.requested_at).toLocaleDateString()} {getStatusBadge(request.status)} {request.status === 'pending' && (
)} {request.status !== 'pending' && ( {request.responded_at && `Responded ${new Date(request.responded_at).toLocaleDateString()}`} )}
) : (

No enrollment requests

{filters.status === 'pending' ? 'There are no pending enrollment requests for your classes.' : 'No enrollment requests match your filters.' }

)} {/* Response Modal */} { setSelectedRequest(null); setActionType(null); setNotes(''); }} title={actionType === 'approve' ? 'Approve Enrollment' : 'Reject Enrollment'} maxWidth="max-w-md" >

{actionType === 'approve' ? 'Are you sure you want to approve this enrollment request? The student will be added to the class.' : 'Are you sure you want to reject this enrollment request?' }