Skip to content
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
8 changes: 8 additions & 0 deletions .vite/deps/_metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"hash": "625b799d",
"configHash": "a9b0ffca",
"lockfileHash": "a6ff8f94",
"browserHash": "6b8947ac",
"optimized": {},
"chunks": {}
}
3 changes: 3 additions & 0 deletions .vite/deps/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"type": "module"
}
59 changes: 59 additions & 0 deletions package-lock.json

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

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@
},
"dependencies": {
"@tailwindcss/vite": "^4.0.2",
"framer-motion": "^12.4.1",
"prettier": "^3.4.2",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-icons": "^5.4.0",
"react-router-dom": "^7.1.5",
"tailwindcss": "^4.0.2"
},
Expand Down
15 changes: 13 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,27 @@ import React, { useState } from "react";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import Catalog from "./pages/Catalog";
import Planner from "./pages/Planner";
import Toolbox from "./components/Toolbox/Toolbox";

function App() {
const [toolboxCourses, setToolboxCourses] = useState({});
return (
<>
<div>
<div className="font-['Helvetica']">
<Router>
<Routes>
<Route path="/" element={<Catalog />}></Route>
<Route
path="/"
element={
<Catalog
toolboxCourses={toolboxCourses}
setToolboxCourses={setToolboxCourses}
/>
}
></Route>
<Route path="/planner" element={<Planner />}></Route>
</Routes>
<Toolbox courses={toolboxCourses} />
</Router>
</div>
</>
Expand Down
7 changes: 0 additions & 7 deletions src/components/Course.tsx

This file was deleted.

20 changes: 20 additions & 0 deletions src/components/Course/AddButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from "react";
import { IoAdd } from "react-icons/io5";

interface AddButtonProps {
addCourse: (e: React.MouseEvent<HTMLButtonElement>) => void;
}
const AddButton: React.FC<AddButtonProps> = ({ addCourse }) => {
return (
<>
<button
className={`border-2 border-black rounded-full p-1 text-4xl`}
onClick={addCourse}
>
<IoAdd />
</button>
</>
);
};

export default AddButton;
85 changes: 85 additions & 0 deletions src/components/Course/Course.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import React, { useState } from "react";
import Tag from "./Tag";
import AddButton from "./AddButton";
import { motion } from "framer-motion";
import { CourseType } from "../../types/interfaces/Course.interface";

interface CourseProps {
course: CourseType;
toolboxCourses: { [key: string]: number };
setToolboxCourses: React.Dispatch<
React.SetStateAction<{ [key: string]: number }>
>;
}

const Course: React.FC<CourseProps> = ({
course,
toolboxCourses,
setToolboxCourses,
}) => {
const [isOpen, setIsOpen] = useState(false);
const toggleOpen = (e: React.MouseEvent<HTMLDivElement>) => {
const target = e.target as HTMLElement;
if (target.id !== "add-button") setIsOpen((open) => !open);
};

const courseDisplay = `${course.department + course.code} ${course.name}`;
const addCourse = (e: React.MouseEvent<HTMLButtonElement>) => {
e.stopPropagation();
setToolboxCourses((prevCourses) => ({
...prevCourses,
[courseDisplay]: (prevCourses[courseDisplay] || 0) + 1,
}));
};

const courseCount = toolboxCourses[courseDisplay];
return (
<>
<div
className={`relative bg-[#F5CECE] border-2 border-black w-11/12 rounded-xl p-4 m-auto mt-4
`}
onClick={toggleOpen}
>
<div
className={`${
courseCount === undefined ? "hidden" : ""
} absolute right-[-10px] top-[-10px] rounded-full bg-[#78A1BB] w-8 h-8 flex justify-center items-center text-white`}
>
<p>{courseCount}</p>
</div>
<div className={`flex items-center justify-between`}>
<div className={`w-11/12`}>
<p className={`text-xl`}>
{course.department}
{course.code} {course.name}
</p>
<div className={`flex flex-wrap mt-1`}>
<Tag name={course.department} color={"4D5E87"} />
{course.attributesList.map((attr) => {
return <Tag name={attr} color={"4D5E87"} />;
})}
{course.semestersOffered.map((semester) => {
return <Tag name={semester} color={"4D5E87"} />;
})}
</div>
</div>
<div id="add-button" className={``}>
<AddButton addCourse={addCourse} />
</div>
</div>
<div className={`${isOpen ? "" : "hidden"} mt-2`}>
<motion.p
initial={{ height: 0, opacity: 0 }}
animate={isOpen ? { height: "auto", opacity: 1 } : {}}
className={`text-sm`}
transition={{ duration: 0.05 }}
>
{course.description}
</motion.p>
</div>
</div>
</>
);
};

export default Course;
20 changes: 20 additions & 0 deletions src/components/Course/Tag.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from "react";

interface TagProp {
name: string;
color: string;
}
const Tag: React.FC<TagProp> = ({ name, color }) => {
return (
<>
<div
className={`rounded-2xl text-white px-3 py-1 text-xs mr-1 mb-1 font-thin`}
style={{ backgroundColor: `#${color}` }}
>
{name}
</div>
</>
);
};

export default Tag;
40 changes: 40 additions & 0 deletions src/components/PlannerComponents/PlannerCourse.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React from "react";
import { MdDragIndicator, MdOutlineMoreHoriz } from "react-icons/md";
import { CourseType } from "../../types/interfaces/Course.interface";

interface PlannerCourseProps {
course: CourseType;
}

const PlannerCourse: React.FC<PlannerCourseProps> = ({ course }) => {
return (
<>
<div
className={`bg-[#283044] w-3/4 h-18 rounded-lg text-[#F5CECE] flex items-center`}
>
<div className={`flex justify-between w-11/12 m-auto text-2xl`}>
<div className={`flex items-center`}>
<MdDragIndicator />
<div className={`text-sm ml-1`}>
<b>
{course.department}
{course.code}
</b>
<p>{course.name}</p>
</div>
</div>
<div className={`flex items-center`}>
<div
className={`rounded-full bg-[#F5CECE] text-[#283044] w-5 h-5 flex items-center justify-center text-sm mr-1 font-medium`}
>
<p>{course.credits}</p>
</div>
<MdOutlineMoreHoriz />
</div>
</div>
</div>
</>
);
};

export default PlannerCourse;
20 changes: 20 additions & 0 deletions src/components/Toolbox/NavButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from "react";
import { Link, useLocation } from "react-router-dom";

const NavButton = () => {
const location = useLocation();
const path = location.pathname;

return (
<>
<Link
className={`bg-[#283044] text-[#F5CECE] border-[#F5CECE] border-1 px-[35vw] rounded-t-2xl py-1 absolute bottom-0`}
to={`${path == "/" ? "/planner" : "/"}`}
>
{path == "/" ? "Go to Planner" : "Go to Courses"}
</Link>
</>
);
};

export default NavButton;
Loading