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" ;
45import { useEventsListQuery } from "@community/lib-client/api/api-hooks" ;
5- import { CalendarIcon } from "@heroicons/react/24/outline" ;
66import 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" ;
79import { useTranslations } from "next-intl" ;
810import {
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" ;
1416import { EventCard } from "./EventCard" ;
1517import { EventCardCompact } from "./EventCardCompact" ;
16- import { CardSkeleton } from "@/modules/public/shared/components/CardSkeleton" ;
17- import { EmptyState } from "@/modules/public/shared/components/EmptyState" ;
1818
1919type 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
3134function 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