Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions admin/src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
import Sidebar from "./components/Sidebar";
import BranchRepresentatives from "./pages/BranchRepresentatives";
import Students from "./pages/Students";
import Courses from "./pages/Courses";
import CourseLinking from "./pages/CourseLinking";
import PrivateRoute from "./router_utils/PrivateRoutes";
Expand Down Expand Up @@ -31,6 +32,14 @@ function App() {
</PrivateRoute>
}
/>
<Route
path="/admin/students"
element={
<PrivateRoute>
<Students />
</PrivateRoute>
}
/>
<Route
path="/admin/course-linking"
element={
Expand Down
77 changes: 77 additions & 0 deletions admin/src/apis/student.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { API_BASE_URL } from "./server.js";

// Fetch all students, sorted by rollNumber descending (server-side)
// Pass brOnly=true to fetch only Branch Representatives
export const fetchStudents = async (brOnly = false) => {
try {
const url = `${API_BASE_URL}api/student/all${brOnly ? "?isBR=true" : ""}`;
const response = await fetch(url, { credentials: "include" });
return await response.json();
} catch (error) {
console.error("Error fetching students:", error);
throw error;
}
};

// Search students by name or roll number
// Pass brOnly=true to restrict search results to Branch Representatives
export const searchStudents = async (query, brOnly = false) => {
try {
const params = new URLSearchParams({ q: query });
if (brOnly) params.set("isBR", "true");

const response = await fetch(
`${API_BASE_URL}api/student/search?${params.toString()}`,
{ credentials: "include" }
);
return await response.json();
} catch (error) {
console.error("Error searching students:", error);
throw error;
}
};

export const refreshStudentCourses = async (id) => {
try {
const response = await fetch(`${API_BASE_URL}api/student/refresh/${id}`, {
method: "PUT",
credentials: "include",
});
const result = await response.json();
if (!response.ok) throw new Error(result.error || result.message || "Failed to refresh courses");
return result;
} catch (error) {
console.error("Error refreshing student courses:", error);
throw error;
}
};

export const deleteStudent = async (id) => {
try {
const response = await fetch(`${API_BASE_URL}api/student/${id}`, {
method: "DELETE",
credentials: "include",
});
const result = await response.json();
if (!response.ok) throw new Error(result.error || result.message || "Failed to delete student");
return result;
} catch (error) {
console.error("Error deleting student:", error);
throw error;
}
};

export const semesterReset = async () => {
try {
const response = await fetch(`${API_BASE_URL}api/student/semester-reset`, {
method: "POST",
credentials: "include",
});
const result = await response.json();
if (!response.ok) throw new Error(result.error || result.message || "Semester reset failed");
return result;
} catch (error) {
console.error("Error during semester reset:", error);
throw error;
}
};
3 changes: 2 additions & 1 deletion admin/src/components/Sidebar.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import React from "react";
import { Link, useLocation } from "react-router-dom";
import { FaBook, FaUsers, FaLayerGroup, FaLink } from "react-icons/fa";
import { FaBook, FaUsers, FaLayerGroup, FaLink, FaUserGraduate } from "react-icons/fa";
import { adminLogout } from "@/apis/auth";

const navItems = [
{ label: "Branch Representatives", to: "/admin/", icon: FaUsers },
{ label: "Students", to: "/admin/students", icon: FaUserGraduate },
{ label: "Courses", to: "/admin/courses", icon: FaBook },
{ label: "Course Linking", to: "/admin/course-linking", icon: FaLink },
];
Expand Down
Loading