Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated Finals Page #779

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
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
2 changes: 1 addition & 1 deletion src/api/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ uvicorn==0.14.0
python-multipart==0.0.5
fastapi-cache2==0.1.8
itsdangerous==2.0.1
sqlalchemy==1.4.2
sqlalchemy==1.4.1
245 changes: 169 additions & 76 deletions src/web/src/pages/FinalExamScheduler.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,57 @@
<b-col md="5">
<b-card title="Final Exam Schedule">
<b-form @submit.prevent="searchExams">
<div
v-for="(course, index) in selectedCourses"
:key="index"
class="mb-3"
>
<b-form-group :label="'Course ' + (index + 1)">
<b-form-select
v-model="selectedCourses[index]"
:options="courseOptions"
></b-form-select>
</b-form-group>
</div>
<b-button @click="addCourse" variant="primary">Add Course</b-button>
<b-button type="submit" variant="success" class="ml-3">
Search
</b-button>

<template>
<!-- COURSES CURRENTLY SELECTED AND DISPLAYED -->
<div v-for="(course, index) in selectedCourses" :key="index" class="mb-3">
<div class="d-flex align-items-center">
<b-form-group :label="'Course ' + (index + 1)" class="flex-grow-1">
<b-form-select @change="searchExams" v-model="selectedCourses[index]" :options="filterCourses(index)"></b-form-select>
</b-form-group>
<b-button @click="deleteCourse(index)" variant="danger" class="delete-button ml-2 mt-3">X</b-button>
</div>
</div>
</template>

<template>
<div class = "button-container">

<!-- ADD COURSE BUTTON FOR ADDING NEW COURSE -->
<b-button @click="$bvModal.show('add-modal-id')" variant="primary" class = "mt-3">Add Course</b-button>

<b-modal id="add-modal-id" hide-footer title="Add Course"
@close="$bvModal.hide('add-modal-id')"
@keydown.esc="$bvModal.hide('add-modal-id')">

<b-form-group :label="''">
<b-form-select
v-model="currCourse"
:options="filterCourses()"
></b-form-select>
</b-form-group>

<!-- CONFIRM / CANCEL BUTTONS WITHIN ADD CLASS -->
<b-button class="mt-3" variant="success" block
@click="currCourse ? ($bvModal.hide('add-modal-id'), addCourse(currCourse), searchExams()) : null">
Confirm
</b-button>
<b-button class="mt-3" variant="danger" block @click="$bvModal.hide('add-modal-id')">
Cancel
</b-button>

</b-modal>
<!-- Remove All Classes Button -->
<b-button v-if="this.selectedCourses.length > 1" @click="deleteAllCourses()" variant="danger" class="mt-3">
Remove All Courses
</b-button>

</div>
</template>
</b-form>
<b-card v-if="examDetails" class="mt-3">

<!-- EXAM DETAILS CARD -->
<b-card v-if="examDetails && this.selectedCourses.length!==0" class="mt-3">
<h5 class="card-title">Exam Details</h5>
<div v-for="exam in examDetails" :key="exam.id">
<div>
Expand All @@ -45,10 +78,26 @@
<strong>Date:</strong>
{{ exam.day }}, {{ exam.dayOfWeek }}
</div>
<hr v-if="exam !== examDetails[examDetails.length - 1]" />
<hr v-if="exam !== examDetails[examDetails.length - 1]"/>
</div>
</b-card>
</b-card>

<b-col md="7">
<div class="mt-3">
<b-button variant="secondary" class = "button-color" @click="showConfirmModal">Get Updated PDF for All </b-button>

<b-modal id="confirm-modal-id" hide-footer title="Confirmation">

<p>Are you sure you want to go to this page?</p>
<b-button class = "mt-3" variant="primary" @click="goToSchoolWebsite">Yes</b-button>
<b-button class = "mt-3" variant="danger" @click="cancelNavigation">No</b-button>

</b-modal>

</div>
</b-col>

</b-col>
<b-col md="7">
<calendar :exam-details="examDetails"></calendar>
Expand All @@ -61,6 +110,7 @@
import Finals from "./Finals.json";
import Calendar from "./Calendar.vue";


