Show APMs on the new Payments menu (#34581)

* Initial commit

* Implement APMs toggle button
- Add valid links to each APM
- Add valid link to the marketplace

* Implement APMs toggle button
- Add valid links to each APM
- Add valid link to the marketplace

* Refactor the code to be more explicit

* Delete the apm on toggle off if it's local state

* Implement FAQ simple block
- Style a notice about APM is enabled
- Add noreferrer and target=_blank to external links

* Add todo comments

* FAQ simple styling fix (improve padding)

* Fixes after inner review

* Add changelog item

* Address PR review comments

* Remove Affirm as it's not in the store

* Style fixes, proper internationalization and put valid link

* Styling fixes, translators comment, rename ApmsProps component to ApmListProps

* Two more styling fixes

* Styling fix

* Styling fix

* Remove text-decoration: none to match the design
This commit is contained in:
Oleksandr Aratovskyi 2022-09-23 15:36:12 +03:00 committed by GitHub
parent b9f1f57e43
commit 013a5f25ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 322 additions and 4 deletions

View File

@ -0,0 +1,136 @@
/**
* External dependencies
*/
import { List } from '@woocommerce/components';
import { download, Icon } from '@wordpress/icons';
import {
Card,
CardBody,
CardFooter,
CardHeader,
ExternalLink,
Notice,
ToggleControl,
} from '@wordpress/components';
/**
* Internal dependencies
*/
import strings from './strings';
import { WC_ASSET_URL } from '~/utils/admin-settings';
export interface Apm {
id: string;
title: string;
icon: string;
description: string;
link: string;
extension: string;
}
export const apms: Apm[] = [
{
id: 'paypal',
title: strings.apms.paypal.title,
icon: `${ WC_ASSET_URL }images/payment_methods/72x72/paypal.png`,
description: strings.apms.paypal.description,
link: 'https://woocommerce.com/products/woocommerce-paypal-payments/',
extension: 'woocommerce-paypal-payments',
},
{
id: 'amazonpay',
title: strings.apms.amazonpay.title,
icon: `${ WC_ASSET_URL }images/payment_methods/72x72/amazonpay.png`,
description: strings.apms.amazonpay.description,
link: 'https://woocommerce.com/products/pay-with-amazon/',
extension: 'woocommerce-gateway-amazon-payments-advanced',
},
{
id: 'klarna',
title: strings.apms.klarna.title,
icon: `${ WC_ASSET_URL }images/payment_methods/72x72/klarna.png`,
description: strings.apms.klarna.description,
link: 'https://woocommerce.com/products/klarna-payments/',
extension: 'klarna-payments-for-woocommerce',
},
];
interface ApmListProps {
enabledApms: Set< Apm >;
setEnabledApms: ( value: Set< Apm > ) => void;
}
const ApmNotice = ( { enabledApms }: { enabledApms: Set< Apm > } ) => {
if ( ! enabledApms.size ) {
return null;
}
const extensions = [ ...enabledApms ]
.map( ( apm ) => apm.title )
.join( ', ' );
return (
<Card className="connect-account__apms-notice">
<CardBody>
<Notice status={ 'info' } isDismissible={ false }>
<Icon icon={ download } />
<div>{ strings.apms.installText( extensions ) }</div>
</Notice>
</CardBody>
</Card>
);
};
const ApmList: React.FunctionComponent< ApmListProps > = ( {
enabledApms,
setEnabledApms,
} ) => {
const handleToggleChange = ( apm: Apm ) => {
if ( enabledApms.has( apm ) ) {
enabledApms.delete( apm );
} else {
enabledApms.add( apm );
}
setEnabledApms( new Set< Apm >( enabledApms ) );
};
const apmsList = apms.map( ( apm ) => ( {
key: apm.id,
title: apm.title,
content: (
<>
{ apm.description }{ ' ' }
<a href={ apm.link } target="_blank" rel="noreferrer">
{ strings.learnMore }
</a>
</>
),
before: <img src={ apm.icon } alt="" />,
after: (
<ToggleControl
checked={ enabledApms.has( apm ) }
onChange={ () => handleToggleChange( apm ) }
/>
),
} ) );
return (
<>
<ApmNotice enabledApms={ enabledApms } />
<Card size="large" className="connect-account__apms">
<CardHeader>
<h1>{ strings.apms.addMoreWaysToPay }</h1>
</CardHeader>
<CardBody>
<List items={ apmsList } />
</CardBody>
<CardFooter>
<ExternalLink href="https://woocommerce.com/product-category/woocommerce-extensions/payment-gateways/wallets/?categoryIds=28682&collections=product&page=1">
{ strings.apms.seeMore }
</ExternalLink>
</CardFooter>
</Card>
</>
);
};
export default ApmList;

View File

@ -0,0 +1,29 @@
/**
* External dependencies
*/
import { Icon, help } from '@wordpress/icons';
/**
* Internal dependencies
*/
import strings from './strings';
const FrequentlyAskedQuestionsSimple: React.FC = () => {
return (
<div className="faq__card">
<div className="help-section-simple">
<Icon icon={ help } />
<span>{ strings.faq.haveMoreQuestions }</span>
<a
href="https://www.woocommerce.com/my-account/tickets/"
target="_blank"
rel="noreferrer"
>
{ strings.faq.getInTouch }
</a>
</div>
</div>
);
};
export default FrequentlyAskedQuestionsSimple;

View File

@ -31,10 +31,11 @@ import {
*/
import strings from './strings';
import Banner from './banner';
import ApmList, { Apm } from './apms';
import './style.scss';
import FrequentlyAskedQuestions from './faq';
import ExitSurveyModal from './exit-survey-modal';
import { getAdminSetting } from '~/utils/admin-settings';
import FrequentlyAskedQuestionsSimple from './faq-simple';
declare global {
interface Window {
@ -111,12 +112,14 @@ const ConnectPageOnboarding = ( {
installAndActivatePlugins,
setErrorMessage,
connectUrl,
enabledApms,
}: {
isJetpackConnected?: boolean;
installAndActivatePlugins: PluginsStoreActions[ 'installAndActivatePlugins' ];
// eslint-disable-next-line @typescript-eslint/ban-types
setErrorMessage: Function;
connectUrl: string;
enabledApms: Set< Apm >;
} ) => {
const [ isSubmitted, setSubmitted ] = useState( false );
const [ isNoThanksClicked, setNoThanksClicked ] = useState( false );
@ -145,11 +148,20 @@ const ConnectPageOnboarding = ( {
wpcom_connection: isJetpackConnected ? 'Yes' : 'No',
} );
const pluginsToInstall = [ ...enabledApms ].map(
( apm ) => apm.extension
);
try {
const installAndActivateResponse = await installAndActivatePlugins(
[ 'woocommerce-payments' ]
[ 'woocommerce-payments' ].concat( pluginsToInstall )
);
if ( installAndActivateResponse?.success ) {
recordEvent( 'wcpay_extension_installed', {
extensions: [ ...enabledApms ]
.map( ( apm ) => apm.id )
.join( ', ' ),
} );
await activatePromo();
} else {
throw new Error( installAndActivateResponse.message );
@ -223,6 +235,8 @@ const ConnectPageOnboarding = ( {
const ConnectAccountPage = () => {
const [ errorMessage, setErrorMessage ] = useState( '' );
const [ enabledApms, setEnabledApms ] = useState( new Set< Apm >() );
const { isJetpackConnected, connectUrl, hasViewedWelcomePage } = useSelect(
( select ) => {
const { getOption } = select( OPTIONS_STORE_NAME );
@ -277,9 +291,14 @@ const ConnectAccountPage = () => {
installAndActivatePlugins={ installAndActivatePlugins }
connectUrl={ connectUrl }
setErrorMessage={ setErrorMessage }
enabledApms={ enabledApms }
/>
<Banner />
<FrequentlyAskedQuestions />
<ApmList
enabledApms={ enabledApms }
setEnabledApms={ setEnabledApms }
/>
<FrequentlyAskedQuestionsSimple />
</div>
</div>
);

View File

@ -2,7 +2,7 @@
/**
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import { __, _n, sprintf } from '@wordpress/i18n';
import { createInterpolateElement } from '@wordpress/element';
export default {
@ -378,4 +378,58 @@ export default {
getInTouch: __( 'Get in touch', 'woocommerce' ),
},
apms: {
addMoreWaysToPay: __(
'Add more ways for buyers to pay',
'woocommerce'
),
seeMore: __( 'See more', 'woocommerce' ),
paypal: {
title: __( 'PayPal Payments', 'woocommerce' ),
description: __(
'Enable PayPal Payments alongside WooCommerce Payments. Give your customers another way to pay safely and conveniently via PayPal, PayLater, and Venmo.',
'woocommerce'
),
},
amazonpay: {
title: __( 'Amazon Pay', 'woocommerce' ),
description: __(
'Enable Amazon Pay alongside WooCommerce Payments and give buyers the ability to pay via Amazon Pay. Transactions take place via Amazon embedded widgets, so the buyer never leaves your site.',
'woocommerce'
),
},
klarna: {
title: __( 'Klarna', 'woocommerce' ),
description: __(
'Enable Klarna alongside WooCommerce Payments. With Klarna Payments buyers can choose the payment installment option they want, Pay Now, Pay Later, or Slice It. No credit card numbers, no passwords, no worries.',
'woocommerce'
),
},
affirm: {
title: __( 'Affirm', 'woocommerce' ),
description: __(
'Enable Affirm alongside WooCommerce Payments and give buyers the ability to pick the payment option that works for them and their budget — from 4 interest-free payments every 2 weeks to monthly installments.',
'woocommerce'
),
},
installText: ( extensionsString: string ) => {
const extensionsNumber = extensionsString.split( ', ' ).length;
return createInterpolateElement(
sprintf(
/* translators: %s = names of the installed extensions */
_n(
'Installing <strong>WooCommerce Payments</strong> will automatically activate <strong>%s</strong> extension in your store.',
'Installing <strong>WooCommerce Payments</strong> will automatically activate <strong>%s</strong> extensions in your store.',
extensionsNumber,
'woocommerce'
),
extensionsString
),
{
strong: <strong />,
}
);
},
installTextPost: __( 'extension in your store.', 'woocommerce' ),
},
};

View File

@ -37,6 +37,8 @@
.connect-account__card,
.woocommerce-payments-banner,
.connect-account__apms,
.connect-account__apms-notice,
.faq__card {
box-shadow: none;
border: 1px solid #e2e4e7;
@ -109,6 +111,19 @@
margin-left: 10px;
}
}
.help-section-simple {
font-size: 16px;
padding: $gap;
span {
vertical-align: 6px;
margin-left: $gap-small;
}
a {
vertical-align: 6px;
margin-left: $gap-small;
}
}
}
.connect-account__card {
@ -165,6 +180,67 @@
border-radius: 3px;
}
}
.connect-account__apms {
.components-card__header {
padding: $gap-small $gap-large;
h1 {
font-size: 20px;
line-height: 28px;
}
}
.components-card__body {
padding: 0;
.woocommerce-list__item {
> .woocommerce-list__item-inner {
padding: $gap-large;
.woocommerce-list__item-title {
color: $gray-900;
font-weight: 700;
font-size: 14px;
line-height: 18px;
}
.woocommerce-list__item-content {
color: $gray-700;
font-size: 13px;
line-height: 16px;
}
.woocommerce-list__item-after {
margin-left: $gap-large;
}
.woocommerce-list__item-before {
img {
width: 36px;
}
}
}
}
}
.components-card__footer {
padding: $gap $gap-large;
}
}
.connect-account__apms-notice {
.components-card__body {
padding: 0;
}
.components-notice {
margin: 0;
padding: 0;
background-color: #f0f6fc;
.components-notice__content {
margin: 0;
padding: $gap $gap-large;
display: flex;
align-items: center;
svg {
margin-right: $gap;
height: 16px;
}
}
}
}
}
.banner-heading-copy {

View File

@ -0,0 +1,4 @@
Significance: minor
Type: update
Additional payment methods on new WCPay promotion page (payment-welcome)