diff --git a/backend/src/main/java/edu/gcc/hallmonitor/Filter.java b/backend/src/main/java/edu/gcc/hallmonitor/Filter.java index 5ed1745..f676d67 100644 --- a/backend/src/main/java/edu/gcc/hallmonitor/Filter.java +++ b/backend/src/main/java/edu/gcc/hallmonitor/Filter.java @@ -43,6 +43,7 @@ static void registerFilterType( static void init() { Days.init(); Department.init(); + Semester.init(); NumCredits.init(); ProfName.init(); Time.init(); diff --git a/backend/src/main/java/edu/gcc/hallmonitor/Semester.java b/backend/src/main/java/edu/gcc/hallmonitor/Semester.java new file mode 100644 index 0000000..27f76eb --- /dev/null +++ b/backend/src/main/java/edu/gcc/hallmonitor/Semester.java @@ -0,0 +1,39 @@ +package edu.gcc.hallmonitor; + +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + +public record Semester(String semester) implements Filter { + + @Override + public boolean filter(Course course) { + return course.semester().equals(semester); + } + + @Override + public JsonNode toJSON() { + ObjectNode root = Main.MAPPER.createObjectNode(); + root.put("type", "semester"); + root.put("value", semester); + return root; + } + + private static Filter deserialize(JsonNode value) { + return new Semester(value.asText()); + } + + private static Set possibleValues(List courses) { + return courses.stream() + .map(Course::semester) + .collect(Collectors.toSet()); + } + + public static void init() { + Filter.registerFilterType("semester", Semester::deserialize, Semester::possibleValues); + } +} + diff --git a/backend/src/test/java/edu/gcc/hallmonitor/SemesterTest.java b/backend/src/test/java/edu/gcc/hallmonitor/SemesterTest.java new file mode 100644 index 0000000..48da53b --- /dev/null +++ b/backend/src/test/java/edu/gcc/hallmonitor/SemesterTest.java @@ -0,0 +1,44 @@ +package edu.gcc.hallmonitor; + +import java.time.LocalTime; +import java.util.List; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class SemesterTest { + @Test + public void testSemesterFilter() { + Course fall = emptyWithSemester("2023_Fall"); + Course spring = emptyWithSemester("2024_Spring"); + + Semester filter = new Semester("2023_Fall"); + + assertEquals(true, filter.filter(fall)); + assertEquals(false, filter.filter(spring)); + } + + private static Course emptyWithSemester(String semester) { + return new Course( + "", + List.of(""), + "", + 0, + ' ', + "", + 0, + semester, + List.of(new CourseTime( + "M", + LocalTime.of(0, 0), + LocalTime.of(0, 0) + )), + false, + false, + 0, + 0 + ); + } +} + diff --git a/frontend/src/SearchPage.tsx b/frontend/src/SearchPage.tsx index 4f06a56..da3394e 100644 --- a/frontend/src/SearchPage.tsx +++ b/frontend/src/SearchPage.tsx @@ -22,6 +22,8 @@ interface Course { export default function SearchPage() { const courses_per_page = 10; const [query, setQuery] = useState(''); + const [semester, setSemester] = useState('ALL'); + const [semesters, setSemesters] = useState([]); const [department, setDepartment] = useState('ALL'); const [professor, setProfessor] = useState('ALL'); const [courses, setCourses] = useState([]); @@ -70,7 +72,7 @@ export default function SearchPage() { } search(); - }, [department, professor, days, credits, timeStart, timeEnd]); + }, [semester, department, professor, days, credits, timeStart, timeEnd]); //Toggles a course in the user's schedule and syncs with the backend. @@ -137,6 +139,12 @@ export default function SearchPage() { // updating all the filters + const updateSem = async (event: React.ChangeEvent) => { + const updated = event.target.value; + await updateFilter('semester', semester, updated); + setSemester(updated); + }; + const updateDept = async (event: React.ChangeEvent) => { const updated = event.target.value; await updateFilter('department', department, updated); @@ -179,6 +187,8 @@ export default function SearchPage() { }; const updateFilters = async () => { // Update: + // Semesters + setSemesters(await getValues('semester')); // Departments setDepartments(await getValues('department')); // Professors @@ -215,6 +225,9 @@ export default function SearchPage() { const resp = await fetch('/search/filter'); for (const filter of await resp.json()) { switch (filter.type) { + case "semester": + setSemester(filter.value); + break; case "department": setDepartment(filter.value); break; @@ -276,6 +289,7 @@ export default function SearchPage() { }); setDepartment('ALL'); + setSemester('ALL'); setProfessor('ALL'); setDays(new Set()); setCredits('ALL'); @@ -306,6 +320,13 @@ export default function SearchPage() {

Filters

+

Semester

+ + +

Department & Professor