Skip to content

Commit

Permalink
Add Stripe embedded account notifications component on the Overview p…
Browse files Browse the repository at this point in the history
…age (#10314)

Co-authored-by: mordeth <[email protected]>
Co-authored-by: oaratovskyi <[email protected]>
  • Loading branch information
3 people authored Feb 16, 2025
1 parent 31dacc8 commit 93e4b14
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 3 deletions.
4 changes: 4 additions & 0 deletions changelog/add-9128-account-notifs-component-on-overview-page
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: add

Add Stripe embedded account notifications component on the Overview page
102 changes: 100 additions & 2 deletions client/overview/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/**
* External dependencies
*/
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
import { Card, Notice } from '@wordpress/components';
import { getQuery } from '@woocommerce/navigation';
import { __ } from '@wordpress/i18n';
Expand Down Expand Up @@ -32,6 +32,13 @@ import { useDisputes, useGetSettings, useSettings } from 'data';
import SandboxModeSwitchToLiveNotice from 'wcpay/components/sandbox-mode-switch-to-live-notice';
import './style.scss';
import BannerNotice from 'wcpay/components/banner-notice';
import useAccountSession from 'wcpay/utils/embedded-components/account-session';
import appearance from 'wcpay/utils/embedded-components/appearance';
import {
ConnectComponentsProvider,
ConnectNotificationBanner,
} from '@stripe/react-connect-js';
import { recordEvent } from 'wcpay/tracks';

const OverviewPageError = () => {
const queryParams = getQuery();
Expand Down Expand Up @@ -63,10 +70,31 @@ const OverviewPage = () => {
enabledPaymentMethods,
featureFlags: { isPaymentOverviewWidgetEnabled },
overviewTasksVisibility,
showUpdateDetailsTask,
wpcomReconnectUrl,
} = wcpaySettings;

// Don't show the update details and verify business tasks by default due to embedded component.
const [ showUpdateDetailsTask, setShowUpdateDetailsTask ] = useState(
false
);
const [
showGetVerifyBankAccountTask,
setShowGetVerifyBankAccountTask,
] = useState( false );

const [
stripeNotificationsBannerErrorMessage,
setStripeNotificationsBannerErrorMessage,
] = useState( '' );
const [
notificationsBannerMessage,
setNotificationsBannerMessage,
] = React.useState( '' );
const stripeConnectInstance = useAccountSession( {
setLoadErrorMessage: setStripeNotificationsBannerErrorMessage,
appearance,
} );

const isTestModeOnboarding = wcpaySettings.testModeOnboarding;
const { isLoading: settingsIsLoading } = useSettings();
const [
Expand All @@ -85,6 +113,7 @@ const OverviewPage = () => {
wpcomReconnectUrl,
activeDisputes,
enabledPaymentMethods,
showGetVerifyBankAccountTask,
} );
const tasks =
Array.isArray( tasksUnsorted ) && tasksUnsorted.sort( taskSort );
Expand Down Expand Up @@ -157,6 +186,42 @@ const OverviewPage = () => {
setTestDriveSuccessDisplayed( true );
}

// Show old tasks if the embedded component fails to load.
useEffect( () => {
if ( stripeNotificationsBannerErrorMessage ) {
setShowUpdateDetailsTask( true );
setShowGetVerifyBankAccountTask( true );
}
}, [ stripeNotificationsBannerErrorMessage ] );

// eslint-disable-next-line valid-jsdoc
/**
* Configure custom banner behaviour so the banner isn't shown when there are no action items.
* We'll use notificationBannerMessage for that.
* See https://docs.stripe.com/connect/supported-embedded-components/notification-banner#configure-custom-banner-behavior
*/
const handleNotificationsChange = ( response ) => {
if ( response.actionRequired > 0 ) {
// eslint-disable-next-line max-len
// Do something related to required actions, such as adding margins to the banner container or tracking the current number of notifications.
setNotificationsBannerMessage(
'You must resolve the notifications on this page before proceeding.'
);
} else if ( response.total > 0 ) {
// Do something related to notifications that don't require action.
setNotificationsBannerMessage( 'The items below are in review.' );
} else {
setNotificationsBannerMessage( '' );
}
if ( response.actionRequired > 0 || response.total > 0 ) {
// Record the event indicating user got the notifications banner with some actionRequired or total items.
recordEvent( 'wcpay_overview_stripe_notifications_banner_update', {
action_required_count: response.actionRequired,
total_count: response.total,
} );
}
};

return (
<Page isNarrow className="wcpay-overview">
<OverviewPageError />
Expand Down Expand Up @@ -205,6 +270,39 @@ const OverviewPage = () => {
<ErrorBoundary>
<Welcome />

{ stripeConnectInstance && (
<div
className="stripe-notifications-banner-wrapper"
style={ {
display: notificationsBannerMessage
? 'block'
: 'none',
} }
>
<ErrorBoundary>
<ConnectComponentsProvider
connectInstance={ stripeConnectInstance }
>
<ConnectNotificationBanner
onLoadError={ ( loadError ) =>
setStripeNotificationsBannerErrorMessage(
loadError.error.message ||
'Unknown error'
)
}
collectionOptions={ {
fields: 'eventually_due',
futureRequirements: 'omit',
} }
onNotificationsChange={
handleNotificationsChange
}
/>
</ConnectComponentsProvider>
</ErrorBoundary>
</div>
) }

{ showTaskList && (
<Card>
<ErrorBoundary>
Expand Down
8 changes: 8 additions & 0 deletions client/overview/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,14 @@
position: fixed;
}

.stripe-notifications-banner-wrapper {
padding-bottom: 0.25rem; // Stripe does it in their furever.dev site too so the border is visible.
overflow: hidden; // Stripe does it in their furever.dev site too so the border is visible.
margin-bottom: 24px;
margin-left: -1px; // For some reason we lack 1px left and right.
margin-right: -1px;
}

.wcpay-setup-real-payments {
&__body {
display: grid;
Expand Down
7 changes: 6 additions & 1 deletion client/overview/task-list/tasks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ interface TaskListProps {
activeDisputes?: CachedDispute[];
enabledPaymentMethods?: string[];
showGoLiveTask: boolean;
showGetVerifyBankAccountTask: boolean;
}

export const getTasks = ( {
Expand All @@ -38,6 +39,7 @@ export const getTasks = ( {
activeDisputes = [],
enabledPaymentMethods = [],
showGoLiveTask = false,
showGetVerifyBankAccountTask = true,
}: TaskListProps ): TaskItemProps[] => {
const {
status,
Expand Down Expand Up @@ -93,6 +95,9 @@ export const getTasks = ( {
isInTestModeOnboarding( false ) &&
showGoLiveTask;

const isGetVerifyBankAccountTaskVisible =
showGetVerifyBankAccountTask && isPoEnabled && detailsSubmitted;

return [
isUpdateDetailsTaskVisible &&
getUpdateBusinessDetailsTask(
Expand All @@ -105,7 +110,7 @@ export const getTasks = ( {
),
wpcomReconnectUrl && getReconnectWpcomTask( wpcomReconnectUrl ),
isDisputeTaskVisible && getDisputeResolutionTask( activeDisputes ),
isPoEnabled && detailsSubmitted && getVerifyBankAccountTask(),
isGetVerifyBankAccountTaskVisible && getVerifyBankAccountTask(),
isAddApmsTaskVisible && getAddApmsTask(),
isGoLiveTaskVisible && getGoLiveTask(),
].filter( Boolean );
Expand Down
1 change: 1 addition & 0 deletions client/overview/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ jest.mock( 'wcpay/data', () => ( {
.mockReturnValue( { overviews: { currencies: [] } } ),
useActiveLoanSummary: jest.fn().mockReturnValue( { isLoading: true } ),
} ) );
jest.mock( 'wcpay/utils/embedded-components/account-session' );

select.mockReturnValue( {
getSettings: () => settingsMock,
Expand Down

0 comments on commit 93e4b14

Please sign in to comment.