Skip to content

Commit

Permalink
chore: Clean up Carousel and recent classes
Browse files Browse the repository at this point in the history
  • Loading branch information
mathhulk committed Mar 8, 2025
1 parent a47f9cf commit 0d9b587
Show file tree
Hide file tree
Showing 13 changed files with 231 additions and 343 deletions.
124 changes: 78 additions & 46 deletions apps/frontend/src/app/Catalog/Dashboard/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import { Dispatch, SetStateAction, useMemo } from "react";
import {
Dispatch,
SetStateAction,
useCallback,
useEffect,
useMemo,
useState,
} from "react";

import { useApolloClient } from "@apollo/client";
import {
ArrowSeparateVertical,
BookmarkSolid,
Expand All @@ -14,9 +22,11 @@ import { Button, Container, IconButton, Tooltip } from "@repo/theme";
import { DropdownMenu } from "@repo/theme";

import Carousel from "@/components/Carousel";
import ClassCard from "@/components/ClassCard";
import ClassDrawer from "@/components/ClassDrawer";
import { useReadUser } from "@/hooks/api";
import { ITerm } from "@/lib/api";
import { sortDescendingTerm } from "@/lib/classes";
import { IClass, ITerm, READ_CLASS, ReadClassResponse } from "@/lib/api";
import { sortByTermDescending } from "@/lib/classes";
import { getRecentClasses } from "@/lib/recent-classes";

import styles from "./Dashboard.module.scss";
Expand All @@ -37,18 +47,57 @@ export default function Dashboard({
setOpen,
}: DashboardProps) {
const navigate = useNavigate();
const { data: user, loading: userLoading } = useReadUser();
const client = useApolloClient();

const { data: user } = useReadUser();

const recentClasses = useMemo(
const bookmarkedClasses = useMemo(
() =>
getRecentClasses().filter(
(recentClass) =>
recentClass.semester === term.semester &&
recentClass.year === term.year
user?.bookmarkedClasses.filter(
(bookmarkedClass) =>
bookmarkedClass.year === term.year &&
bookmarkedClass.semester === term.semester
),
[term]
[term, user]
);

const [recentClasses, setRecentClasses] = useState<IClass[]>([]);

const initialize = useCallback(async () => {
const recentClasses = getRecentClasses();

const responses = await Promise.all(
recentClasses.map(async (recentClass) => {
const { subject, year, semester, courseNumber, number } = recentClass;

try {
const response = await client.query<ReadClassResponse>({
query: READ_CLASS,
variables: {
subject,
year,
semester,
courseNumber,
number,
},
});

return response.data.class;
} catch {
// TODO: Handle errors

return;
}
})
);

setRecentClasses(responses.filter((response) => !!response));
}, [client]);

useEffect(() => {
initialize();
}, [initialize]);

return (
<div className={styles.root}>
<Container size="sm">
Expand All @@ -69,7 +118,7 @@ export default function Dashboard({
(term) => term.semester === semester && term.year === year
)
)
.toSorted(sortDescendingTerm((d) => d))
.toSorted(sortByTermDescending)
.map(({ year, semester }) => {
return (
<DropdownMenu.Item
Expand Down Expand Up @@ -108,51 +157,34 @@ export default function Dashboard({
Icon={<BookmarkSolid />}
to="/account"
>
{userLoading || !user ? (
{/* TODO: Better placeholder states */}
{!bookmarkedClasses ? (
<div className={styles.card}>
<div className={styles.error}>Sign in to bookmark classes</div>
</div>
) : user?.bookmarkedClasses.length == 0 ? (
) : bookmarkedClasses.length === 0 ? (
<div className={styles.card}>
<div className={styles.error}>No bookmarked classes</div>
</div>
) : (
user?.bookmarkedClasses
.filter(
(bookmarkedClass) =>
bookmarkedClass.year === term.year &&
bookmarkedClass.semester === term.semester
)
.map((bookmarkedClass, i) => {
return (
<Carousel.Class
key={i}
subject={bookmarkedClass.subject}
year={bookmarkedClass.year}
semester={bookmarkedClass.semester}
courseNumber={bookmarkedClass.courseNumber}
number={bookmarkedClass.number}
/>
);
})
bookmarkedClasses.map((bookmarkedClass, index) => (
<ClassDrawer {...bookmarkedClass}>
<Carousel.Item key={index}>
<ClassCard class={bookmarkedClass} />
</Carousel.Item>
</ClassDrawer>
))
)}
</Carousel.Root>
{recentClasses.length !== 0 && (
{recentClasses.length > 0 && (
<Carousel.Root title="Recently viewed" Icon={<Search />}>
{recentClasses.map(
({ subject, year, semester, courseNumber, number }, i) => {
return (
<Carousel.Class
key={i}
subject={subject}
year={year}
semester={semester}
courseNumber={courseNumber}
number={number}
/>
);
}
)}
{recentClasses.map((recentClass, index) => (
<ClassDrawer {...recentClass}>
<Carousel.Item key={index}>
<ClassCard class={recentClass} />
</Carousel.Item>
</ClassDrawer>
))}
</Carousel.Root>
)}
</Container>
Expand Down
13 changes: 7 additions & 6 deletions apps/frontend/src/components/Capacity/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import { Tooltip } from "radix-ui";

import styles from "./Capacity.module.scss";

const getColor = (count: number | undefined, capacity: number | undefined) => {
if (count === undefined || capacity === undefined)
const getColor = (count?: number, capacity?: number) => {
if (typeof count !== "number" || typeof capacity !== "number")
return "var(--paragraph-color)";

const percentage = count / capacity;

return percentage >= 0.75
Expand All @@ -18,10 +19,10 @@ const getColor = (count: number | undefined, capacity: number | undefined) => {
};

interface CapacityProps {
enrolledCount: number | undefined;
maxEnroll: number | undefined;
waitlistedCount: number | undefined;
maxWaitlist: number | undefined;
enrolledCount?: number;
maxEnroll?: number;
waitlistedCount?: number;
maxWaitlist?: number;
}

export default function Capacity({
Expand Down
5 changes: 5 additions & 0 deletions apps/frontend/src/components/Carousel/Carousel.module.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
.item {
flex-shrink: 0;
width: 288px;
}

.root {
display: flex;
flex-direction: column;
Expand Down
6 changes: 0 additions & 6 deletions apps/frontend/src/components/Carousel/Class/Class.module.scss

This file was deleted.

88 changes: 0 additions & 88 deletions apps/frontend/src/components/Carousel/Class/index.tsx

This file was deleted.

15 changes: 12 additions & 3 deletions apps/frontend/src/components/Carousel/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { ReactNode, UIEvent, useRef, useState } from "react";
import {
ComponentPropsWithRef,
ReactNode,
UIEvent,
useRef,
useState,
} from "react";

import classNames from "classnames";
import { ArrowRight, NavArrowLeft, NavArrowRight } from "iconoir-react";
Expand All @@ -7,7 +13,10 @@ import { Link, To } from "react-router-dom";
import { IconButton } from "@repo/theme";

import styles from "./Carousel.module.scss";
import Class from "./Class";

function Item({ className, ...props }: ComponentPropsWithRef<"div">) {
return <div className={classNames(styles.item, className)} {...props} />;
}

interface RootProps {
title: string;
Expand Down Expand Up @@ -101,7 +110,7 @@ function Root({ title, Icon, children, to }: RootProps) {

const Carousel = {
Root,
Class,
Item,
};

export default Carousel;
14 changes: 7 additions & 7 deletions apps/frontend/src/components/ClassBrowser/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -183,9 +183,9 @@ export default function ClassBrowser({

if (sortBy === SortBy.OpenSeats) {
const getOpenSeats = ({ primarySection: { enrollment } }: IClass) =>
enrollment === undefined
? 0
: enrollment.latest.maxEnroll - enrollment.latest.enrolledCount;
enrollment
? enrollment.latest.maxEnroll - enrollment.latest.enrolledCount
: 0;

return getOpenSeats(b) - getOpenSeats(a);
}
Expand All @@ -194,11 +194,11 @@ export default function ClassBrowser({
const getPercentOpenSeats = ({
primarySection: { enrollment },
}: IClass) =>
enrollment === undefined || enrollment.latest.maxEnroll === 0
? 0
: (enrollment.latest.maxEnroll -
enrollment?.latest.maxEnroll
? (enrollment.latest.maxEnroll -
enrollment.latest.enrolledCount) /
enrollment.latest.maxEnroll;
enrollment.latest.maxEnroll
: 0;

return getPercentOpenSeats(b) - getPercentOpenSeats(a);
}
Expand Down
14 changes: 7 additions & 7 deletions apps/frontend/src/components/ClassBrowser/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,9 @@ addEventListener(

if (sortBy === SortBy.OpenSeats) {
const getOpenSeats = ({ primarySection: { enrollment } }: IClass) =>
enrollment === undefined
? 0
: enrollment.latest.maxEnroll - enrollment.latest.enrolledCount;
enrollment
? enrollment.latest.maxEnroll - enrollment.latest.enrolledCount
: 0;

return getOpenSeats(b) - getOpenSeats(a);
}
Expand All @@ -129,10 +129,10 @@ addEventListener(
const getPercentOpenSeats = ({
primarySection: { enrollment },
}: IClass) =>
enrollment === undefined || enrollment.latest.maxEnroll === 0
? 0
: (enrollment.latest.maxEnroll - enrollment.latest.enrolledCount) /
enrollment.latest.maxEnroll;
enrollment?.latest.maxEnroll
? (enrollment.latest.maxEnroll - enrollment.latest.enrolledCount) /
enrollment.latest.maxEnroll
: 0;

return getPercentOpenSeats(b) - getPercentOpenSeats(a);
}
Expand Down
Loading

0 comments on commit 0d9b587

Please sign in to comment.