Skip to content

Commit

Permalink
Use Reporting API in components (#8589)
Browse files Browse the repository at this point in the history
Co-authored-by: Jessy <[email protected]>
Co-authored-by: Naman Malhotra <[email protected]>
Co-authored-by: Nagesh Pai <[email protected]>
Co-authored-by: Shendy <[email protected]>
Co-authored-by: Eric Jinks <[email protected]>
  • Loading branch information
6 people authored Apr 17, 2024
1 parent 1b9b52a commit 45719a0
Show file tree
Hide file tree
Showing 25 changed files with 533 additions and 19 deletions.
4 changes: 4 additions & 0 deletions changelog/add-8519-reporting-api-to-component
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: add

Not user-facing: hidden behind feature flag. Use Reporting API to fetch and populate data in the Payment Activity widget.
66 changes: 56 additions & 10 deletions client/components/payment-activity/payment-activity-data.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* External dependencies
*/
import * as React from 'react';
import moment from 'moment';
import { __ } from '@wordpress/i18n';
import HelpOutlineIcon from 'gridicons/dist/help-outline';

Expand All @@ -10,17 +11,43 @@ import HelpOutlineIcon from 'gridicons/dist/help-outline';
*/
import PaymentDataTile from './payment-data-tile';
import { ClickTooltip } from '../tooltip';
import { usePaymentActivityData } from 'wcpay/data';
import { getAdminUrl } from 'wcpay/utils';
import type { DateRange } from './types';

import './style.scss';

/**
* This will be replaces in the future with a dynamic date range picker.
*/
const getDateRange = (): DateRange => {
return {
// Subtract 7 days from the current date.
date_start: moment()
.subtract( 7, 'd' )
.format( 'YYYY-MM-DD\\THH:mm:ss' ),
date_end: moment().format( 'YYYY-MM-DD\\THH:mm:ss' ),
};
};

const PaymentActivityData: React.FC = () => {
const { paymentActivityData, isLoading } = usePaymentActivityData(
getDateRange()
);

const totalPaymentVolume = paymentActivityData?.total_payment_volume ?? 0;
const charges = paymentActivityData?.charges ?? 0;
const fees = paymentActivityData?.fees ?? 0;
const disputes = paymentActivityData?.disputes ?? 0;
const refunds = paymentActivityData?.refunds ?? 0;
const { storeCurrency } = wcpaySettings;

return (
<div className="wcpay-payment-activity-data">
<PaymentDataTile
id="wcpay-payment-activity-data__total-payment-volume"
label={ __( 'Total payment volume', 'woocommerce-payments' ) }
currencyCode="EUR"
amount={ 156373 }
currencyCode={ storeCurrency }
tooltip={
<ClickTooltip
className="total-payment-volume__tooltip"
Expand All @@ -35,17 +62,25 @@ const PaymentActivityData: React.FC = () => {
) }
/>
}
amount={ totalPaymentVolume }
reportLink={ getAdminUrl( {
page: 'wc-admin',
path: '/payments/transactions',
'date_between[0]': moment(
getDateRange().date_start
).format( 'YYYY-MM-DD' ),
'date_between[1]': moment( getDateRange().date_end ).format(
'YYYY-MM-DD'
),
filter: 'advanced',
} ) }
isLoading={ isLoading }
/>
<div className="wcpay-payment-data-highlights">
<PaymentDataTile
id="wcpay-payment-data-highlights__charges"
label={ __( 'Charges', 'woocommerce-payments' ) }
currencyCode="EUR"
amount={ 314300 }
currencyCode={ storeCurrency }
tooltip={
<ClickTooltip
className="payment-data-highlights__charges__tooltip"
Expand All @@ -57,41 +92,50 @@ const PaymentActivityData: React.FC = () => {
content={ __( 'test charge content' ) }
/>
}
amount={ charges }
reportLink={ getAdminUrl( {
page: 'wc-admin',
path: '/payments/transactions',
filter: 'advanced',
type_is: 'charge',
} ) }
isLoading={ isLoading }
/>
<PaymentDataTile
id="wcpay-payment-data-highlights__refunds"
label={ __( 'Refunds', 'woocommerce-payments' ) }
currencyCode="EUR"
amount={ 153200 }
currencyCode={ storeCurrency }
amount={ refunds }
reportLink={ getAdminUrl( {
page: 'wc-admin',
path: '/payments/transactions',
filter: 'advanced',
type_is: 'refund',
'date_between[0]': moment(
getDateRange().date_start
).format( 'YYYY-MM-DD' ),
'date_between[1]': moment(
getDateRange().date_end
).format( 'YYYY-MM-DD' ),
} ) }
isLoading={ isLoading }
/>
<PaymentDataTile
id="wcpay-payment-data-highlights__disputes"
label={ __( 'Disputes', 'woocommerce-payments' ) }
currencyCode="EUR"
amount={ 4727 }
currencyCode={ storeCurrency }
amount={ disputes }
reportLink={ getAdminUrl( {
page: 'wc-admin',
path: '/payments/disputes',
filter: 'awaiting_response',
} ) }
isLoading={ isLoading }
/>
<PaymentDataTile
id="wcpay-payment-data-highlights__fees"
label={ __( 'Fees', 'woocommerce-payments' ) }
currencyCode="EUR"
amount={ 9429 }
currencyCode={ storeCurrency }
tooltip={
<ClickTooltip
className="payment-data-highlights__fees__tooltip"
Expand All @@ -106,6 +150,8 @@ const PaymentActivityData: React.FC = () => {
) }
/>
}
amount={ fees }
isLoading={ isLoading }
/>
</div>
</div>
Expand Down
4 changes: 2 additions & 2 deletions client/components/payment-activity/payment-data-tile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import { Link } from '@woocommerce/components';
/**
* Internal dependencies
*/
import './style.scss';

import { formatCurrency } from 'wcpay/utils/currency';
import Loadable from '../loadable';

import './style.scss';
interface PaymentDataTileProps {
/**
* The id for the tile, can be used for CSS styling.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,11 @@ exports[`PaymentActivity component should render 1`] = `
aria-labelledby="wcpay-payment-activity-data__total-payment-volume"
class="wcpay-payment-data-highlights__item__wrapper__amount"
>
€1,563.73
$0.00
</p>
<a
data-link-type="wc-admin"
href="admin.php?page=wc-admin&path=%2Fpayments%2Ftransactions"
href="admin.php?page=wc-admin&path=%2Fpayments%2Ftransactions&date_between%5B0%5D=2024-04-01&date_between%5B1%5D=2024-04-08&filter=advanced"
>
View report
</a>
Expand Down Expand Up @@ -130,7 +130,7 @@ exports[`PaymentActivity component should render 1`] = `
aria-labelledby="wcpay-payment-data-highlights__charges"
class="wcpay-payment-data-highlights__item__wrapper__amount"
>
€3,143.00
$0.00
</p>
<a
data-link-type="wc-admin"
Expand Down Expand Up @@ -158,11 +158,11 @@ exports[`PaymentActivity component should render 1`] = `
aria-labelledby="wcpay-payment-data-highlights__refunds"
class="wcpay-payment-data-highlights__item__wrapper__amount"
>
€1,532.00
$0.00
</p>
<a
data-link-type="wc-admin"
href="admin.php?page=wc-admin&path=%2Fpayments%2Ftransactions&filter=advanced&type_is=refund"
href="admin.php?page=wc-admin&path=%2Fpayments%2Ftransactions&filter=advanced&type_is=refund&date_between%5B0%5D=2024-04-01&date_between%5B1%5D=2024-04-08"
>
View report
</a>
Expand All @@ -186,7 +186,7 @@ exports[`PaymentActivity component should render 1`] = `
aria-labelledby="wcpay-payment-data-highlights__disputes"
class="wcpay-payment-data-highlights__item__wrapper__amount"
>
€47.27
$0.00
</p>
<a
data-link-type="wc-admin"
Expand Down Expand Up @@ -242,7 +242,7 @@ exports[`PaymentActivity component should render 1`] = `
aria-labelledby="wcpay-payment-data-highlights__fees"
class="wcpay-payment-data-highlights__item__wrapper__amount"
>
€94.29
$0.00
</p>
</div>
</div>
Expand Down
7 changes: 7 additions & 0 deletions client/components/payment-activity/test/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,13 @@ describe( 'PaymentActivity component', () => {
},
},
};
Date.now = jest.fn( () =>
new Date( '2024-04-08T12:33:37.000Z' ).getTime()
);
} );

afterEach( () => {
Date.now = () => new Date().getTime();
} );

it( 'should render', () => {
Expand Down
4 changes: 4 additions & 0 deletions client/components/payment-activity/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface DateRange {
date_start: string; // Start date
date_end: string; // End date
}
1 change: 1 addition & 0 deletions client/data/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ export * from './documents/hooks';
export * from './payment-intents/hooks';
export * from './authorizations/hooks';
export * from './files/hooks';
export * from './payment-activity/hooks';
5 changes: 5 additions & 0 deletions client/data/payment-activity/action-types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/** @format */

export default {
SET_PAYMENT_ACTIVITY_DATA: 'SET_PAYMENT_ACTIVITY_DATA',
};
16 changes: 16 additions & 0 deletions client/data/payment-activity/actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/** @format */

/**
* Internal Dependencies
*/
import TYPES from './action-types';
import { PaymentActivityData, PaymentActivityAction } from './types';

export function updatePaymentActivity(
data: PaymentActivityData
): PaymentActivityAction {
return {
type: TYPES.SET_PAYMENT_ACTIVITY_DATA,
data,
};
}
24 changes: 24 additions & 0 deletions client/data/payment-activity/hooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/** @format */
/**
* External dependencies
*/
import { useSelect } from '@wordpress/data';

/**
* Internal dependencies
*/
import { STORE_NAME } from '../constants';
import { PaymentActivityState, PaymentActivityQuery } from './types';

// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
export const usePaymentActivityData = (
query: PaymentActivityQuery
): PaymentActivityState =>
useSelect( ( select ) => {
const { getPaymentActivityData, isResolving } = select( STORE_NAME );

return {
paymentActivityData: getPaymentActivityData( query ),
isLoading: isResolving( 'getPaymentActivityData', [ query ] ),
};
}, [] );
12 changes: 12 additions & 0 deletions client/data/payment-activity/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/** @format */

/**
* Internal dependencies
*/
import reducer from './reducer';
import * as selectors from './selectors';
import * as actions from './actions';
import * as resolvers from './resolvers';

export { reducer, selectors, actions, resolvers };
export * from './hooks';
24 changes: 24 additions & 0 deletions client/data/payment-activity/reducer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/** @format */

/**
* Internal dependencies
*/
import TYPES from './action-types';
import { PaymentActivityAction, PaymentActivityState } from './types';

const receivePaymentActivity = (
state: PaymentActivityState = {},
{ type, data }: PaymentActivityAction
): PaymentActivityState => {
switch ( type ) {
case TYPES.SET_PAYMENT_ACTIVITY_DATA:
state = {
...state,
paymentActivityData: data,
};
break;
}
return state;
};

export default receivePaymentActivity;
45 changes: 45 additions & 0 deletions client/data/payment-activity/resolvers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/** @format */

/**
* External dependencies
*/
import { apiFetch } from '@wordpress/data-controls';
import { controls } from '@wordpress/data';
import { addQueryArgs } from '@wordpress/url';
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import { NAMESPACE } from '../constants';
import { updatePaymentActivity } from './actions';
import { PaymentActivityData, QueryDate } from './types';

/**
* Retrieves payment activity data from the reporting API.
*
* @param {string} query Data on which to parameterize the selection.
*/
export function* getPaymentActivityData(
query: QueryDate
): Generator< unknown > {
const path = addQueryArgs(
`${ NAMESPACE }/reporting/payment_activity`,
query
);

try {
const results = yield apiFetch( { path } );

yield updatePaymentActivity( results as PaymentActivityData );
} catch ( e ) {
yield controls.dispatch(
'core/notices',
'createErrorNotice',
__(
'Error retrieving payment activity data.',
'woocommerce-payments'
)
);
}
}
11 changes: 11 additions & 0 deletions client/data/payment-activity/selectors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/** @format */

/**
* Internal Dependencies
*/
import { State } from 'wcpay/data/types';
import { PaymentActivityData } from './types';

export const getPaymentActivityData = ( state: State ): PaymentActivityData => {
return state?.paymentActivity?.paymentActivityData || {};
};
Loading

0 comments on commit 45719a0

Please sign in to comment.