web: colocate graphql fragments, unmask where needed, more idiomatic client-preset use

This commit is contained in:
ponas committed 2026-05-19 01:49:58 +02:00
1 parent bc8642b1fc
commit b09ce9808d
29 files changed
+2065 -7283

No files matched your search

+43 -33
View File
@@ -9,7 +9,10 @@ import {
} from "nuqs";
import { EventItem } from "./EventItem";
import { EventFilter, EventFilterExplained } from "./EventFilter";
import { unmaskFragment } from "@/gql";
import {
EventCategoryFragmentDefinition,
EventOrganizerFragmentDefinition,
EventFragment,
EventCategory,
SingularEvent,
@@ -48,11 +51,11 @@ export const EventContainer = ({
}) => {
const [mode, setMode] = useQueryState(
"mode",
parseAsStringLiteral(["list", "calendar"]).withDefault("list")
parseAsStringLiteral(["list", "calendar"]).withDefault("list"),
);
const [categories, setCategories] = useQueryState(
"category",
parseAsArrayOf(parseAsString, ",")
parseAsArrayOf(parseAsString, ","),
);
const [organizer, setOrganizer] = useQueryState("organizer", parseAsString);
const [venue, setVenue] = useQueryState("venue", parseAsString);
@@ -75,13 +78,15 @@ export const EventContainer = ({
Filtering on an organizer with no upcoming events will work,
and in that case it's included in the dropdown
*/
const allOrganizers = unmaskFragment(
EventOrganizerFragmentDefinition,
events.flatMap((x) => x.organizers),
);
const uniqueOrganizers: string[] = unique(
events
.map((x) => x.organizers)
.flat()
allOrganizers
.filter((x) => x.__typename === "EventOrganizer")
.map((x) => x.slug)
.filter((x) => typeof x === "string" && x !== "")
.filter((x) => typeof x === "string" && x !== ""),
);
const filterableOrganizers = uniqueOrganizers
.map((slug) => eventOrganizers.find((haystack) => haystack.slug === slug))
@@ -118,11 +123,11 @@ export const EventContainer = ({
.flat()
.filter((x) => x.venue?.__typename === "VenuePage")
.map((x) => x.venue?.slug)
.filter((x) => typeof x === "string")
.filter((x) => typeof x === "string"),
);
const filterableVenues = venues
.filter(
(x) => venueSlugsWithUpcomingEvents.includes(x.slug) || x.slug === venue
(x) => venueSlugsWithUpcomingEvents.includes(x.slug) || x.slug === venue,
)
.map((x) => venues.find((haystack) => haystack.slug === x.slug))
.filter((x) => x !== undefined) as VenueFragment[];
@@ -134,27 +139,32 @@ export const EventContainer = ({
}
}, [venues, venue]);
const filteredEvents = events
.filter(
(x) =>
!organizer ||
x.organizers.map((organizer) => organizer.slug).includes(organizer)
)
.filter(
(x) =>
!categories ||
x.categories
.map((eventCategory) => eventCategory.slug)
.filter((x) => categories.includes(x)).length !== 0
)
.filter(
(x) =>
!venue ||
x.occurrences
.map((occurrence) => occurrence.venue?.slug)
.filter((x) => typeof x === "string")
.includes(venue)
);
const filteredEvents = events.filter((event) => {
if (organizer) {
const organizers = unmaskFragment(
EventOrganizerFragmentDefinition,
event.organizers,
);
if (!organizers.some((o) => o.slug === organizer)) {
return false;
}
}
if (categories) {
const eventCategories = unmaskFragment(
EventCategoryFragmentDefinition,
event.categories,
);
if (!eventCategories.some((c) => categories.includes(c.slug))) {
return false;
}
}
if (venue) {
if (!event.occurrences.some((occ) => occ.venue?.slug === venue)) {
return false;
}
}
return true;
});
const [showFilter, setShowFilter] = useState(false);
function toggleFilter() {
@@ -302,12 +312,12 @@ function maybeYear(yearMonthString: string) {
const EventCalendar = ({ events }: { events: EventFragment[] }) => {
const futureSingularEvents = getSingularEvents(events).filter(
(x) => x.occurrence?.start && isTodayOrFuture(x.occurrence.start)
(x) => x.occurrence?.start && isTodayOrFuture(x.occurrence.start),
);
const eventsByDate = organizeEventsInCalendar(futureSingularEvents);
const yearMonths = Object.keys(eventsByDate);
const [visibleYearMonths, setVisibleYearMonths] = useState(
yearMonths.slice(0, 2)
yearMonths.slice(0, 2),
);
const toggleYearMonth = (yearMonth: string) => {
@@ -327,9 +337,9 @@ const EventCalendar = ({ events }: { events: EventFragment[] }) => {
yearMonthSum +
Object.values(week).reduce(
(weekSum, day) => weekSum + day.length,
0
0,
),
0
0,
);
return (