CourseRegistrationFaculty Component
Overview
The CourseRegistrationFaculty component is a React functional component designed for faculty members to review and approve student course registrations. It displays a filterable list of students who have registered for a specific course and allows faculty to select and approve multiple students at once.
Code Structure and Explanation
Imports
import React, { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import axios from "axios";
React,useEffect, anduseStatehooks for component structure and state managementuseParamsfrom React Router for accessing URL parametersaxiosfor making HTTP requests to the backend API
Component Definition and State Management
const CourseRegistrationFaculty = () => {
const { courseCode } = useParams();
const [students, setStudents] = useState([]);
const [filters, setFilters] = useState({ rollNo: "", name: "", program: "", semester: "" });
const [selectedStudents, setSelectedStudents] = useState([]);
const [loading, setLoading] = useState(true);
// ... component implementation
}
- courseCode: Extracted from URL parameters to identify which course to display
- students: Array state to store the list of registered students
- filters: Object state with properties for filtering the student list
- selectedStudents: Array state to track which students are selected for approval
- loading: Boolean state to manage loading state during API calls
Data Fetching
const fetchStudents = async () => {
try {
const response = await axios.get(`http://localhost:8000/api/facultyCourse/course-registrations/${courseCode}`);
if (response.data.success) {
setStudents(response.data.students);
}
} catch (error) {
console.error("Error fetching students:", error);
} finally {
setLoading(false);
}
};
useEffect(() => {
fetchStudents();
}, [courseCode]);
fetchStudents: Asynchronous function that retrieves student registration data from the APIuseEffect: Hook that callsfetchStudentswhen the component mounts or whencourseCodechanges- Error handling with console logging
- Loading state management (set to false after fetch completes, regardless of success/failure)
Filtering Logic
const filteredStudents = students.filter((student) =>
Object.entries(filters).every(([key, value]) =>
(student[key] || "").toString().toLowerCase().includes(value.toLowerCase())
)
);
- Creates a filtered subset of students based on current filter values
- Uses
Object.entriesto loop through all filter criteria - Applies case-insensitive substring matching for each filter field
- Handles potential null/undefined values with fallback to empty string
- Shows only students that match ALL filter criteria (using
.every())
Student Selection Handler
const handleSelectStudent = (rollNo) => {
setSelectedStudents((prev) =>
prev.includes(rollNo) ? prev.filter((id) => id !== rollNo) : [...prev, rollNo]
);
};
- Toggles a student's selection status when their checkbox is clicked
- If student is already selected, removes them from the array
- If student is not selected, adds them to the array
- Uses functional update pattern to safely update based on previous state
Approval Handler
const handleApprove = async () => {
try {
const response = await axios.post("http://localhost:8000/api/facultyCourse/approve-registrations", {
courseCode,
students: selectedStudents,
});
if (response.data.success) {
alert(`Approved ${selectedStudents.length} students!`);
setSelectedStudents([]);
fetchStudents(); // Refresh the list
} else {
alert("Some error occurred while approving.");
}
} catch (error) {
console.error("Error approving students:", error);
alert("An error occurred.");
}
};
- Sends a POST request to approve the selected students for the course
- Provides payload with course code and array of selected student roll numbers
- Handles successful approval with user feedback and list refresh
- Clears selection after successful approval
- Provides error feedback for both API errors and unsuccessful responses
Render Function
return (
<div className="p-5">
<h2 className="text-2xl font-bold mb-4">Students Registered for {courseCode}</h2>
<div className="grid grid-cols-1 md:grid-cols-4 gap-4 mb-4">
{["rollNo", "name", "program", "semester"].map((key) => (
<input
key={key}
type="text"
placeholder={`Filter by ${key}`}
className="border p-2 rounded-md"
value={filters[key]}
onChange={(e) => setFilters({ ...filters, [key]: e.target.value })}
/>
))}
</div>
{loading ? (
<p>Loading students...</p>
) : (
<table className="w-full border-collapse border border-gray-300">
<thead>
<tr className="bg-gray-200">
<th className="border p-2">
<input
type="checkbox"
onChange={(e) =>
setSelectedStudents(e.target.checked ? students.map((s) => s.rollNo) : [])
}
checked={selectedStudents.length === students.length}
/>
</th>
<th className="border p-2">Roll No</th>
<th className="border p-2">Name</th>
<th className="border p-2">Program</th>
<th className="border p-2">Semester</th>
</tr>
</thead>
<tbody>
{filteredStudents.map((student) => (
<tr key={student.rollNo} className="hover:bg-gray-100">
<td className="border p-2 text-center">
<input
type="checkbox"
checked={selectedStudents.includes(student.rollNo)}
onChange={() => handleSelectStudent(student.rollNo)}
/>
</td>
<td className="border p-2">{student.rollNo}</td>
<td className="border p-2">{student.name}</td>
<td className="border p-2">{student.program}</td>
<td className="border p-2">{student.semester}</td>
</tr>
))}
</tbody>
</table>
)}
<button
onClick={handleApprove}
className="mt-4 px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 disabled:opacity-50"
disabled={selectedStudents.length === 0}
>
Approve Selected
</button>
</div>
);
UI Structure and Elements
- Page Header: Displays the course code being viewed
- Filter Inputs:
- Dynamic generation of four filter inputs using array mapping
- Responsive grid layout (single column on mobile, four columns on larger screens)
- Real-time filtering as user types
- Loading State: Conditional rendering of loading message or table
- Student Table:
- Header with select-all checkbox functionality
- Columns for student details (roll number, name, program, semester)
- Individual row selection checkboxes
- Hover effect for better user experience
- Approval Button:
- Disabled when no students are selected
- Visual feedback with hover state
- Triggers the approval process for selected students
Technical Considerations
State Management
- Component uses local state for all functionality
- Separation of concerns between data, UI state, and selection state
- Optimized updates with functional state updates
Data Flow
- Course code is extracted from URL parameters
- Student data is fetched from the API based on course code
- Filtered view is derived from state rather than re-fetching
- Selections are maintained in state
- Approval action sends data to API and refreshes list
Filtering Implementation
- Client-side filtering for immediate response
- Dynamic filter criteria across multiple fields
- Case-insensitive matching for better usability
- Real-time filtering as users type in filter inputs
User Experience Features
- Loading state during data fetching
- Row hover effects for better visibility
- Disabled approval button when no selections are made
- Select all/none functionality
- Visual feedback after successful operations
- Error handling with user notifications
API Integration
- GET request to fetch registered students for a specific course
- POST request to approve selected students
- Error handling for both API requests
- Success/failure feedback to user
Integration Points
- Depends on React Router for URL parameter extraction
- Connects to faculty course API endpoints
- Uses Tailwind CSS for styling
- Assumes authentication/authorization is handled elsewhere