export default {
components: {
Calendar,
Expand All @@ -78,10 +128,13 @@ export default {
},
],
exams: Finals,
selectedCourses: [null],
currCourse: null,
selectToDelete: [],
selectedCourses: [],
courseOptions: [],
examDetails: [],
calendarWeeks: [],
coursesOnSchedule: [],
};
},
mounted() {
Expand All @@ -100,11 +153,11 @@ export default {
endDateTime.setHours(parseInt(endHour));
endDateTime.setMinutes(parseInt(endMinutes));

return { startTime: startDateTime, endTime: endDateTime };
return {startTime: startDateTime, endTime: endDateTime};
},

formatDate(date) {
const month = date.toLocaleString("default", { month: "short" });
const month = date.toLocaleString("default", {month: "short"});
const day = date.getDate();
return `${month} ${day}`;
},
Expand All @@ -118,7 +171,7 @@ export default {
initCourseOptions() {
const groupedCourses = this.exams.reduce((acc, exam) => {
const key =
exam.Department + " - " + exam.CourseCode + " - " + exam.Section;
exam.Department + " - " + exam.CourseCode + " - " + exam.Section;
if (!acc[key]) {
acc[key] = {
value: exam,
Expand All @@ -132,52 +185,55 @@ export default {

this.courseOptions = Object.values(groupedCourses);
},
addCourse() {
this.selectedCourses.push(null);
addCourse(currCourse) {
if (currCourse !== null) {
this.selectedCourses.push(currCourse);
}
this.currCourse = null;
},
searchExams() {
const examDetailsRaw = this.selectedCourses.flatMap((course) => {
return this.exams
.filter(
(exam) =>
exam.CourseCode === course.CourseCode &&
exam.Section === course.Section
)
.map((exam) => {
const { startTime, endTime } = this.formatExamDateTime(
exam.Day,
exam.Hour
);
return {
id:
course.Department +
" " +
course.CourseCode +
" " +
course.Section +
" " +
exam.Day,
course: course.Department + " " + course.CourseCode,
section: course.Section,
room: exam.Room,
time: exam.Hour,
day: exam.Day,
dayOfWeek: (() => {
const dateObj = new Date(exam.Day);
const dayIndex = (dateObj.getDay() + 6) % 7;
const options = { weekday: "long" };
return new Intl.DateTimeFormat("default", options).format(
new Date(
dateObj.setDate(
dateObj.getDate() - dateObj.getDay() + dayIndex
)
)
);
})(),
time_start: startTime.toISOString(),
time_end: endTime.toISOString(),
};
});
.filter(
(exam) =>
exam.CourseCode === course.CourseCode &&
exam.Section === course.Section
)
.map((exam) => {
const {startTime, endTime} = this.formatExamDateTime(
exam.Day,
exam.Hour
);
return {
id:
course.Department +
" " +
course.CourseCode +
" " +
course.Section +
" " +
exam.Day,
course: course.Department + " " + course.CourseCode,
section: course.Section,
room: exam.Room,
time: exam.Hour,
day: exam.Day,
dayOfWeek: (() => {
const dateObj = new Date(exam.Day);
const dayIndex = (dateObj.getDay() + 6) % 7;
const options = {weekday: "long"};
return new Intl.DateTimeFormat("default", options).format(
new Date(
dateObj.setDate(
dateObj.getDate() - dateObj.getDay() + dayIndex
)
)
);
})(),
time_start: startTime.toISOString(),
time_end: endTime.toISOString(),
};
});
});

const examDetailsGrouped = examDetailsRaw.reduce((acc, exam) => {
Expand All @@ -191,24 +247,46 @@ export default {

this.examDetails = Object.values(examDetailsGrouped);

console.log(this.examDetails);
},

deleteCourse(index) {
// Remove the course from selectedCourses using the removeCourse method
this.selectedCourses.splice(index, 1);
this.searchExams();
},

deleteAllCourses() {
// Remove all Courses by resetting the array of selected courses.
this.selectedCourses = [];
this.searchExams();
},

filterCourses(index) {
return this.courseOptions.filter(option => {
if (index !== undefined) {
return !this.selectedCourses.includes(option.value) || option.value === this.selectedCourses[index];
} else {
return !this.selectedCourses.includes(option.value);
}
});
},

showConfirmModal() {
this.$bvModal.show('confirm-modal-id');
},

goToSchoolWebsite() {
window.open('https://info.rpi.edu/registrar/grades', '_blank');
},

cancelNavigation() {
this.$bvModal.hide('confirm-modal-id');
},
},
};
</script>

<style>
.pathway-button {
display: inline-block;
background: white;
border-style: none;
text-align: justify;
width: 95%;
}

.pathway-button:hover {
background: rgba(108, 90, 90, 0.15) !important;
}

.text-left {
position: absolute;
Expand All @@ -225,4 +303,19 @@ export default {
width: 20%;
position: relative;
}

.button-container {
display: flex;
gap: 20px;
}

.button-color {
color:white;
}

.button-color:hover {
color: black;

}

</style>
Loading