Skip to content
This repository was archived by the owner on Jul 31, 2025. It is now read-only.

Commit 8d389a0

Browse files
Merge pull request #48 from ApprenticeofEnder/dev
QoL fixes and linting
2 parents 9295ccd + f40918d commit 8d389a0

7 files changed

Lines changed: 110 additions & 92 deletions

File tree

‎client/@coursefull/index.d.ts‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export interface SemesterProgressType {
1616
num_graded_courses: number;
1717
goal: number;
1818
status: ItemStatus;
19-
grade_colour?: string;
19+
grade_colour?: GradeColours;
2020
}
2121

2222
export interface BasicUserData {
@@ -29,4 +29,9 @@ export interface BasicUserData {
2929

3030
export interface AuthHeaders {
3131
Authorization: string;
32+
}
33+
34+
export interface GradeColours {
35+
bgColour: string;
36+
textColour: string;
3237
}

‎client/app/dashboard/courses/page.tsx‎

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ function CoursePage({ session }: SessionProps) {
108108
}
109109
return deliverables.at(currentDeliverableIndex) || null;
110110
}, [deliverables, currentDeliverableIndex]);
111-
111+
112112
const totalWeight = useMemo(() => {
113113
return deliverables?.reduce((totalWeight, deliverable) => {
114114
return totalWeight + deliverable.weight;
@@ -210,7 +210,7 @@ function CoursePage({ session }: SessionProps) {
210210
<div className="flex flex-col md:flex-row gap-4 my-4 md:h-screen">
211211
<div className="w-full md:basis-1/3 order-2 md:order-1 flex flex-col gap-4">
212212
<Button
213-
className="top-2 order-last md:order-first"
213+
className="top-2 order-last md:order-first flex-shrink-0"
214214
endContent={<PlusIcon className="h-6 w-6" />}
215215
onPressEnd={createDeliverableModal.onOpen}
216216
buttonType="confirm"
@@ -259,7 +259,7 @@ function CoursePage({ session }: SessionProps) {
259259
You need{' '}
260260
<strong>
261261
{courseQuery.data?.deliverable_goal &&
262-
courseQuery.data?.deliverable_goal.toFixed(
262+
courseQuery.data.deliverable_goal.toFixed(
263263
1
264264
)}
265265
%
@@ -285,6 +285,8 @@ function CoursePage({ session }: SessionProps) {
285285
<Modal
286286
isOpen={createDeliverableModal.isOpen}
287287
onOpenChange={createDeliverableModal.onOpenChange}
288+
isDismissable={false}
289+
isKeyboardDismissDisabled={true}
288290
className="bg-sky-100"
289291
scrollBehavior="inside"
290292
>
@@ -297,6 +299,8 @@ function CoursePage({ session }: SessionProps) {
297299
<Modal
298300
isOpen={updateDeliverableModal.isOpen}
299301
onOpenChange={updateDeliverableModal.onOpenChange}
302+
isDismissable={false}
303+
isKeyboardDismissDisabled={true}
300304
className="bg-sky-100"
301305
scrollBehavior="inside"
302306
>
@@ -308,15 +312,16 @@ function CoursePage({ session }: SessionProps) {
308312
) as Updated<Deliverable>) || null
309313
}
310314
totalWeight={
311-
totalWeight! -
312-
(currentDeliverable?.weight || 0)
315+
totalWeight! - (currentDeliverable?.weight || 0)
313316
}
314317
/>
315318
</Modal>
316319
<Modal
317320
isOpen={updateCourseModal.isOpen}
318321
onOpenChange={updateCourseModal.onOpenChange}
319322
className="bg-sky-100"
323+
isDismissable={false}
324+
isKeyboardDismissDisabled={true}
320325
scrollBehavior="inside"
321326
>
322327
<UpdateCourseModal

‎client/app/dashboard/semesters/page.tsx‎

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,8 @@ import Link from '@components/Link';
2727
import CreateCourseModal from '@components/Modal/CreateCourse';
2828
import UpdateCourseModal from '@components/Modal/UpdateCourse';
2929
import UpdateSemesterModal from '@components/Modal/UpdateSemester';
30-
import {
31-
Course,
32-
Endpoints,
33-
SessionProps,
34-
Updated,
35-
} from '@coursefull';
36-
import {
37-
classNames,
38-
} from '@lib/helpers';
30+
import { Course, Endpoints, SessionProps, Updated } from '@coursefull';
31+
import { classNames } from '@lib/helpers';
3932
import { useProtectedEndpoint, useSession } from '@lib/supabase/SessionContext';
4033
import { deleteSemester, getSemester } from '@services/semesterService';
4134
import CourseCard from '@components/Card/Course';
@@ -277,6 +270,8 @@ function SemesterPage({ session }: SessionProps) {
277270
<Modal
278271
isOpen={createCourseModal.isOpen}
279272
onOpenChange={createCourseModal.onOpenChange}
273+
isDismissable={false}
274+
isKeyboardDismissDisabled={true}
280275
className="bg-sky-100"
281276
>
282277
<CreateCourseModal
@@ -287,6 +282,8 @@ function SemesterPage({ session }: SessionProps) {
287282
<Modal
288283
isOpen={updateCourseModal.isOpen}
289284
onOpenChange={updateCourseModal.onOpenChange}
285+
isDismissable={false}
286+
isKeyboardDismissDisabled={true}
290287
className="bg-sky-100"
291288
>
292289
<UpdateCourseModal
@@ -299,13 +296,14 @@ function SemesterPage({ session }: SessionProps) {
299296
<Modal
300297
isOpen={updateSemesterModal.isOpen}
301298
onOpenChange={updateSemesterModal.onOpenChange}
299+
isDismissable={false}
300+
isKeyboardDismissDisabled={true}
302301
className="bg-sky-100"
303302
>
304303
<UpdateSemesterModal
305304
session={session}
306305
semester={semesterData!}
307306
/>
308-
<></>
309307
</Modal>
310308
</Fragment>
311309
);

‎client/components/Dashboard/Dashboard.tsx‎

Lines changed: 30 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,18 @@
11
import { PlusIcon } from '@heroicons/react/24/outline';
2-
import {
3-
Chip,
4-
Listbox,
5-
ListboxItem,
6-
Modal,
7-
Spinner,
8-
useDisclosure,
9-
} from '@nextui-org/react';
2+
import { cn, Listbox, ListboxItem, Modal, useDisclosure } from '@nextui-org/react';
103
import { useQuery } from '@tanstack/react-query';
114
import { useRouter } from 'next/navigation';
125
import { useMemo } from 'react';
136

14-
import {
15-
classNames,
16-
determineGradeBGColour,
17-
ReadableStatus,
18-
semesterURL,
19-
} from '@lib/helpers';
7+
import { classNames, determineGradeBGColour, semesterURL } from '@lib/helpers';
208
import Button from '@components/Button/Button';
219
import LinkButton from '@components/Button/LinkButton';
2210
import CreateSemesterModal from '@components/Modal/CreateSemester';
23-
import {
24-
ItemStatus,
25-
SemesterProgressType,
26-
SessionProps,
27-
User,
28-
} from '@coursefull';
11+
import { ItemStatus, SemesterProgressType, SessionProps } from '@coursefull';
2912
import { getProgress, getUserData } from '@services/userService';
3013
import Loading from '@app/loading';
3114
import StatusChip from '@components/Chip/StatusChip';
15+
import { useGradeColours, useProgressColours } from '@lib/hooks/ui';
3216

3317
function renderAverage(item: SemesterProgressType | null | undefined): string {
3418
if (!item) {
@@ -41,17 +25,6 @@ function renderAverage(item: SemesterProgressType | null | undefined): string {
4125
return average;
4226
}
4327

44-
function getChipColour(status: ItemStatus) {
45-
switch (status) {
46-
case ItemStatus.NOT_STARTED:
47-
return 'default';
48-
case ItemStatus.ACTIVE:
49-
return 'primary';
50-
case ItemStatus.COMPLETE:
51-
return 'success';
52-
}
53-
}
54-
5528
function renderSemester(item: SemesterProgressType) {
5629
return (
5730
<ListboxItem
@@ -73,11 +46,7 @@ function renderSemester(item: SemesterProgressType) {
7346
</div>
7447
}
7548
className={
76-
(item.status === ItemStatus.ACTIVE ||
77-
item.status === ItemStatus.COMPLETE) &&
78-
item.average
79-
? determineGradeBGColour(item.goal, item.average)
80-
: ''
49+
cn(Object.values(item.grade_colour!))
8150
}
8251
textValue={`${item.average} % out of ${item.goal} %`}
8352
>
@@ -89,37 +58,39 @@ function renderSemester(item: SemesterProgressType) {
8958
}
9059

9160
export default function Dashboard({ session }: SessionProps) {
92-
const progressResult = useQuery({
61+
const {
62+
data: progressData,
63+
isLoading: loadingProgress,
64+
error: progressError,
65+
} = useQuery({
9366
queryKey: ['progress'],
9467
queryFn: () => {
9568
return getProgress(session);
9669
},
9770
});
9871

99-
const progress: SemesterProgressType[] | undefined = progressResult.data;
100-
const loadingProgress: boolean = progressResult.isLoading;
101-
const progressError: Error | null = progressResult.error;
10272
if (progressError) {
10373
throw progressError;
10474
}
10575

10676
const activeSemester = useMemo(
10777
() =>
108-
progress
78+
progressData
10979
?.filter((semester) => semester.status === ItemStatus.ACTIVE)
11080
.shift() || null,
111-
[progress]
81+
[progressData]
11282
);
11383

114-
const userResult = useQuery({
84+
const {
85+
data: userData,
86+
isLoading: loadingUserData,
87+
error: userError,
88+
} = useQuery({
11589
queryKey: ['user'],
11690
queryFn: () => {
11791
return getUserData(session);
11892
},
11993
});
120-
const userData: User | undefined = userResult.data;
121-
const loadingUserData: boolean = userResult.isLoading;
122-
const userError: Error | null = userResult.error;
12394
if (userError) {
12495
throw progressError;
12596
}
@@ -128,6 +99,10 @@ export default function Dashboard({ session }: SessionProps) {
12899

129100
const router = useRouter();
130101

102+
const colorizedSemesters = useProgressColours(progressData);
103+
104+
const { bgColour, textColour } = useGradeColours(activeSemester?.goal, activeSemester?.average);
105+
131106
return (
132107
<div className="h-full">
133108
<h1>Hey, {session.user.user_metadata.first_name}!</h1>
@@ -138,12 +113,8 @@ export default function Dashboard({ session }: SessionProps) {
138113
<div
139114
className={classNames(
140115
'basis-1/2 border-2 border-primary-600/15 rounded-lg p-4 flex flex-col justify-between gap-4',
141-
activeSemester?.average
142-
? determineGradeBGColour(
143-
activeSemester?.goal,
144-
activeSemester.average
145-
)
146-
: 'bg-primary-800'
116+
bgColour,
117+
textColour
147118
)}
148119
>
149120
<h3 className="text-left">Active Semester</h3>
@@ -185,7 +156,7 @@ export default function Dashboard({ session }: SessionProps) {
185156
</div>
186157

187158
<Listbox
188-
items={progress}
159+
items={colorizedSemesters}
189160
aria-label="Semesters"
190161
className="my-4"
191162
itemClasses={{
@@ -199,12 +170,13 @@ export default function Dashboard({ session }: SessionProps) {
199170
}}
200171
emptyContent={
201172
<div className="text-center">
202-
You don&apos;t have any semesters. Start by
203-
adding some!
173+
{
174+
"You don't have any semesters. Start by adding some!"
175+
}
204176
</div>
205177
}
206178
>
207-
{(item) => renderSemester(item)}
179+
{(item: SemesterProgressType) => renderSemester(item)}
208180
</Listbox>
209181
</div>
210182
</div>
@@ -216,6 +188,8 @@ export default function Dashboard({ session }: SessionProps) {
216188
onOpenChange={onOpenChange}
217189
className="bg-sky-100"
218190
scrollBehavior="inside"
191+
isDismissable={false}
192+
isKeyboardDismissDisabled={true}
219193
classNames={{ footer: 'justify-between' }}
220194
>
221195
<CreateSemesterModal

‎client/components/Form/LoginForm.tsx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,12 @@ export default function LoginForm() {
8383
});
8484
submitForm();
8585
}}
86-
isLoading={loginMutation.isPending}
86+
isLoading={loginMutation.isPending || isNavigating}
8787
isDisabled={!isValid}
8888
buttonType="confirm"
8989
data-testid="login-button"
9090
>
91-
{loginMutation.isPending ? 'Logging in...' : 'Log In'}
91+
{(loginMutation.isPending || isNavigating) ? 'Logging in...' : 'Log In'}
9292
</Button>
9393
</div>
9494
</Fragment>

‎client/components/Modal/CreateDeliverable.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export default function CreateDeliverableModal({
3131
mark: 0,
3232
notes: '',
3333
start_date: now(getLocalTimeZone()),
34-
deadline: now(getLocalTimeZone()),
34+
deadline: now(getLocalTimeZone()).set({hour: 23, minute: 59}),
3535
});
3636

3737
const queryClient = useQueryClient();

0 commit comments

Comments
 (0)