Skip to content

Adding Filter #5

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

Merged
merged 16 commits into from
Dec 12, 2023
Merged
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
Binary file added .DS_Store
Binary file not shown.
47 changes: 47 additions & 0 deletions overload/src/app/CourseFilter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
'use client'
import React from 'react';
import { FilterObject } from './course-rating/page';

type CourseFilterProps = {
filterOn: FilterObject;
setFilterOn: React.Dispatch<React.SetStateAction<FilterObject>>;
}

export const CourseFilter = ({ filterOn, setFilterOn }: CourseFilterProps) => {
const handleCheckboxChange = (target: string) => {
setFilterOn(prev => ({ ...prev, [target]: !prev[target] }))
};


return (
<div className="ml-20 mt-5 flex bg-white w-1/4 justify-center rounded-md">
<label className="space-x-10 ml-3 mr-3">
<input
type="checkbox"
checked={filterOn['Term 1']}
onChange={() => handleCheckboxChange('Term 1')}
className="mr-2 ml-2"
/>
Term 1
</label>
<label className="space-x-10 ml-3 mr-3">
<input
type="checkbox"
checked={filterOn['Term 2']}
onChange={() => handleCheckboxChange('Term 2')}
className="mr-2 ml-2"
/>
Term 2
</label>
<label className="-x-10 ml-3 mr-3">
<input
type="checkbox"
checked={filterOn['Term 3']}
onChange={() => handleCheckboxChange('Term 3')}
className="mr-2 ml-2"
/>
Term 3
</label>
</div>
)
}
7 changes: 2 additions & 5 deletions overload/src/app/api/home/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,9 @@ import { NextRequest, NextResponse } from 'next/server';
import prisma from '../../../../prisma/client';

