Add organizer filtering

This commit is contained in:
ponas committed 2019-07-31 23:25:50 +02:00
1 parent b0bc7c2889
commit 1002827a72
5 files changed
+166 -98

No files matched your search

+1
View File
@@ -29,6 +29,7 @@
"prop-types": "^15.6.0",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-dropdown": "^1.6.4",
"react-helmet": "^5.2.1",
"uuid": "^3.2.1"
},
+135 -70
View File
@@ -1,6 +1,7 @@
import React from 'react'
import PropTypes from 'prop-types'
import { Link, graphql } from 'gatsby'
import Dropdown from 'react-dropdown'
import { Link, graphql, useStaticQuery, navigate } from 'gatsby'
import Img from 'gatsby-image'
import classNames from 'classnames'
import _ from 'lodash'
@@ -9,38 +10,22 @@ import 'moment/locale/nb'
moment.locale('nb')
export default class EventList extends React.Component {
renderEventsByDate(filteredEvents, groupBy) {
let groupByFormat = null
if (groupBy === 'day') {
groupByFormat = 'YYYY-MM-DD'
const eventOrganizersQuery = graphql`
query EventOrganizers {
allWordpressWpEventOrganizers {
edges {
node {
name
slug
path
}
}
}
if (groupBy === 'month') {
groupByFormat = 'YYYY-MM'
}
const grouper = ({ node: event }) => {
return moment(event.start_time).format(groupByFormat)
}
const groupedEvents = _.groupBy(filteredEvents, grouper)
return _.map(groupedEvents, (theseEvents, date) => {
return (
<div className={`event-group event-grouped-by-${groupBy}`}>
<div className="event-group-header">
{groupBy === 'day' && moment(date).format('dddd D. MMMM')}
{groupBy === 'month' && moment(date).format('MMMM')}
</div>
<div className="event-list">
{theseEvents.map(({ node: event }) => {
return this.renderEvent(event)
})}
</div>
</div>
)
})
}
renderEvent(event) {
const { compactDate } = this.props
`
const EventList = props => {
const renderEvent = event => {
const { compactDate } = props
return (
<Link to={event.path} className="event" key={event.id}>
<div className="event-image">
@@ -93,50 +78,123 @@ export default class EventList extends React.Component {
)
}
render() {
const {
events,
title,
classes,
onlyUpcoming,
maxEvents,
groupBy,
showMore,
} = this.props
let filteredEvents = events.filter(({ node: event }) => {
const startTime = moment(event.start_time)
if (onlyUpcoming && !startTime.isSameOrAfter(new Date(), 'day')) {
return false
}
return true
})
if (maxEvents) {
filteredEvents = filteredEvents.slice(0, maxEvents)
const renderEventsByDate = (filteredEvents, groupBy) => {
let groupByFormat = null
if (groupBy === 'day') {
groupByFormat = 'YYYY-MM-DD'
}
return (
<section className={classNames("events", classes)}>
{title && <h1 className="section-title">{title}</h1>}
{groupBy && this.renderEventsByDate(filteredEvents, groupBy)}
{!groupBy && (
if (groupBy === 'month') {
groupByFormat = 'YYYY-MM'
}
const grouper = ({ node: event }) => {
return moment(event.start_time).format(groupByFormat)
}
const groupedEvents = _.groupBy(filteredEvents, grouper)
return _.map(groupedEvents, (theseEvents, date) => {
return (
<div className={`event-group event-grouped-by-${groupBy}`}>
<div className="event-group-header">
{groupBy === 'day' && moment(date).format('dddd D. MMMM')}
{groupBy === 'month' && moment(date).format('MMMM')}
</div>
<div className="event-list">
{filteredEvents.map(({ node: event }) => {
return this.renderEvent(event)
{theseEvents.map(({ node: event }) => {
return renderEvent(event)
})}
</div>
)}
{showMore && (
<div className="show-more">
<Link to="/program/" className="button">
Vis alle
</Link>
</div>
)}
</section>
)
</div>
)
})
}
const handleOrganizerFilterChange = ({ value }) => {
navigate(`/organizer/${value}/`)
}
const {
events,
title,
classes,
onlyUpcoming,
maxEvents,
groupBy,
showMore,
showFilter,
filterOrganizer,
} = props
let filteredEvents = events.filter(({ node: event }) => {
const startTime = moment(event.start_time)
if (onlyUpcoming && !startTime.isSameOrAfter(new Date(), 'day')) {
return false
}
return true
})
const data = useStaticQuery(eventOrganizersQuery)
const { edges: organizers } = data.allWordpressWpEventOrganizers
const organizerOptions = organizers.map(({ node: organizer }) => {
return { value: organizer.slug, label: organizer.name }
})
const selectedOrganizer =
filterOrganizer !== null
? organizers.find(obj => filterOrganizer === obj.node.slug).node
: null
const organizerOptionsDefault =
selectedOrganizer !== null
? {
value: selectedOrganizer.slug,
label: selectedOrganizer.name,
}
: null
if (maxEvents) {
filteredEvents = filteredEvents.slice(0, maxEvents)
}
return (
<section className={classNames('events', classes)}>
{title && <h1 className="section-title">{title}</h1>}
{showFilter && organizers && (
<div className="event-list-filter">
<Dropdown
className="event-list-filter-dropdown"
options={organizerOptions}
onChange={handleOrganizerFilterChange}
value={organizerOptionsDefault}
placeholder="Arrangør"
/>
</div>
)}
{groupBy && renderEventsByDate(filteredEvents, groupBy)}
{!groupBy && (
<div className="event-list">
{filteredEvents.map(({ node: event }) => {
return renderEvent(event)
})}
</div>
)}
{showMore && (
<div className="show-more">
<Link to="/program/" className="button">
Vis alle
</Link>
</div>
)}
{filteredEvents.length === 0 && (
<div className="event-list-tumbleweed">
{!selectedOrganizer && (
<>
Det ligger ingenting i programmet akkurat nå. Prøv igjen senere!
</>
)}
{selectedOrganizer && (
<>{selectedOrganizer.name} har ingen kommende arrangementer.</>
)}
</div>
)}
</section>
)
}
EventList.propTypes = {
@@ -148,6 +206,8 @@ EventList.propTypes = {
groupBy: PropTypes.string,
compactDate: PropTypes.bool,
showMore: PropTypes.bool,
showFilter: PropTypes.bool,
filterOrganizer: PropTypes.string,
}
EventList.defaultProps = {
@@ -155,8 +215,13 @@ EventList.defaultProps = {
maxEvents: 0,
groupBy: null,
compactDate: false,
showMore: false,
showFilter: false,
filterOrganizer: null,
}
export default EventList
export const pageQuery = graphql`
fragment EventTypeFields on wordpress__wp_events {
event_types {
+6 -1
View File
@@ -13,7 +13,12 @@ export default class EventProgram extends React.Component {
return (
<Layout>
<Helmet title="Program" />
<EventList events={events} title="Dette skjer" groupBy="month" />
<EventList
events={events}
title="Dette skjer"
groupBy="month"
showFilter
/>
</Layout>
)
}
+16 -26
View File
@@ -2,48 +2,38 @@ import React from 'react'
import PropTypes from 'prop-types'
import Helmet from 'react-helmet'
import { graphql } from 'gatsby'
import Layout from '../components/Layout'
import EventList from '../components/EventList'
import moment from 'moment'
import 'moment/locale/nb'
import Layout from '../components/Layout'
import EventList from '../components/EventList'
moment.locale('nb')
export default class EventOrganizerPage extends React.Component {
render() {
const { data, pageContext } = this.props
const { edges: events, totalCount } = data.allWordpressWpEvents
const { name, description } = pageContext
const future = events.filter(({ node: event }) => {
const startTime = moment(event.start_time)
return !!startTime.isSameOrAfter(new Date(), 'day')
})
const past = events.filter(({ node: event }) => {
const startTime = moment(event.start_time)
return !startTime.isSameOrAfter(new Date(), 'day')
})
const { name, description, slug } = pageContext
return (
<Layout>
<Helmet title={`Arrangør: ${name}`} />
<section className="event-organizer-page">
<Layout classes="organizer-page">
<Helmet title={`${name} | Program`} />
<EventList
events={events}
title={`Program for ${name}`}
groupBy="month"
filterOrganizer={slug}
showFilter
/>
{/* <section className="event-organizer-page">
<h1 className="page-title">{name}</h1>
<div
className="event-organizer-description wp-content"
dangerouslySetInnerHTML={{ __html: description }}
/>
{future.length !== 0 && (
<EventList
events={future}
onlyUpcoming={false}
title="I fremtiden"
/>
)}
{past.length !== 0 && (
<EventList events={past} onlyUpcoming={false} title="I fortiden" />
)}
</section>
<EventList events={events} title="I fremtiden" />
</section> */}
</Layout>
)
}
+8 -1
View File
@@ -3417,7 +3417,7 @@ class-utils@^0.3.5:
isobject "^3.0.0"
static-extend "^0.1.1"
classnames@^2.2.6:
classnames@^2.2.3, classnames@^2.2.6:
version "2.2.6"
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce"
integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==
@@ -11192,6 +11192,13 @@ react-dom@^16.8.6:
prop-types "^15.6.2"
scheduler "^0.13.6"
react-dropdown@^1.6.4:
version "1.6.4"
resolved "https://registry.yarnpkg.com/react-dropdown/-/react-dropdown-1.6.4.tgz#8dce141bb26fb6b3c3696d16e06f4517728c57f4"
integrity sha512-zTlNRZ6vzjEPsodBNgh6Xjp9IempEx9sReH3crT2Jw4S6KW2wS/BRIH3d/grYf/iXARadDRD91//uUCs9yjoLg==
dependencies:
classnames "^2.2.3"
react-error-overlay@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-3.0.0.tgz#c2bc8f4d91f1375b3dad6d75265d51cd5eeaf655"