Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | 1x 7x 7x 20x 20x 20x 20x 20x 20x 10x 10x 1x 9x 2x 7x 20x | import {
Button,
Card,
Link,
LinkButton,
Stack,
Text,
Spinner,
VisuallyHidden,
} from '@jetpack-premium-analytics/externals';
import { formatMetricValue } from '@jetpack-premium-analytics/formatters';
import {
getOverLimitMessage,
getPlanUpgradeUrl,
usePlanUsage,
useTrackEvent,
} from '@jetpack-premium-analytics/widgets-toolkit';
import { ProgressBar } from '@wordpress/components';
import { useCallback } from '@wordpress/element';
import { __, _n, sprintf } from '@wordpress/i18n';
import styles from './stats-settings.module.scss';
import type { JSX } from 'react';
const TIERED_BILLING_URL =
'https://jetpack.com/support/jetpack-stats/free-or-paid/paid-stats-tier-billing/';
/**
* The usage meter: views used against the plan's limit, and when the cycle restarts.
*
* @param props - Component props.
* @param props.limit - The plan's billable views limit for the cycle.
* @param props.usage - The billable views counted so far this cycle.
* @param props.daysToReset - Days until the cycle restarts.
* @return The meter.
*/
function UsageMeter( {
limit,
usage = 0,
daysToReset,
}: {
limit: number;
usage?: number;
daysToReset?: number;
} ): JSX.Element {
const label = sprintf(
/* translators: 1: views used in the current cycle, 2: the plan's views limit. */
__( '%1$s / %2$s views', 'jetpack-premium-analytics-pkg' ),
formatMetricValue( usage, 'number', { decimals: 0 } ),
formatMetricValue( limit, 'number', { decimals: 0 } )
);
return (
<Stack direction="column" gap="sm">
<Stack direction="row" justify="space-between" align="baseline" gap="md">
<Text className={ styles.usageCount }>{ label }</Text>
{ daysToReset !== undefined && (
<Text className={ styles.usageReset }>
{ sprintf(
/* translators: %d: number of days until the billing cycle resets. */
_n(
'Restarts in %d day',
'Restarts in %d days',
daysToReset,
'jetpack-premium-analytics-pkg'
),
daysToReset
) }
</Text>
) }
</Stack>
{ /* Until the @wordpress/ui update (Automattic/jetpack#53004) ships `Meter`, which fits usage against a limit; switch to it then. */ }
<ProgressBar
className={ styles.usageBar }
value={ Math.min( 100, ( usage / limit ) * 100 ) }
aria-label={ label }
/>
</Stack>
);
}
/**
* The Settings tab's "Your current plan" card.
*
* @return The card.
*/
export function PlanUsageCard(): JSX.Element {
const { data, isLoading, isError, refetch, limit, overLimitMonths } = usePlanUsage();
const trackEvent = useTrackEvent();
const upgradeUrl = getPlanUpgradeUrl();
const retry = useCallback( () => refetch(), [ refetch ] );
const trackUpgrade = useCallback(
() => trackEvent( 'jetpack_premium_analytics_plan_upgrade_click' ),
[ trackEvent ]
);
let content: JSX.Element;
if ( isLoading ) {
content = (
<>
<Spinner />
<VisuallyHidden role="status">
{ __( 'Loading your plan usageā¦', 'jetpack-premium-analytics-pkg' ) }
</VisuallyHidden>
</>
);
} else if ( ! data && isError ) {
content = (
<Stack direction="column" align="start" gap="md">
<Text>
{ __(
"We couldn't load plan usage. Please try again in a moment.",
'jetpack-premium-analytics-pkg'
) }
</Text>
<Button variant="outline" onClick={ retry }>
{ __( 'Retry', 'jetpack-premium-analytics-pkg' ) }
</Button>
</Stack>
);
} else if ( limit === null ) {
content = (
<Text>
{ __(
"Plan usage isn't available for your current plan.",
'jetpack-premium-analytics-pkg'
) }
</Text>
);
} else {
content = (
<Stack direction="column" align="start" gap="lg">
<div className={ styles.usageMeter }>
<UsageMeter
limit={ limit }
usage={ data?.current_usage?.views_count }
daysToReset={ data?.current_usage?.days_to_reset }
/>
</div>
{ overLimitMonths ? (
<Text className={ styles.usageWarning }>{ getOverLimitMessage( overLimitMonths ) }</Text>
) : null }
<Text className={ styles.usageNote }>
{ __(
'Billable views are the page views counted against your plan each cycle. Excluded logged-in role views are not counted.',
'jetpack-premium-analytics-pkg'
) }{ ' ' }
<Link href={ TIERED_BILLING_URL } openInNewTab>
{ __( 'Learn more', 'jetpack-premium-analytics-pkg' ) }
</Link>
</Text>
{ upgradeUrl && (
<LinkButton href={ upgradeUrl } onClick={ trackUpgrade }>
{ __( 'Upgrade', 'jetpack-premium-analytics-pkg' ) }
</LinkButton>
) }
</Stack>
);
}
return (
<Card.Root>
<Card.Header>
<Card.Title>{ __( 'Your current plan', 'jetpack-premium-analytics-pkg' ) }</Card.Title>
</Card.Header>
<Card.Content>{ content }</Card.Content>
</Card.Root>
);
}
|