export async function GET(request: NextRequest) {
const courses = await prisma.term.findMany({
where: {
term: 'Term 2'
},
const courses = await prisma.course.findMany({
include: {
course: true
termsOffered: true
}
})
return NextResponse.json(courses);
Expand Down
52 changes: 43 additions & 9 deletions overload/src/app/components/SearchBar.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
'use client';
import React from 'react';
import React, { useMemo } from 'react';
import CourseCard from './CourseCard';
import { CourseFilter } from '../CourseFilter';
import { FilterObject } from '../course-rating/page';

type Course = {
courseCode: string;
courseName: string;
termsOffered: Term[]
};

type Term = {
Expand All @@ -14,9 +17,15 @@ type Term = {
course: Course;
};

export const SearchBar = () => {
type SearchBarProps = {
setFilterOn: React.Dispatch<React.SetStateAction<FilterObject>>;
filterOn: FilterObject;
};


export const SearchBar = ({ filterOn, setFilterOn }: SearchBarProps) => {
const [searchTerm, setSearchTerm] = React.useState('');
const [dataList, setDataList] = React.useState([]);
const [dataList, setDataList] = React.useState<Course[]>([]);

React.useEffect(() => {
// Fetch the term list
Expand All @@ -31,17 +40,35 @@ export const SearchBar = () => {
});
}, []);

const filteredData: Term[] = dataList.filter((item: Term) =>
item.course.courseName.toLowerCase().includes(searchTerm.toLowerCase()) ||
item.course.courseCode.toLowerCase().includes(searchTerm.toLowerCase())
);
const filteredData = useMemo(() => {
let result = dataList;

// Filter by search
if (searchTerm) {
result = result.filter(item =>
item.courseName.toLowerCase().includes(searchTerm.toLowerCase()) ||
item.courseCode.toLowerCase().includes(searchTerm.toLowerCase())
);
}

// Filter by checkboxes
Object.keys(filterOn).forEach(termKey => {
if (filterOn[termKey]) {
result = result.filter(item =>
item.termsOffered.some(term => term.term === termKey)
);
}
});

return result;
}, [dataList, searchTerm, filterOn]);

const courseCards = filteredData.map((item, idx) => {
return (
<div key={idx}>
<CourseCard
courseCode={item.course.courseCode}
courseName={item.course.courseName}
courseCode={item.courseCode}
courseName={item.courseName}
/>
</div>
);
Expand All @@ -58,7 +85,14 @@ export const SearchBar = () => {
onChange={(e) => setSearchTerm(e.target.value)}
/>
</div>
<CourseFilter
setFilterOn={setFilterOn}
filterOn={filterOn}
/>
<ul className="flex flex-wrap justify-center">{courseCards}</ul>
</div>
);
};

// pull filter
// for each thingy
11 changes: 7 additions & 4 deletions overload/src/app/components/coursesList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,20 @@ type Term = {
course: Course;
};

export const CoursesList = async () => {
type CoursesListProps = {
selectedTerm: number
}

export const CoursesList = async ({ selectedTerm }: CoursesListProps) => {
//imitate delay

const res = await fetch('http://localhost:3000/api/home', {
cache: 'no-store',
});

const terms: Term[] = await res.json();
const courses: Course[] = await res.json();

const allCourses = terms.map((term, index) => {
const course = term.course;
const allCourses = courses.map((course, index) => {
return (
<CourseOption
key={index}
Expand Down
9 changes: 7 additions & 2 deletions overload/src/app/components/selectedCourse.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
export const SelectedCourse = () => {
type SelectedCourseProps = {
courseCode: string
courseName: string
}

export const SelectedCourse = ({ courseCode, courseName }: SelectedCourseProps) => {
return (
<div className="bg-white w-[100%] m-3 rounded-md">
SelectedCourse
{courseCode}: {courseName}
</div>
)
}
Expand Down
17 changes: 12 additions & 5 deletions overload/src/app/components/selectedCourses.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
"use client"
import { Course } from "../home/page";
import SelectedCourse from "./selectedCourse";
import Dropdown from "./termSelectDropDown";

export const SelectedCourses = () => {
type SelectedCoursesProps = {
selectedCourses: Course[]
handleSelectTerm: (term: number) => void;
}

export const SelectedCourses = ({ selectedCourses, handleSelectTerm }: SelectedCoursesProps) => {
const courses = selectedCourses.map((course) => <SelectedCourse key={course.courseCode} courseCode={course.courseCode} courseName={course.courseName}/>)

return (
<div className="flex flex-col h-[70%]">
<div className="flex justify-center pb-8">
<Dropdown />
<Dropdown handleSelectTerm={handleSelectTerm}/>
</div>
<div className="flex flex-col items-center p-8 bg-black ">
<SelectedCourse />
<SelectedCourse />
<SelectedCourse />
{courses}
</div>
</div>
)
Expand Down
20 changes: 13 additions & 7 deletions overload/src/app/components/termSelectDropDown.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
"use client"
import React, { useState } from 'react';

export default function Dropdown() {
// const [selectedOption, setSelectedOption] = useState('');
type DropdownProps = {
handleSelectTerm: (term: number) => void;
}

export default function Dropdown({ handleSelectTerm }: DropdownProps) {
const [selectedOption, setSelectedOption] = useState(1);

// const handleChange = (event: any) => {
// setSelectedOption(event.target.value);
// };
const handleChange = (event: any) => {
setSelectedOption(event.target.value);
};

return (
<div className="w-60">
<select
className="block w-full px-4 py-2 mt-2 bg-red-500 border border-gray-200 rounded-md shadow-sm focus:border-blue-500 focus:ring focus:ring-blue-200 focus:ring-opacity-50"
//value={selectedOption}
//onChange={handleChange}
defaultValue={1}
// value={selectedOption}
// onChange={() =>handleSelectTerm(selectedOption)}
>
<option value="">Select a Term</option>
<option value="term1">Term 1</option>
Expand Down
16 changes: 13 additions & 3 deletions overload/src/app/course-rating/page.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,29 @@
'use client';
import React from 'react'
import { SearchBar } from "../components/SearchBar"

export type FilterObject = {
[key: string]: boolean
}

export default function CourseRatingPage() {
const [filterOn, setFilterOn] = React.useState<FilterObject>({ 'Term 1': false, 'Term 2': false, 'Term 3': false });
return (
<div className="@apply bg-[#221f1f] h-screen">
<div className="@apply bg-[#221f1f] min-h-screen">
{/* <NavBar/> */}
<h1 className="pt-20 font-sans text-5xl text-white font-semibold p-5 text-left px-20">OverLoad</h1>
<SearchBar/>
<SearchBar
filterOn={filterOn}
setFilterOn={setFilterOn}
/>
{/* <SortButton/> */}
</div>
)
}

// Plan
// navbar
// search bar (look at to do list for inspo)
// search bar (look at to do list for inspo)
// array of CourseCards
// sort button
//
Expand Down
36 changes: 33 additions & 3 deletions overload/src/app/home/page.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,51 @@
"use client"
import SelectedCourses from "../components/selectedCourses";
import CoursesList from "../components/coursesList";
import { useState } from "react";
import Navbar from "../components/NavBar";

export type Course = {
courseCode: string
courseName: string
}

export const Home = async () => {
const [selectedTerm, setSelectedTerm] = useState<number>(1);
const [selectedCourses, setSelectedCourses] = useState<Course[]>([
{
courseCode: "COMP1511",
courseName: "Programming fundementalss"
}
])

const handleSelectTerm = (term: number) => {
setSelectedTerm(term);
}

const handleSelectCourse = (course: Course) => {
const currentlySelectedCourses = [...selectedCourses]
if (currentlySelectedCourses.length > 2) return;
currentlySelectedCourses.push(course);
setSelectedCourses(currentlySelectedCourses);
}

return (
<div className="bg-gray-500 h-[100vh]">
{/* <div className="text-center h-[20vh]">
hello
</div> */}
<Navbar />
<div className="text-center h-[20vh]">
top

</div>
<div className="flex pr-[8vw] pl-[8vw]">
<div className="w-[70%]">
{/* Content for the 70% width div */}
<SelectedCourses />
<SelectedCourses selectedCourses={selectedCourses} handleSelectTerm={handleSelectTerm}/>
</div>
<div className="w-[30%] bg-black">
{/* Content for the 30% width div */}
<CoursesList />
<CoursesList selectedTerm={selectedTerm}/>
</div>
</div>
</div>
Expand Down