/**
* 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 (
);
};
// ============
// 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()
);
}