diff --git a/backend/app/routes.py b/backend/app/routes.py index 9b9e64e..5c57a2e 100644 --- a/backend/app/routes.py +++ b/backend/app/routes.py @@ -24,7 +24,6 @@ def check_data(data, required_fields): def instructor_required(func): @wraps(func) def dec(*args, **kwargs): - print(current_user) if current_user.role != "instructor": return error_response(400, "User is not instructor!") return func(*args, **kwargs) @@ -173,3 +172,28 @@ def enroll_student(uid, cid): resp = {"user": u.to_dict(), "course": c.to_dict()} return jsonify(resp) +@bp.route("/user//enroll/", methods=["POST"]) +@login_required +@instructor_required +def enroll_student_by_username(username, cid): + u = User.query.filter_by(username=username).first() + if not u: + return error_response(400, f"User with username {username} does not exist") + + c = Course.query.get(cid) + if not c: + return error_response(400, f"Course with id {cid} does not exist") + + if request.method == "POST": + if not u.enroll(c): + return error_response( + 400, f"User {u.id} is already enrolled in course {cid}" + ) + + elif request.method == "DELETE": + if not u.unenroll(c): + return error_response(400, f"User {u.id} is not enrolled in course {cid}") + + resp = {"user": u.to_dict(), "course": c.to_dict()} + return jsonify(resp) + diff --git a/frontend/src/App.js b/frontend/src/App.js index 0f1ece6..946d60a 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -6,6 +6,7 @@ import LogoutPage from "./pages/LogoutPage"; import RegisterPage from "./pages/RegisterPage"; import CoursePage from "./pages/CoursePage"; import ManagePage from "./pages/ManagePage"; +import ManageStudentsPage from "./pages/ManageStudentsPage"; import AuthenticatedRoute from "./components/AuthenticatedRoute"; function App() { @@ -22,7 +23,7 @@ function App() { - + @@ -47,6 +48,16 @@ function App() { + + + {(params) => { + return ( + + + + ); + }} + ); } diff --git a/frontend/src/pages/ManageStudentsPage.jsx b/frontend/src/pages/ManageStudentsPage.jsx new file mode 100644 index 0000000..2da86f2 --- /dev/null +++ b/frontend/src/pages/ManageStudentsPage.jsx @@ -0,0 +1,123 @@ +import { useEffect, useState } from "react"; +import { Container, Table, Button, Form } from "react-bootstrap"; +import MyNavbar from "../components/MyNavbar"; +import { makeRequest } from "../utils.ts"; + +const ManageStutentsPage = ({ cid }) => { + const [studentData, setStudentData] = useState([]); + const [showAddStudentForm, setShowAddStudentForm] = useState(false); + + const submitStudentForm = async (username) => { + await makeRequest({ + url: `http://localhost:5000/user/${username}/enroll/${cid}`, + method: "POST", + }); + window.location.reload(); + return false; + }; + + const AddStudentForm = () => { + const [username, setUsername] = useState(""); + + return ( +
+
{ + submitStudentForm(username); + }} + > + + Username + setUsername(e.target.value)} + /> + + Make sure that a user with the username exists and is not already + enrolled in this course + + + +
+
+ ); + }; + useEffect(() => { + makeRequest({ + url: `http://localhost:5000/course/${cid}/students`, + method: "GET", + }) + .then((req) => req.json()) + .then(async (data) => { + setStudentData(data.students); + }) + .catch((err) => { + console.error(err); + }); + }, []); + + const sendUnenrollRequest = (uid) => { + makeRequest({ + url: `http://localhost:5000/user/${uid}/enroll/${cid}`, + method: "DELETE", + }).then((resp) => { + window.location.reload(); + }); + }; + + return ( +
+ + +

Manage Students

+ + {showAddStudentForm && } + + + + + + + + + + + {studentData.map((student, k) => { + return ( + + + + + + + ); + })} + +
#UsernameEmailManage
{student.id}{student.username}{student.email} +
+ +
+
+
+
+ ); +}; + +export default ManageStutentsPage;