160 lines
6.2 KiB
JavaScript
160 lines
6.2 KiB
JavaScript
// Kyler Olsen
|
|
// July 2025
|
|
|
|
let examSchedule = {};
|
|
|
|
function dark_mode() {
|
|
if (document.querySelector("body").getAttribute("mode") == "dark") {
|
|
document.querySelector("body").setAttribute("mode", "light");
|
|
// localStorage.removeItem("projects_color_mode");
|
|
localStorage.setItem("projects_color_mode", "light");
|
|
} else {
|
|
document.querySelector("body").setAttribute("mode", "dark");
|
|
localStorage.setItem("projects_color_mode", "dark");
|
|
}
|
|
}
|
|
|
|
function get_exam_time(classDays, classTime) {
|
|
const toMinutes = t => {
|
|
const [h, m] = t.split(":").map(Number);
|
|
return h * 60 + m;
|
|
};
|
|
const [hours, minutes] = classTime.split(":").map(Number);
|
|
// One credit courses will test on the last day of the regularly scheduled class period.
|
|
if (classDays.length === 1) {
|
|
// Get the last date of the class given 'earliest_date' in examSchedule
|
|
const earliestDate = new Date(examSchedule.earliest_date);
|
|
const classDay = classDays[0];
|
|
let lastDate = new Date(earliestDate);
|
|
lastDate.setDate(lastDate.getDate() - 1);
|
|
let dayMap = { "M": 1, "T": 2, "W": 3, "Th": 4, "F": 5 };
|
|
|
|
while (lastDate.getDay() !== dayMap[classDay]) {
|
|
lastDate.setDate(lastDate.getDate() - 1);
|
|
}
|
|
// Set the time to the class time
|
|
lastDate.setHours(hours, minutes, 0, 0);
|
|
return lastDate;
|
|
}
|
|
// Classes that meet on the quarter or three quarter hour (i.e. 2:15 or 2:45)
|
|
// will need to check with the instructor for the finals schedule.
|
|
if (minutes === 15 || minutes === 45) { return null; }
|
|
// Normal classes will test according to the exam schedule.
|
|
for (let schedule of examSchedule.schedule) {
|
|
if (
|
|
schedule.day === classDays[0] &&
|
|
toMinutes(schedule.start_time) <= toMinutes(classTime) &&
|
|
toMinutes(schedule.end_time) >= toMinutes(classTime)
|
|
) {
|
|
return new Date(schedule.exam_datetime);
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function remove_class(event) {
|
|
if (event.target.classList.contains("remove-class")) {
|
|
let row = event.target.closest("tr");
|
|
row.remove();
|
|
}
|
|
if (document.querySelector("#class-list").children.length === 0) {
|
|
document.querySelector(".class-list").classList.add("no-classes");
|
|
}
|
|
}
|
|
|
|
function add_class() {
|
|
// check if there is a time and at least one day selected
|
|
if (!document.querySelector("#time").value.trim() || (
|
|
!document.querySelector("#Mon").checked &&
|
|
!document.querySelector("#Tue").checked &&
|
|
!document.querySelector("#Wed").checked &&
|
|
!document.querySelector("#Thu").checked &&
|
|
!document.querySelector("#Fri").checked
|
|
)) {
|
|
document.querySelector(".error-message").classList.remove("hidden");
|
|
return;
|
|
}
|
|
document.querySelector(".error-message").classList.add("hidden");
|
|
|
|
if (document.querySelector(".class-list").classList.contains("no-classes")) {
|
|
document.querySelector(".class-list").classList.remove("no-classes");
|
|
}
|
|
|
|
let className = document.querySelector("#class-name").value.trim();
|
|
let classDaysReset = [];
|
|
let classDays = [];
|
|
if (document.querySelector("#Mon").checked) {classDaysReset.push("#Mon"); classDays.push("M");}
|
|
if (document.querySelector("#Tue").checked) {classDaysReset.push("#Tue"); classDays.push("T");}
|
|
if (document.querySelector("#Wed").checked) {classDaysReset.push("#Wed"); classDays.push("W");}
|
|
if (document.querySelector("#Thu").checked) {classDaysReset.push("#Thu"); classDays.push("Th");}
|
|
if (document.querySelector("#Fri").checked) {classDaysReset.push("#Fri"); classDays.push("F");}
|
|
let classTime = document.querySelector("#time").value.trim();
|
|
|
|
let examTime = get_exam_time(classDays, classTime);
|
|
let examTime_formatted = "";
|
|
if (examTime) {
|
|
examTime_formatted = examTime.toLocaleString('en-US', {
|
|
weekday: 'long',
|
|
month: 'long',
|
|
day: 'numeric',
|
|
hour: 'numeric',
|
|
minute: '2-digit',
|
|
hour12: true
|
|
});
|
|
} else {
|
|
examTime_formatted = "Check with instructor for final schedule";
|
|
}
|
|
|
|
if (className && classDays.length > 0 && classTime) {
|
|
let newRow = document.createElement("tr");
|
|
newRow.innerHTML = `
|
|
<td>${className}</td>
|
|
<td>${classDays.join(", ")}</td>
|
|
<td>${classTime}</td>
|
|
<td colspan="2">${examTime_formatted}</td>
|
|
<td><button class="remove-class">Remove</button></td>
|
|
`;
|
|
document.querySelector("#class-list").appendChild(newRow);
|
|
document.querySelector("#class-name").value = "";
|
|
document.querySelector("#time").value = "";
|
|
classDaysReset.forEach(day => {
|
|
if (document.querySelector(day).checked) {
|
|
document.querySelector(day).checked = false;
|
|
}
|
|
});
|
|
newRow.querySelector(".remove-class").addEventListener("click", remove_class);
|
|
}
|
|
}
|
|
|
|
function schedule_loaded() {
|
|
document.querySelector('h1 .semester').innerText = examSchedule.semester;
|
|
document.querySelector('#official-schedule').href = examSchedule.url;
|
|
document.querySelector('#official-schedule').innerText = "Snow College Official Final Exam Schedule";
|
|
}
|
|
|
|
function main() {
|
|
document.querySelector("#dark").addEventListener("click", dark_mode);
|
|
document.querySelector("#add-class").addEventListener("click", add_class);
|
|
|
|
const savedMode = localStorage.getItem("projects_color_mode");
|
|
const isDarkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
if (savedMode) {
|
|
document.querySelector("body").setAttribute("mode", savedMode);
|
|
} else if (isDarkMode) {
|
|
document.querySelector("body").setAttribute("mode", "dark");
|
|
}
|
|
|
|
fetch('./final_exams.json')
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
examSchedule = data;
|
|
schedule_loaded();
|
|
})
|
|
.catch(error => {
|
|
console.error('Error fetching exam schedule:', error);
|
|
document.querySelector('h1 .semester').innerText = 'Error loading exam schedule';
|
|
});
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded', main);
|