-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Colleen Polka
authored and
Colleen Polka
committed
Oct 17, 2023
1 parent
5b214fc
commit 59cf91b
Showing
5 changed files
with
216 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
body { | ||
font-family: sans-serif; | ||
padding: 1rem 2rem; | ||
display: flex; | ||
gap: 4rem; | ||
} | ||
|
||
body > div { | ||
flex-basis: 50%; | ||
} | ||
|
||
h2 { | ||
font-weight: bold; | ||
font-size: 2em; | ||
} | ||
|
||
.register { | ||
padding-bottom: 2rem; | ||
} | ||
|
||
.class-list { | ||
padding: 1rem 0; | ||
} | ||
|
||
.form { | ||
padding-top: 2.2rem; | ||
} | ||
|
||
.class-list > div { | ||
margin-bottom: 2rem; | ||
} | ||
|
||
.error-text { | ||
color: red; | ||
white-space: pre; | ||
height: 1.5rem; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<title>Course Registration</title> | ||
<link rel="stylesheet" type="text/css" href="frontend.css"/> | ||
</head> | ||
<body> | ||
<div> | ||
<div class="register"> | ||
<h2>Course Registration</h2> | ||
|
||
<div class="form"> | ||
<label for="class-select"> | ||
Select class to register for: | ||
</label> | ||
<select id="class-select"> | ||
</select> | ||
<button onclick="enroll()" id="register">Register</button> | ||
</div> | ||
<p id="error" class="error-text"></p> | ||
</div> | ||
|
||
<div> | ||
<h3>Currently Registered Classes</h3> | ||
<p>You are currently registered for <span id="registered">0</span> courses</p> | ||
<div class="class-list" id="registered-class-list"></div> | ||
</div> | ||
</div> | ||
<div> | ||
<h2>All Courses</h2> | ||
<label> | ||
Display only open courses? | ||
<input type="checkbox" onclick="toggleVisibleCourses()"/> | ||
</label> | ||
<div class="class-list" id="class-list"></div> | ||
</div> | ||
<script src="scripts.js" defer></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
// List of all courses | ||
const courses = []; | ||
|
||
// List of courses the user is enrolled in | ||
const enrolledCourses = []; | ||
|
||
// Holds error message for any issues with enrolling | ||
let enrollmentError = " "; | ||
|
||
// If only open classes are being displayed | ||
let onlyOpen = false; | ||
|
||
// Runs when the document successfully loads | ||
document.addEventListener("DOMContentLoaded", async () => { | ||
// Make a request for which classes are currently open | ||
const response = await fetch("http://localhost:8000/list-courses"); | ||
const data = await response.json(); | ||
|
||
// Take the courses returned by the endpoint and turn them into something we can actually use | ||
for (const [id, course] of Object.entries(data)) { | ||
courses.push({...course, id: id}) | ||
} | ||
|
||
// Render the interface | ||
render(); | ||
}) | ||
|
||
// Enroll in a course | ||
async function enroll() { | ||
// Get the ID of the course the user wants to register in | ||
const courseId = document.getElementById("class-select").value; | ||
|
||
// Make a request to enroll in the class | ||
const response = await fetch(`http://localhost:8000/class/${courseId}/enroll`, {method: "PUT"}); | ||
|
||
// Check that the request to enroll was successful | ||
if (response.ok) { | ||
// Reset the error message | ||
enrollmentError = ""; | ||
|
||
const enrolled = courses.find((course) => course.id === courseId) | ||
// Increment the enrollment by 1 since the user just enrolled | ||
enrolled.current_enr += 1; | ||
|
||
// Add the course to the user's list of courses | ||
enrolledCourses.push(enrolled); | ||
} else { | ||
const error = await response.json(); | ||
enrollmentError = error.detail; | ||
} | ||
|
||
// Re-render the interface | ||
render(); | ||
|
||
|
||
} | ||
|
||
// Toggle between displaying only open courses and all courses | ||
function toggleVisibleCourses() { | ||
onlyOpen = !onlyOpen; | ||
|
||
// Re-render the interface | ||
render(); | ||
} | ||
|
||
// Return a div element that nicely displays a class | ||
function returnCourseDiv(course) { | ||
const entry = document.createElement("div"); | ||
entry.append(Object.assign(document.createElement("h3"), {textContent: course.name})); | ||
entry.append(Object.assign(document.createElement("p"), {textContent: course.professor})); | ||
entry.append(Object.assign(document.createElement("p"), | ||
{ | ||
textContent: `Currently registered: ${course.current_enr}/${course.max_enr} | ||
${course.current_enr < course.max_enr ? "" : "FULL"}` | ||
})); | ||
return entry; | ||
} | ||
|
||
// Re-render data | ||
function render() { | ||
// Filter the course list to only display the courses the user has requested (either open or all) | ||
const filtered = courses.filter((course) => | ||
!(onlyOpen && course.current_enr >= course.max_enr) | ||
) | ||
|
||
// Populate the select with courses the user has not already registered for | ||
const select = document.getElementById("class-select"); | ||
// Reset the currently selected item | ||
select.selectedIndex = -1; | ||
// Clear the current contents of the select | ||
select.innerHTML = " "; | ||
|
||
// List all courses that the user has | ||
const open = filtered.filter((course) => !enrolledCourses.includes(course)); | ||
open.forEach((course) => { | ||
select.append(new Option(course.name, course.id)) | ||
}); | ||
|
||
// If there are no classes that can be registered for, disable the register button | ||
document.getElementById("register").disabled = open.length === 0; | ||
|
||
// Populate the course list with all the courses listed in the backend | ||
const list = document.getElementById("class-list"); | ||
// Clear the current list before using append | ||
list.innerHTML = ""; | ||
filtered.forEach((course) => { | ||
list.append(returnCourseDiv(course)); | ||
}) | ||
|
||
// Populate the list of registered courses | ||
const registeredList = document.getElementById("registered-class-list"); | ||
|
||
// Remove any of the current options in the list | ||
registeredList.innerHTML = ""; | ||
|
||
// Create an entry for every class the user is registered in | ||
enrolledCourses.forEach((course) => { | ||
registeredList.append(returnCourseDiv(course)); | ||
}) | ||
|
||
// Update the number of enrolled courses to match the number of courses the user is in | ||
document.getElementById("registered").innerText = enrolledCourses.length; | ||
|
||
// Render the error text | ||
document.getElementById("error").innerText = enrollmentError; | ||
} |