Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion amplify/auth/PostConfirmation/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ export const handler: PostConfirmationTriggerHandler = async (event) => {
role: "Participant",
id: event.request.userAttributes.sub,
email: event.request.userAttributes.email,
checkedIn: false,
willEatMeals: false,
allergies: "",
institution: "",
Expand Down
28 changes: 6 additions & 22 deletions amplify/data/resource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,6 @@ const schema = a
completedRegistration: a.boolean(),
allergies: a.string(),
willEatMeals: a.boolean(),
checkedIn: a
.boolean()
.default(false)
.authorization((allow) => [
allow.ownerDefinedIn("profileOwner").to(["read"]),
allow.groups(["Admin"]).to(["read", "update", "delete", "create"]),
]),
teamId: a
.id()
.authorization((allow) => [
Expand Down Expand Up @@ -94,6 +87,12 @@ const schema = a
members: a.hasMany("User", "teamId"),
scores: a.hasMany("Score", "teamId"),
teamRooms: a.hasMany("TeamRoom", "teamId"),
devPostLink: a
.string()
.authorization((allow) => [
allow.groups(["Admin"]).to(["read", "update"]),
allow.authenticated().to(["read", "update"]),
]),
})
.authorization((allow) => [
allow.group("Admin").to(["read", "update", "create", "delete"]),
Expand Down Expand Up @@ -279,21 +278,6 @@ const schema = a
.authorization((allow) => [allow.group("Admin")])
.handler(a.handler.function(ResetHackathon))
.returns(a.ref("StatusCodeFunctionResponse")),

// Custom resolvers
SetUserAsCheckedIn: a
.mutation()
.arguments({
userId: a.string().required(),
})
.returns(a.ref("User"))
.authorization((allow) => [allow.authenticated()])
.handler(
a.handler.custom({
dataSource: a.ref("User"),
entry: "./user/SetUserAsCheckedIn.js",
}),
),
})

.authorization((allow) => [
Expand Down
14 changes: 0 additions & 14 deletions amplify/data/user/SetUserAsCheckedIn.js

This file was deleted.

174 changes: 90 additions & 84 deletions amplify/function/BusinessLogic/CreateTeamWithCode/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Amplify } from "aws-amplify";
import { generateClient } from "aws-amplify/data";
import type { AppSyncIdentityCognito } from "aws-lambda";
import type { Schema } from "../../../data/resource";
import { tryCatch } from "../utils/try-catch";
import { createTeam, updateUser } from "./graphql/mutations";
import { getTeam } from "./graphql/queries";

Expand Down Expand Up @@ -37,101 +38,106 @@ const client = generateClient<Schema>({
authMode: "iam",
});

const createNewTeam = (teamName: string, teamId: string) =>
client.graphql({
query: createTeam,
variables: {
input: {
name: teamName,
id: teamId,
},
},
});
const updateUserTeam = (id: string, teamId: string) =>
client.graphql({
query: updateUser,
variables: {
input: {
id,
teamId,
},
},
});
const generateTeamId = () =>
Array.from(Array(4), () =>
Math.floor(Math.random() * 36)
.toString(36)
.toUpperCase(),
).join("");
const getTeamFromId = (teamId: string) =>
client.graphql({
query: getTeam,
variables: {
id: teamId,
},
});
export const handler: Schema["CreateTeamWithCode"]["functionHandler"] = async (
event,
) => {
let team = null;
let teamId: string | null = null;
try {
do {
teamId = Array.from(Array(4), () =>
Math.floor(Math.random() * 36)
.toString(36)
.toUpperCase(),
).join("");
const {
arguments: { addCallerToTeam, teamName },
} = event;

team = (
await client.graphql({
query: getTeam,
variables: {
id: teamId,
},
})
).data.getTeam;
} while (team != null);
let teamId = generateTeamId();
let { error: teamIdTaken } = await tryCatch(getTeamFromId(teamId));
let attempts = 0;
const MAX_ATTEMPTS = 100; // Define a maximum number of attempts

const teamCreation = await client
.graphql({
query: createTeam,
variables: {
input: {
name: event.arguments.teamName,
id: teamId,
},
},
})
.catch(() => {
throw new Error(
JSON.stringify({
body: { value: `Error creating team` },
statusCode: 500,
headers: { "Content-Type": "application/json" },
}),
);
});
while (teamIdTaken && attempts < MAX_ATTEMPTS) {
teamId = generateTeamId();
({ error: teamIdTaken } = await tryCatch(getTeamFromId(teamId)));
attempts++;
}

if (teamCreation) {
if (event.arguments.addCallerToTeam) {
return await client
.graphql({
query: updateUser,
variables: {
input: {
id: (event.identity as AppSyncIdentityCognito).sub,
teamId: teamId,
},
},
})
.then(() => {
return {
body: { value: teamId },
statusCode: 200,
headers: { "Content-Type": "application/json" },
};
})
.catch(() => {
throw new Error(
JSON.stringify({
body: { value: `Error updating user (team was created)` },
statusCode: 500,
headers: { "Content-Type": "application/json" },
}),
);
});
} else {
return {
body: { value: teamId },
statusCode: 200,
headers: { "Content-Type": "application/json" },
};
}
} else {
throw new Error(
JSON.stringify({
body: { value: `Error creating team` },
statusCode: 500,
headers: { "Content-Type": "application/json" },
}),
);
}
} catch (error) {
console.error(error);
if (teamIdTaken) {
// Handle the case where a unique team ID could not be generated
throw new Error(
JSON.stringify({
body: {
value: `Failed to generate a unique team ID after ${MAX_ATTEMPTS} attempts.`,
},
statusCode: 500,
headers: { "Content-Type": "application/json" },
}),
);
}
const { error: createTeamError } = await tryCatch(
createNewTeam(teamName, teamId),
);
if (createTeamError) {
throw new Error(
JSON.stringify({
body: { value: `Unhandled Internal Server Error` },
body: { value: `Error creating team` },
statusCode: 500,
headers: { "Content-Type": "application/json" },
}),
);
}
if (!addCallerToTeam) {
return {
body: { value: teamId },
statusCode: 200,
headers: { "Content-Type": "application/json" },
};
}
const { error: updateUserError, data: updateUserSuccess } = await tryCatch(
updateUserTeam((event.identity as AppSyncIdentityCognito).sub, teamId),
);
if (updateUserSuccess) {
return {
body: { value: teamId },
statusCode: 200,
headers: { "Content-Type": "application/json" },
};
}

throw new Error(
JSON.stringify({
body: {
value: `Error updating user ( ${(event.identity as AppSyncIdentityCognito).sub}) (team was created) ${updateUserError}`,
},
statusCode: 500,
headers: { "Content-Type": "application/json" },
}),
);
};
24 changes: 24 additions & 0 deletions amplify/function/BusinessLogic/utils/try-catch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Types for the result object with discriminated union
type Success<T> = {
data: T;
error: null;
};

type Failure<E> = {
data: null;
error: E;
};

type Result<T, E = Error> = Success<T> | Failure<E>;

// Main wrapper function
export async function tryCatch<T, E = Error>(
promise: Promise<T>,
): Promise<Result<T, E>> {
try {
const data = await promise;
return { data, error: null };
} catch (error) {
return { data: null, error: error as E };
}
}
8 changes: 0 additions & 8 deletions src/app/admin/teams/TeamTableSetup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,6 @@ export const teamColumns = [
filterFn: "includesString",
sortingFn: "alphanumeric",
}),
columnHelper.accessor("members", {
cell: (info) =>
info.getValue().every((member) => member.checkedIn)
? "Checked In"
: "Not Checked In",
header: "Check-in Status",
sortingFn: "basic",
}),
columnHelper.accessor("approved", {
cell: ({
getValue,
Expand Down
32 changes: 13 additions & 19 deletions src/app/admin/teams/components/TeamsTablePage.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,20 @@
import type { Schema } from "@/amplify/data/resource";
import client from "@/components/_Amplify/AmplifyBackendClient";
import TeamsTable from "./TeamsTable";

type Members = Pick<
Schema["User"]["type"],
"id" | "firstName" | "lastName" | "checkedIn"
>;
export type Team = Pick<Schema["Team"]["type"], "name" | "approved" | "id"> & {
members: Members[];
};
const getTeams = client.models.Team.list({
selectionSet: [
"name",
"approved",
"id",
"devPostLink",
"members.id",
"members.firstName",
"members.lastName",
],
});
export type Team = Awaited<typeof getTeams>["data"][number];
export default async function TeamsTablePage() {
const { data: teams } = await client.models.Team.list({
selectionSet: [
"name",
"approved",
"id",
"members.id",
"members.firstName",
"members.lastName",
"members.checkedIn",
],
});
const { data: teams } = await getTeams;
if (!teams || !Array.isArray(teams)) return "No teams were found";
return <TeamsTable teams={teams} />;
}
4 changes: 1 addition & 3 deletions src/app/admin/teams/components/ViewButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,7 @@ export default function ViewButton({ team }: { team: Team }) {
<td className={"rounded-md p-2"}>
{`${member.firstName} ${member.lastName}`}
</td>
<td className={"rounded-md p-2"}>
{member.checkedIn ? "Checked In" : "Not Checked In"}
</td>
<td className={"rounded-md p-2"}>{member.id}</td>
</tr>
))}
</tbody>
Expand Down
Loading
Loading