/** * WordPress dependencies */ import apiFetch from '@safe-wordpress/api-fetch'; import { dispatch, resolveSelect, select } from '@safe-wordpress/data'; import { _x, sprintf } from '@safe-wordpress/i18n'; /** * External dependencies */ import { store as NAB_DATA } from '@nab/data'; import { createErrorNotice, getValue, setValue } from '@nab/utils'; import type { Account, Invoice, Maybe, Site, SubscriptionId, SubscriptionPromo, } from '@nab/types'; /** * Internal dependencies */ import { store as NAB_ACCOUNT } from '../../store'; export async function getAccount(): Promise< void > { try { const account = await apiFetch< Account >( { path: '/nab/v1/account', } ); await dispatch( NAB_ACCOUNT ).receiveAccount( account ); } catch ( error ) { await createErrorNotice( error, _x( 'Error while accessing site info.', 'text', 'nelio-ab-testing' ) ); throw error; } } export async function getSubscriptionPromo(): Promise< void > { if ( select( NAB_DATA ).isSubscribedTo( 'basic', 'or-above' ) ) { return; } if ( select( NAB_DATA ).getPluginSetting( 'hasUserObjectedToProductOffers' ) ) { return; } const promo = await fetchActivePromo(); if ( ! promo ) { return; } await dispatch( NAB_ACCOUNT ).receiveActiveSubscriptionPromo( promo ); } export async function getSubscriptionQuota(): Promise< void > { await resolveSelect( NAB_ACCOUNT ).getAccount(); } export async function getSites( id: SubscriptionId ): Promise< void > { if ( ! id ) { return; } try { const sites = await apiFetch< ReadonlyArray< Site > >( { path: `/nab/v1/subscription/${ id }/sites`, } ); await dispatch( NAB_ACCOUNT ).receiveSites( sites ); } catch ( error ) { await createErrorNotice( error, sprintf( /* translators: %s: Subscription id. */ _x( 'Error while accessing sites in subscription %s.', 'text', 'nelio-ab-testing' ), id ) ); throw error; } } export async function getInvoices( id: SubscriptionId ): Promise< void > { if ( ! id ) { return; } try { const invoices = await apiFetch< ReadonlyArray< Invoice > >( { path: `/nab/v1/subscription/${ id }/invoices`, } ); await dispatch( NAB_ACCOUNT ).receiveInvoices( invoices ); } catch ( error ) { await createErrorNotice( error, sprintf( /* translators: %s: Subscription id. */ _x( 'Error while accessing invoices in subscription %s.', 'text', 'nelio-ab-testing' ), id ) ); throw error; } } // ======= // HELPERS // ======= async function fetchActivePromo(): Promise< Maybe< SubscriptionPromo > > { const cachedPromo = getCachedPromo(); if ( cachedPromo ) { return cachedPromo; } try { const apiUrl = select( NAB_DATA ).getPluginSetting( 'apiUrl' ); const siteId = select( NAB_DATA ).getPluginSetting( 'siteId' ); const promo = await apiFetch< Maybe< SubscriptionPromo > >( { url: `${ apiUrl }/site/${ siteId }/subscription/active-subscription-promo`, credentials: 'omit', method: 'POST', mode: 'cors', data: { lang: select( NAB_DATA ).getPluginSetting( 'userLocale' ) }, } ); cachePromo( promo, 24 ); return promo; } catch ( _ ) { cachePromo( undefined, 2 ); return undefined; } } function getCachedPromo(): Maybe< SubscriptionPromo > { const value = getValue< Maybe< { value: SubscriptionPromo; expires: string } > >( 'active-promo', undefined ); if ( ! value ) { return undefined; } const today = new Date().toISOString(); if ( today >= value.expires ) { cachePromo( undefined, 2 ); return undefined; } return value.value; } function cachePromo( promo: Maybe< SubscriptionPromo >, hours: number ): void { const dayInMillis = hours * 60 * 60 * 1000; const date = new Date(); date.setTime( date.getTime() + dayInMillis ); const expires = date.toISOString(); setValue( 'active-promo', { value: promo, expires } ); }