Skip to content

Commit 6f9db8d

Browse files
authored
feat: New Ap credit UI (#117)
* feat: new UI * feat: Various UI Changes
1 parent d45f06e commit 6f9db8d

File tree

3 files changed

+102
-30
lines changed

3 files changed

+102
-30
lines changed

src/commands/ap-credit-calculator.ts

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import {
22
ContainerBuilder,
3+
hyperlink,
34
MessageFlags,
45
SeparatorBuilder,
56
SlashCommandBuilder,
67
} from "discord.js";
7-
import { DEFAULT_EMBED_COLOR, SCHOOLS } from "../constants.js";
8+
import { DEFAULT_EMBED_COLOR, SCHOOLS, SCOTTYLABS_URL } from "../constants.js";
89
import apCoursesData from "../data/ap-courses.json" with { type: "json" };
910
import apCreditData from "../data/ap-credit.json" with { type: "json" };
1011
import CoursesData from "../data/finalCourseJSON.json" with { type: "json" };
@@ -69,7 +70,7 @@ async function loadApCreditData(): Promise<Exam[]> {
6970
if (!course) {
7071
return {
7172
id,
72-
name: exam.name,
73+
name: "Equivalent Course not Found",
7374
syllabi: [],
7475
desc: "",
7576
prereqs: [],
@@ -79,6 +80,19 @@ async function loadApCreditData(): Promise<Exam[]> {
7980
units: "",
8081
department: "",
8182
};
83+
} else if (course.name.startsWith("AP")) {
84+
return {
85+
id,
86+
name: exam.name + " (*Not Offered Course*)",
87+
syllabi: [],
88+
desc: "",
89+
prereqs: [],
90+
prereqString: "",
91+
coreqs: [],
92+
crosslisted: [],
93+
units: course.units,
94+
department: "",
95+
};
8296
}
8397

8498
return course;
@@ -111,7 +125,7 @@ function getGenedsForCourse(courseId: string, geneds: GenEd[]): string[] {
111125

112126
const command: SlashCommand = {
113127
data: new SlashCommandBuilder()
114-
.setName("credit-calculator")
128+
.setName("credits")
115129
.setDescription("Credit calculator for CMU courses")
116130
.addSubcommand((subcommand) =>
117131
subcommand
@@ -263,7 +277,9 @@ const command: SlashCommand = {
263277
const container = new ContainerBuilder()
264278
.setAccentColor(DEFAULT_EMBED_COLOR)
265279
.addTextDisplayComponents((t) =>
266-
t.setContent("Awarded CMU Credit"),
280+
t.setContent(
281+
"## Awarded CMU Credit\n*Gened data is incomplete and partly outdated*",
282+
),
267283
);
268284

269285
if (awarded.length === 0) {
@@ -278,14 +294,6 @@ const command: SlashCommand = {
278294
let genedCreditTotal = 0;
279295

280296
for (const { exam, courses: awardedCourses } of awarded) {
281-
container.addSeparatorComponents(
282-
new SeparatorBuilder(),
283-
);
284-
285-
container.addTextDisplayComponents((t) =>
286-
t.setContent(`### ${exam.name}`),
287-
);
288-
289297
let geneds: GenEd[] = [];
290298

291299
if (userSchool == "DC") {
@@ -305,6 +313,10 @@ const command: SlashCommand = {
305313
}
306314

307315
for (const course of awardedCourses) {
316+
container.addSeparatorComponents(
317+
new SeparatorBuilder(),
318+
);
319+
308320
const units = Number(course.units) || 0;
309321
genedCreditTotal += units;
310322

@@ -317,29 +329,32 @@ const command: SlashCommand = {
317329
: [];
318330

319331
const genedTags = genedList.length
320-
? genedList.map((g) => `[${g}]`).join(" ")
321-
: "_None_";
332+
? genedList.map((g) => `${g}`).join(" ")
333+
: "n/a";
322334

323335
container.addTextDisplayComponents((t) =>
324336
t.setContent(
325337
[
326-
`> **${course.id}** — ${courseName}`,
327-
`> **${units} units** · GenEds: ${genedTags}`,
338+
courseName.endsWith(
339+
"(*Not Offered Course*)",
340+
)
341+
? `**${course.id}** — AP ${courseName} (${units} units) `
342+
: hyperlink(
343+
`**${course.id}** — ${courseName} (${units} units)`,
344+
`${SCOTTYLABS_URL}/course/${course.id}`,
345+
),
346+
genedTags != "n/a"
347+
? `AP ${exam.name} • Fulfills ${genedTags} Gened Requirement`
348+
: `AP ${exam.name}`,
349+
`${exam.info}`,
328350
].join("\n"),
329351
),
330352
);
331353
}
332-
if (exam.info !== "") {
333-
container.addTextDisplayComponents((t) =>
334-
t.setContent(`${exam.info}`),
335-
);
336-
}
337354
}
338355

339356
container.addTextDisplayComponents((t) =>
340-
t.setContent(
341-
`**GenEd Unit Total:** ${genedCreditTotal}`,
342-
),
357+
t.setContent(`**Unit Total:** ${genedCreditTotal}`),
343358
);
344359
return container;
345360
},

src/data/ap-credit.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
"courses": ["03-110"],
5454
"subject": "STEM",
5555
"school": [],
56-
"info": "Students can elect to take an attainment exam. Students who pass this exam by September 30 will receive credit for 03-121 instead of 03-110."
56+
"info": "(Students can elect to take an attainment exam. Students who pass this exam by September 30 will receive credit for 03-121 instead of 03-110.)"
5757
},
5858
{
5959
"exams": [{ "name": "Calculus AB", "score": 4 }],

src/utils/creditCalculatorForm.ts

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
StringSelectMenuInteraction,
1111
} from "discord.js";
1212

13+
import { DEFAULT_EMBED_COLOR } from "../constants.js";
1314
export interface SetupField {
1415
key: string;
1516
label: string;
@@ -94,7 +95,7 @@ export class SetupForm {
9495
): ActionRowBuilder<StringSelectMenuBuilder> {
9596
const select = new StringSelectMenuBuilder()
9697
.setCustomId(`setup;${this.schema.name};string;${field.key}`)
97-
.setPlaceholder(field.label);
98+
.setPlaceholder("Select an exam");
9899

99100
if (field.options) {
100101
select.addOptions(field.options);
@@ -117,7 +118,7 @@ export class SetupForm {
117118
this.rendNonce++;
118119

119120
const container = new ContainerBuilder()
120-
.setAccentColor(0x393a41)
121+
.setAccentColor(DEFAULT_EMBED_COLOR)
121122
.addTextDisplayComponents((text) =>
122123
text.setContent(`# ${this.schema.name}`),
123124
);
@@ -137,14 +138,55 @@ export class SetupForm {
137138
container.addSeparatorComponents(new SeparatorBuilder());
138139
}
139140

141+
const hasCollectedData = Object.values(this.state.collectedData).some(
142+
(v) => Array.isArray(v) && v.length > 0,
143+
);
144+
145+
if (hasCollectedData) {
146+
container.addTextDisplayComponents((text) =>
147+
text.setContent("**Selected Exams**\n"),
148+
);
149+
}
150+
for (const key of Object.keys(this.state.collectedData)) {
151+
const items = this.state.collectedData[key];
152+
if (!Array.isArray(items)) continue;
153+
154+
for (const item of items) {
155+
const display = item.score
156+
? `- ${item.examName} - Score: ${item.score}`
157+
: `- ${item.examName} - Pending score`;
158+
container.addTextDisplayComponents((text) =>
159+
text.setContent(display),
160+
);
161+
}
162+
}
163+
164+
container.addSeparatorComponents(new SeparatorBuilder());
165+
140166
const submitButton = new ButtonBuilder()
141167
.setCustomId(`setup;${this.schema.name};submit`)
142168
.setLabel("Submit")
143169
.setStyle(ButtonStyle.Success);
144170

145-
container.addActionRowComponents(
146-
new ActionRowBuilder<ButtonBuilder>().addComponents(submitButton),
147-
);
171+
const clearButton = new ButtonBuilder()
172+
.setCustomId(`setup;${this.schema.name};clear`)
173+
.setLabel("Clear Selected")
174+
.setStyle(ButtonStyle.Danger);
175+
176+
if (hasCollectedData) {
177+
container.addActionRowComponents(
178+
new ActionRowBuilder<ButtonBuilder>().addComponents(
179+
submitButton,
180+
clearButton,
181+
),
182+
);
183+
} else {
184+
container.addActionRowComponents(
185+
new ActionRowBuilder<ButtonBuilder>().addComponents(
186+
submitButton,
187+
),
188+
);
189+
}
148190

149191
return container;
150192
}
@@ -167,6 +209,21 @@ export class SetupForm {
167209
return;
168210
}
169211

212+
if (
213+
i.isButton() &&
214+
i.customId === `setup;${this.schema.name};clear`
215+
) {
216+
for (const key of Object.keys(this.state.collectedData)) {
217+
if (Array.isArray(this.state.collectedData[key])) {
218+
this.state.collectedData[key] = [];
219+
}
220+
}
221+
222+
await i.update({
223+
components: [this.buildFormContainer()],
224+
});
225+
}
226+
170227
if (i.customId.startsWith(`setup;${this.schema.name};score;`)) {
171228
await this.handleScoreSelect(i as StringSelectMenuInteraction);
172229
} else if (

0 commit comments

Comments
 (0)