add filter on venue
This commit is contained in:
@ -18,6 +18,7 @@ import { parse } from "date-fns";
|
||||
import { unique } from "@/lib/common";
|
||||
import Icon from "../general/Icon";
|
||||
import { useState } from "react";
|
||||
import { VenueFragment } from "@/gql/graphql";
|
||||
|
||||
/*
|
||||
TODO: canonical / alternate URLs https://github.com/47ng/nuqs?tab=readme-ov-file#seo
|
||||
@ -27,10 +28,12 @@ export const EventContainer = ({
|
||||
events,
|
||||
eventCategories,
|
||||
eventOrganizers,
|
||||
venues,
|
||||
}: {
|
||||
events: EventFragment[];
|
||||
eventCategories: EventCategory[];
|
||||
eventOrganizers: EventOrganizer[];
|
||||
venues: VenueFragment[];
|
||||
}) => {
|
||||
const [mode, setMode] = useQueryState(
|
||||
"mode",
|
||||
@ -38,20 +41,46 @@ export const EventContainer = ({
|
||||
);
|
||||
const [category, setCategory] = useQueryState("category", parseAsString);
|
||||
const [organizer, setOrganizer] = useQueryState("organizer", parseAsString);
|
||||
const [venue, setVenue] = useQueryState("venue", parseAsString);
|
||||
|
||||
/* Allow filtering on all categories that are configured to be shown */
|
||||
const filterableCategories = eventCategories.filter((x) => x.showInFilters);
|
||||
|
||||
/*
|
||||
Allow filtering on all organizers that have upcoming events
|
||||
Filtering on an organizer with no upcoming events will work, but be hidden from dropdown
|
||||
*/
|
||||
const uniqueOrganizers: string[] = unique(
|
||||
events
|
||||
.map((x) => x.organizers)
|
||||
.flat()
|
||||
.filter((x) => x.__typename === "EventOrganizer")
|
||||
.map((x) => x.slug)
|
||||
.filter((x) => typeof x === "string")
|
||||
);
|
||||
const filterableOrganizers = uniqueOrganizers
|
||||
.map((slug) => eventOrganizers.find((haystack) => haystack.slug === slug))
|
||||
.filter((x) => x !== undefined) as EventOrganizer[];
|
||||
|
||||
/*
|
||||
Allow filtering on all venues that have upcoming events
|
||||
Filtering on a venue with no upcoming events will work,
|
||||
and in that case it's included in the dropdown
|
||||
*/
|
||||
const venueSlugsWithUpcomingEvents = events
|
||||
.map((x) => x.occurrences)
|
||||
.flat()
|
||||
.filter((x) => x.venue?.__typename === "VenuePage")
|
||||
.map((x) => x.venue?.slug)
|
||||
.filter((x) => typeof x === "string");
|
||||
const filterableVenues = venues
|
||||
.map((x) =>
|
||||
venues.find(
|
||||
(haystack) => haystack.slug === x.slug || haystack.slug === venue
|
||||
)
|
||||
)
|
||||
.filter((x) => x !== undefined) as VenueFragment[];
|
||||
|
||||
const filteredEvents = events
|
||||
.filter(
|
||||
(x) =>
|
||||
@ -64,6 +93,14 @@ export const EventContainer = ({
|
||||
x.categories
|
||||
.map((eventCategory) => eventCategory.slug)
|
||||
.includes(category)
|
||||
)
|
||||
.filter(
|
||||
(x) =>
|
||||
!venue ||
|
||||
x.occurrences
|
||||
.map((occurrence) => occurrence.venue?.slug)
|
||||
.filter((x) => typeof x === "string")
|
||||
.includes(venue)
|
||||
);
|
||||
|
||||
const [showFilter, setShowFilter] = useState(false);
|
||||
@ -98,6 +135,9 @@ export const EventContainer = ({
|
||||
eventOrganizers={filterableOrganizers}
|
||||
setOrganizer={setOrganizer}
|
||||
activeOrganizer={organizer}
|
||||
venues={filterableVenues}
|
||||
setVenue={setVenue}
|
||||
activeVenue={venue}
|
||||
isVisible={showFilter}
|
||||
/>
|
||||
{mode === "list" && <EventList events={filteredEvents} />}
|
||||
|
Reference in New Issue
Block a user