From 49c50e717ce274767c8eb2afbd6f9aabb8b258e9 Mon Sep 17 00:00:00 2001
From: Daniel Pan <57362494+daniel-panhead@users.noreply.github.com>
Date: Sat, 12 Oct 2024 23:38:04 -0700
Subject: [PATCH 1/7] Add placeholder attended events card + basic rewards
layout
---
src/assets/checkmark.svg | 5 ++
src/components/Rewards/AttendedEvents.jsx | 38 +++++++++
src/components/Rewards/AttendedEventsCard.jsx | 80 +++++++++++++++++++
src/components/Schedule/Schedule.jsx | 10 ++-
src/components/Schedule/Tag.jsx | 22 +++--
src/containers/Rewards.jsx | 33 +++++++-
6 files changed, 171 insertions(+), 17 deletions(-)
create mode 100644 src/assets/checkmark.svg
create mode 100644 src/components/Rewards/AttendedEvents.jsx
create mode 100644 src/components/Rewards/AttendedEventsCard.jsx
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/components/Rewards/AttendedEvents.jsx b/src/components/Rewards/AttendedEvents.jsx
new file mode 100644
index 00000000..1a6cb162
--- /dev/null
+++ b/src/components/Rewards/AttendedEvents.jsx
@@ -0,0 +1,38 @@
+import styled, { useTheme } from 'styled-components'
+import { TagLegendContainer, TagLegends } from '../Schedule/Tag'
+import { H1 } from '../Typography'
+import AttendedEventsCard from './AttendedEventsCard'
+
+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 AttendedEvents = () => {
+ const theme = useTheme()
+
+ return (
+
+
+ Attended events
+
+
+
+
+
+
+ )
+}
+
+export default AttendedEvents
diff --git a/src/components/Rewards/AttendedEventsCard.jsx b/src/components/Rewards/AttendedEventsCard.jsx
new file mode 100644
index 00000000..864d78cd
--- /dev/null
+++ b/src/components/Rewards/AttendedEventsCard.jsx
@@ -0,0 +1,80 @@
+import styled, { useTheme } from 'styled-components'
+import { StyledSVG } from '../Schedule/Tag'
+import { EVENT_TYPES } from '../Schedule/Constants'
+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: 1em 1.5em;
+`
+
+const EventDetailsContainer = styled.div`
+ flex-grow: 1;
+ display: flex;
+ justify-content: space-between;
+ 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;
+`
+
+const AttendedEventsCard = () => {
+ const theme = useTheme()
+ const event_type = Object.entries(EVENT_TYPES(theme)).map(([key, event_type], i) => event_type)[0]
+ return (
+
+
+
+
+ Some Event
+ 10:00AM - 11:00AM
+
+
+
+ 600 pts earned
+
+
+
+ )
+}
+
+export default AttendedEventsCard
diff --git a/src/components/Schedule/Schedule.jsx b/src/components/Schedule/Schedule.jsx
index 545c4b18..15a2381e 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'
@@ -311,7 +311,9 @@ const Schedule = ({ events, hackathonStart, hackathonEnd }) => {
-
+
+
+
Saturday
@@ -338,7 +340,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/containers/Rewards.jsx b/src/containers/Rewards.jsx
index b7b2b74c..a527d22a 100644
--- a/src/containers/Rewards.jsx
+++ b/src/containers/Rewards.jsx
@@ -1,3 +1,34 @@
-const Rewards = () => {}
+import styled from 'styled-components'
+import AttendedEvents from '../components/Rewards/AttendedEvents'
+
+const RewardsContainer = styled.div`
+ display: flex;
+ height: 100%;
+ width: 100%;
+
+ ${p => p.theme.mediaQueries.mobile} {
+ flex-direction: column;
+ }
+`
+
+const RewardsSummaryContainer = styled.div`
+ display: flex;
+ flex-direction: column;
+ flex-basis: 35%;
+ flex-shrink: 0;
+`
+
+const RewardsContentContainer = styled.div``
+
+const Rewards = () => {
+ return (
+
+
+
+
+
+
+ )
+}
export default Rewards
From f721672174a3218b98463cbc4dbe4b17ea840ee6 Mon Sep 17 00:00:00 2001
From: Daniel Pan <57362494+daniel-panhead@users.noreply.github.com>
Date: Sun, 13 Oct 2024 00:01:47 -0700
Subject: [PATCH 2/7] Make attended events card dynamic
---
src/components/Rewards/AttendedEvents.jsx | 31 ++++++++++++++++++-
src/components/Rewards/AttendedEventsCard.jsx | 28 ++++++++++-------
2 files changed, 47 insertions(+), 12 deletions(-)
diff --git a/src/components/Rewards/AttendedEvents.jsx b/src/components/Rewards/AttendedEvents.jsx
index 1a6cb162..b9a48aed 100644
--- a/src/components/Rewards/AttendedEvents.jsx
+++ b/src/components/Rewards/AttendedEvents.jsx
@@ -2,6 +2,7 @@ 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'
const AttendedEventsContainer = styled.div`
display: flex;
@@ -19,8 +20,26 @@ const TagLegendsContainer = styled(TagLegendContainer)`
padding-right: 0;
`
+const EventsList = styled.div`
+ display: flex;
+ flex-direction: column;
+ gap: 0.75em;
+ width: 85%;
+
+ ${p => p.theme.mediaQueries.mobile} {
+ width: 100%;
+ }
+`
+
const AttendedEvents = () => {
const theme = useTheme()
+ const event_type = EVENT_TYPES(theme)
+
+ const events = [
+ { name: 'Some Event', time: '10:00AM - 11:00AM', points: 600, event_type: 'main' },
+ { name: 'Some Event 2', time: '10:00AM - 11:00AM', points: 400, event_type: 'workshops' },
+ { name: 'Some Event 3', time: '10:00AM - 11:00AM', points: 300, event_type: 'minievents' },
+ ]
return (
@@ -30,7 +49,17 @@ const AttendedEvents = () => {
-
+
+ {events.map((event, i) => (
+
+ ))}
+
)
}
diff --git a/src/components/Rewards/AttendedEventsCard.jsx b/src/components/Rewards/AttendedEventsCard.jsx
index 864d78cd..087fbeca 100644
--- a/src/components/Rewards/AttendedEventsCard.jsx
+++ b/src/components/Rewards/AttendedEventsCard.jsx
@@ -1,6 +1,5 @@
-import styled, { useTheme } from 'styled-components'
+import styled from 'styled-components'
import { StyledSVG } from '../Schedule/Tag'
-import { EVENT_TYPES } from '../Schedule/Constants'
import { P } from '../Typography'
import Icon from '../../assets/checkmark.svg?react'
@@ -12,13 +11,14 @@ const AttendedEventsCardContainer = styled.div`
color: ${p => p.theme.colors.cardText};
background: ${p => p.theme.colors.backgroundTertiary};
border-radius: 5px;
- padding: 1em 1.5em;
+ padding: 0.875em 1em;
`
const EventDetailsContainer = styled.div`
flex-grow: 1;
display: flex;
justify-content: space-between;
+ gap: 2em;
align-items: center;
`
@@ -55,22 +55,28 @@ const PointsText = styled(P)`
font-weight: 700;
color: ${props => props.color};
font-size: 0.875em;
+ margin: 0;
`
-const AttendedEventsCard = () => {
- const theme = useTheme()
- const event_type = Object.entries(EVENT_TYPES(theme)).map(([key, event_type], i) => event_type)[0]
+/**
+ * @typedef {{name: string, time: string, points: number, color: string}} AttendedEventsCardProps
+ */
+
+/**
+ * @param {AttendedEventsCardProps} param0
+ */
+const AttendedEventsCard = ({ name, time, points, color }) => {
return (
-
+
- Some Event
- 10:00AM - 11:00AM
+ {name}
+ {time}
-
- 600 pts earned
+
+ {points} pts earned
From 3d611c95be45dd4d7547acdde49c68b682831378 Mon Sep 17 00:00:00 2001
From: Daniel Pan <57362494+daniel-panhead@users.noreply.github.com>
Date: Mon, 14 Oct 2024 15:06:04 -0700
Subject: [PATCH 3/7] Update theme with new hc colors
---
src/theme/ThemeProvider.jsx | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/theme/ThemeProvider.jsx b/src/theme/ThemeProvider.jsx
index 6da8cf33..25ec95e8 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',
@@ -104,8 +104,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',
},
From ef4913588d3d93e0493921a2974386516ff76bb2 Mon Sep 17 00:00:00 2001
From: Daniel Pan <57362494+daniel-panhead@users.noreply.github.com>
Date: Mon, 14 Oct 2024 15:26:45 -0700
Subject: [PATCH 4/7] Add type hinting to auth context user object
---
src/utility/Auth.jsx | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/utility/Auth.jsx b/src/utility/Auth.jsx
index 397f2639..72d7f4fd 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() {
From 30c9c8033ad476b81e7144a56ab9210e3319b35c Mon Sep 17 00:00:00 2001
From: Daniel Pan <57362494+daniel-panhead@users.noreply.github.com>
Date: Mon, 14 Oct 2024 16:09:51 -0700
Subject: [PATCH 5/7] Load user details and pass to attended events component
---
src/components/Rewards/AttendedEvents.jsx | 27 +++++++++++++----------
src/containers/Rewards.jsx | 19 ++++++++++++++--
2 files changed, 32 insertions(+), 14 deletions(-)
diff --git a/src/components/Rewards/AttendedEvents.jsx b/src/components/Rewards/AttendedEvents.jsx
index b9a48aed..40dd0722 100644
--- a/src/components/Rewards/AttendedEvents.jsx
+++ b/src/components/Rewards/AttendedEvents.jsx
@@ -24,6 +24,7 @@ const EventsList = styled.div`
display: flex;
flex-direction: column;
gap: 0.75em;
+ overflow-y: scroll;
width: 85%;
${p => p.theme.mediaQueries.mobile} {
@@ -31,7 +32,7 @@ const EventsList = styled.div`
}
`
-const AttendedEvents = () => {
+const AttendedEvents = ({ userDetails }) => {
const theme = useTheme()
const event_type = EVENT_TYPES(theme)
@@ -49,17 +50,19 @@ const AttendedEvents = () => {
-
- {events.map((event, i) => (
-
- ))}
-
+ {userDetails && (
+
+ {events.map((event, i) => (
+
+ ))}
+
+ )}
)
}
diff --git a/src/containers/Rewards.jsx b/src/containers/Rewards.jsx
index a527d22a..c4c46e46 100644
--- a/src/containers/Rewards.jsx
+++ b/src/containers/Rewards.jsx
@@ -1,5 +1,10 @@
import styled from 'styled-components'
import AttendedEvents from '../components/Rewards/AttendedEvents'
+import { useAuth } from '../utility/Auth'
+import { getUserApplication } from '../utility/firebase'
+import { useHackathon } from '../utility/HackathonProvider'
+import { useState } from 'react'
+import { useEffect } from 'react'
const RewardsContainer = styled.div`
display: flex;
@@ -21,12 +26,22 @@ const RewardsSummaryContainer = styled.div`
const RewardsContentContainer = styled.div``
const Rewards = () => {
+ const { user } = useAuth()
+ const { dbHackathonName } = useHackathon()
+ const [userDetails, setUserDetails] = useState(null)
+
+ useEffect(() => {
+ getUserApplication(user.uid, dbHackathonName).then(user => {
+ setUserDetails(user)
+ })
+ }, [user, dbHackathonName])
+
return (
-
+
-
+
)
}
From 2f6589581f4728ec9231332ccf4c17ba4f41417c Mon Sep 17 00:00:00 2001
From: Daniel Pan <57362494+daniel-panhead@users.noreply.github.com>
Date: Wed, 16 Oct 2024 20:49:14 -0700
Subject: [PATCH 6/7] Get user attended events from firebase
---
src/components/Rewards/AttendedEvents.jsx | 28 ++++++++++++++++-------
src/utility/firebase.js | 7 ++++++
2 files changed, 27 insertions(+), 8 deletions(-)
diff --git a/src/components/Rewards/AttendedEvents.jsx b/src/components/Rewards/AttendedEvents.jsx
index 40dd0722..5c9b2316 100644
--- a/src/components/Rewards/AttendedEvents.jsx
+++ b/src/components/Rewards/AttendedEvents.jsx
@@ -3,6 +3,10 @@ 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;
@@ -33,14 +37,22 @@ const EventsList = styled.div`
`
const AttendedEvents = ({ userDetails }) => {
+ const { dbHackathonName } = useHackathon()
const theme = useTheme()
const event_type = EVENT_TYPES(theme)
+ const [events, setEvents] = useState([])
- const events = [
- { name: 'Some Event', time: '10:00AM - 11:00AM', points: 600, event_type: 'main' },
- { name: 'Some Event 2', time: '10:00AM - 11:00AM', points: 400, event_type: 'workshops' },
- { name: 'Some Event 3', time: '10:00AM - 11:00AM', points: 300, event_type: 'minievents' },
- ]
+ useEffect(() => {
+ // prettier insisted on the semicolon
+ ;(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))
+ setEvents(filteredEvents)
+ }
+ })()
+ }, [userDetails, dbHackathonName])
return (
@@ -55,10 +67,10 @@ const AttendedEvents = ({ userDetails }) => {
{events.map((event, i) => (
))}
diff --git a/src/utility/firebase.js b/src/utility/firebase.js
index 4a50a807..ee1f8787 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')
}
@@ -51,6 +54,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 = {
From fa26440400216fda67cd5f37d827951e799c776d Mon Sep 17 00:00:00 2001
From: Daniel Pan <57362494+daniel-panhead@users.noreply.github.com>
Date: Wed, 23 Oct 2024 19:17:24 -0700
Subject: [PATCH 7/7] Display correct attended events type
---
src/components/Rewards/AttendedEvents.jsx | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/components/Rewards/AttendedEvents.jsx b/src/components/Rewards/AttendedEvents.jsx
index 5c9b2316..017a9347 100644
--- a/src/components/Rewards/AttendedEvents.jsx
+++ b/src/components/Rewards/AttendedEvents.jsx
@@ -46,6 +46,7 @@ const AttendedEvents = ({ userDetails }) => {
// 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))
@@ -70,7 +71,7 @@ const AttendedEvents = ({ userDetails }) => {
name={event.title}
time={new Date(event.date.seconds * 1000).toLocaleString()}
points={event.points}
- color={event_type[event.event_type]?.colour ?? theme.colors.schedule.mainEventTag}
+ color={event_type[event.type]?.colour ?? 'gray'}
/>
))}