diff --git a/app/services/api/webflow-api.ts b/app/services/api/webflow-api.ts index a8a48121..a127f5a4 100644 --- a/app/services/api/webflow-api.ts +++ b/app/services/api/webflow-api.ts @@ -1,4 +1,4 @@ -import { useQuery } from "@tanstack/react-query" +import { useQueries, useQuery, UseQueryOptions } from "@tanstack/react-query" import { Schedule } from "../../screens" import { axiosInstance, PaginatedItems } from "./axios" import type { @@ -31,76 +31,127 @@ import { cleanedWorkshops, convertScheduleToScheduleCard, } from "./webflow-helpers" +import { queryClient } from "./react-query" -const useWebflowAPI = (key: string, collectionId: string, enabled = true) => - useQuery({ - queryKey: [key], - queryFn: async () => { - const { data } = await axiosInstance.get>( - `/collections/${collectionId}/items`, - ) - return data.items - }, - enabled, - }) +const getCollectionById = async (collectionId: string) => { + const { data } = await axiosInstance.get>(`/collections/${collectionId}/items`) + return data.items +} + +const useRecommendationsOptions = { + queryKey: [RECOMMENDATIONS.key, RECOMMENDATIONS.collectionId], + queryFn: async () => getCollectionById(RECOMMENDATIONS.collectionId), +} satisfies UseQueryOptions export const useRecommendations = () => { - return useWebflowAPI(RECOMMENDATIONS.key, RECOMMENDATIONS.collectionId) + return useQuery(useRecommendationsOptions) } +const useRecurringEventsOptions = { + queryKey: [RECURRING_EVENTS.key, RECURRING_EVENTS.collectionId], + queryFn: async () => getCollectionById(RECURRING_EVENTS.collectionId), +} satisfies UseQueryOptions + export const useRecurringEvents = () => { - return useWebflowAPI(RECURRING_EVENTS.key, RECURRING_EVENTS.collectionId) + return useQuery(useRecurringEventsOptions) } +const useSpeakersOptions = { + queryKey: [SPEAKERS.key, SPEAKERS.collectionId], + queryFn: async () => getCollectionById(SPEAKERS.collectionId), +} satisfies UseQueryOptions + export const useSpeakers = () => { - return useWebflowAPI(SPEAKERS.key, SPEAKERS.collectionId) + return useQuery(useSpeakersOptions) } +const useSpeakerNamesOptions = { + queryKey: [SPEAKER_NAMES.key, SPEAKER_NAMES.collectionId], + queryFn: async () => getCollectionById(SPEAKER_NAMES.collectionId), +} satisfies UseQueryOptions + export const useSpeakerNames = () => { - return useWebflowAPI(SPEAKER_NAMES.key, SPEAKER_NAMES.collectionId) + return useQuery(useSpeakerNamesOptions) } -export const useSponsors = (): { isLoading: boolean; data: RawSponsor[] } => { - const { data: sponsors, isLoading } = useWebflowAPI( - SPONSORS.key, - SPONSORS.collectionId, - ) +const useSponsorsOptions = { + queryKey: [SPONSORS.key, SPONSORS.collectionId], + queryFn: async () => getCollectionById(SPONSORS.collectionId), +} satisfies UseQueryOptions + +export const useSponsors = () => { + const { data: sponsors, isLoading } = useQuery(useSponsorsOptions) const data = cleanedSponsors(sponsors) return { isLoading, data } } + +const useTalksOptions = { + queryKey: [TALKS.key, TALKS.collectionId], + queryFn: async () => getCollectionById(TALKS.collectionId), +} satisfies UseQueryOptions + export const useTalks = () => { - return useWebflowAPI(TALKS.key, TALKS.collectionId) + return useQuery(useTalksOptions) } +const useVenuesOptions = { + queryKey: [VENUES.key, VENUES.collectionId], + queryFn: async () => getCollectionById(VENUES.collectionId), +} satisfies UseQueryOptions + export const useVenues = () => { - return useWebflowAPI(VENUES.key, VENUES.collectionId) + return useQuery(useVenuesOptions) } +const useWorkshopsOptions = { + queryKey: [WORKSHOPS.key, WORKSHOPS.collectionId], + queryFn: async () => getCollectionById(WORKSHOPS.collectionId), +} satisfies UseQueryOptions + export const useWorkshops = () => { - return useWebflowAPI(WORKSHOPS.key, WORKSHOPS.collectionId) + return useQuery(useWorkshopsOptions) } -export const useScheduledEvents = () => { - const { data: speakers, isLoading } = useSpeakers() - const { data: workshops } = useWorkshops() - const { data: recurringEvents } = useRecurringEvents() - const { data: talks } = useTalks() - const { data: scheduledEvents, ...rest } = useWebflowAPI( - SCHEDULE.key, - SCHEDULE.collectionId, - !isLoading && !!speakers && !!workshops && !!recurringEvents && !!talks, +const useScheduledEventsOptions = { + queryKey: [SCHEDULE.key, SCHEDULE.collectionId], + queryFn: async () => getCollectionById(SCHEDULE.collectionId), +} satisfies UseQueryOptions + +const useScheduledEventsQueries = [ + useSpeakersOptions, + useWorkshopsOptions, + useRecurringEventsOptions, + useTalksOptions, + useScheduledEventsOptions, +] as const + +export const prefetchScheduledEvents = async () => { + await Promise.all( + useScheduledEventsQueries.map(async (query) => { + return queryClient.prefetchQuery(query) + }), ) +} + +export const useScheduledEvents = () => { + const queries = useQueries({ + queries: useScheduledEventsQueries, + }) + + const [speakers, workshops, recurringEvents, talks, scheduledEvents] = queries return { data: cleanedSchedule({ - recurringEvents, - scheduledEvents, - speakers: cleanedSpeakers(speakers), - talks: cleanedTalks({ speakers, talks }), - workshops: cleanedWorkshops(workshops, cleanedSpeakers(speakers)), + recurringEvents: recurringEvents.data, + scheduledEvents: scheduledEvents.data, + speakers: cleanedSpeakers(speakers.data), + talks: cleanedTalks({ speakers: speakers.data, talks: talks.data }), + workshops: cleanedWorkshops(workshops.data, cleanedSpeakers(speakers.data)), }), - ...rest, + refetch: async () => Promise.all(queries.map((query) => query.refetch())), + isLoading: queries.map((query) => query.isLoading).some((isLoading) => isLoading), + isRefetching: queries.map((query) => query.isFetching).some((isFetching) => isFetching), } } @@ -126,7 +177,7 @@ export const useScheduleScreenData = () => { title: "Conference Day 2", events: convertScheduleToScheduleCard(events, "Friday"), }, - ] as Schedule[], + ] satisfies Schedule[], refetch, } }