Skip to content

Commit f8dde27

Browse files
authored
Merge pull request #311 from nwplus/cmd-f-2025-export-raffle
Raffle!!!
2 parents da2ef60 + 21643d5 commit f8dde27

2 files changed

Lines changed: 160 additions & 1 deletion

File tree

pages/[id]/HackerInfo.js

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useState, useEffect, useRef, useMemo } from 'react'
22
import styled from 'styled-components'
33
import { CSVLink } from 'react-csv'
4-
import { getHackathonPaths, getHackathons, getHackerInfo } from '../../utility/firebase'
4+
import { getHackathonPaths, getHackathons, getHackerInfo, getRaffleWheelEmails } from '../../utility/firebase'
55
import Page from '../../components/page'
66
import Button from '../../components/button'
77
import Menu from '../../components/menu'
@@ -102,6 +102,7 @@ const Calculate = styled.select`
102102
export default function HackerInfo({ id, hackathons }) {
103103
const [unfilteredData, setUnfilteredData] = useState([])
104104
const [filteredData, setFilteredData] = useState([])
105+
const [raffleData, setRaffleData] = useState([])
105106
const [currTable, setCurrTable] = useState('Applicants')
106107
const [unfilteredTableKeys, setUnfilteredTableKeys] = useState([])
107108
const [filteredTableKeys, setFilteredTableKeys] = useState([])
@@ -122,6 +123,7 @@ export default function HackerInfo({ id, hackathons }) {
122123
const [filter, setFilter] = useState({})
123124
const [calculate, setCalculate] = useState({})
124125
const downloadLink = useRef()
126+
const raffleDownloadLink = useRef()
125127
const [uniqueEvents, setUniqueEvents] = useState([])
126128
const [selectedEvents, setSelectedEvents] = useState([])
127129

@@ -229,6 +231,7 @@ export default function HackerInfo({ id, hackathons }) {
229231
})
230232
}
231233

234+
232235
const HackerInfoRow = ({ data }) => {
233236
return (
234237
<TableRow>
@@ -329,6 +332,22 @@ export default function HackerInfo({ id, hackathons }) {
329332
</Button>
330333
<CSVLink style={{ visibility: 'hidden' }} ref={downloadLink} filename="hackerinfo.csv" data={filteredData} />
331334
</ExportButton>
335+
336+
{/* TODO raffle */}
337+
<ExportButton>
338+
<Button
339+
onClick={async () => {
340+
const data = await getRaffleWheelEmails()
341+
setRaffleData(data)
342+
raffleDownloadLink.current.link.click()
343+
}}
344+
>
345+
cmd-f 2025 Raffle
346+
</Button>
347+
<CSVLink style={{ visibility: 'hidden' }} ref={raffleDownloadLink} filename="cmd-f2025-raffle-emails.csv" data={raffleData} />
348+
</ExportButton>
349+
350+
332351
</Buttons>
333352
<Filters>
334353
<FilterPills>

utility/firebase.js

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,146 @@ export const getCSVData = async () => {
754754
return CSV
755755
}
756756

757+
758+
// export const getRaffleNumbers = async () => {
759+
// const apps = await db
760+
// .collection('Hackathons')
761+
// .doc(HackerEvaluationHackathon)
762+
// .collection('Applicants')
763+
// .where('dayOf.checkedIn', '==', true)
764+
// .get();
765+
766+
// // Use Promise.all to handle asynchronous logic for each applicant
767+
// const CSV = await Promise.all(
768+
// apps.docs.map(async (doc) => {
769+
// const {
770+
// basicInfo: {
771+
// legalFirstName,
772+
// legalLastName,
773+
// preferredName,
774+
// email,
775+
// phoneNumber,
776+
// },
777+
// dayOf,
778+
// } = doc.data();
779+
780+
// // Ensure dayOf.events exists before proceeding
781+
// if (!dayOf?.events || !Array.isArray(dayOf.events)) return null;
782+
783+
// // Fetch event documents for each event in dayOf.events
784+
// const dayOfDocsPromises = dayOf.events.map((e) =>
785+
// db
786+
// .collection('Hackathons')
787+
// .doc(HackerEvaluationHackathon)
788+
// .collection('DayOf')
789+
// .doc(e.eventId)
790+
// .get()
791+
// );
792+
793+
// // Wait for all dayOfDocs to resolve
794+
// const dayOfDocs = await Promise.all(dayOfDocsPromises);
795+
796+
// // Calculate total points from events
797+
// const totalPoints = dayOfDocs.reduce(
798+
// (acc, curr) => acc + Number(curr.data()?.points ?? 0),
799+
// 0
800+
// );
801+
802+
// // Calculate raffle entries based on total points
803+
// const totalRaffleEntries = Math.floor(totalPoints / 15);
804+
805+
// return [
806+
// legalFirstName,
807+
// legalLastName,
808+
// preferredName,
809+
// email,
810+
// phoneNumber,
811+
// totalPoints.toString(),
812+
// totalRaffleEntries.toString(),
813+
// ];
814+
// })
815+
// );
816+
817+
// // Filter out null results (in case any docs didn't have events or checked-in status)
818+
// const validCSV = CSV.filter((entry) => entry !== null);
819+
820+
// // Add headers to CSV
821+
// validCSV.unshift([
822+
// 'First Name',
823+
// 'Last Name',
824+
// 'Preferred Name',
825+
// 'Email',
826+
// 'Phone Number',
827+
// 'Total Points',
828+
// 'Raffle Entries',
829+
// ]);
830+
831+
// console.log(validCSV);
832+
833+
// return validCSV;
834+
// };
835+
836+
837+
export const getRaffleWheelEmails = async () => {
838+
const apps = await db
839+
.collection('Hackathons')
840+
.doc(HackerEvaluationHackathon)
841+
.collection('Applicants')
842+
.where('dayOf.checkedIn', '==', true)
843+
.get();
844+
845+
// Create an array to hold all rows for the raffle entries
846+
const raffleEntries = [];
847+
848+
// Iterate over the documents and calculate raffle entries for each user
849+
for (const doc of apps.docs) {
850+
const {
851+
basicInfo: { email },
852+
dayOf,
853+
} = doc.data();
854+
855+
if (!dayOf?.events || !Array.isArray(dayOf.events)) continue;
856+
857+
// Fetch event documents for each event in dayOf.events
858+
const dayOfDocsPromises = dayOf.events.map((e) =>
859+
db
860+
.collection('Hackathons')
861+
.doc(HackerEvaluationHackathon)
862+
.collection('DayOf')
863+
.doc(e.eventId)
864+
.get()
865+
);
866+
867+
const dayOfDocs = await Promise.all(dayOfDocsPromises);
868+
869+
// Calculate total points from events
870+
// +15 is from check in : cmd-f 2025
871+
const totalPoints = 15 + dayOfDocs.reduce(
872+
(acc, curr) => acc + Number(curr.data()?.points ?? 0),
873+
0
874+
);
875+
876+
// Calculate raffle entries based on total points
877+
const totalRaffleEntries = Math.floor(totalPoints / 15);
878+
879+
// Add the user's email multiple times based on raffle entries
880+
for (let i = 0; i < totalRaffleEntries; i++) {
881+
raffleEntries.push(email); // Repeat the email for each raffle entry
882+
}
883+
}
884+
885+
// Prepare CSV with only the "Raffle Entries" column
886+
const CSV = [
887+
['Raffle Entries'],
888+
...raffleEntries.map(email => [email]), // Convert to array format for CSV
889+
];
890+
891+
console.log(CSV);
892+
893+
return CSV;
894+
};
895+
896+
757897
export const getResumeFile = async userId => {
758898
try {
759899
const ref = storage.ref(`applicantResumes/${userId}`)

0 commit comments

Comments
 (0)