Skip to content

Commit

Permalink
feat: use new catalog data (#1698)
Browse files Browse the repository at this point in the history
  • Loading branch information
Josh-Cena committed May 13, 2024
1 parent 62a743e commit 3981d27
Show file tree
Hide file tree
Showing 20 changed files with 321 additions and 323 deletions.
73 changes: 37 additions & 36 deletions frontend/src/components/CourseModal/CourseModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,8 @@ import { toast } from 'react-toastify';
import { CUR_YEAR } from '../../config';
import { useFerry } from '../../contexts/ferryContext';
import { useUser } from '../../contexts/userContext';
import type {
Season,
Crn,
ExtraInfo,
TimesByDay,
} from '../../queries/graphql-types';
import type { Listings } from '../../generated/graphql-types';
import type { Season, Crn } from '../../queries/graphql-types';
import { extraInfo } from '../../utilities/constants';
import { toSeasonString, truncatedText } from '../../utilities/course';
import { suspended, useCourseModalLink } from '../../utilities/display';
Expand All @@ -24,20 +20,27 @@ import { TextComponent } from '../Typography';
import WorksheetToggleButton from '../Worksheet/WorksheetToggleButton';
import styles from './CourseModal.module.css';

export type CourseModalHeaderData = {
readonly season_code: Season;
readonly crn: Crn;
readonly title: string;
readonly course_code: string;
readonly all_course_codes: string[];
readonly section: string;
readonly skills: string[];
readonly areas: string[];
readonly extra_info: ExtraInfo;
readonly description: string | null;
readonly times_by_day: TimesByDay;
readonly same_course_id: number;
readonly professor_ids: number[];
export type CourseModalHeaderData = Pick<
Listings,
'season_code' | 'crn' | 'course_code' | 'section'
> & {
course: Pick<
Listings['course'],
| 'title'
| 'skills'
| 'areas'
| 'extra_info'
| 'description'
| 'times_by_day'
| 'same_course_id'
> & {
listings: Pick<Listings, 'crn' | 'course_code'>[];
course_professors: {
professor: {
professor_id: number;
};
}[];
};
};

function ShareButton({ listing }: { readonly listing: CourseModalHeaderData }) {
Expand Down Expand Up @@ -169,22 +172,16 @@ function CourseModal() {
void requestSeasons([seasonCode]).then(() => {
const listingFromQuery = courses[seasonCode]?.get(Number(crn) as Crn);
if (!listingFromQuery) return;
setHistory([
{
...listingFromQuery,
// TODO: remove once api returns numbers
professor_ids: listingFromQuery.professor_ids.map(Number),
},
]);
setHistory([listingFromQuery]);
});
}, [history.length, searchParams, requestSeasons, courses]);
const listing = history[history.length - 1];
const backTarget = useCourseModalLink(history[history.length - 2]);

if (!listing) return null;
const title = `${listing.course_code} ${listing.section.padStart(2, '0')} ${listing.title} | CourseTable`;
const title = `${listing.course_code} ${listing.section.padStart(2, '0')} ${listing.course.title} | CourseTable`;
const description = truncatedText(
listing.description,
listing.course.description,
300,
'No description available',
);
Expand Down Expand Up @@ -227,14 +224,14 @@ function CourseModal() {
<div>
<Modal.Title>
<div className={styles.modalTitle}>
{listing.extra_info !== 'ACTIVE' ? (
{listing.course.extra_info !== 'ACTIVE' ? (
<span className={styles.cancelledText}>
{extraInfo[listing.extra_info]}{' '}
{extraInfo[listing.course.extra_info]}{' '}
</span>
) : (
''
)}
{listing.title}{' '}
{listing.course.title}{' '}
<TextComponent type="tertiary">
({toSeasonString(listing.season_code)})
</TextComponent>
Expand All @@ -244,12 +241,16 @@ function CourseModal() {
<div className={styles.badges}>
<p className={styles.courseCodes}>
<TextComponent type="tertiary">
{listing.all_course_codes.join(' • ')}
{listing.course.listings
.map((l) => l.course_code)
.join(' • ')}
</TextComponent>
</p>
{[...listing.skills, ...listing.areas].map((skill) => (
<SkillBadge skill={skill} key={skill} />
))}
{[...listing.course.skills, ...listing.course.areas].map(
(skill) => (
<SkillBadge skill={skill} key={skill} />
),
)}
</div>
</div>
</div>
Expand Down
6 changes: 4 additions & 2 deletions frontend/src/components/CourseModal/CourseModalOverview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ function CourseModalOverview({
seasonCode: header.season_code,
crn: header.crn,
hasEval: Boolean(user.hasEvals),
same_course_id: header.same_course_id,
professor_ids: header.professor_ids,
same_course_id: header.course.same_course_id,
professor_ids: header.course.course_professors.map(
(p) => p.professor.professor_id,
),
},
});

Expand Down
10 changes: 1 addition & 9 deletions frontend/src/components/CourseModal/OverviewInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -362,15 +362,7 @@ function OverviewInfo({
/>
<DataField
name="Enrollment"
value={getEnrolled(
{
enrolled: course.evaluation_statistic?.enrolled,
last_enrollment: course.last_enrollment,
last_enrollment_same_professors:
course.last_enrollment_same_professors,
},
'modal',
)}
value={getEnrolled(course, 'modal')}
tooltip={
CUR_SEASON === listing.season_code ? (
<span>
Expand Down
15 changes: 2 additions & 13 deletions frontend/src/components/CourseModal/OverviewRatings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,21 +130,10 @@ function CourseLink({
// We have to "massage" this data to fit the flat shape like the one
// sent by the api. This will be changed.
const targetCourses = course.listings.map((l) => ({
...l,
season_code: course.season_code,
crn: l.crn,
title: course.title,
course_code: l.course_code,
all_course_codes: course.listings.map((l) => l.course_code),
section: course.section,
skills: course.skills,
areas: course.areas,
extra_info: course.extra_info,
description: course.description,
times_by_day: course.times_by_day,
same_course_id: course.same_course_id,
professor_ids: course.course_professors.map(
(p) => p.professor.professor_id,
),
course,
}));
const extraText =
filter === 'professor'
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/Search/Results.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import Spinner from '../Spinner';
import styles from './Results.module.css';

export type ResultItemData = {
readonly courses: Listing[];
readonly listings: Listing[];
readonly columnCount: number;
readonly multiSeasons: boolean;
};
Expand Down Expand Up @@ -96,7 +96,7 @@ function Results({
ref={ref}
width={window.innerWidth}
height={Math.min(window.innerHeight, rowCount * rowHeight)}
itemData={{ courses: data, columnCount, multiSeasons }}
itemData={{ listings: data, columnCount, multiSeasons }}
{...(isGrid
? { columnCount, rowCount, rowHeight, columnWidth }
: { itemCount: rowCount, itemSize: rowHeight })}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/Search/ResultsColumnSort.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const isNumeric: { [key in SortKeys]: boolean } = {
title: false,
friend: true,
average_rating: true,
average_professor: true,
average_professor_rating: true,
average_workload: true,
average_gut_rating: true,
last_enrollment: true,
Expand Down
58 changes: 31 additions & 27 deletions frontend/src/components/Search/ResultsGridItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,16 @@ import WorksheetToggleButton from '../Worksheet/WorksheetToggleButton';
import styles from './ResultsGridItem.module.css';

function Rating({
course,
listing,
hasEvals,
name,
}: {
readonly course: Listing;
readonly listing: Listing;
readonly hasEvals: boolean | undefined;
readonly name: 'Class' | 'Professor' | 'Workload';
}) {
const { Icon, getRating, colorMap } = ratingTypes[name];
const rating = getRating(course, 'stat');
const rating = getRating(listing.course, 'stat');
return (
<OverlayTrigger
placement="top"
Expand All @@ -49,15 +49,15 @@ function Rating({
? colorMap(rating)
: undefined
: generateRandomColor(
`${course.crn}${course.season_code}${name}`,
`${listing.crn}${listing.season_code}${name}`,
)
)
?.darken()
.saturate()
.css() ?? '#cccccc',
}}
>
{hasEvals ? getRating(course, 'display') : '???'}
{hasEvals ? getRating(listing.course, 'display') : '???'}
</div>
<div className={styles.iconContainer}>
<Icon className={styles.icon} />
Expand All @@ -68,29 +68,29 @@ function Rating({
}

function ResultsGridItem({
data: { courses, columnCount, multiSeasons },
data: { listings, columnCount, multiSeasons },
rowIndex,
columnIndex,
style,
}: GridChildComponentProps<ResultItemData>) {
const course = courses[rowIndex * columnCount + columnIndex];
const target = useCourseModalLink(course);
const listing = listings[rowIndex * columnCount + columnIndex];
const target = useCourseModalLink(listing);
const { user } = useUser();
const { worksheetNumber } = useWorksheet();

const inWorksheet = useMemo(
() =>
course &&
listing &&
isInWorksheet(
course.season_code,
course.crn,
listing.season_code,
listing.crn,
worksheetNumber,
user.worksheets,
),
[course, worksheetNumber, user.worksheets],
[listing, worksheetNumber, user.worksheets],
);

if (!course) return null;
if (!listing) return null;

return (
<li className={styles.container} style={style}>
Expand All @@ -104,53 +104,57 @@ function ResultsGridItem({
>
<div className="d-flex justify-content-between">
<div className={styles.courseCodes}>
<CourseCode course={course} subdueSection={false} />
<CourseCode listing={listing} subdueSection={false} />
</div>
{multiSeasons && (
<SeasonTag season={course.season_code} className={styles.season} />
<SeasonTag season={listing.season_code} className={styles.season} />
)}
</div>
<div>
<strong className={styles.oneLine}>{course.title}</strong>
<strong className={styles.oneLine}>{listing.course.title}</strong>
</div>
<div className="d-flex justify-content-between">
<div>
<TextComponent
type="secondary"
className={clsx(styles.oneLine, styles.professors)}
>
{course.professor_names.length > 0
? course.professor_names.join(' • ')
{listing.course.course_professors.length > 0
? listing.course.course_professors
.map((p) => p.professor.name)
.join(' • ')
: 'Professor: TBA'}
</TextComponent>
<TextComponent
type="secondary"
className={clsx(styles.oneLine, styles.smallText)}
>
{course.times_summary === 'TBA'
{listing.course.times_summary === 'TBA'
? 'Times: TBA'
: course.times_summary}
: listing.course.times_summary}
</TextComponent>
<TextComponent
type="secondary"
className={clsx(styles.oneLine, styles.smallText)}
>
{course.locations_summary === 'TBA'
{listing.course.locations_summary === 'TBA'
? 'Location: TBA'
: course.locations_summary}
: listing.course.locations_summary}
</TextComponent>
<div className={styles.skillsAreas}>
{[...course.skills, ...course.areas].map((skill) => (
<SkillBadge skill={skill} key={skill} />
))}
{[...listing.course.skills, ...listing.course.areas].map(
(skill) => (
<SkillBadge skill={skill} key={skill} />
),
)}
</div>
</div>
<div className="d-flex align-items-end">
<div className="ms-auto">
{(['Class', 'Professor', 'Workload'] as const).map((name) => (
<Rating
key={name}
course={course}
listing={listing}
hasEvals={user.hasEvals}
name={name}
/>
Expand All @@ -163,7 +167,7 @@ function ResultsGridItem({
nested */}
<div className={styles.worksheetBtn}>
<WorksheetToggleButton
listing={course}
listing={listing}
modal={false}
inWorksheet={inWorksheet}
/>
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/Search/ResultsHeaders.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ function ResultsHeaders({
them)
</span>
}
sortOption="average_professor"
sortOption="average_professor_rating"
>
Professors
</HeaderCol>
Expand Down

0 comments on commit 3981d27

Please sign in to comment.