/** * WordPress dependencies */ import { Dashicon } from '@safe-wordpress/components'; import { useRef } from '@safe-wordpress/element'; import { useSelect } from '@safe-wordpress/data'; import { dateI18n } from '@wordpress/date'; import { _nx, _x, sprintf } from '@safe-wordpress/i18n'; /** * External dependencies */ import clsx from 'clsx'; import { store as NAB_DATA } from '@nab/data'; import { formatNumber } from '@nab/i18n'; import type { Maybe, Quota } from '@nab/types'; /** * Internal dependencies */ import './style.scss'; export type QuotaMeterProps = { readonly disabled?: boolean; readonly subscriptionQuota?: Quota; }; export const QuotaMeter = ( { disabled, subscriptionQuota, }: QuotaMeterProps ): JSX.Element => { const { quota, status } = useQuota( subscriptionQuota ); const title = useTitle( quota ); const isLoading = ! quota; const isBarDisabled = disabled || isLoading; const { availableQuota = 0, percentage = 100 } = quota ?? {}; return (

{ title }

); }; // ============ // HELPER VIEWS // ============ const AmountLabel = ( { mode, quota, expirationDate, }: { readonly mode: 'ready' | 'loading' | 'error'; readonly quota: number; readonly expirationDate: Maybe< string >; } ) => { if ( 'loading' === mode ) { return ( { _x( 'Loading…', 'text', 'nelio-ab-testing' ) } ); } if ( 'error' === mode ) { return ( { _x( 'Unable to retrieve quota', 'text', 'nelio-ab-testing' ) } ); } if ( expirationDate && ! isDateOver( expirationDate ) ) { return ( ); } return ( { ! quota && ( ) } { quota > 0 ? sprintf( /* translators: %s: Quota number. */ _nx( '%s available page view', '%s available page views', quota, 'text', 'nelio-ab-testing' ), formatNumber( quota ) ) : _x( 'There are no more available page views', 'text', 'nelio-ab-testing' ) } ); }; const QuotaBoostLabel = ( { quota, expirationDate, }: { readonly quota: number; expirationDate: string; } ) => { if ( ! quota ) { return ( { _x( 'There are no more available page views', 'text', 'nelio-ab-testing' ) } ); } const remainingQuota = sprintf( /* translators: %d: Number of page views. */ _nx( '%d remaining', '%d remaining', quota, 'text (quota)', 'nelio-ab-testing' ), quota ); const expiration = isToday( expirationDate ) ? _x( 'Ends today', 'text', 'nelio-ab-testing' ) : sprintf( /* translators: %s: Date. */ _x( 'Ends on %s', 'text', 'nelio-ab-testing' ), dateI18n( _x( 'F j', 'date wihout year', 'nelio-ab-testing' ), expirationDate ) ); return ( 🚀 { ' ' + _x( 'Activation Boost', 'text', 'nelio-ab-testing' ) } { sprintf( ' · %1$s · %2$s', remainingQuota, expiration ) } ); }; const Bar = ( { disabled, percentage, }: { readonly disabled: boolean; readonly percentage: number; } ) => { const size = percentage.toFixed( 0 ); const nodeRef = useRef( null ); return (
); }; // ===== // HOOKS // ===== const useTitle = ( quota: Maybe< Quota > ) => useSelect( ( select ): string => { select( NAB_DATA ); if ( ! quota ) { return _x( 'Quota', 'text', 'nelio-ab-testing' ); } if ( 'site' === quota.mode ) { return _x( 'Site Quota', 'text', 'nelio-ab-testing' ); } const { isSubscribedTo } = select( NAB_DATA ); if ( isSubscribedTo( 'basic', 'or-above' ) ) { return _x( 'Subscription Quota', 'text', 'nelio-ab-testing' ); } return _x( 'Quota', 'text', 'nelio-ab-testing' ); }, [ quota ] ); const useQuota = ( subscriptionQuota: Maybe< Quota > ) => useSelect( ( select ): { quota: Maybe< Quota >; status: 'ready' | 'loading' | 'error' } => { select( NAB_DATA ); if ( subscriptionQuota ) { return { quota: subscriptionQuota, status: 'ready' }; } /* eslint-disable @wordpress/no-unused-vars-before-return */ const quota = select( NAB_DATA ).getQuota(); const isLoading = ! select( NAB_DATA ).hasFinishedResolution( 'getQuota' ); const isError = select( NAB_DATA ).hasResolutionFailed( 'getQuota' ); /* eslint-enable @wordpress/no-unused-vars-before-return */ if ( isLoading ) { return { quota: undefined, status: 'loading' }; } if ( isError || ! quota ) { return { quota: undefined, status: 'error' }; } return { quota, status: 'ready' }; }, [ subscriptionQuota ] ); function isDateOver( datetime: string ): boolean { const now = new Date().toISOString(); return datetime <= now; } function isToday( datetime: string ): boolean { const today = new Date(); const date = new Date( datetime ); return ( date.getFullYear() === today.getFullYear() && date.getMonth() === today.getMonth() && date.getDate() === today.getDate() ); }