import React, { useEffect, useMemo, useReducer } from "react"; import { ComponentDataSourceContext, ZappPipesDataProps } from "../types"; const generateStaticUrl = (component: ZappUIComponent) => { const { id, position } = component || {}; return `static://component?id=${id}&position=${position}`; }; const reducer = (state, action) => { switch (action.type) { case "SET_DATA": return { ...state, data: action.payload, loading: false }; case "SET_ERROR": return { ...state, error: action.payload, loading: false }; default: return state; } }; type StaticFeedResolverProps = ComponentDataSourceContext & { children: (dataProps: ZappPipesDataProps) => React.ReactNode; }; export function StaticFeedResolver({ children, getStaticComponentFeed, component, componentIndex, }: StaticFeedResolverProps) { const url = generateStaticUrl(component); const [{ loading, data, error }, dispatch] = useReducer(reducer, { loading: true, data: null, error: null, }); useEffect(() => { const getData = async () => { try { const res = await getStaticComponentFeed({ index: componentIndex, component, }); dispatch({ type: "SET_DATA", payload: res }); } catch (err) { dispatch({ type: "SET_ERROR", payload: err }); } }; if (getStaticComponentFeed) { getData(); } }, [getStaticComponentFeed, component, componentIndex]); const reloadData = async () => { if (!getStaticComponentFeed) return Promise.resolve(); try { const res = await getStaticComponentFeed({ index: componentIndex, component, }); dispatch({ type: "SET_DATA", payload: res }); return res; } catch (err) { dispatch({ type: "SET_ERROR", payload: err }); return Promise.reject(err); } }; const zappPipesDataProps = useMemo( () => ({ zappPipesData: { url, loading, data, error }, reloadData, loadNextData: undefined, // Static resolver doesn't support pagination }), [url, loading, data, error] ); return <>{children(zappPipesDataProps)}; }