Add organizer filtering
This commit is contained in:
1 parent
b0bc7c2889
commit
1002827a72
5 files changed
+166
-98
No files matched your search
@@ -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
@@ -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 {
|
||||
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in new issue
Block a user