/** * Hook: the requirements for a service on a lane. A failed fetch leaves `requirements` null and * the server's own validation still decides. */ import { useEffect, useState } from '@wordpress/element'; import apiFetch from '@wordpress/api-fetch'; import type { ServiceRequirements } from '../../types'; import { addBreadcrumb, captureMessage } from '../sentry'; export interface UseServiceRequirementsReturn { requirements: ServiceRequirements | null; isLoading: boolean; } export function useServiceRequirements( serviceSlug: string | null | undefined, originCountry: string | null | undefined, destinationCountry: string | null | undefined ): UseServiceRequirementsReturn { const [ requirements, setRequirements ] = useState< ServiceRequirements | null >( null ); const [ isLoading, setIsLoading ] = useState( false ); useEffect( () => { setRequirements( null ); if ( ! serviceSlug || ! originCountry || ! destinationCountry ) { setIsLoading( false ); return; } // A later lane or service must not be overwritten by an earlier, slower response. let current = true; setIsLoading( true ); const query = new URLSearchParams( { service: serviceSlug, origin: originCountry, destination: destinationCountry, } ); apiFetch( { path: `/parcel2go-shipping/v1/requirements?${ query.toString() }`, } ) .then( ( response ) => { if ( current ) { setRequirements( response as ServiceRequirements ); } } ) .catch( () => { if ( ! current ) { return; } addBreadcrumb( 'Service requirements unavailable', { serviceSlug }, 'api' ); captureMessage( 'Failed to fetch service requirements', 'warning', { serviceSlug, } ); } ) .finally( () => { if ( current ) { setIsLoading( false ); } } ); return () => { current = false; }; }, [ serviceSlug, originCountry, destinationCountry ] ); return { requirements, isLoading }; }