Skip to content

Commit

Permalink
Fix Hackathon Check-In Scanner (acmutsa#130)
Browse files Browse the repository at this point in the history
  • Loading branch information
christianhelp authored and snehab2 committed Nov 16, 2024
1 parent 2a0bbcc commit 5d247ad
Show file tree
Hide file tree
Showing 55 changed files with 1,282 additions and 998 deletions.
1 change: 0 additions & 1 deletion apps/web/src/actions/admin/modify-nav-item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ const redis = new Redis({
url: process.env.UPSTASH_REDIS_REST_URL,
token: process.env.UPSTASH_REDIS_REST_TOKEN,
});


// Maybe a better way to do this for revalidation? Who knows.
const navAdminPage = "/admin/toggles/landing";
Expand Down
10 changes: 8 additions & 2 deletions apps/web/src/actions/admin/registration-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,21 @@ export const toggleRegistrationEnabled = adminAction
export const toggleRegistrationMessageEnabled = adminAction
.schema(defaultRegistrationToggleSchema)
.action(async ({ parsedInput: { enabled }, ctx: { user, userId } }) => {
await redis.set("config:registration:registrationMessageEnabled", enabled);
await redis.set(
"config:registration:registrationMessageEnabled",
enabled,
);
revalidatePath("/admin/toggles/registration");
return { success: true, statusSet: enabled };
});

export const toggleSecretRegistrationEnabled = adminAction
.schema(defaultRegistrationToggleSchema)
.action(async ({ parsedInput: { enabled }, ctx: { user, userId } }) => {
await redis.set("config:registration:secretRegistrationEnabled", enabled);
await redis.set(
"config:registration:secretRegistrationEnabled",
enabled,
);
revalidatePath("/admin/toggles/registration");
return { success: true, statusSet: enabled };
});
Expand Down
22 changes: 17 additions & 5 deletions apps/web/src/actions/admin/scanner-admin-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { z } from "zod";
import { db, sql } from "db";
import { scans, userCommonData } from "db/schema";
import { eq, and } from "db/drizzle";

export const createScan = adminAction
.schema(
z.object({
Expand Down Expand Up @@ -65,12 +66,23 @@ export const getScan = adminAction
},
);

export const checkInUser = adminAction
.schema(z.string())
.action(async ({ parsedInput: user }) => {
// Schema will be moved over when rewrite of the other scanner happens
const checkInUserSchema = z.object({
userID: z.string(),
QRTimestamp: z
.number()
.positive()
.refine((timestamp) => {
return Date.now() - timestamp < 5 * 60 * 1000;
}, "QR Code has expired. Please tell user refresh the QR Code"),
});

export const checkInUserToHackathon = adminAction
.schema(checkInUserSchema)
.action(async ({ parsedInput: { userID } }) => {
// Set checkinTimestamp
return await db
await db
.update(userCommonData)
.set({ checkinTimestamp: sql`now()` })
.where(eq(userCommonData.clerkID, user));
.where(eq(userCommonData.clerkID, userID));
});
91 changes: 45 additions & 46 deletions apps/web/src/actions/teams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,64 +30,63 @@ export const leaveTeam = authenticatedAction
message: "User is not on a team",
};
}
let result:{ success: boolean; message: string };
let result: { success: boolean; message: string };

try{
try {
const webSocketDb = getWebSocketDb();
result = await webSocketDb.transaction(async (tx) => {
await tx
.update(userHackerData)
.set({ teamID: null })
.where(eq(userHackerData.clerkID, user.clerkID));
const team = await tx.query.teams.findFirst({
where: eq(teams.id, user.hackerData.teamID as string), // Converted to string since TS does not realise for some reason that we checked above.
with: {
members: {
with: {
commonData: true,
await tx
.update(userHackerData)
.set({ teamID: null })
.where(eq(userHackerData.clerkID, user.clerkID));
const team = await tx.query.teams.findFirst({
where: eq(teams.id, user.hackerData.teamID as string), // Converted to string since TS does not realise for some reason that we checked above.
with: {
members: {
with: {
commonData: true,
},
},
},
},
});
});

if (!team) {
revalidatePath("/dash/team");
return {
success: false,
message: "Team not found.",
};
}
if (!team) {
revalidatePath("/dash/team");
return {
success: false,
message: "Team not found.",
};
}

if (team.members.length < 1) {
await tx.delete(teams).where(eq(teams.id, team.id));
await tx.delete(invites).where(eq(invites.teamID, team.id));
revalidatePath("/dash/team");
return {
success: true,
message:
"Team has been left. Team has been deleted since it has no members.",
};
}
if (team.members.length < 1) {
await tx.delete(teams).where(eq(teams.id, team.id));
await tx.delete(invites).where(eq(invites.teamID, team.id));
revalidatePath("/dash/team");
return {
success: true,
message:
"Team has been left. Team has been deleted since it has no members.",
};
}

if (team.ownerID == userId) {
await tx
.update(teams)
.set({ ownerID: team.members[0].clerkID })
.where(eq(teams.id, team.id));
if (team.ownerID == userId) {
await tx
.update(teams)
.set({ ownerID: team.members[0].clerkID })
.where(eq(teams.id, team.id));
revalidatePath("/dash/team");
return {
success: true,
message: `Team has been left. Ownership has been transferred to ${team.members[0].commonData.firstName} ${team.members[0].commonData.lastName}.`,
};
}
revalidatePath("/dash/team");
return {
success: true,
message: `Team has been left. Ownership has been transferred to ${team.members[0].commonData.firstName} ${team.members[0].commonData.lastName}.`,
message: "Team has been left.",
};
}
revalidatePath("/dash/team");
return {
success: true,
message: "Team has been left.",
};
});
}
catch(e){
});
} catch (e) {
console.error(e);
return {
success: false,
Expand Down
4 changes: 3 additions & 1 deletion apps/web/src/app/admin/check-in/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ export default async function Page({
);

const scanUser = await getUser(searchParams.user);
if (!scanUser)
console.log(scanUser);
if (!scanUser) {
return (
<div>
<CheckinScanner
Expand All @@ -30,6 +31,7 @@ export default async function Page({
/>
</div>
);
}

return (
<div>
Expand Down
8 changes: 4 additions & 4 deletions apps/web/src/app/admin/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export default async function AdminLayout({ children }: AdminLayoutProps) {
<div className="h-[45%] w-[2px] rotate-[25deg] bg-muted-foreground" />
<h2 className="font-bold tracking-tight">Admin</h2>
</div>
<div className="items-center justify-end gap-x-4 flex pt-6 md:pt-0">
<div className="flex items-center justify-end gap-x-4 pt-6 md:pt-0">
<div className="hidden items-center justify-end gap-x-4 md:flex">
<Link href={"/"}>
<Button
Expand All @@ -74,10 +74,10 @@ export default async function AdminLayout({ children }: AdminLayoutProps) {
Discord
</Button>
</Link>

</div>
<div className='-mt-4 md:-mt-0'><ProfileButton /></div>

<div className="-mt-4 md:-mt-0">
<ProfileButton />
</div>
</div>
<div className="flex items-center justify-end gap-x-4 md:hidden"></div>
</div>
Expand Down
6 changes: 3 additions & 3 deletions apps/web/src/app/admin/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ export default async function Page() {
getRecentRegistrationData(allUsers);

return (
<div className="mx-auto h-16 w-full max-w-7xl pt-12 px-4">
<div className="mx-auto h-16 w-full max-w-7xl px-4 pt-12">
<div className="w-full px-2">
<h2 className="text-xl font-bold">Welcome,</h2>
<h1 className="text-5xl font-black text-hackathon">
{adminUser.firstName}
</h1>
</div>
<div className="grid md:grid-cols-4 gap-y-3 md:gap-x-2 pt-10">
<div className="grid gap-y-3 pt-10 md:grid-cols-4 md:gap-x-2">
<Card className="text-[#D09C51]">
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium">
Expand Down Expand Up @@ -89,7 +89,7 @@ export default async function Page() {
</CardContent>
</Card>
</div>
<div className="grid md:grid-cols-3 gap-y-3 md:gap-x-2 py-2 pb-24">
<div className="grid gap-y-3 py-2 pb-24 md:grid-cols-3 md:gap-x-2">
<Card className="col-span-2 text-[#D09C51]">
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<div>
Expand Down
95 changes: 47 additions & 48 deletions apps/web/src/app/api/registration/create/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export async function POST(req: Request) {
"You must accept the MLH Code of Conduct and Privacy Policy.",
});
}

// added: check resume url
// resume is given a default value
// only do resume upload when there's a successful database
Expand All @@ -83,57 +83,56 @@ export async function POST(req: Request) {
// });
// }

try{
try {
const webSocketDb = getWebSocketDb();
await webSocketDb.transaction(async (tx) => {
await tx.insert(userCommonData).values({
clerkID: user.id,
firstName: body.firstName,
lastName: body.lastName,
email: body.email,
hackerTag: body.hackerTag.toLowerCase(),
age: body.age,
gender: body.gender,
race: body.race,
ethnicity: body.ethnicity,
shirtSize: body.shirtSize,
dietRestrictions: body.dietaryRestrictions,
accommodationNote: body.accommodationNote || null,
discord: body.profileDiscordName,
pronouns: body.pronouns,
bio: body.bio,
skills: body.skills.map((v) => v.text.toLowerCase()),
profilePhoto: user.imageUrl,
isFullyRegistered: true,
phoneNumber: body.phoneNumber,
isSearchable: body.profileIsSearchable,
countryOfResidence: body.countryOfResidence,
});
await tx.insert(userCommonData).values({
clerkID: user.id,
firstName: body.firstName,
lastName: body.lastName,
email: body.email,
hackerTag: body.hackerTag.toLowerCase(),
age: body.age,
gender: body.gender,
race: body.race,
ethnicity: body.ethnicity,
shirtSize: body.shirtSize,
dietRestrictions: body.dietaryRestrictions,
accommodationNote: body.accommodationNote || null,
discord: body.profileDiscordName,
pronouns: body.pronouns,
bio: body.bio,
skills: body.skills.map((v) => v.text.toLowerCase()),
profilePhoto: user.imageUrl,
isFullyRegistered: true,
phoneNumber: body.phoneNumber,
isSearchable: body.profileIsSearchable,
countryOfResidence: body.countryOfResidence,
});

await tx.insert(userHackerData).values({
clerkID: user.id,
university: body.university,
major: body.major,
// schoolID: body.schoolID,
levelOfStudy: body.levelOfStudy,
hackathonsAttended: body.hackathonsAttended,
softwareExperience: body.softwareBuildingExperience,
heardFrom: body.heardAboutEvent || null,
GitHub: body.github,
LinkedIn: body.linkedin,
PersonalWebsite: body.personalWebsite,
resume: body.resume,
group: totalUserCount[0].count % Object.keys(c.groups).length,
hasAcceptedMLHCoC: body.hasAcceptedMLHCoC,
hasSharedDataWithMLH: body.hasSharedDataWithMLH,
isEmailable: body.isEmailable,
questionOne: body.questionOne,
questionTwo: body.questionTwo,
questionThree: body.questionThree,
await tx.insert(userHackerData).values({
clerkID: user.id,
university: body.university,
major: body.major,
// schoolID: body.schoolID,
levelOfStudy: body.levelOfStudy,
hackathonsAttended: body.hackathonsAttended,
softwareExperience: body.softwareBuildingExperience,
heardFrom: body.heardAboutEvent || null,
GitHub: body.github,
LinkedIn: body.linkedin,
PersonalWebsite: body.personalWebsite,
resume: body.resume,
group: totalUserCount[0].count % Object.keys(c.groups).length,
hasAcceptedMLHCoC: body.hasAcceptedMLHCoC,
hasSharedDataWithMLH: body.hasSharedDataWithMLH,
isEmailable: body.isEmailable,
questionOne: body.questionOne,
questionTwo: body.questionTwo,
questionThree: body.questionThree,
});
});
});
}
catch(e){
} catch (e) {
console.log(e);
return NextResponse.json({
success: false,
Expand Down
Loading

0 comments on commit 5d247ad

Please sign in to comment.