Skip to content
Permalink

Comparing changes

This is a direct comparison between two commits made in this repository or its related repositories. View the default comparison for this range or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: LaurierHawkHacks/Dashboard
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: ac1fe4680859b4056775bd037bece86c371670d3
Choose a base ref
..
head repository: LaurierHawkHacks/Dashboard
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 05a9a447fdbf3ed33edce013c758a8e2c910ff78
Choose a head ref
Showing with 2,507 additions and 846 deletions.
  1. +1 −0 .github/workflows/eslint.yml
  2. +1 −1 .npmrc
  3. +8 −0 config/firestore.rules
  4. +0 −1 firebase.json
  5. +30 −113 functions/src/index.ts
  6. +617 −0 functions/src/rsvp.ts
  7. +89 −0 functions/src/teams.ts
  8. +2 −1 package.json
  9. +31 −0 pnpm-lock.yaml
  10. BIN public/NEAR_Track.pdf
  11. BIN public/TENAMINTxGamingDao.pdf
  12. +8 −6 src/assets/index.tsx
  13. BIN src/assets/sponsors/metis.png
  14. BIN src/assets/sponsors/neurelo.png
  15. +9 −4 src/components/LoadingAnimation.tsx
  16. +26 −9 src/components/Navbar.tsx
  17. +1 −1 src/data/appCloseDate.ts
  18. +35 −18 src/data/perks.ts
  19. +5 −3 src/data/sponsorLinks.ts
  20. +24 −12 src/data/sponsors.ts
  21. +7 −1 src/navigation/ProtectedRoutes/ProtectedRoutes.tsx
  22. +177 −90 src/pages/Home/Home.page.tsx
  23. +190 −46 src/pages/MyTeam.page.tsx
  24. +328 −135 src/pages/Networking/Networking.page.tsx
  25. +70 −50 src/pages/Perks/Perks.page.tsx
  26. +39 −8 src/pages/Schedule/schedule.page.tsx
  27. +6 −1 src/pages/Ticket/Ticket.page.tsx
  28. +17 −4 src/pages/admin/Admin.page.tsx
  29. +169 −119 src/pages/admin/ManageEvents.page.tsx
  30. +105 −107 src/pages/admin/ViewTicket.page.tsx
  31. +305 −81 src/pages/miscellaneous/VerifyRSVP.page.tsx
  32. +15 −2 src/pages/miscellaneous/ViewTicket.page.tsx
  33. +7 −1 src/providers/auth.provider.tsx
  34. +29 −4 src/providers/routes.provider.tsx
  35. +46 −21 src/services/utils/index.ts
  36. +17 −0 src/services/utils/teams.ts
  37. +13 −6 src/services/utils/types.ts
  38. +43 −0 src/stores/events.store.ts
  39. +36 −0 src/stores/user.store.ts
  40. +1 −1 vite.config.ts
1 change: 1 addition & 0 deletions .github/workflows/eslint.yml
Original file line number Diff line number Diff line change
@@ -20,6 +20,7 @@ on:

jobs:
eslint:
if: false
name: Run eslint scanning
runs-on: ubuntu-latest
permissions:
2 changes: 1 addition & 1 deletion .npmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
@nessprim:registry=https://npm.pkg.github.com/:_authToken=${PLANBY_AUTH_TOKEN}
@nessprim:registry=https://npm.pkg.github.com/
8 changes: 8 additions & 0 deletions config/firestore.rules
Original file line number Diff line number Diff line change
@@ -32,6 +32,14 @@ service cloud.firestore {
match /rsvpCounter-dev/{counterId} {
allow read, write: if isAuthenticated() && isAdmin();
}
match /waitlist/{docId} {
allow read: if isAuthenticated();
allow write: if isAuthenticated() && isAdmin();
}
match /spots/{docId} {
allow read: if isAuthenticated();
allow write: if isAuthenticated() && isAdmin();
}

// Tickets Collection Rules
match /tickets/{ticketId} {
1 change: 0 additions & 1 deletion firebase.json
Original file line number Diff line number Diff line change
@@ -14,7 +14,6 @@
"firebase-debug.*.log"
],
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint",
"npm --prefix \"$RESOURCE_DIR\" run build"
]
}
143 changes: 30 additions & 113 deletions functions/src/index.ts
Original file line number Diff line number Diff line change
@@ -164,6 +164,7 @@ interface Socials {
resumeRef: string;
docId: string;
uid: string;
resumeVisibility: "Public" | "Private" | "Sponsors Only";
}

