Skip to content

Commit 8025dc1

Browse files
committed
fix(events): default to all hosts and prioritize community events
1 parent 6294185 commit 8025dc1

1 file changed

Lines changed: 103 additions & 19 deletions

File tree

apps/web/src/modules/public/events/components/EventListWithFilters.tsx

Lines changed: 103 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
"use client";
22

3-
import { Button } from "@community/ui/ui/button";
3+
import { CardSkeleton } from "@/modules/public/shared/components/CardSkeleton";
4+
import { EmptyState } from "@/modules/public/shared/components/EmptyState";
45
import { useEventsListQuery } from "@community/lib-client/api/api-hooks";
5-
import { CalendarIcon } from "@heroicons/react/24/outline";
66
import type { EventListItem } from "@community/lib-shared/api/api-fetchers";
7+
import { Button } from "@community/ui/ui/button";
8+
import { CalendarIcon } from "@heroicons/react/24/outline";
79
import { useTranslations } from "next-intl";
810
import {
11+
type ReadonlyURLSearchParams,
912
useRouter,
1013
useSearchParams,
11-
type ReadonlyURLSearchParams,
1214
} from "next/navigation";
13-
import { Suspense, useEffect, useRef, useState } from "react";
15+
import { Suspense, useEffect, useMemo, useRef, useState } from "react";
1416
import { EventCard } from "./EventCard";
1517
import { EventCardCompact } from "./EventCardCompact";
16-
import { CardSkeleton } from "@/modules/public/shared/components/CardSkeleton";
17-
import { EmptyState } from "@/modules/public/shared/components/EmptyState";
1818

1919
type Event = EventListItem;
2020

@@ -23,10 +23,13 @@ interface EventFilters {
2323
selectedHostType: "organization" | "individual" | "all";
2424
}
2525

26-
const DEFAULT_FILTERS: EventFilters = {
27-
selectedStatus: "active",
28-
selectedHostType: "organization",
29-
};
26+
function prioritizeOrganizationHostedEvents(events: Event[]) {
27+
return [...events].sort((a, b) => {
28+
const aPriority = a.organization ? 0 : 1;
29+
const bPriority = b.organization ? 0 : 1;
30+
return aPriority - bPriority;
31+
});
32+
}
3033

3134
function getFiltersFromSearchParams(
3235
searchParams: ReadonlyURLSearchParams | null,
@@ -35,9 +38,9 @@ function getFiltersFromSearchParams(
3538
const selectedHostType =
3639
hostTypeParam === "individual"
3740
? "individual"
38-
: hostTypeParam === "all"
39-
? "all"
40-
: "organization";
41+
: hostTypeParam === "organization"
42+
? "organization"
43+
: "all";
4144

4245
return {
4346
selectedStatus: searchParams?.get("status") || "active",
@@ -53,7 +56,7 @@ function buildSearchParams(filters: EventFilters) {
5356
}
5457
if (
5558
filters.selectedHostType === "individual" ||
56-
filters.selectedHostType === "all"
59+
filters.selectedHostType === "organization"
5760
) {
5861
params.append("hostType", filters.selectedHostType);
5962
}
@@ -144,33 +147,114 @@ function EventListContent() {
144147
: undefined) as "organization" | "individual" | undefined,
145148
};
146149

147-
const { data: events = [], isLoading: eventsLoading } =
148-
useEventsListQuery(eventsQueryParams);
150+
const {
151+
data: hostTypeEvents = [],
152+
isLoading: hostTypeEventsLoading,
153+
error: hostTypeEventsError,
154+
} = useEventsListQuery(eventsQueryParams);
155+
156+
const shouldUseClientHostTypeFallback = Boolean(
157+
hostTypeEventsError && eventsQueryParams.hostType,
158+
);
159+
160+
const { data: fallbackEvents = [], isLoading: fallbackEventsLoading } =
161+
useEventsListQuery(
162+
{
163+
...eventsQueryParams,
164+
hostType: undefined,
165+
},
166+
{ enabled: shouldUseClientHostTypeFallback },
167+
);
168+
169+
const events = useMemo(() => {
170+
const sourceEvents = shouldUseClientHostTypeFallback
171+
? fallbackEvents
172+
: hostTypeEvents;
173+
174+
const sortedSourceEvents =
175+
filters.selectedHostType === "all"
176+
? prioritizeOrganizationHostedEvents(sourceEvents)
177+
: sourceEvents;
178+
179+
if (!shouldUseClientHostTypeFallback) {
180+
return sortedSourceEvents;
181+
}
182+
183+
if (filters.selectedHostType === "organization") {
184+
return sortedSourceEvents.filter((event) =>
185+
Boolean(event.organization),
186+
);
187+
}
188+
189+
if (filters.selectedHostType === "individual") {
190+
return sortedSourceEvents.filter((event) => !event.organization);
191+
}
192+
193+
return sortedSourceEvents;
194+
}, [
195+
fallbackEvents,
196+
filters.selectedHostType,
197+
hostTypeEvents,
198+
shouldUseClientHostTypeFallback,
199+
]);
200+
201+
const eventsLoading =
202+
hostTypeEventsLoading ||
203+
(shouldUseClientHostTypeFallback && fallbackEventsLoading);
149204

150205
const isActiveInsufficient =
151206
!eventsLoading &&
152207
events.length < 3 &&
153208
filters.selectedStatus === "active";
154209

155-
const { data: pastEvents = [], isLoading: pastEventsLoading } =
210+
const { data: pastEventsRaw = [], isLoading: pastEventsLoading } =
156211
useEventsListQuery(
157212
{
158213
status: "COMPLETED",
159214
showExpired: true,
160-
hostType: eventsQueryParams.hostType,
215+
hostType: shouldUseClientHostTypeFallback
216+
? undefined
217+
: eventsQueryParams.hostType,
161218
},
162219
{ enabled: isActiveInsufficient },
163220
);
164221

222+
const pastEvents = useMemo(() => {
223+
const sortedPastEvents =
224+
filters.selectedHostType === "all"
225+
? prioritizeOrganizationHostedEvents(pastEventsRaw)
226+
: pastEventsRaw;
227+
228+
if (!shouldUseClientHostTypeFallback) {
229+
return sortedPastEvents;
230+
}
231+
232+
if (filters.selectedHostType === "organization") {
233+
return sortedPastEvents.filter((event) =>
234+
Boolean(event.organization),
235+
);
236+
}
237+
238+
if (filters.selectedHostType === "individual") {
239+
return sortedPastEvents.filter((event) => !event.organization);
240+
}
241+
242+
return sortedPastEvents;
243+
}, [
244+
filters.selectedHostType,
245+
pastEventsRaw,
246+
shouldUseClientHostTypeFallback,
247+
]);
248+
165249
const statusOptions = [
166250
{ value: "active", label: t("events.status.active") },
167251
{ value: "completed", label: t("events.status.completed") },
168252
];
169253

170254
const hostTypeOptions = [
255+
{ value: "all", label: t("events.filters.hostAll") },
171256
{ value: "organization", label: t("events.filters.hostOrganizations") },
172257
{ value: "individual", label: t("events.filters.hostIndividuals") },
173-
{ value: "all", label: t("events.filters.hostAll") },
174258
];
175259

176260
const handleHostTypeChange = (value: string) => {

0 commit comments

Comments
 (0)