diff --git a/src/assets/checkmark.svg b/src/assets/checkmark.svg
new file mode 100644
index 00000000..85c424e3
--- /dev/null
+++ b/src/assets/checkmark.svg
@@ -0,0 +1,5 @@
+
diff --git a/src/assets/hc2024qrcode.svg b/src/assets/hc2024qrcode.svg
new file mode 100644
index 00000000..d3a1af3d
--- /dev/null
+++ b/src/assets/hc2024qrcode.svg
@@ -0,0 +1,521 @@
+
diff --git a/src/assets/hc_background.svg b/src/assets/hc_background.svg
new file mode 100644
index 00000000..342ceda7
--- /dev/null
+++ b/src/assets/hc_background.svg
@@ -0,0 +1,24 @@
+
diff --git a/src/components/ApplicationDashboard.jsx b/src/components/ApplicationDashboard.jsx
index 564dec75..999dfc86 100644
--- a/src/components/ApplicationDashboard.jsx
+++ b/src/components/ApplicationDashboard.jsx
@@ -252,6 +252,22 @@ export const hackerStatuses = (relevantDates, hackerName = null, activeHackathon
nwplus.io
{' '}
to learn about more events and other ways to engage with the technology community.
+
+ While we are currently at full capacity, we'd love to still have you join our community!
+ Join us for Learn Day - a jam-packed day of workshops that's open to everyone, regardless of
+ your application status. Everyone is welcome to attend our{' '}
+
+ pre-hackathon workshops
+
+ , where you can expand your technical and career knowledge while connecting with other
+ students. Visit the workshop page to find detailed descriptions and pre-requisite
+ information for each session!
>
),
},
@@ -373,12 +389,14 @@ const Dashboard = ({
setMediaConsentCheck,
ageOfMajoritySelect,
setAgeOfMajoritySelect,
- willBeAttendingSelect,
- setWillBeAttendingSelect,
+ willBeAttendingCheck,
+ setWillBeAttendingCheck,
safewalkSelect,
setSafewalkSelect,
- nwMentorshipSelect,
- setNwMentorshipSelect,
+ // nwMentorshipSelect,
+ // setNwMentorshipSelect,
+ hcFeatureSelect,
+ setHcFeatureSelect,
username,
editApplication,
relevantDates,
@@ -395,9 +413,10 @@ const Dashboard = ({
const [releaseLiability, setReleaseLiability] = useState(releaseLiabilityCheck || undefined)
const [mediaConsent, setMediaConsent] = useState(mediaConsentCheck || undefined)
// const [ageOfMajority, setAgeOfMajority] = useState(ageOfMajoritySelect || undefined)
- const [willBeAttending, setWillBeAttending] = useState(willBeAttendingSelect || undefined)
+ const [willBeAttending, setWillBeAttending] = useState(willBeAttendingCheck || false)
const [safewalk, setSafewalk] = useState(safewalkSelect || undefined)
- const [nwMentorship, setNwMentorship] = useState(nwMentorshipSelect || undefined)
+ // const [nwMentorship, setNwMentorship] = useState(nwMentorshipSelect || undefined)
+ const [hcFeature, setHcFeature] = useState(hcFeatureSelect || false)
const hackerRSVPStatus = hackerStatuses()[hackerStatus]?.sidebarText
@@ -430,9 +449,9 @@ const Dashboard = ({
// setAgeOfMajoritySelect(e.target.value)
// }
- const handleWillBeAttendingSelectChange = e => {
- setWillBeAttending(e.target.value)
- setWillBeAttendingSelect(e.target.value)
+ const handleWillBeAttendingChange = () => {
+ setWillBeAttending(!willBeAttending)
+ setWillBeAttendingCheck(!willBeAttendingCheck)
}
const handleSafewalkSelectChange = e => {
@@ -440,9 +459,14 @@ const Dashboard = ({
setSafewalkSelect(e.target.value)
}
- const handleNwMentorshipSelectChange = e => {
- setNwMentorship(e.target.value)
- setNwMentorshipSelect(e.target.value)
+ // const handleNwMentorshipSelectChange = e => {
+ // setNwMentorship(e.target.value)
+ // setNwMentorshipSelect(e.target.value)
+ // }
+
+ const handleHcFeatureChange = value => {
+ setHcFeature(value)
+ setHcFeatureSelect(value)
}
const handleRSVPClick = () => {
@@ -495,15 +519,11 @@ const Dashboard = ({
{relevantDates.hackathonWeekend}?
-
-
@@ -594,7 +614,7 @@ const Dashboard = ({
width="130px"
target="_blank"
rel="noopener noreferrer"
- href={waiversAndForms.COVID}
+ href={waiversAndForms.covid}
>
Read Full Waiver.
{' '}
@@ -632,6 +652,30 @@ const Dashboard = ({
+ HackCamp 2024 Feature Preference
+
+ We are looking for people to be featured in interview videos about their experience
+ at HackCamp. Filming will take ~10 mins and will take place during Build Day
+ (Sunday, November 10th). If chosen, our team will reach out with further
+ instructions. Are you interested in participating?{' '}
+
+
+ handleHcFeatureChange(true)}
+ label="Yes"
+ />
+
+
+ handleHcFeatureChange(false)}
+ label="No"
+ />
+
+
+
+ {/*
nwMentorship Program
I would like to participate in the nwMentorship program to connect with an industry
@@ -669,7 +713,7 @@ const Dashboard = ({
/>
-
+ */}
>
)}
diff --git a/src/components/MobileMenuBar.jsx b/src/components/MobileMenuBar.jsx
index 2733184f..799a4c65 100644
--- a/src/components/MobileMenuBar.jsx
+++ b/src/components/MobileMenuBar.jsx
@@ -24,25 +24,22 @@ const MobileMenuBarContainer = styled.div`
display: none;
z-index: 100;
${p => p.theme.mediaQueries.mobile} {
- padding: 15px;
- display: inline-block;
- text-align: center;
+ padding: 15px 0;
width: 100%;
- box-sizing: border-box;
- // -webkit-box-shadow: 0 6px 8px -8px #000;
- // -moz-box-shadow: 0 6px 8px -8px #000;
- // box-shadow: 0 6px 8px -8px #000;
+
+ display: flex;
+ justify-content: center;
+ align-items: center;
}
`
const Logo = styled.img`
- display: inline-block;
- margin-left: -50px;
- width: 40px;
+ height: 60px;
`
const Menu = styled.img`
- float: left;
+ position: absolute;
+ left: 20px;
width: 30px;
cursor: pointer;
`
diff --git a/src/components/QrCode.jsx b/src/components/QrCode.jsx
index 1ec182d8..949cde5d 100644
--- a/src/components/QrCode.jsx
+++ b/src/components/QrCode.jsx
@@ -3,15 +3,18 @@ import styled from 'styled-components'
import { useQRCode } from 'next-qrcode'
// import JsPDF from 'jspdf'
// import html2canvas from 'html2canvas'
-import qrcodeBackground from '../assets/cmdf2024qrcode.svg'
+import qrcodeBackground from '../assets/hc2024qrcode.svg'
import AppleWalletButtonImage from '../assets/apple_wallet_button.svg'
const QRContainer = styled.div`
display: flex;
z-index: 98;
- ${p => p.theme.mediaQueries.mobile} {
+ justify-content: space-around;
+
+ ${p => p.theme.mediaQueries.tabletLarge} {
flex-direction: column;
align-items: center;
+ justify-content: center;
}
`
@@ -20,21 +23,43 @@ const QRContainer = styled.div`
// display: flex;
// `
-const QRCodeDesignContainer = styled.div``
+const QRTicketContainer = styled.div`
+ position: relative;
+ width: 442.8px;
+ height: 583.2px;
+ margin-top: 30px;
+
+ ${p => p.theme.mediaQueries.mobile} {
+ width: 354.24px;
+ height: 464.4px;
+ }
+`
+
+const QRCodeBackground = styled.img`
+ position: absolute;
+ width: 442.8px;
+ height: 583.2px;
+
+ ${p => p.theme.mediaQueries.mobile} {
+ width: 354.24px;
+ height: 464.4px;
+ }
+`
const QRCodeDesign = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
position: relative;
- width: 300px;
- height: 500px;
- background-size: 100% auto;
- background-repeat: no-repeat;
- padding: 45px;
+ left: 50px;
+ top: 80px;
border-radius: 20px;
z-index: 10;
- background-image: url(${qrcodeBackground});
- margin: 0 auto;
- display: block;
- margin-top: 30px;
+
+ ${p => p.theme.mediaQueries.mobile} {
+ left: 30px;
+ top: 40px;
+ }
`
const HackerName = styled.h1`
@@ -43,12 +68,20 @@ const HackerName = styled.h1`
margin-top: 60px;
position: relative;
color: ${p => p.theme.colors.cardText};
+
+ ${p => p.theme.mediaQueries.mobile} {
+ font-size: 1.5em;
+ }
`
const HackerEmail = styled.p`
color: #2e2e2e !important;
font-size: 1.2em;
margin-top: -10px;
+
+ ${p => p.theme.mediaQueries.mobile} {
+ font-size: 1em;
+ }
`
const QRTags = styled.div`
@@ -78,14 +111,6 @@ const QRTags = styled.div`
// display: block;
// `
-const QRTicketContainer = styled.div`
- float: left;
- width: 50%;
- ${p => p.theme.mediaQueries.mobile} {
- float: none;
- width: 100%;
- }
-`
const QRInfo = styled.div`
float: right;
width: 45%;
@@ -94,7 +119,7 @@ const QRInfo = styled.div`
${p => p.theme.mediaQueries.mobile} {
float: none;
- margin-top: 0;
+ margin-top: 20px;
width: 100%;
padding-left: 0px;
}
@@ -125,9 +150,6 @@ const QRInfoName = styled.h1`
const QRInfoDes = styled.p``
const AppleWalletButton = styled.button`
- position: absolute;
- left: 40px;
- bottom: 100px;
width: 110px;
height: 35px;
padding: 10px;
@@ -136,7 +158,9 @@ const AppleWalletButton = styled.button`
background-size: auto auto;
background-color: transparent;
cursor: pointer;
+ margin-top: 30px;
`
+
// temporary comment out for lint fix
// const generatePDF = () => {
// // const report = new JsPDF('portrait', 'pt', [300, 500.01])
@@ -171,40 +195,33 @@ const QrCode = ({ userInfo, userId }) => {
Welcome, {userInfo.displayName}!
-
-
- {userInfo.displayName}
- {userInfo.email}
+
+
+ {userInfo.displayName}
+ {userInfo.email}
-
- {/* {userInfo.safewalkNote ? SafeWalk: Yes : SafeWalk: No}
+
+ {/* {userInfo.safewalkNote ? SafeWalk: Yes : SafeWalk: No}
*/}
-
-
-
-
- {/* Please hold onto this QR Code for check-in, meals, etc */}
- downloadAppleWalletPass()} />
-
-
-
- {/*
- {' '}
- Save as PDF
- */}
+
+
+
+
+ {/* downloadAppleWalletPass()} /> */}
+
@@ -212,7 +229,7 @@ const QrCode = ({ userInfo, userId }) => {
{userInfo.displayName}!
This ticket contains your personal QR code which will be scanned throughout the event.
- Please add this ticket to your mobile wallet or take a screenshot.
+ Please take a screenshot or otherwise have your QR code ready to scan.
diff --git a/src/components/Rewards/AttendedEvents.jsx b/src/components/Rewards/AttendedEvents.jsx
new file mode 100644
index 00000000..017a9347
--- /dev/null
+++ b/src/components/Rewards/AttendedEvents.jsx
@@ -0,0 +1,83 @@
+import styled, { useTheme } from 'styled-components'
+import { TagLegendContainer, TagLegends } from '../Schedule/Tag'
+import { H1 } from '../Typography'
+import AttendedEventsCard from './AttendedEventsCard'
+import { EVENT_TYPES } from '../Schedule/Constants'
+import { getEvents } from '../../utility/firebase'
+import { useHackathon } from '../../utility/HackathonProvider'
+import { useEffect } from 'react'
+import { useState } from 'react'
+
+const AttendedEventsContainer = styled.div`
+ display: flex;
+ flex-direction: column;
+ gap: 0.75em;
+`
+
+const AttendedEventsHeader = styled.div`
+ display: flex;
+ flex-direction: column;
+`
+
+const TagLegendsContainer = styled(TagLegendContainer)`
+ justify-content: start;
+ padding-right: 0;
+`
+
+const EventsList = styled.div`
+ display: flex;
+ flex-direction: column;
+ gap: 0.75em;
+ overflow-y: scroll;
+ width: 85%;
+
+ ${p => p.theme.mediaQueries.mobile} {
+ width: 100%;
+ }
+`
+
+const AttendedEvents = ({ userDetails }) => {
+ const { dbHackathonName } = useHackathon()
+ const theme = useTheme()
+ const event_type = EVENT_TYPES(theme)
+ const [events, setEvents] = useState([])
+
+ useEffect(() => {
+ // prettier insisted on the semicolon
+ ;(async () => {
+ if (userDetails && dbHackathonName) {
+ console.log(userDetails)
+ const eventIds = userDetails.dayOf.events.map(event => event.eventId)
+ const events = await getEvents(dbHackathonName)
+ const filteredEvents = events.filter(event => eventIds.includes(event.key))
+ setEvents(filteredEvents)
+ }
+ })()
+ }, [userDetails, dbHackathonName])
+
+ return (
+
+
+ Attended events
+
+
+
+
+ {userDetails && (
+
+ {events.map((event, i) => (
+
+ ))}
+
+ )}
+
+ )
+}
+
+export default AttendedEvents
diff --git a/src/components/Rewards/AttendedEventsCard.jsx b/src/components/Rewards/AttendedEventsCard.jsx
new file mode 100644
index 00000000..087fbeca
--- /dev/null
+++ b/src/components/Rewards/AttendedEventsCard.jsx
@@ -0,0 +1,86 @@
+import styled from 'styled-components'
+import { StyledSVG } from '../Schedule/Tag'
+import { P } from '../Typography'
+import Icon from '../../assets/checkmark.svg?react'
+
+const AttendedEventsCardContainer = styled.div`
+ display: flex;
+ align-items: center;
+ gap: 1em;
+
+ color: ${p => p.theme.colors.cardText};
+ background: ${p => p.theme.colors.backgroundTertiary};
+ border-radius: 5px;
+ padding: 0.875em 1em;
+`
+
+const EventDetailsContainer = styled.div`
+ flex-grow: 1;
+ display: flex;
+ justify-content: space-between;
+ gap: 2em;
+ align-items: center;
+`
+
+const TagPointsContainer = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: end;
+`
+
+const CheckmarkSVG = styled(Icon)`
+ fill: ${props => props.color};
+ ${p => p.theme.mediaQueries.mobile} {
+ height: 0.75em;
+ width: 0.75em;
+ }
+`
+
+const EventDetails = styled.div`
+ display: flex;
+ flex-direction: column;
+`
+
+const EventName = styled(P)`
+ margin: 0;
+ font-weight: 700;
+`
+
+const EventTime = styled(P)`
+ margin: 0;
+ font-size: 0.875em;
+`
+
+const PointsText = styled(P)`
+ font-weight: 700;
+ color: ${props => props.color};
+ font-size: 0.875em;
+ margin: 0;
+`
+
+/**
+ * @typedef {{name: string, time: string, points: number, color: string}} AttendedEventsCardProps
+ */
+
+/**
+ * @param {AttendedEventsCardProps} param0
+ */
+const AttendedEventsCard = ({ name, time, points, color }) => {
+ return (
+
+
+
+
+ {name}
+ {time}
+
+
+
+ {points} pts earned
+
+
+
+ )
+}
+
+export default AttendedEventsCard
diff --git a/src/components/Rewards/TotalPoints.jsx b/src/components/Rewards/TotalPoints.jsx
new file mode 100644
index 00000000..ff9c81d5
--- /dev/null
+++ b/src/components/Rewards/TotalPoints.jsx
@@ -0,0 +1,69 @@
+import styled from 'styled-components'
+import { getEvents } from '../../utility/firebase'
+import { useHackathon } from '../../utility/HackathonProvider'
+import { useState, useEffect } from 'react'
+
+const TotalPointsName = styled.h2`
+ color: ${p => p.theme.colors.highlight};
+ font-weight: 700;
+ font-size: 30px;
+`
+
+const TotalPointsCard = styled.div`
+ background: ${p => p.theme.colors.backgroundTertiary};
+ display: flex;
+ flex-direction: column;
+ align-items: left;
+ justify-content: center;
+ padding-left: 29px;
+ border-radius: 5px;
+ width: 302px;
+ height: 113px;
+`
+
+const PointsTitle = styled.div`
+ color: ${p => p.theme.colors.textSecondary};
+ font-size: 18px;
+ font-weight: 700;
+`
+
+const PointsValue = styled.div`
+ color: ${p => p.theme.colors.highlight};
+ font-size: 40px;
+ font-weight: 700;
+`
+
+const TotalPoints = ({ userDetails }) => {
+ const { dbHackathonName } = useHackathon()
+ const [name, setName] = useState('')
+ const [totalPoints, setTotalPoints] = useState(0)
+
+ useEffect(() => {
+ ;(async () => {
+ if (userDetails && dbHackathonName) {
+ const eventIds = userDetails.dayOf.events.map(event => event.eventId)
+ const events = await getEvents(dbHackathonName)
+ const filteredEvents = events.filter(event => eventIds.includes(event.key))
+
+ setName(`${userDetails.basicInfo.preferredName} ${userDetails.basicInfo.legalLastName}`)
+ setTotalPoints(
+ filteredEvents.reduce((accumulator, event) => {
+ return accumulator + parseInt(event.points)
+ }, 0)
+ )
+ }
+ })()
+ }, [userDetails, dbHackathonName])
+
+ return (
+
+
{name}
+
+ TOTAL POINTS
+ {totalPoints.toLocaleString()} pts
+
+
+ )
+}
+
+export default TotalPoints
diff --git a/src/components/Schedule/Event.jsx b/src/components/Schedule/Event.jsx
index 2b6db893..157d03b0 100644
--- a/src/components/Schedule/Event.jsx
+++ b/src/components/Schedule/Event.jsx
@@ -76,7 +76,7 @@ const EventCard = styled(Card)`
margin-right: 0;
margin-top: -0.5em;
width: 100%;
- height: ${MOBILE_HOUR_HEIGHT - EVENT_GAP} px;
+ height: ${MOBILE_HOUR_HEIGHT - EVENT_GAP}px;
}
}
diff --git a/src/components/Schedule/Schedule.jsx b/src/components/Schedule/Schedule.jsx
index 545c4b18..e485ccff 100644
--- a/src/components/Schedule/Schedule.jsx
+++ b/src/components/Schedule/Schedule.jsx
@@ -4,7 +4,7 @@ import { ScrollbarLike } from '../Common'
import { H1 } from '../Typography'
import { EVENT_GAP, MOBILE_HOUR_HEIGHT } from './Constants'
import Event from './Event'
-import { TagLegend } from './Tag'
+import { TagLegends, TagLegendContainer } from './Tag'
import { TimelineColumn } from './Timeline'
import { useTheme } from 'styled-components'
@@ -45,6 +45,7 @@ const MobileScrollableContainer = styled.div`
margin-top: 1em;
border-radius: 10px;
background: #244556;
+ background: ${p => p.theme.colors.schedule.background};
&:after {
content: '';
position: fixed;
@@ -311,7 +312,9 @@ const Schedule = ({ events, hackathonStart, hackathonEnd }) => {
-
+
+
+
Saturday
@@ -338,7 +341,9 @@ const Schedule = ({ events, hackathonStart, hackathonEnd }) => {
-
+
+
+
diff --git a/src/components/Schedule/Tag.jsx b/src/components/Schedule/Tag.jsx
index 69922572..27a6131e 100644
--- a/src/components/Schedule/Tag.jsx
+++ b/src/components/Schedule/Tag.jsx
@@ -45,17 +45,13 @@ export const StyledSVG = styled(Icon)`
}
`
-export const TagLegend = ({ theme }) => {
- return (
-
- {Object.entries(EVENT_TYPES(theme)).map(([key, event_type], i) => {
- return (
-
-
- {event_type.label}
-
- )
- })}
-
- )
+export const TagLegends = ({ theme }) => {
+ return Object.entries(EVENT_TYPES(theme)).map(([key, event_type], i) => {
+ return (
+
+
+ {event_type.label}
+
+ )
+ })
}
diff --git a/src/components/Sidebar.jsx b/src/components/Sidebar.jsx
index b519fcf1..be7c7af6 100644
--- a/src/components/Sidebar.jsx
+++ b/src/components/Sidebar.jsx
@@ -195,7 +195,7 @@ const Sidebar = ({
{ location: '/', text: 'Home' },
{ location: '/schedule', text: 'Schedule' },
{ location: '/livestream', text: 'Livestream' },
- { location: '/rewards', text: 'Rewards' },
+ // { location: '/rewards', text: 'Rewards' },
{ location: '/sponsors', text: 'Sponsors' },
],
// Tools
@@ -266,9 +266,9 @@ const Sidebar = ({
links.tools.push({ location: '/judging/admin', text: 'Judging Admin' })
}
- if (import.meta.env.NODE_ENV !== 'production') {
- links.information.push({ location: '/charcuterie', text: 'CHARCUTERIE' })
- }
+ // if (import.meta.env.NODE_ENV !== 'production') {
+ // links.information.push({ location: '/charcuterie', text: 'CHARCUTERIE' })
+ // }
if (isApplicationOpen) {
// List the application as the last item on the menu
diff --git a/src/containers/Application/Dashboard.jsx b/src/containers/Application/Dashboard.jsx
index 562d0854..77f7fc4b 100644
--- a/src/containers/Application/Dashboard.jsx
+++ b/src/containers/Application/Dashboard.jsx
@@ -137,10 +137,10 @@ const ApplicationDashboardContainer = () => {
forceSave()
}
- const setWillBeAttendingSelect = willBeAttendingSelect => {
+ const setWillBeAttendingCheck = willBeAttendingCheck => {
updateApplication({
basicInfo: {
- willBeAttendingSelect,
+ willBeAttendingCheck,
},
})
forceSave()
@@ -164,6 +164,15 @@ const ApplicationDashboardContainer = () => {
forceSave()
}
+ const setHcFeatureSelect = hcFeatureSelect => {
+ updateApplication({
+ basicInfo: {
+ hcFeatureSelect,
+ },
+ })
+ forceSave()
+ }
+
const handleWaiver = async waiver => {
// check to make sure its under 2mb
const size = (waiver.size / 1024 / 1024).toFixed(2)
@@ -206,14 +215,16 @@ const ApplicationDashboardContainer = () => {
setMediaConsentCheck={mediaConsentCheck => setMediaConsentCheck(mediaConsentCheck)}
ageOfMajoritySelect={application.basicInfo.ageOfMajoritySelect || undefined}
setAgeOfMajoritySelect={ageOfMajoritySelect => setAgeOfMajoritySelect(ageOfMajoritySelect)}
- willBeAttendingSelect={application.basicInfo.willBeAttendingSelect || undefined}
- setWillBeAttendingSelect={willBeAttendingSelect =>
- setWillBeAttendingSelect(willBeAttendingSelect)
+ willBeAttendingCheck={application.basicInfo.willBeAttendingCheck || false}
+ setWillBeAttendingCheck={willBeAttendingCheck =>
+ setWillBeAttendingCheck(willBeAttendingCheck)
}
safewalkSelect={application.basicInfo.safewalkSelect || undefined}
setSafewalkSelect={safewalkSelect => setSafewalkSelect(safewalkSelect)}
- nwMentorshipSelect={application.basicInfo.nwMentorshipSelect || undefined}
- setNwMentorshipSelect={nwMentorshipSelect => setNwMentorshipSelect(nwMentorshipSelect)}
+ // nwMentorshipSelect={application.basicInfo.nwMentorshipSelect || undefined}
+ // setNwMentorshipSelect={nwMentorshipSelect => setNwMentorshipSelect(nwMentorshipSelect)}
+ hcFeatureSelect={application.basicInfo.hcFeatureSelect || undefined}
+ setHcFeatureSelect={hcFeatureSelect => setHcFeatureSelect(hcFeatureSelect)}
relevantDates={relevantDates}
waiversAndForms={waiversAndForms}
notionLinks={notionLinks}
diff --git a/src/containers/Rewards.jsx b/src/containers/Rewards.jsx
index 49bec6be..103b322d 100644
--- a/src/containers/Rewards.jsx
+++ b/src/containers/Rewards.jsx
@@ -1,8 +1,12 @@
+import styled from 'styled-components'
import React, { useEffect, useState } from 'react'
import { useHackathon } from '../utility/HackathonProvider'
import { rewardsRef } from '../utility/firebase'
-import styled from 'styled-components'
import RewardCard from '../components/RewardCard'
+// import TotalPoints from '../components/Rewards/TotalPoints'
+// import AttendedEvents from '../components/Rewards/AttendedEvents'
+// import { useAuth } from '../utility/Auth'
+// import { getUserApplication } from '../utility/firebase'
const Container = styled.div`
display: grid;
@@ -30,7 +34,7 @@ const Subtitle = styled.h3`
const Cards = styled.div`
display: grid;
grid-template-columns: 1fr 1fr;
- column-gap: 0px;
+ column-gap: 32px;
row-gap: 32px;
@media (max-width: 768px) {
@@ -62,10 +66,13 @@ const Rewards = () => {
return (
-
+ {/* */}
-
Enter a raffle for prizes by collecting points or attending events!
+
+ A list of hackathon and raffle prizes available! Enter a raffle for prizes by collecting
+ points or attending events!
+
{rewards.map((reward, index) => (
{
)
}
-export default Rewards
\ No newline at end of file
+export default Rewards
diff --git a/src/pages/Home.jsx b/src/pages/Home.jsx
index 9cec8c3e..0783d3e3 100644
--- a/src/pages/Home.jsx
+++ b/src/pages/Home.jsx
@@ -8,10 +8,11 @@ import QrCode from '../components/QrCode'
import { useAuth } from '../utility/Auth'
// import Hackcamp2023BG from '../components/BackgroundImage'
import { APPLICATION_STATUS } from '../utility/Constants'
-import backgroundImage from '../assets/cmdf_homebg.svg'
+import backgroundImage from '../assets/hc_background.svg'
import mobileBackgroundImage from '../assets/cmdf_mobilebg.svg'
import { copyText } from '../utility/Constants'
import { useHackathon } from '../utility/HackathonProvider'
+import { css } from 'styled-components'
//My Ticket
const HomeContainer = styled.div`
@@ -21,7 +22,6 @@ const HomeContainer = styled.div`
flex-direction: column;
gap: 1.5em;
z-index: 3;
- background-color: ${p => p.theme.colors.background};
${p => p.theme.mediaQueries.mobile} {
gap: 1em;
}
@@ -38,13 +38,11 @@ const HomeContainerBackground = styled.div`
${props =>
props.backgroundImage &&
css`
- background-image: url(${backgroundImage});
+ background-image: url(${props.backgroundImage});
background-size: cover;
background-position: right bottom;
${p => p.theme.mediaQueries.mobile} {
- background-image: url(${mobileBackgroundImage});
- background-size: cover;
background-position: center;
}
`}
@@ -68,7 +66,7 @@ export default withTheme(({ announcements, theme }) => {
return (
<>
-
+
{/* {activeHackathon === 'hackcamp' && } */}
diff --git a/src/pages/Judging/index.jsx b/src/pages/Judging/index.jsx
index 17ead80f..694c100e 100644
--- a/src/pages/Judging/index.jsx
+++ b/src/pages/Judging/index.jsx
@@ -15,50 +15,68 @@ const StyledJudgingCard = styled(JudgingCard)`
const getProjects = async (userId, projectId, dbHackathonName) => {
const getAndAssignProjects = async () => {
- const projectDocs = await projectsRef(dbHackathonName)
- .where('draftStatus', '==', 'public')
- .orderBy('countAssigned')
- .limit(PROJECTS_TO_JUDGE_COUNT + 1) // get an extra in case we got our own project
- .get()
- let projectIds = projectDocs.docs.map(project => project.id)
- projectIds = projectIds.filter(id => id !== projectId)
- if (projectIds.length > PROJECTS_TO_JUDGE_COUNT) {
- projectIds.pop()
- }
- const batch = db.batch()
+ try {
+ return db.runTransaction(async transaction => {
+ const projectDocs = await transaction.get(
+ projectsRef(dbHackathonName)
+ .where('draftStatus', '==', 'public')
+ .orderBy('countAssigned')
+ .limit(PROJECTS_TO_JUDGE_COUNT + 1) // get an extra in case we got our own project
+ )
- // increment assigned counters
- projectIds.forEach(projectId => {
- batch.update(projectsRef(dbHackathonName).doc(projectId), {
- countAssigned: firestore.FieldValue.increment(1),
- })
- })
+ let projectIds = projectDocs.docs.map(project => project.id)
+ projectIds = projectIds.filter(id => id !== projectId)
+ if (projectIds.length > PROJECTS_TO_JUDGE_COUNT) {
+ projectIds.pop()
+ }
- // add projects to user
- batch.update(applicantsRef(dbHackathonName).doc(userId), { projectsAssigned: projectIds })
- await batch.commit()
- return projectIds
+ // increment assigned counters
+ projectIds.forEach(projectId => {
+ const projectRef = projectsRef(dbHackathonName).doc(projectId)
+ transaction.update(projectRef, {
+ countAssigned: firestore.FieldValue.increment(1),
+ })
+ })
+
+ // add projects to user
+ const applicantRef = applicantsRef(dbHackathonName).doc(userId)
+ transaction.update(applicantRef, {
+ projectsAssigned: projectIds,
+ })
+ return projectIds
+ })
+ } catch (error) {
+ console.error('Error assigning projects:', error)
+ }
}
const queryProjects = async projectIds => {
- const projectDocs = await projectsRef(dbHackathonName)
- .where(firestore.FieldPath.documentId(), 'in', projectIds)
- .get()
- if (projectDocs.docs.length < 1) {
- // projects are missing
- const newProjectIds = await getAndAssignProjects()
- return await queryProjects(newProjectIds)
+ try {
+ const projectDocs = await projectsRef(dbHackathonName)
+ .where(firestore.FieldPath.documentId(), 'in', projectIds)
+ .get()
+ if (projectDocs.docs.length < 1) {
+ // projects are missing
+ const newProjectIds = await getAndAssignProjects()
+ return await queryProjects(newProjectIds)
+ }
+ return projectDocs
+ } catch (error) {
+ console.error('Error querying projects:', error)
}
- return projectDocs
}
const getProjectsData = async projectIds => {
- let projectDocs = await queryProjects(projectIds)
- return projectDocs.docs.map(project => {
- const formattedProject = formatProject({ ...project.data(), id: project.id })
- formattedProject.judged = formattedProject.grades && formattedProject.grades[userId]
- return formattedProject
- })
+ try {
+ let projectDocs = await queryProjects(projectIds)
+ return projectDocs.docs.map(project => {
+ const formattedProject = formatProject({ ...project.data(), id: project.id })
+ formattedProject.judged = formattedProject.grades && formattedProject.grades[userId]
+ return formattedProject
+ })
+ } catch (error) {
+ console.error('Error getting project data:', error)
+ }
}
const applicantDoc = await applicantsRef(dbHackathonName).doc(userId).get()
diff --git a/src/theme/ThemeProvider.jsx b/src/theme/ThemeProvider.jsx
index 3d253981..c152f8df 100644
--- a/src/theme/ThemeProvider.jsx
+++ b/src/theme/ThemeProvider.jsx
@@ -45,8 +45,8 @@ const hackcampTheme = {
...base,
name: 'hackcamp',
colors: {
- background: 'linear-gradient(0deg, #94D6EF, #94D6EF)',
- backgroundSecondary: '#75AEE2',
+ background: '#C8E5F0',
+ backgroundSecondary: '#93BEE5',
backgroundTertiary: 'linear-gradient(180deg, #F9C745 0%, #FF880F 100%)',
text: '#45171A',
textSecondary: '#01033D',
@@ -106,8 +106,8 @@ const hackcampTheme = {
schedule: {
background:
'linear-gradient(180deg, rgba(0, 163, 224, 0.6) 0%, rgba(255, 248, 229, 0.6) 99.98%)',
- mainEventTag: '#00A3E0',
- workshopTag: '#F3F3F3',
+ mainEventTag: '#3268A5',
+ workshopTag: '#DE0148',
activityTag: '#A9158D',
lines: '#FFFFFF',
},
diff --git a/src/utility/Auth.jsx b/src/utility/Auth.jsx
index 397f2639..cf93917c 100644
--- a/src/utility/Auth.jsx
+++ b/src/utility/Auth.jsx
@@ -7,6 +7,7 @@ import Spinner from '../components/Loading'
import { useLocation } from 'wouter'
import { useHackathon } from './HackathonProvider'
+/** @type {React.Context<{isAuthed: boolean, user: firebase.User | null, setUser: React.Dispatch>, logout: () => Promise}>} */
const AuthContext = createContext()
export function useAuth() {
@@ -81,7 +82,7 @@ export const getRedirectUrl = (redirect, activeHackathon) => {
case REDIRECT_STATUS.ApplicationNotSubmitted:
return `/app/${activeHackathon}/application/part-0`
case REDIRECT_STATUS.ApplicationSubmitted:
- return `/app/${activeHackathon}`
+ return `/app/${activeHackathon}/application`
default:
return `/app/${activeHackathon}/application`
}
diff --git a/src/utility/HackerApplicationContext.jsx b/src/utility/HackerApplicationContext.jsx
index bdf058f9..ad9883ca 100644
--- a/src/utility/HackerApplicationContext.jsx
+++ b/src/utility/HackerApplicationContext.jsx
@@ -211,7 +211,7 @@ export function HackerApplicationProvider({ children }) {
return null
}
- if (!applicationOpen && window.location.pathname !== '/application') {
+ if (!applicationOpen && !window.location.pathname.endsWith('/application')) {
return
}
diff --git a/src/utility/Routes.jsx b/src/utility/Routes.jsx
index 73bc1f2d..eba39f64 100644
--- a/src/utility/Routes.jsx
+++ b/src/utility/Routes.jsx
@@ -15,8 +15,9 @@ const NestedRoutes = props => {
const hackathonFromURL = props.base.split('/')[2].toLowerCase()
useEffect(() => {
- if (VALID_HACKATHONS.includes(hackathonFromURL) && hackathonFromURL !== activeHackathon) {
+ if (VALID_HACKATHONS.includes(hackathonFromURL)) {
setActiveHackathon(hackathonFromURL)
+ localStorage.setItem('activeHackathon', activeHackathon)
}
}, [props.base, activeHackathon, setActiveHackathon])
@@ -48,7 +49,8 @@ const PageRoute = ({ path, children }) => {
return (
- {livesiteDoc?.applicationsOpen[activeHackathon] ? (
+ {livesiteDoc?.applicationsOpen[activeHackathon] ||
+ !livesiteDoc?.portalLive[activeHackathon] ? (
) : (
{children}
diff --git a/src/utility/firebase.js b/src/utility/firebase.js
index bffc4194..a0f49184 100644
--- a/src/utility/firebase.js
+++ b/src/utility/firebase.js
@@ -41,6 +41,9 @@ export const applicantsRef = dbHackathonName => {
export const projectsRef = dbHackathonName => {
return db.collection(DB_COLLECTION).doc(dbHackathonName).collection('Projects')
}
+export const eventsRef = dbHackathonName => {
+ return db.collection(DB_COLLECTION).doc(dbHackathonName).collection('Events')
+}
export const announcementsRef = dbHackathonName => {
return db.collection(DB_COLLECTION).doc(dbHackathonName).collection('Announcements')
}
@@ -54,6 +57,10 @@ export const getLivesiteDoc = callback => {
})
}
+export const getEvents = async dbHackathonName => {
+ return (await eventsRef(dbHackathonName).get()).docs.map(doc => doc.data())
+}
+
const createNewApplication = async (user, dbHackathonName) => {
analytics.logEvent(ANALYTICS_EVENTS.signup, { userId: user.uid })
const userId = {