export const requestSocials = functions.https.onCall(async (_, context) => {
@@ -212,6 +213,7 @@ export const requestSocials = functions.https.onCall(async (_, context) => {
resumeRef: "",
docId,
uid: context.auth.uid,
resumeVisibility: "Public",
};
} else {
functions.logger.info(
@@ -228,6 +230,7 @@ export const requestSocials = functions.https.onCall(async (_, context) => {
: app.generalResumeRef,
docId,
uid: context.auth.uid,
resumeVisibility: "Public",
};
}
await admin.firestore().collection("socials").doc(docId).set(socials);
@@ -267,17 +270,20 @@ export const updateSocials = functions.https.onCall(async (data, context) => {
functions.logger.info("Updating socials for application:", doc.id);
functions.logger.info("Data in ref:", doc);

await admin.firestore().collection("socials").doc(doc.id).update({
const db = admin.firestore();
db.settings({ ignoreUndefinedProperties: true });
await db.collection("socials").doc(doc.id).update({
instagram: data.instagram,
linkedin: data.linkedin,
github: data.github,
discord: data.discord,
resumeRef: data.resumeRef,
resumeVisibility: data.resumeVisibility,
});
functions.logger.info("Socials updated:", data);
return response(HttpStatus.OK, { message: "ok" });
} catch (error) {
functions.logger.error("Failed to update socials:", error);
functions.logger.error("Failed to update socials", { error });
throw new functions.https.HttpsError(
"internal",
"Failed to update socials",
@@ -385,109 +391,6 @@ export const logEvent = functions.https.onCall((data, context) => {
}
});

export const verifyRSVP = functions.https.onCall(async (_, context) => {
if (!context.auth) {
throw new functions.https.HttpsError(
"permission-denied",
"Not authenticated"
);
}

functions.logger.info("Verify RSVP called.", { uid: context.auth.uid });

// only verify once
const user = await admin.auth().getUser(context.auth.uid);
if (user.customClaims?.rsvpVerified) {
return {
status: 200,
verified: true,
message: "RSVP already verified.",
};
} else if (user.customClaims?.isTestAccount) {
const counterDocRef = admin
.firestore()
.collection("rsvpCounter-dev")
.doc("counter");
const counterDoc = await counterDocRef.get();

if (counterDoc.exists) {
const count = counterDoc.data()?.count || 0;

if (count >= 5) {
functions.logger.info("RSVP limit reached.", {
uid: context.auth.uid,
});
return {
status: 400,
verified: false,
message: "RSVP limit reached.",
};
} else {
await counterDocRef.set({ count: count + 1 }, { merge: true });
}
} else {
await counterDocRef.set({ count: 1 });
}
await admin.auth().setCustomUserClaims(user.uid, {
...user.customClaims,
rsvpVerified: true,
});

return {
status: 200,
verified: true,
};
} else {
const counterDocRef = admin
.firestore()
.collection("rsvpCounter")
.doc("counter");
const counterDoc = await counterDocRef.get();

if (counterDoc.exists) {
const count = counterDoc.data()?.count || 0;

if (count >= 700) {
functions.logger.info("RSVP limit reached.", {
uid: context.auth.uid,
});
return {
status: 400,
verified: false,
message: "RSVP limit reached.",
};
} else {
await counterDocRef.set({ count: count + 1 }, { merge: true });
}
} else {
await counterDocRef.set({ count: 1 });
}

try {
functions.logger.info("Verifying RSVP. User: " + context.auth.uid);
// add to custom claims
await admin.auth().setCustomUserClaims(user.uid, {
...user.customClaims,
rsvpVerified: true,
});
} catch (e) {
functions.logger.error("Error verifying RSVP.", {
uid: context.auth.uid,
error: (e as Error).message,
});
throw new functions.https.HttpsError(
"internal",
"Service down. 1101"
);
}

return {
status: 200,
verified: true,
};
}
});

async function internalGetTicketData(id: string, extended = false) {
functions.logger.info("Checking for ticket data...");
const ticketDoc = await admin
@@ -520,6 +423,7 @@ async function internalGetTicketData(id: string, extended = false) {
let linkedin = "";
let github = "";
let resumeRef = "";
let allergies: string[] = [];

if (!app) {
// grab from user record
@@ -541,6 +445,7 @@ async function internalGetTicketData(id: string, extended = false) {
app.participatingAs === "Mentor"
? app.mentorResumeRef
: app.generalResumeRef;
allergies = app.allergies ?? [];
}

// get social ticket
@@ -561,6 +466,7 @@ async function internalGetTicketData(id: string, extended = false) {
discord: discord ?? "",
resumeRef: resumeRef ?? "",
docId: "",
resumeVisibility: "Public",
} as Socials;
}

@@ -570,6 +476,7 @@ async function internalGetTicketData(id: string, extended = false) {
pronouns,
foods: [] as string[],
events: [] as string[],
allergies,
...socials,
};

@@ -634,7 +541,7 @@ export const redeemItem = functions.https.onCall(async (data, context) => {
.object({
ticketId: z.string(),
itemId: z.string(),
type: z.string().refine((v) => v === "event" || v === "food"),
action: z.string().refine((v) => v === "check" || "uncheck"),
})
.safeParse(data);
if (!validateResults.success) {
@@ -650,23 +557,24 @@ export const redeemItem = functions.https.onCall(async (data, context) => {
if (!ticket)
return response(HttpStatus.NOT_FOUND, { message: "ticket not found" });

if (data.type === "event") {
let events = [];
if (data.action === "check") {
events = [...ticket.events, data.itemId];
await admin
.firestore()
.collection("tickets")
.doc(data.ticketId)
.update({ events: [...ticket.events, data.itemId] });
} else if (data.type === "food") {
.update({ events });
} else {
events = ticket.events.filter((evt: string) => evt !== data.itemId);
await admin
.firestore()
.collection("tickets")
.doc(data.ticketId)
.update({ foods: [...ticket.foods, data.itemId] });
} else {
return response(HttpStatus.BAD_REQUEST, { message: "invalid type" });
.update({ events });
}

return response(HttpStatus.OK);
return response(HttpStatus.OK, { data: events });
});

export {
@@ -680,8 +588,17 @@ export {
validateTeamInvitation,
rejectInvitation,
checkInvitation,
getUserInvitations,
} from "./teams";

export { createTicket } from "./apple";

export { createPassClass, createPassObject } from "./google";

export {
verifyRSVP,
withdrawRSVP,
joinWaitlist,
// expiredSpotCleanup,
// moveToSpots,
} from "./rsvp";
Loading