v1.5 - history and timeline as well as many datastructure updates added, polished, fixes
This commit is contained in:
parent
1f0aa3078f
commit
1d84400aef
63 changed files with 7927 additions and 208 deletions
|
|
@ -7,10 +7,17 @@
|
|||
narrows the result to what it shows.
|
||||
|
||||
useEvents({ section: "national" }) one band
|
||||
useEvents({ host: "northwest" }) a region's own events
|
||||
useEvents({ host: "northwest" }) one host's events
|
||||
useEvents({ status: "upcoming" }) a home page strip
|
||||
useEvents({ type: "workshop" }) one kind, wherever it is
|
||||
useEvents({ type: ["class", "workshop"] })
|
||||
useEvents() everything
|
||||
|
||||
`section` and `type` are different questions and stack rather
|
||||
than overlap: the section is which band of the page an event
|
||||
belongs to, the type is what kind of gathering it is. A regional
|
||||
class matches both { section: "regional" } and { type: "class" }.
|
||||
|
||||
Filtering here rather than in the query keeps the endpoint to
|
||||
one cached response. At a few dozen events that's the right
|
||||
trade; if the list ever runs to hundreds, move the filters into
|
||||
|
|
@ -23,18 +30,30 @@ import { useResource } from "../lib/useResource.js";
|
|||
|
||||
const EMPTY = { events: [] };
|
||||
|
||||
export function useEvents({ section, host, status } = {}) {
|
||||
export function useEvents({ section, host, status, type } = {}) {
|
||||
const { data, error, loading } = useResource("/events", { fallback: EMPTY });
|
||||
|
||||
const all = data?.events;
|
||||
|
||||
/* An array prop is a new identity on every render, which would
|
||||
restart the memo each time. Joining it gives the dependency
|
||||
list something stable to compare. */
|
||||
const typeKey = Array.isArray(type) ? type.join(",") : (type ?? "");
|
||||
|
||||
const events = useMemo(() => {
|
||||
let list = all ?? [];
|
||||
if (section) list = list.filter(e => e.section_id === section);
|
||||
if (host) list = list.filter(e => e.host?.id === host);
|
||||
// `host` is an organization or a person slug, and an event can
|
||||
// have several of either — co-hosting puts one event on both
|
||||
// hosts' lists, which is the point.
|
||||
if (host) list = list.filter(e => e.hosts?.some(h => h.id === host));
|
||||
if (status) list = list.filter(e => e.status === status);
|
||||
if (typeKey) {
|
||||
const wanted = new Set(typeKey.split(","));
|
||||
list = list.filter(e => wanted.has(e.event_type));
|
||||
}
|
||||
return list;
|
||||
}, [all, section, host, status]);
|
||||
}, [all, section, host, status, typeKey]);
|
||||
|
||||
return { events, loading, error };
|
||||
}
|
||||
|
|
@ -52,3 +71,12 @@ export function splitByStatus(events = []) {
|
|||
|
||||
return { upcoming, past };
|
||||
}
|
||||
|
||||
/* Which of the declared types a list actually contains, in
|
||||
EVENT_TYPES order rather than whatever order the rows arrived
|
||||
in. A section with one type has nothing to filter, which is what
|
||||
lets the chip bar hide itself. */
|
||||
export function typesPresent(events = [], declared = []) {
|
||||
const seen = new Set(events.map(e => e.event_type));
|
||||
return declared.filter(entry => seen.has(entry.id));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue