Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Attended Events component #627

Open
wants to merge 7 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/assets/checkmark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
83 changes: 83 additions & 0 deletions src/components/Rewards/AttendedEvents.jsx
Original file line number Diff line number Diff line change
@@ -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 (
<AttendedEventsContainer>
<AttendedEventsHeader>
<H1>Attended events</H1>
<TagLegendsContainer>
<TagLegends theme={theme} />
</TagLegendsContainer>
</AttendedEventsHeader>
{userDetails && (
<EventsList>
{events.map((event, i) => (
<AttendedEventsCard
key={i}
name={event.title}
time={new Date(event.date.seconds * 1000).toLocaleString()}
points={event.points}
color={event_type[event.type]?.colour ?? 'gray'}
/>
))}
</EventsList>
)}
</AttendedEventsContainer>
)
}

export default AttendedEvents
86 changes: 86 additions & 0 deletions src/components/Rewards/AttendedEventsCard.jsx
Original file line number Diff line number Diff line change
@@ -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 (
<AttendedEventsCardContainer>
<CheckmarkSVG color={color} />
<EventDetailsContainer>
<EventDetails>
<EventName>{name}</EventName>
<EventTime>{time}</EventTime>
</EventDetails>
<TagPointsContainer>
<StyledSVG color={color} />
<PointsText color={color}>{points} pts earned</PointsText>
</TagPointsContainer>
</EventDetailsContainer>
</AttendedEventsCardContainer>
)
}

export default AttendedEventsCard
10 changes: 7 additions & 3 deletions src/components/Schedule/Schedule.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'

Expand Down Expand Up @@ -311,7 +311,9 @@ const Schedule = ({ events, hackathonStart, hackathonEnd }) => {
<OverflowContainer>
<HeaderContainer>
<Header>Day-Of-Events Schedule</Header>
<TagLegend theme={theme} />
<TagLegendContainer>
<TagLegends theme={theme} />
</TagLegendContainer>
</HeaderContainer>
<DayLabelContainer>
<DayLabel style={{ opacity: isSunday ? 0 : 1 }}>Saturday</DayLabel>
Expand All @@ -338,7 +340,9 @@ const Schedule = ({ events, hackathonStart, hackathonEnd }) => {
<MobileOverflowContainer>
<HeaderContainer>
<Header>Day-Of-Events Schedule</Header>
<TagLegend />
<TagLegendContainer>
<TagLegends theme={theme} />
</TagLegendContainer>
</HeaderContainer>
<MobileScrollableContainer>
<ScheduleFlexContainer>
Expand Down
22 changes: 9 additions & 13 deletions src/components/Schedule/Tag.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,13 @@ export const StyledSVG = styled(Icon)`
}
`

export const TagLegend = ({ theme }) => {
return (
<TagLegendContainer>
{Object.entries(EVENT_TYPES(theme)).map(([key, event_type], i) => {
return (
<React.Fragment key={key}>
<StyledSVG color={event_type.colour} />
<Tag>{event_type.label}</Tag>
</React.Fragment>
)
})}
</TagLegendContainer>
)
export const TagLegends = ({ theme }) => {
return Object.entries(EVENT_TYPES(theme)).map(([key, event_type], i) => {
return (
<React.Fragment key={key}>
<StyledSVG color={event_type.colour} />
<Tag>{event_type.label}</Tag>
</React.Fragment>
)
})
}
48 changes: 47 additions & 1 deletion src/containers/Rewards.jsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,49 @@
const Rewards = () => {}
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;
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 = () => {
const { user } = useAuth()
const { dbHackathonName } = useHackathon()
const [userDetails, setUserDetails] = useState(null)

useEffect(() => {
getUserApplication(user.uid, dbHackathonName).then(user => {
setUserDetails(user)
})
}, [user, dbHackathonName])

return (
<RewardsContainer>
<RewardsSummaryContainer>
<AttendedEvents userDetails={userDetails} />
</RewardsSummaryContainer>
<RewardsContentContainer></RewardsContentContainer>
</RewardsContainer>
)
}

export default Rewards
8 changes: 4 additions & 4 deletions src/theme/ThemeProvider.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -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',
},
Expand Down
1 change: 1 addition & 0 deletions src/utility/Auth.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<React.SetStateAction<firebase.User | null>>, logout: () => Promise<void>}>} */
const AuthContext = createContext()

export function useAuth() {
Expand Down
7 changes: 7 additions & 0 deletions src/utility/firebase.js
Original file line number Diff line number Diff line change
Expand Up @@ -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')
}
Expand All @@ -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 = {
Expand Down
Loading