From 43e9d0b87bc1f7cdcd2f8d107e91419df257b1e4 Mon Sep 17 00:00:00 2001 From: Matthew Rowland Date: Sun, 26 Jan 2025 11:38:15 -0800 Subject: [PATCH] chore: Clean up --- .../Catalog/Dashboard/Dashboard.module.scss | 1 + .../src/app/Catalog/Dashboard/index.tsx | 144 ++++++++---------- apps/frontend/src/app/Catalog/index.tsx | 4 +- .../components/Carousel/Carousel.module.scss | 2 +- .../Class/Class.module.scss} | 12 +- .../src/components/Carousel/Class/index.tsx | 76 +++++++++ .../src/components/Carousel/index.tsx | 12 +- .../src/components/CarouselClass/index.tsx | 71 --------- apps/frontend/src/components/Class/index.tsx | 10 +- apps/frontend/src/lib/recent-classes.ts | 58 +++++++ apps/frontend/src/lib/recents.ts | 47 ------ .../theme/src/components/Button/index.tsx | 4 +- .../theme/src/components/IconButton/index.tsx | 4 +- .../theme/src/components/MenuItem/index.tsx | 3 +- 14 files changed, 225 insertions(+), 223 deletions(-) rename apps/frontend/src/components/{CarouselClass/CarouselClass.module.scss => Carousel/Class/Class.module.scss} (83%) create mode 100644 apps/frontend/src/components/Carousel/Class/index.tsx delete mode 100644 apps/frontend/src/components/CarouselClass/index.tsx create mode 100644 apps/frontend/src/lib/recent-classes.ts delete mode 100644 apps/frontend/src/lib/recents.ts diff --git a/apps/frontend/src/app/Catalog/Dashboard/Dashboard.module.scss b/apps/frontend/src/app/Catalog/Dashboard/Dashboard.module.scss index 608e65b95..7733df435 100644 --- a/apps/frontend/src/app/Catalog/Dashboard/Dashboard.module.scss +++ b/apps/frontend/src/app/Catalog/Dashboard/Dashboard.module.scss @@ -8,6 +8,7 @@ border-radius: 8px; background-color: var(--foreground-color); flex-shrink: 0; + .error { color: var(--paragraph-color); text-align: center; diff --git a/apps/frontend/src/app/Catalog/Dashboard/index.tsx b/apps/frontend/src/app/Catalog/Dashboard/index.tsx index 0c9d6e397..6a9115c8e 100644 --- a/apps/frontend/src/app/Catalog/Dashboard/index.tsx +++ b/apps/frontend/src/app/Catalog/Dashboard/index.tsx @@ -1,4 +1,4 @@ -import { Dispatch, SetStateAction } from "react"; +import { Dispatch, SetStateAction, useMemo } from "react"; import { ArrowSeparateVertical, @@ -14,16 +14,15 @@ import { Button, Container, IconButton, Tooltip } from "@repo/theme"; import { DropdownMenu } from "@repo/theme"; import Carousel from "@/components/Carousel"; -import CarouselClass from "@/components/CarouselClass"; import { useReadUser } from "@/hooks/api"; import { ITerm } from "@/lib/api"; -import { getRecents } from "@/lib/recents"; +import { getRecentClasses } from "@/lib/recent-classes"; import styles from "./Dashboard.module.scss"; interface DashboardProps { - term: ITerm | null | undefined; - termList: ITerm[] | undefined; + term: ITerm; + terms: ITerm[]; expanded: boolean; setExpanded: Dispatch>; setOpen: Dispatch>; @@ -31,21 +30,24 @@ interface DashboardProps { export default function Dashboard({ term, - termList, + terms, expanded, setExpanded, setOpen, }: DashboardProps) { + const navigate = useNavigate(); const { data: user, loading: userLoading } = useReadUser(); - if (!term) return <>; - - const recents = getRecents().filter( - (v) => v.semester == term.semester && v.year == term.year + const recentClasses = useMemo( + () => + getRecentClasses().filter( + (recentClass) => + recentClass.semester === term.semester && + recentClass.year === term.year + ), + [term] ); - const navigate = useNavigate(); - return (
@@ -58,32 +60,21 @@ export default function Dashboard({ - {termList ? ( - termList - .filter( - ({ year, semester }, index) => - index === - termList.findIndex( - (term) => - term.semester === semester && term.year === year - ) - ) - .map((t) => { - return ( - - navigate(`/catalog/${t.year}/${t.semester}`) - } - > - {t.semester} {t.year} - - ); - }) - ) : ( - <> - )} - + {terms + .filter( + ({ year, semester }) => + year !== term.year || semester !== term.semester + ) + .map(({ year, semester }) => { + return ( + navigate(`/catalog/${year}/${semester}`)} + > + {semester} {year} + + ); + })}
@@ -101,20 +92,17 @@ export default function Dashboard({

{term.semester} {term.year}

- {term.startDate && term.endDate ? ( + {term.startDate && term.endDate && (

{moment(term.startDate).format("MMMM Do")} through{" "} {moment(term.endDate).format("MMMM Do")}

- ) : ( - <> )} - {/* } to="/semesters"> -
-
-
-
*/} - } to="/account"> + } + to="/account" + > {userLoading || !user ? (
Sign in to bookmark classes
@@ -126,47 +114,41 @@ export default function Dashboard({ ) : ( user?.bookmarkedClasses .filter( - (c) => - !term || (c.year == term.year && c.semester == term.semester) + (bookmarkedClass) => + bookmarkedClass.year === term.year && + bookmarkedClass.semester === term.semester ) - .map((c, i) => { + .map((bookmarkedClass, i) => { return ( -
- -
+ ); }) )} - - {recents.length !== 0 && ( - }> - {" "} - {recents - .filter( - (c) => - !term || (c.year == term.year && c.semester == term.semester) - ) - .reverse() - .map((c, i) => { + + {recentClasses.length !== 0 && ( + }> + {recentClasses.map( + ({ subject, year, semester, courseNumber, number }, i) => { return ( -
- -
+ ); - })} -
+ } + )} + )}
diff --git a/apps/frontend/src/app/Catalog/index.tsx b/apps/frontend/src/app/Catalog/index.tsx index 07f1d759e..77a2d6949 100644 --- a/apps/frontend/src/app/Catalog/index.tsx +++ b/apps/frontend/src/app/Catalog/index.tsx @@ -102,7 +102,7 @@ export default function Catalog() { } // TODO: Error state - if (!term) { + if (!terms || !term) { return <>; } @@ -145,7 +145,7 @@ export default function Catalog() { ) : ( data, [data]); + + return loading || !_class ? ( + <> + ) : ( + +
+
+

+ {_class.subject} {_class.courseNumber} #{_class.number} +

+

+ {_class.title ?? _class.course.title} +

+
+ + + +
+
+
+
+ +
+
+
+
+ ); +} diff --git a/apps/frontend/src/components/Carousel/index.tsx b/apps/frontend/src/components/Carousel/index.tsx index caede1b83..5c31476b6 100644 --- a/apps/frontend/src/components/Carousel/index.tsx +++ b/apps/frontend/src/components/Carousel/index.tsx @@ -7,15 +7,16 @@ import { Link, To } from "react-router-dom"; import { IconButton } from "@repo/theme"; import styles from "./Carousel.module.scss"; +import Class from "./Class"; -interface CarouselProps { +interface RootProps { title: string; Icon: ReactNode; children: ReactNode; to?: To; } -export default function Carousel({ title, Icon, children, to }: CarouselProps) { +function Root({ title, Icon, children, to }: RootProps) { const [start, setStart] = useState(false); const [end, setEnd] = useState(false); @@ -97,3 +98,10 @@ export default function Carousel({ title, Icon, children, to }: CarouselProps) {
); } + +const Carousel = { + Root, + Class, +}; + +export default Carousel; diff --git a/apps/frontend/src/components/CarouselClass/index.tsx b/apps/frontend/src/components/CarouselClass/index.tsx deleted file mode 100644 index da34d48d1..000000000 --- a/apps/frontend/src/components/CarouselClass/index.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import { useMemo } from "react"; - -import { OpenInWindow } from "iconoir-react"; -import { Link } from "react-router-dom"; - -import AverageGrade from "@/components/AverageGrade"; -import Capacity from "@/components/Capacity"; -import Units from "@/components/Units"; -import { useReadClass } from "@/hooks/api"; -import { Semester } from "@/lib/api"; - -import styles from "./CarouselClass.module.scss"; - -interface CarouselClassProps { - year: number; - semester: Semester; - subject: string; - courseNumber: string; - number: string; -} - -export default function CarouselClass({ - year, - semester, - subject, - courseNumber, - number, -}: CarouselClassProps) { - const { data, loading } = useReadClass( - year as number, - semester as Semester, - subject as string, - courseNumber as string, - number as string - ); - - const _class = useMemo(() => data, [data]); - - return loading || !_class ? ( - <> - ) : ( - -
-

- {_class.subject} {_class.courseNumber} #{_class.number} -

-

- {_class.title ?? _class.course.title} -

-
- - - -
-
-
-
- -
-
- - ); -} diff --git a/apps/frontend/src/components/Class/index.tsx b/apps/frontend/src/components/Class/index.tsx index dfa5bcbe7..a6e253550 100644 --- a/apps/frontend/src/components/Class/index.tsx +++ b/apps/frontend/src/components/Class/index.tsx @@ -44,7 +44,7 @@ import { useReadCourse, useReadUser, useUpdateUser } from "@/hooks/api"; import { useReadClass } from "@/hooks/api/classes/useReadClass"; import usePins from "@/hooks/usePins"; import { IClass, Semester } from "@/lib/api"; -import { addToRecent } from "@/lib/recents"; +import { addRecentClass } from "@/lib/recent-classes"; import { getExternalLink } from "@/lib/section"; import styles from "./Class.module.scss"; @@ -236,9 +236,7 @@ export default function Class({ useEffect(() => { if (!_class) return; - console.log(_class); - - addToRecent({ + addRecentClass({ subject: _class.subject, year: _class.year, semester: _class.semester, @@ -277,7 +275,7 @@ export default function Class({ [styles.active]: bookmarked, })} onClick={() => bookmark()} - disabled={userLoading} // setting disabled to false still appears on my version + disabled={userLoading} > {bookmarked ? : } @@ -361,7 +359,7 @@ export default function Class({ as={Link} to={{ ...location, - pathname: `/catalog/${year}/${semester}`, + pathname: `/catalog/${_class.year}/${_class.semester}`, }} onClick={() => onClose()} > diff --git a/apps/frontend/src/lib/recent-classes.ts b/apps/frontend/src/lib/recent-classes.ts new file mode 100644 index 000000000..0bec4d1b6 --- /dev/null +++ b/apps/frontend/src/lib/recent-classes.ts @@ -0,0 +1,58 @@ +import { Semester } from "./api"; + +interface RecentClassData { + subject: string; + year: number; + semester: Semester; + courseNumber: string; + number: string; +} + +const RECENT_CLASSES_KEY = "recent-classes"; + +const RECENT_CLASSES_MAX_LENGTH = 10; + +export function addRecentClass({ + subject, + year, + semester, + courseNumber, + number, +}: RecentClassData) { + let recentClasses = getRecentClasses(); + + recentClasses = recentClasses.filter( + (recentClass) => + !( + subject == recentClass.subject && + year == recentClass.year && + semester == recentClass.semester && + courseNumber == recentClass.courseNumber && + number == recentClass.number + ) + ); + + recentClasses.unshift({ + subject: subject, + year: year, + semester: semester, + courseNumber: courseNumber, + number: number, + }); + + recentClasses = recentClasses.slice(0, RECENT_CLASSES_MAX_LENGTH); + + const item = JSON.stringify(recentClasses); + localStorage.setItem(RECENT_CLASSES_KEY, item); +} + +export function getRecentClasses() { + try { + const item = localStorage.getItem(RECENT_CLASSES_KEY); + if (!item) return []; + + return JSON.parse(item) as RecentClassData[]; + } catch { + return []; + } +} diff --git a/apps/frontend/src/lib/recents.ts b/apps/frontend/src/lib/recents.ts deleted file mode 100644 index 143d8b56f..000000000 --- a/apps/frontend/src/lib/recents.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { Semester } from "./api"; - -interface RecentClassData { - subject: string; - year: number; - semester: Semester; - courseNumber: string; - number: string; -} - -const RECENTS_LIST_MAX_LENGTH = 10; - -export function addToRecent({ - subject, - year, - semester, - courseNumber, - number, -}: RecentClassData) { - let recents = getRecents(); - const newRcd = { - subject: subject, - year: year, - semester: semester, - courseNumber: courseNumber, - number: number, - } as RecentClassData; - recents = recents.filter( - (rcd) => - !( - newRcd.subject == rcd.subject && - newRcd.year == rcd.year && - newRcd.semester == rcd.semester && - newRcd.courseNumber == rcd.courseNumber && - newRcd.number == rcd.number - ) - ); - recents.push(newRcd); - recents.splice(0, recents.length - RECENTS_LIST_MAX_LENGTH); - localStorage.setItem("recents-data", JSON.stringify(recents)); -} - -export function getRecents() { - const res = localStorage.getItem("recents-data"); - if (res) return JSON.parse(res) as RecentClassData[]; - return []; -} diff --git a/packages/theme/src/components/Button/index.tsx b/packages/theme/src/components/Button/index.tsx index eccd08137..e73038558 100644 --- a/packages/theme/src/components/Button/index.tsx +++ b/packages/theme/src/components/Button/index.tsx @@ -29,8 +29,8 @@ export const Button = forwardRef( {...props} ref={ref} data-variant={variant} - disabled={disabled} - data-disabled={disabled} + disabled={disabled || undefined} + data-disabled={disabled || undefined} className={classNames(styles.root, className)} > {children} diff --git a/packages/theme/src/components/IconButton/index.tsx b/packages/theme/src/components/IconButton/index.tsx index 3eed717cd..430399d8a 100644 --- a/packages/theme/src/components/IconButton/index.tsx +++ b/packages/theme/src/components/IconButton/index.tsx @@ -26,8 +26,8 @@ export const IconButton = forwardRef( ) => { return (