Skip to content

Commit

Permalink
Add completed frontend code
Browse files Browse the repository at this point in the history
  • Loading branch information
Colleen Polka authored and Colleen Polka committed Oct 17, 2023
1 parent 5b214fc commit 59cf91b
Show file tree
Hide file tree
Showing 5 changed files with 216 additions and 0 deletions.
37 changes: 37 additions & 0 deletions workshop-four/frontend.css
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;
}
40 changes: 40 additions & 0 deletions workshop-four/frontend.html
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>
7 changes: 7 additions & 0 deletions workshop-four/main.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
from fastapi import FastAPI, Path, Query, HTTPException
from starlette.middleware.cors import CORSMiddleware
from typing import Optional
from courses import COURSES
from admin import admin

app = FastAPI()

app.add_middleware(CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"])

app.include_router(admin, tags=["admin"])

my_courses= {}
Expand Down
6 changes: 6 additions & 0 deletions workshop-four/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

126 changes: 126 additions & 0 deletions workshop-four/scripts.js
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;
}

0 comments on commit 59cf91b

Please sign in to comment.