Files
appointment_to_examiner/client/src/Pages/AdminCoursePage.jsx
2025-03-29 15:40:41 +05:30

314 lines
12 KiB
JavaScript

import React, { useState, useEffect } from 'react';
import axios from 'axios';
import Navbar from './Navbar';
import { toast, ToastContainer } from "react-toastify";
import 'react-toastify/dist/ReactToastify.css';
import { useNavigate } from 'react-router-dom';
export const AdminCoursePage = () => {
const [courses, setCourses] = useState([]);
const [showForm, setShowForm] = useState(false);
const [isEditMode, setIsEditMode] = useState(false);
const [searchQuery, setSearchQuery] = useState('');
const [isLoading, setIsLoading] = useState(true);
const [currentCourse, setCurrentCourse] = useState({
courseId: '',
name: '',
department: '',
program: '',
scheme: '',
semester: '',
status: 'not submitted',
});
const navigate = useNavigate();
// Fetch all courses
useEffect(() => {
const checkAdmin = async () => {
try {
const res = await axios.get("http://localhost:8080/api/me", { withCredentials: true });
if (!res.data.isAdmin) {
handleUnauthorizedAccess();
} else {
setIsLoading(false);
}
} catch (error) {
console.error("Unauthorized access:", error);
handleUnauthorizedAccess();
}
};
fetchCourses();
checkAdmin();
}, []);
const handleUnauthorizedAccess = async () => {
try {
toast.warning("Unauthorized access. Logging out...", { position: "top-center" });
// Attempt to log out
await axios.get("http://localhost:8080/auth/logout", { withCredentials: true });
// Delay redirection to show the toast message
setTimeout(() => {
navigate("/"); // Redirect to login
}, 1500);
} catch (error) {
console.error("Error during unauthorized access handling:", error);
}
};
// Fetch all courses after confirming admin status
useEffect(() => {
if (!isLoading) {
fetchCourses();
}
}, [isLoading]);
const fetchCourses = async () => {
try {
const res = await axios.get('http://localhost:8080/api/courses');
setCourses(res.data);
} catch (error) {
console.error("Error fetching courses: ", error);
}
};
// Add or Update Course
const handleAddOrUpdateCourse = async (e) => {
e.preventDefault();
try {
if (isEditMode) {
await axios.put(`http://localhost:8080/api/courses/${currentCourse.courseId}`, currentCourse);
toast.success('Course updated successfully!', { position: 'top-center' });
} else {
await axios.post('http://localhost:8080/api/courses', currentCourse);
toast.success('Course added successfully!', { position: 'top-center' });
}
resetForm();
fetchCourses();
} catch (error) {
console.error("Error adding/updating course:", error);
toast.error("An error occurred!", { position: 'top-center' });
}
};
// Delete Course
const handleDeleteCourse = async (courseId) => {
const confirm = window.confirm('⚠️ Are you sure you want to delete this course?');
if (confirm) {
try {
await axios.delete(`http://localhost:8080/api/courses/${courseId}`);
fetchCourses();
toast.success('Course deleted successfully!', { position: 'top-center' });
} catch (error) {
console.error("Error deleting course:", error);
toast.error("An error occurred!", { position: 'top-center' });
}
}
};
// Open Form for Edit
const handleOpenEditForm = (course) => {
setCurrentCourse(course);
setIsEditMode(true);
setShowForm(true);
};
// Open Form for Add
const handleOpenAddForm = () => {
resetForm();
setIsEditMode(false);
setShowForm(true);
};
// Reset form
const resetForm = () => {
setCurrentCourse({
courseId: '',
name: '',
department: '',
program: '',
scheme: '',
semester: '',
status: 'not submitted',
});
setShowForm(false);
};
const filteredCourses = courses.filter((course) =>
course.name.toLowerCase().includes(searchQuery.toLowerCase())
);
if (isLoading) {
return <p style={{ textAlign: 'center', marginTop: '50px', fontSize: '18px' }}>Loading...</p>;
}
return (
<>
<Navbar />
<ToastContainer />
<div style={{ fontFamily: 'Arial, sans-serif', backgroundColor: '#f4f6f9', padding: '20px' }}>
<h2 style={{ textAlign: 'center', color: '#333', marginBottom: '20px' }}>Course Management</h2>
<div style={{ textAlign: 'center', marginBottom: '20px' }}>
<input
type="text"
placeholder="Search course by name..."
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
style={inputStyle}
/>
<button onClick={handleOpenAddForm} style={addButtonStyle}>
+ Add New Course
</button>
</div>
</div>
{showForm && (
<div style={formStyle}>
<h3>{isEditMode ? 'Edit Course' : 'Add New Course'}</h3>
<form onSubmit={handleAddOrUpdateCourse}>
<input
placeholder="Course ID"
value={currentCourse.courseId}
onChange={(e) => setCurrentCourse({ ...currentCourse, courseId: e.target.value })}
style={inputStyle}
/>
<input
placeholder="Course Name"
value={currentCourse.name}
onChange={(e) => setCurrentCourse({ ...currentCourse, name: e.target.value })}
style={inputStyle}
/>
<input
placeholder="Department"
value={currentCourse.department}
onChange={(e) => setCurrentCourse({ ...currentCourse, department: e.target.value })}
style={inputStyle}
/>
<input
placeholder="Program"
value={currentCourse.program}
onChange={(e) => setCurrentCourse({ ...currentCourse, program: e.target.value })}
style={inputStyle}
/>
<input
placeholder="Scheme"
value={currentCourse.scheme}
onChange={(e) => setCurrentCourse({ ...currentCourse, scheme: e.target.value })}
style={inputStyle}
/>
<input
type="number"
placeholder="Semester"
value={currentCourse.semester}
onChange={(e) => setCurrentCourse({ ...currentCourse, semester: e.target.value })}
style={inputStyle}
/>
<select
value={currentCourse.status}
onChange={(e) => setCurrentCourse({ ...currentCourse, status: e.target.value })}
style={inputStyle}
>
<option value="submitted">Submitted</option>
<option value="not submitted">Not Submitted</option>
</select>
<div >
<button type="submit" style={submitButtonStyle}>
{isEditMode ? 'Update Course' : 'Add Course'}
</button>
<button type="button" onClick={() => setShowForm(false)} style={cancelButtonStyle}>
Cancel
</button>
</div>
</form>
</div>
)}
{/* TABLE DATA */}
<table style={tableStyle}>
<thead>
<tr>
<th>Course ID</th>
<th>Name</th>
<th>Department</th>
<th>Program</th>
<th>Scheme</th>
<th>Semester</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{filteredCourses.length > 0 ? (
filteredCourses.map((c) => (
<tr key={c.courseId}>
<td>{c.courseId}</td>
<td>{c.name}</td>
<td>{c.department}</td>
<td>{c.program}</td>
<td>{c.scheme}</td>
<td>{c.semester}</td>
<td>{c.status}</td>
<td>
<button onClick={() => handleOpenEditForm(c)} style={editButtonStyle}>Edit</button>
<button onClick={() => handleDeleteCourse(c.courseId)} style={deleteButtonStyle}>Delete</button>
</td>
</tr>
))
) : (
<tr>
<td colSpan="5" style={{ textAlign: 'center', color: 'red' }}>
No courses found
</td>
</tr>
)}
</tbody>
</table>
</>
);
};
const tableStyle = {
width: '100%',
borderCollapse: 'collapse',
marginTop: '20px',
};
const inputStyle = {
padding: '10px',
width: '250px',
borderRadius: '5px',
border: '1px solid #ddd',
fontSize: '16px',
marginRight: '10px',
};
const formStyle = {
backgroundColor: '#fff',
padding: '20px',
borderRadius: '10px',
maxWidth: '500px',
margin: '0 auto',
boxShadow: '0 5px 20px rgba(0,0,0,0.1)',
};
const addButtonStyle = {
backgroundColor: '#4CAF50',
color: '#fff',
padding: '10px 15px',
borderRadius: '5px',
border: 'none',
cursor: 'pointer',
};
const submitButtonStyle = { backgroundColor: '#4CAF50', color: 'white', padding: '10px 20px', borderRadius: '5px' };
const cancelButtonStyle = { backgroundColor: '#f44336', color: 'white', padding: '10px 20px', borderRadius: '5px' };
const editButtonStyle = { backgroundColor: '#4CAF50', color: 'white', padding: '5px 10px', borderRadius: '5px' };
const deleteButtonStyle = { backgroundColor: '#f44336', color: 'white', padding: '5px 10px', borderRadius: '5px' };
export default AdminCoursePage;