Skip to content

Commit 782c0ae

Browse files
authored
Merge branch 'main' into HMT/general-fixes
2 parents 021ac53 + 0fed25c commit 782c0ae

File tree

23 files changed

+522
-213
lines changed

23 files changed

+522
-213
lines changed

amplify/function/BusinessLogic/AssignUsersToTeams/graphql/API.ts

+14-14
Original file line numberDiff line numberDiff line change
@@ -379,10 +379,10 @@ export type AddUserToGroupResponse = {
379379
};
380380

381381
export type ScheduleTeamsAndJudgesResponse = {
382-
__typename: "ScheduleTeamsAndJudgesResponse",
383-
body?: string | null,
384-
headers?: string | null,
385-
statusCode?: number | null,
382+
__typename: "ScheduleTeamsAndJudgesResponse";
383+
body?: string | null;
384+
headers?: string | null;
385+
statusCode?: number | null;
386386
};
387387

388388
export type ModelFoodEventConditionInput = {
@@ -1373,19 +1373,19 @@ export type ResetHackathonMutation = {
13731373
};
13741374

13751375
export type ScheduleTeamsAndJudgesMutationVariables = {
1376-
judgingSessionsPerTeam: number,
1377-
numOfJudgingRooms: number,
1378-
presentationDuration: number,
1379-
startDateAndTime: string,
1376+
judgingSessionsPerTeam: number;
1377+
numOfJudgingRooms: number;
1378+
presentationDuration: number;
1379+
startDateAndTime: string;
13801380
};
13811381

13821382
export type ScheduleTeamsAndJudgesMutation = {
1383-
ScheduleTeamsAndJudges?: {
1384-
__typename: "ScheduleTeamsAndJudgesResponse",
1385-
body?: string | null,
1386-
headers?: string | null,
1387-
statusCode?: number | null,
1388-
} | null,
1383+
ScheduleTeamsAndJudges?: {
1384+
__typename: "ScheduleTeamsAndJudgesResponse";
1385+
body?: string | null;
1386+
headers?: string | null;
1387+
statusCode?: number | null;
1388+
} | null;
13891389
};
13901390

13911391
export type SetUserAsCheckedInMutationVariables = {

amplify/function/BusinessLogic/AssignUsersToTeams/graphql/mutations.ts

+7-5
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@ export const ResetHackathon = /* GraphQL */ `mutation ResetHackathon(
9393
APITypes.ResetHackathonMutation
9494
>;
9595

96-
export const ScheduleTeamsAndJudges = /* GraphQL */ `mutation ScheduleTeamsAndJudges(
96+
export const ScheduleTeamsAndJudges =
97+
/* GraphQL */ `mutation ScheduleTeamsAndJudges(
9798
$judgingSessionsPerTeam: Int!
9899
$numOfJudgingRooms: Int!
99100
$presentationDuration: Int!
@@ -112,10 +113,11 @@ export const ScheduleTeamsAndJudges = /* GraphQL */ `mutation ScheduleTeamsAndJu
112113
}
113114
}
114115
` as GeneratedMutation<
115-
APITypes.ScheduleTeamsAndJudgesMutationVariables,
116-
APITypes.ScheduleTeamsAndJudgesMutation
117-
>;
118-
export const SetUserAsCheckedIn = /* GraphQL */ `mutation SetUserAsCheckedIn($userId: String!) {
116+
APITypes.ScheduleTeamsAndJudgesMutationVariables,
117+
APITypes.ScheduleTeamsAndJudgesMutation
118+
>;
119+
export const SetUserAsCheckedIn =
120+
/* GraphQL */ `mutation SetUserAsCheckedIn($userId: String!) {
119121
SetUserAsCheckedIn(userId: $userId) {
120122
JUDGE_givenScores {
121123
nextToken

src/app/judging/JudgingTable.tsx

+42-19
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
"use client";
22

33
import { useState } from "react";
4-
import Skeleton from "react-loading-skeleton";
54

65
import type { Schema } from "@/amplify/data/resource";
6+
import KevinLoadingRing from "@/components/KevinLoadingRing";
77
import { useUser } from "@/components/contexts/UserContext";
88
import ModalPopup from "@/components/judging/ModalPopup";
99
import ScoresTable from "@/components/judging/ScoresTable";
@@ -21,6 +21,8 @@ export default function JudgingTable({
2121
>;
2222
}) {
2323
const [selectedTeam, setSelectedTeamId] = useState("");
24+
const [teamName, setTeamName] = useState("");
25+
const [teamsLeft, setTeamsLeft] = useState(0);
2426

2527
const { currentUser } = useUser();
2628
const { data: roomData, isFetching: roomIsFetching } = useQuery({
@@ -34,7 +36,9 @@ export default function JudgingTable({
3436

3537
return data;
3638
},
39+
enabled: !!currentUser.JUDGE_roomId,
3740
});
41+
3842
const { data: teamsForRoomData, isFetching: teamsForRoomIsFetching } =
3943
useQuery({
4044
queryKey: ["TeamsForRoom", roomData?.id],
@@ -49,43 +53,61 @@ export default function JudgingTable({
4953
return teams;
5054
},
5155
});
52-
const isFetching = roomIsFetching || teamsForRoomIsFetching;
56+
const isFetching = roomIsFetching && teamsForRoomIsFetching;
5357
if (isFetching || !roomData || !teamsForRoomData) {
54-
return (
55-
<div className="flex flex-1">
56-
<Skeleton className="h-full" containerClassName="flex-1" />
57-
</div>
58+
return <KevinLoadingRing />;
59+
}
60+
async function getFilteredTeamsCount() {
61+
// https://medium.com/@debbs119/array-filter-and-array-map-with-async-functions-9636e1ae8d6e --> why it needs to map to a boolean array first
62+
if (!teamsForRoomData) {
63+
return;
64+
}
65+
const boolArray = await Promise.all(
66+
teamsForRoomData?.map(async (team) => {
67+
const scores = await team?.scores();
68+
return (
69+
scores?.data.filter((score) => score.judgeId === currentUser.username)
70+
.length === 0
71+
);
72+
}),
73+
);
74+
setTeamsLeft(
75+
teamsForRoomData?.filter((_, index) => boolArray[index]).length,
5876
);
5977
}
6078

79+
getFilteredTeamsCount();
80+
6181
const panelData = [
6282
{
6383
icon: "/svgs/judging/team_icon.svg",
6484
alt: "Teams assigned icon",
6585
stat: teamsForRoomData.length,
66-
text: `Teams Assigned to ${roomData.name}`,
86+
text:
87+
teamsForRoomData.length === 1
88+
? `Team Assigned to ${roomData.name}`
89+
: `Teams Assigned to ${roomData.name}`,
6790
},
6891
{
6992
icon: "/svgs/judging/teams_left.svg",
7093
alt: "Teams left icon",
71-
stat: teamsForRoomData.filter(
72-
async (team) =>
73-
(await team?.scores())?.data.filter(
74-
(score) => score.judgeId === currentUser.username,
75-
).length === 0,
76-
).length,
77-
text: "Teams Left To Score",
94+
stat: teamsLeft,
95+
text: teamsLeft === 1 ? "Team Left to Score" : "Teams Left to Score",
7896
},
7997
];
98+
8099
const handleCreateScoreClick = (teamId: string) => {
81-
setSelectedTeamId(teamId);
82-
};
83-
const handleEditScoreClick = (teamId: string) => {
84-
setSelectedTeamId(teamId);
100+
const selectedTeam = teamsForRoomData.find((team) => team?.id === teamId);
101+
102+
if (selectedTeam) {
103+
setSelectedTeamId(teamId);
104+
setTeamName(selectedTeam.name);
105+
}
85106
};
86107

87108
const closeModal = () => {
88109
setSelectedTeamId("");
110+
setTeamName("");
89111
};
90112

91113
return (
@@ -105,17 +127,18 @@ export default function JudgingTable({
105127
<ScoresTable
106128
tableData={teamsForRoomData as Schema["Team"]["type"][]}
107129
onCreateScoreClick={handleCreateScoreClick}
108-
onEditScoreClick={handleEditScoreClick}
109130
colorScheme="pink"
110131
entriesPerPage={150}
111132
hackathonData={hackathonData}
112133
/>
113134
</div>
135+
114136
{selectedTeam !== "" && (
115137
<ModalPopup
116138
hackathon={hackathonData}
117139
onClose={closeModal}
118140
teamId={selectedTeam}
141+
teamName={teamName}
119142
/>
120143
)}
121144
</>

src/app/judging/assigned-teams/page.tsx

-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import { NavBar } from "@/components/judging/Navbar";
2-
31
const AssignedTeamsPage = () => {
42
const assignedTeams = [
53
{ id: 1, name: "Team Alpha" },
@@ -9,7 +7,6 @@ const AssignedTeamsPage = () => {
97

108
return (
119
<div>
12-
<NavBar />
1310
<h1> Put assinged teams here Assigned Teams</h1>
1411
<ul>
1512
{assignedTeams.map((team) => (

src/app/judging/layout.tsx

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import NavBar from "@/components/judging/Navbar";
2+
3+
export default function JudgingLayout({
4+
children,
5+
}: {
6+
children: React.ReactNode;
7+
}) {
8+
return (
9+
<div className="flex size-full flex-col bg-dashboard-grey">
10+
<NavBar />
11+
<main className="flex flex-1 flex-col gap-4">{children}</main>
12+
</div>
13+
);
14+
}

src/app/judging/page.tsx

-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import type { Metadata } from "next";
22

3-
import { NavBar } from "@/components/judging/Navbar";
4-
53
import JudgingDashboard from "./JudgingDashboard";
64

75
export const dynamic = "force-dynamic";
@@ -22,7 +20,6 @@ export const metadata: Metadata = {
2220
export default function Judging() {
2321
return (
2422
<main className="flex w-full flex-1 flex-col gap-4 bg-dashboard-grey">
25-
<NavBar />
2623
<JudgingDashboard />
2724
</main>
2825
);

src/app/judging/rubric/page.tsx

-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
1-
import { NavBar } from "@/components/judging/Navbar";
2-
31
const RubricPage = () => {
42
return (
53
<div>
6-
<NavBar />
74
<h1>Judging Rubric here</h1>
85
<ul></ul>
96
</div>

src/app/judging/schedule/page.tsx

+6-45
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,9 @@
1-
"use client";
2-
3-
import { useEffect, useState } from "react";
4-
5-
interface Schedule {
6-
teamName: string;
7-
timeSlot: string;
8-
}
9-
10-
const SchedulePage = () => {
11-
const [schedule, setSchedule] = useState<Schedule[]>([]);
12-
13-
useEffect(() => {
14-
// Fetch schedule data from an API or define it statically
15-
// Template for when we will fetch the schedule
16-
const fetchSchedule = async () => {
17-
const response = await fetch("/api/schedule");
18-
const data = await response.json();
19-
setSchedule(data);
20-
};
21-
22-
fetchSchedule();
23-
}, []);
1+
import JudgeSchedule from "@/components/judging/Schedule/schedule";
242

3+
export default function Schedule() {
254
return (
26-
<div>
27-
<h1>Judging Schedule</h1>
28-
<table>
29-
<thead>
30-
<tr>
31-
<th>Team Name</th>
32-
<th>Time Slot</th>
33-
</tr>
34-
</thead>
35-
<tbody>
36-
{schedule.map((item, index) => (
37-
<tr key={index}>
38-
<td>{item.teamName}</td>
39-
<td>{item.timeSlot}</td>
40-
</tr>
41-
))}
42-
</tbody>
43-
</table>
44-
</div>
5+
<main className="size-full">
6+
<JudgeSchedule />
7+
</main>
458
);
46-
};
47-
48-
export default SchedulePage;
9+
}

src/app/login/page.tsx

+12-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
1-
import Login from "@/components/LoginForm/Login";
1+
import dynamic from "next/dynamic";
2+
3+
import KevinLoadingRing from "@/components/KevinLoadingRing";
24
import RegistrationLayout from "@/components/layouts/RegistrationLayout";
35

6+
const Login = dynamic(() => import("@/components/LoginForm/Login"), {
7+
ssr: false,
8+
loading: () => (
9+
<div className="mt-16 flex w-full items-center justify-center">
10+
<KevinLoadingRing />
11+
</div>
12+
),
13+
});
14+
415
export default function LoginPage() {
516
return (
617
<RegistrationLayout>

src/app/participant/profile/page.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import dynamic from "next/dynamic";
2+
import KevinLoadingRing from "@/components/KevinLoadingRing";
23

3-
import LoadingRing from "@/components/LoadingRing";
4-
4+
// Dynamically import UserProfile with preloading
55
const UserProfile = dynamic(
66
() => import("@/components/UserProfile/UserProfile"),
77
{
88
ssr: false,
99
loading: () => (
10-
<div className="flex h-screen w-full items-center justify-center bg-fuzzy-peach">
11-
<LoadingRing />
10+
<div className="flex w-full items-center justify-center">
11+
<KevinLoadingRing />
1212
</div>
1313
),
1414
},

src/components/Dashboard/Greetings.tsx

+7
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,15 @@ export default function Greetings({
3232
<h2 className="text-lg font-normal md:text-xl lg:text-2xl">
3333
Hack the Change 2024
3434
</h2>
35+
3536
<h1 className="text-3xl md:text-4xl lg:text-6xl">
3637
Hello,
38+
{user.isFetching && (
39+
<span className={`capitalize italic ${nameColor}`}>
40+
{" "}
41+
Loading...
42+
</span>
43+
)}
3744
<span className={`capitalize italic ${nameColor}`}>
3845
{" "}
3946
{firstName} {lastName}!

src/components/KevinLoadingRing.tsx

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import Image from "next/image";
2+
3+
export default function KevinLoadingRing() {
4+
return (
5+
<>
6+
<div className="m-4 flex h-full flex-col justify-center text-center text-2xl">
7+
<Image
8+
className="animate-bounce"
9+
src="/svgs/admin/Kevin.svg"
10+
alt="Kevin Icon"
11+
width={240}
12+
height={240}
13+
/>
14+
<div className="ml-2 flex w-full items-center justify-center space-x-1">
15+
<span className="font-semibold text-gray-700">Loading</span>
16+
<span className=" mt-3 size-1 animate-pulse rounded-full bg-gray-700 delay-200"></span>
17+
<span className="delay-400 mt-3 size-1 animate-pulse rounded-full bg-gray-700"></span>
18+
<span className="delay-600 mt-3 size-1 animate-pulse rounded-full bg-gray-700"></span>
19+
</div>
20+
</div>
21+
</>
22+
);
23+
}

0 commit comments

Comments
 (0)