Skip to content
This repository has been archived by the owner on Sep 3, 2020. It is now read-only.

Commit

Permalink
Filter (#136)
Browse files Browse the repository at this point in the history
* 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
siddise authored and boyeln committed May 26, 2019
1 parent d88eb92 commit b72d653
Show file tree
Hide file tree
Showing 6 changed files with 435 additions and 211 deletions.
232 changes: 232 additions & 0 deletions components/EventList/index.jsx
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;
`;
62 changes: 62 additions & 0 deletions components/Filter/Selector.jsx
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;
`;
17 changes: 17 additions & 0 deletions components/Filter/index.jsx
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};
`;
63 changes: 63 additions & 0 deletions components/Filter/useURLFilter.js
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;
}, {})
});
};
Loading

0 comments on commit b72d653

Please sign in to comment.