Skip to content

Commit 7b5f9ee

Browse files
committed
start work on classes
1 parent 542b187 commit 7b5f9ee

File tree

4 files changed

+350
-7
lines changed

4 files changed

+350
-7
lines changed

src/components/Class.tsx

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
import type { Component } from "solid-js";
22

3-
const Class: Component = (props) => {
3+
import type { Subject } from "~/context/types";
4+
5+
const Class: Component<{
6+
classIndex: number;
7+
classInfo: "placeholder" | Subject;
8+
semesterIndex: number;
9+
// warnings: string[];
10+
}> = (props) => {
411
return <div />;
512
};
613

src/components/Semester.tsx

+101-5
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
1-
import { type Component, Show, createMemo } from "solid-js";
1+
import { type Component, For, createMemo } from "solid-js";
22

33
import { ChevronDownIcon } from "lucide-solid";
4+
import { HStack } from "styled-system/jsx";
5+
import Class from "~/components/Class";
46
import { Accordion } from "~/components/ui/accordion";
7+
import { Text } from "~/components/ui/text";
58

69
import { useCourseDataContext } from "~/context/create";
710
import type {
811
SelectedSubjects,
912
SimplifiedSelectedSubjects,
13+
Subject,
14+
SubjectFull,
1015
} from "~/context/types";
1116

1217
const Semester: Component<{
1318
selectedSubjects: SimplifiedSelectedSubjects;
14-
semesterSubjects: Array<SelectedSubjects>;
19+
semesterSubjects: SelectedSubjects[];
1520
index: number;
1621
roadID: string;
1722
isOpen: boolean;
@@ -54,19 +59,110 @@ const Semester: Component<{
5459
: "";
5560
});
5661

62+
// TODO: copied from courseroad 2, see what's actually needed
63+
const semesterInformation = createMemo(() => {
64+
const classesInfo = props.semesterSubjects
65+
.map((subj) => {
66+
if (subj.public === false) {
67+
return Object.assign({}, subj, {
68+
total_units: subj.units,
69+
});
70+
}
71+
if (subj.subject_id in store.subjectsIndex) {
72+
return store.subjectsInfo[store.subjectsIndex[subj.subject_id]];
73+
}
74+
if (subj.subject_id in store.genericIndex) {
75+
return store.genericCourses[store.genericIndex[subj.subject_id]];
76+
}
77+
return undefined;
78+
})
79+
.filter((subj) => subj !== undefined);
80+
const totalUnits = classesInfo.reduce((units, subj) => {
81+
let tu = subj.total_units;
82+
tu = Number.isNaN(tu) ? 0 : tu;
83+
return units + tu;
84+
}, 0);
85+
const expectedHours = (subj: SubjectFull) => {
86+
let hours =
87+
(subj.in_class_hours ?? Number.NaN) +
88+
(subj.out_of_class_hours ?? Number.NaN);
89+
hours = Number.isNaN(hours) ? subj.total_units : hours;
90+
hours = Number.isNaN(hours) ? 0 : hours;
91+
return {
92+
hours,
93+
subject_id: subj.subject_id,
94+
};
95+
};
96+
const sumExpectedHours = (hours: number, subj: { hours: number }) =>
97+
hours + subj.hours;
98+
const isInQuarter = (subj: Subject, quarter: number) =>
99+
subj.quarter_information === undefined ||
100+
Number.parseInt(subj.quarter_information.split(",")[0]) === quarter;
101+
const expectedHoursQuarter1 = classesInfo
102+
.filter((s) => isInQuarter(s, 0))
103+
.map(expectedHours);
104+
const totalExpectedHoursQuarter1 = expectedHoursQuarter1.reduce(
105+
sumExpectedHours,
106+
0,
107+
);
108+
const expectedHoursQuarter2 = classesInfo
109+
.filter((s) => isInQuarter(s, 1))
110+
.map(expectedHours);
111+
const totalExpectedHoursQuarter2 = expectedHoursQuarter2.reduce(
112+
sumExpectedHours,
113+
0,
114+
);
115+
const totalExpectedHours = Math.max(
116+
totalExpectedHoursQuarter1,
117+
totalExpectedHoursQuarter2,
118+
);
119+
const anyClassInSingleQuarter = classesInfo.some(
120+
(s) => s.quarter_information !== undefined,
121+
);
122+
123+
return {
124+
totalUnits,
125+
totalExpectedHours,
126+
anyClassInSingleQuarter,
127+
expectedHoursQuarter1,
128+
expectedHoursQuarter2,
129+
totalExpectedHoursQuarter1,
130+
totalExpectedHoursQuarter2,
131+
};
132+
});
133+
57134
return (
58135
<Accordion.Item
59136
value={props.index.toString()}
60137
hidden={store.hideIAP && semesterType() === "IAP"}
61138
>
62139
<Accordion.ItemTrigger>
63-
{semesterYearName()} {semesterType()} {semesterYearRendered()}
140+
<HStack gap={6}>
141+
<Text width="12em">
142+
{semesterYearName()} {semesterType()} {semesterYearRendered()}
143+
</Text>
144+
<Text minWidth="4.5em" fontSize="sm">
145+
Units: {semesterInformation().totalUnits}
146+
</Text>
147+
<Text fontSize="sm">
148+
Hours: {semesterInformation().totalExpectedHours.toFixed(1)}
149+
</Text>
150+
</HStack>
64151
<Accordion.ItemIndicator>
65152
<ChevronDownIcon />
66153
</Accordion.ItemIndicator>
67154
</Accordion.ItemTrigger>
68-
<Accordion.ItemContent>
69-
Showing semester {props.index} for {props.roadID}
155+
<Accordion.ItemContent justifyContent="center" display="flex">
156+
<For each={props.semesterSubjects}>
157+
{(subj, index) => (
158+
<Class
159+
classInfo={subj}
160+
semesterIndex={props.index}
161+
// warnings={warnings()[props.index]}
162+
classIndex={index()}
163+
/>
164+
)}
165+
</For>
70166
</Accordion.ItemContent>
71167
</Accordion.Item>
72168
);

src/context/types.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ interface RoadContents {
163163
};
164164
}
165165

166-
export interface SelectedSubjects {
166+
export interface SelectedSubjects extends Subject {
167167
units: number;
168168
semester: number;
169169
overrideWarnings: boolean;

0 commit comments

Comments
 (0)