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 }) => {
Day-Of-Events Schedule
- + + +
Saturday @@ -338,7 +340,9 @@ const Schedule = ({ events, hackathonStart, hackathonEnd }) => {
Day-Of-Events Schedule
- + + +
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'} /> ))}