This repository has been archived by the owner on Sep 3, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* transfer event list to component * add dummy eventfilter button * move EventList component to conditional * add clickable filter buttons * renamed filterbutton component * remove color from filterbutton when visible * change filter design and add lightpink to theme * remove unused methods * remove stuff * create new fileter component * use new filter component and restructure event list * remove console log * add polyfills * add core-js dependency * fix stuff
- Loading branch information
Showing
6 changed files
with
435 additions
and
211 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,232 @@ | ||
import { imageUrlFor } from "@/store/sanity"; | ||
import theme from "@/utils/theme"; | ||
import dayjs from "dayjs"; | ||
import Link from "next/link"; | ||
import React from "react"; | ||
import styled from "styled-components"; | ||
|
||
const EventList = props => { | ||
const { events, venues } = props; | ||
|
||
const displayArena = event => { | ||
switch (event.category) { | ||
case "0": | ||
return "Ekstern arena"; | ||
break; | ||
case "1": | ||
return "Pride Parade"; | ||
break; | ||
case "2": | ||
return "Pride Park"; | ||
break; | ||
case "3": | ||
return "Pride House"; | ||
break; | ||
case "4": | ||
return "Pride Art"; | ||
break; | ||
} | ||
}; | ||
|
||
const displayEventType = event => { | ||
switch (event.eventType) { | ||
case "0": | ||
return "Annet"; | ||
break; | ||
case "1": | ||
return "Konsert"; | ||
break; | ||
case "2": | ||
return "Debatt"; | ||
break; | ||
case "3": | ||
return "Utstilling"; | ||
break; | ||
case "4": | ||
return "Fest"; | ||
break; | ||
} | ||
}; | ||
|
||
const getVenueName = reference => { | ||
const venueData = venues.data.find(venue => venue._id === reference); | ||
return venueData.name; | ||
}; | ||
|
||
return ( | ||
<> | ||
{groupEventsByDay(events).map(day => { | ||
const currentDay = dayjs(day[0].startingTime); | ||
return ( | ||
<Event key={currentDay.format("YYYY-MM-DD")}> | ||
<EventDay> | ||
<h2> | ||
{currentDay.format("dddd")}{" "} | ||
<span>{currentDay.format("D. MMMM")}</span> | ||
</h2> | ||
</EventDay> | ||
<div> | ||
{day.map(event => ( | ||
<Link | ||
key={event._id} | ||
href={`/event?id=${event._id}`} | ||
as={`/events/${event._id}`} | ||
> | ||
<EventLink> | ||
<a> | ||
{event.image ? ( | ||
<EventImage | ||
src={imageUrlFor(event.image) | ||
.height(250) | ||
.url()} | ||
alt="arrangementsbilde" | ||
/> | ||
) : ( | ||
<EventImage | ||
src="/static/placeholder.jpg" | ||
alt="arrangementsbilde" | ||
/> | ||
)} | ||
|
||
<EventInfo> | ||
<EventTitle>{event.title}</EventTitle> | ||
<EventTime> | ||
{dayjs(event.startingTime).format("HH:mm")}- | ||
{dayjs(event.endingTime).format("HH:mm")} | ||
</EventTime> | ||
<EventPlace> | ||
<Descriptor> Hvor: </Descriptor> | ||
{displayArena(event)},{" "} | ||
{event.location.venue | ||
? getVenueName(event.location.venue._ref) | ||
: event.location.name} | ||
</EventPlace> | ||
<EventType> | ||
<Descriptor> Type: </Descriptor> | ||
{displayEventType(event)} | ||
</EventType> | ||
</EventInfo> | ||
</a> | ||
</EventLink> | ||
</Link> | ||
))} | ||
</div> | ||
</Event> | ||
); | ||
})} | ||
</> | ||
); | ||
}; | ||
|
||
const groupEventsByDay = events => { | ||
if (events.length === 0) { | ||
return []; | ||
} | ||
|
||
const sortedEvents = [...events]; | ||
|
||
sortedEvents.sort( | ||
(a, b) => dayjs(a.startingTime).unix() - dayjs(b.startingTime).unix() | ||
); | ||
|
||
const groupedEvents = [[sortedEvents[0]]]; | ||
|
||
sortedEvents.slice(1).forEach(event => { | ||
const lastGroup = groupedEvents[groupedEvents.length - 1]; | ||
const lastEvent = lastGroup[lastGroup.length - 1]; | ||
|
||
const lastEventStart = dayjs(lastEvent.startingTime); | ||
const currentEventStart = dayjs(event.startingTime); | ||
|
||
if (lastEventStart.format("dddd") === currentEventStart.format("dddd")) { | ||
lastGroup.push(event); | ||
} else { | ||
groupedEvents.push([event]); | ||
} | ||
}); | ||
return groupedEvents; | ||
}; | ||
|
||
export default EventList; | ||
|
||
const Event = styled.div` | ||
width: 100%; | ||
max-width: 1000px; | ||
`; | ||
|
||
const EventDay = styled.div` | ||
background-color: ${theme.purple}; | ||
width: 100%; | ||
h2 { | ||
font-size: 25px; | ||
font-weight: 500; | ||
color: white; | ||
text-transform: uppercase; | ||
text-align: center; | ||
} | ||
`; | ||
|
||
const EventLink = styled.div` | ||
cursor: pointer; | ||
border-bottom: 2px solid lightgrey; | ||
padding: 10px 0; | ||
&:last-child { | ||
border-bottom: 0; | ||
} | ||
& > a { | ||
display: flex; | ||
flex-direction: row; | ||
align-items: center; | ||
text-decoration: none; | ||
:hover { | ||
text-decoration: underline; | ||
} | ||
} | ||
`; | ||
|
||
const EventImage = styled.img` | ||
width: 80px; | ||
height: 80px; | ||
object-fit: cover; | ||
`; | ||
|
||
const EventInfo = styled.div` | ||
display: flex; | ||
flex-flow: row wrap; | ||
justify-content: flex-start; | ||
margin-left: 20px; | ||
width: 100%; | ||
`; | ||
|
||
const EventTitle = styled.div` | ||
width: 100%; | ||
font-size: 20px; | ||
font-weight: 500; | ||
`; | ||
|
||
const EventTime = styled.div` | ||
font-size: 18px; | ||
font-weight: 600; | ||
color: ${theme.orange}; | ||
margin-right: 10px; | ||
`; | ||
|
||
const EventPlace = styled.div` | ||
font-size: 18px; | ||
font-weight: 300; | ||
margin-right: 10px; | ||
`; | ||
|
||
const EventType = styled.div` | ||
font-size: 18px; | ||
font-weight: 300; | ||
`; | ||
|
||
const Descriptor = styled.span` | ||
font-size: 18px; | ||
font-weight: 500; | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import React, { useCallback, useState } from "react"; | ||
import styled from "styled-components"; | ||
|
||
const Selector = ({ selectors, defaultSelector, className }) => { | ||
const [checked, setChecked] = useState(defaultSelector); | ||
const onChange = useCallback( | ||
(value, callback) => () => { | ||
setChecked(value); | ||
callback(value); | ||
}, | ||
[setChecked] | ||
); | ||
|
||
const inspectedChecked = selectors.some(({ value }) => value === checked) | ||
? checked | ||
: defaultSelector; | ||
|
||
const selectorElements = selectors.map(({ name, value, callback }) => ( | ||
<label key={name}> | ||
<input | ||
type="radio" | ||
name="event-filter-selectors" | ||
onChange={onChange(value, callback)} | ||
checked={value === inspectedChecked} | ||
/> | ||
<SelectorLabel>{name}</SelectorLabel> | ||
</label> | ||
)); | ||
|
||
return ( | ||
<Container className={className}> | ||
<SelectorTitle>Arena</SelectorTitle> | ||
<SelectorList>{selectorElements}</SelectorList> | ||
</Container> | ||
); | ||
}; | ||
|
||
export default Selector; | ||
|
||
const Container = styled.div` | ||
width: 100%; | ||
`; | ||
|
||
const SelectorTitle = styled.div` | ||
font-weight: bold; | ||
text-align: center; | ||
margin-bottom: 5px; | ||
`; | ||
|
||
const SelectorList = styled.div` | ||
display: flex; | ||
flex-wrap: wrap; | ||
justify-content: center; | ||
label { | ||
margin: 2px 8px; | ||
} | ||
`; | ||
|
||
const SelectorLabel = styled.span` | ||
margin-left: 5px; | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import theme from "@/utils/theme"; | ||
import React from "react"; | ||
import styled from "styled-components"; | ||
import Selector from "./Selector"; | ||
|
||
const Filter = ({ selector }) => ( | ||
<Wrapper>{selector && <Selector {...selector} />}</Wrapper> | ||
); | ||
|
||
export default Filter; | ||
|
||
const Wrapper = styled.div` | ||
display: flex; | ||
flex-direction: column; | ||
padding: 10px; | ||
border: 3px solid ${theme.purple}; | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import Router from "next/router"; | ||
import { useMemo } from "react"; | ||
|
||
const toArray = val => | ||
val === undefined ? [] : Array.isArray(val) ? val : [val]; | ||
|
||
export default (objects, query) => | ||
useMemo(() => { | ||
let filteredObjects = objects; | ||
Object.keys(query).forEach(key => { | ||
const filters = toArray(query[key]); | ||
filteredObjects = | ||
filters.length === 0 | ||
? objects // Return all objects if no filtes are applied | ||
: objects.filter(obj => filters.includes(obj[key])); | ||
}); | ||
return filteredObjects; | ||
}, [objects, query]); | ||
|
||
export const addFilter = (key, value) => { | ||
const prevFilterList = toArray(Router.query[key]); | ||
const newFilterList = prevFilterList.includes(value) | ||
? prevFilterList | ||
: [...prevFilterList, value]; | ||
Router.replace({ | ||
pathname: Router.route, | ||
query: { | ||
...Router.query, | ||
[key]: newFilterList.length === 1 ? newFilterList[0] : newFilterList | ||
} | ||
}); | ||
}; | ||
|
||
export const setFilter = (key, value) => { | ||
Router.replace({ | ||
pathname: Router.route, | ||
query: { ...Router.query, [key]: value } | ||
}); | ||
}; | ||
|
||
export const removeFilter = (key, value) => { | ||
const prevFilterList = toArray(Router.query[key]); | ||
const newFilterList = prevFilterList.filter(v => v !== value); | ||
Router.replace({ | ||
pathname: Router.route, | ||
query: { | ||
...Router.query, | ||
[key]: newFilterList.length === 1 ? newFilterList[0] : newFilterList | ||
} | ||
}); | ||
}; | ||
|
||
export const resetFilter = key => { | ||
Router.replace({ | ||
pathname: Router.route, | ||
query: Object.keys(Router.query).reduce((query, k) => { | ||
if (k !== key) { | ||
query[k] = Router.query[k]; | ||
} | ||
return query; | ||
}, {}) | ||
}); | ||
}; |
Oops, something went wrong.