woocommerce/plugins/woocommerce-admin/client/subscriptions/index.tsx

307 lines
7.3 KiB
TypeScript
Raw Normal View History

2022-04-26 05:22:01 +00:00
/**
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import {
createInterpolateElement,
useEffect,
useState,
} from '@wordpress/element';
import { Button, Card, CardBody, Notice } from '@wordpress/components';
import { PLUGINS_STORE_NAME, OPTIONS_STORE_NAME } from '@woocommerce/data';
2022-04-26 05:37:32 +00:00
import { useDispatch } from '@wordpress/data';
2022-04-27 00:18:11 +00:00
import { recordEvent } from '@woocommerce/tracks';
2022-04-26 05:22:01 +00:00
/**
* Internal dependencies
*/
import Visa from './cards/visa.js';
import MasterCard from './cards/mastercard.js';
import Amex from './cards/amex.js';
import DinersClub from './cards/diners.js';
import Discover from './cards/discover.js';
import JCB from './cards/jcb.js';
import UnionPay from './cards/unionpay.js';
2022-04-26 05:22:01 +00:00
import './style.scss';
2022-04-29 05:05:15 +00:00
declare global {
interface Window {
wcWcpaySubscriptions: {
newSubscriptionProductUrl: string;
onboardingUrl: string;
noThanksUrl: string;
dismissOptionKey: string;
2022-05-11 05:37:14 +00:00
experimentAssignment: 'A' | 'B';
2022-04-29 05:05:15 +00:00
};
}
}
const {
newSubscriptionProductUrl,
onboardingUrl,
noThanksUrl,
dismissOptionKey,
2022-05-11 05:37:14 +00:00
experimentAssignment,
2022-04-29 05:05:15 +00:00
} = window.wcWcpaySubscriptions;
type setHasErrorFunction = React.Dispatch< React.SetStateAction< boolean > >;
const ErrorNotice = () => {
return (
<Notice
className="wcpay-empty-subscriptions__error"
status="error"
isDismissible={ false }
>
{ createInterpolateElement(
__(
'Installing WooCommerce Payments failed. To continue with WooCommerce Payments built-in subscriptions functionality, please install <a>WooCommerce Payments</a> manually.',
'woocommerce'
),
{
a: (
// eslint-disable-next-line jsx-a11y/anchor-has-content
<a
href="https://wordpress.org/plugins/woocommerce-payments/"
target="_blank"
rel="noreferrer"
/>
),
}
) }
</Notice>
);
};
const NoThanksButton = () => {
const [ isNoThanksClicked, setIsNoThanksClicked ] = useState( false );
const { updateOptions } = useDispatch( OPTIONS_STORE_NAME );
return (
<Button
isBusy={ isNoThanksClicked }
isSecondary
onClick={ () => {
setIsNoThanksClicked( true );
recordEvent(
'wccore_subscriptions_empty_state_no_thanks_click',
{}
);
updateOptions( {
[ dismissOptionKey ]: 'yes',
// @ts-expect-error updateOptions returns a Promise, but it is not typed in source.
} ).then( () => {
window.location.href = noThanksUrl;
} );
} }
>
{ __( 'No thanks', 'woocommerce' ) }
</Button>
);
};
type GetStartedButtonProps = {
setHasError: setHasErrorFunction;
};
2022-04-26 05:22:01 +00:00
const GetStartedButton: React.FC< GetStartedButtonProps > = ( {
setHasError,
} ) => {
2022-04-26 05:22:01 +00:00
const [ isGettingStarted, setIsGettingStarted ] = useState( false );
2022-04-26 05:37:32 +00:00
const { installAndActivatePlugins } = useDispatch( PLUGINS_STORE_NAME );
2022-04-26 05:22:01 +00:00
return (
<Button
disabled={ isGettingStarted }
isBusy={ isGettingStarted }
isPrimary
onClick={ () => {
setIsGettingStarted( true );
recordEvent(
'wccore_subscriptions_empty_state_get_started_click',
{}
);
installAndActivatePlugins( [ 'woocommerce-payments' ] )
.then( () => {
2022-05-11 05:37:14 +00:00
window.location.href =
experimentAssignment === 'A'
? newSubscriptionProductUrl
: onboardingUrl;
} )
.catch( () => {
recordEvent(
'wccore_subscriptions_empty_state_get_started_error'
);
setIsGettingStarted( false );
setHasError( true );
} );
} }
>
{ __( 'Get started', 'woocommerce' ) }
</Button>
2022-04-26 05:22:01 +00:00
);
};
const StepNumber: React.FC = ( { children } ) => (
<span className="wcpay-empty-subscriptions-page-step-number">
{ children }
</span>
);
const TermsOfService = () => (
<span className="wcpay-empty-subscriptions-page-terms-of-service">
{ createInterpolateElement(
__(
'By clicking “Get started”, the WooCommerce Payments plugin will be installed and you agree to the <a>Terms of Service</a>',
'woocommerce'
),
{
a: (
// eslint-disable-next-line jsx-a11y/anchor-has-content
<a
href="https://wordpress.com/tos/"
target="_blank"
rel="noreferrer"
/>
),
}
) }
</span>
);
type MainContentProps = {
setHasError: setHasErrorFunction;
};
const MainContent: React.FC< MainContentProps > = ( { setHasError } ) => {
return (
<>
<h2>
{ __( 'Start selling subscriptions today', 'woocommerce' ) }
</h2>
<p>
{ __(
2022-05-09 00:47:06 +00:00
'With WooCommerce Payments, you can sell subscriptions with no setup costs or monthly fees. Create subscription products, track recurring revenue, and manage subscribers directly from your stores dashboard.',
'woocommerce'
) }
<br />
<a
href="https://woocommerce.com/document/payments/subscriptions/"
target="_blank"
rel="noreferrer"
>
{ __( 'Learn more', 'woocommerce' ) }
</a>
</p>
<h3>{ __( 'Accepted payment methods', 'woocommerce' ) }</h3>
<div className="wcpay-empty-subscriptions-page-payment-methods">
<Visa />
<MasterCard />
<Amex />
<DinersClub />
<Discover />
<UnionPay />
<JCB />
</div>
<hr />
<p className="subscriptions__action">
<TermsOfService />
</p>
<div className="wcpay-empty-subscriptions__button_container">
<GetStartedButton setHasError={ setHasError } />
<NoThanksButton />
</div>
</>
);
};
const OnboardingSteps = () => (
<>
<h2>
{ __(
'Youre only steps away from selling subscriptions',
'woocommerce'
) }
</h2>
<div className="subscriptions-page-onboarding-steps">
<div className="subscriptions-page-onboarding-steps-item">
<StepNumber>1</StepNumber>
<h3>
{ __( 'Create and connect your account', 'woocommerce' ) }
</h3>
<p>
{ __(
'To ensure safe and secure transactions, a WordPress.com account is required.',
'woocommerce'
) }
</p>
</div>
<div className="subscriptions-page-onboarding-steps-item">
<StepNumber>2</StepNumber>
<h3>
{ __( 'Provide a few business details', 'woocommerce' ) }
</h3>
<p>
{ __(
'Next well ask you to verify your business and payment details to enable deposits.',
'woocommerce'
) }
</p>
</div>
<div className="subscriptions-page-onboarding-steps-item">
<StepNumber>3</StepNumber>
<h3>{ __( 'Create subscriptions', 'woocommerce' ) }</h3>
<p>
{ __(
'Finally, publish subscription products to offer on your store.',
'woocommerce'
) }
</p>
</div>
</div>
</>
);
const SubscriptionsPage = () => {
const [ hasError, setHasError ] = useState( false );
useEffect( () => {
2022-05-11 05:37:14 +00:00
// TODO: Remove this.
console.log(
experimentAssignment === 'A'
? 'Treatment A: Create a subscription product then WCPay onboarding.'
: 'Treatment B: WCPay onboarding then create a subscription product.'
);
recordEvent( 'wccore_subscriptions_empty_state_view' );
}, [] );
return (
<>
{ hasError && <ErrorNotice /> }
<div className="subscriptions-page">
<div className="subscriptions">
<Card className="subscriptions__card">
<CardBody>
<div className="content">
<MainContent setHasError={ setHasError } />
</div>
</CardBody>
</Card>
<Card className="subscriptions__steps">
<CardBody>
<OnboardingSteps />
</CardBody>
</Card>
</div>
</div>
</>
);
};
2022-04-26 05:22:01 +00:00
export default SubscriptionsPage;