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

344 lines
8.1 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';
/**
* The available experiment treatments.
*/
enum Treatment {
/**
* Treatment A: Create a subscription product then WCPay onboarding.
*/
A = 'A',
/**
* Treatment B: WCPay onboarding then create a subscription product.
*/
B = 'B',
}
2022-04-29 05:05:15 +00:00
declare global {
interface Window {
wcWcpaySubscriptions: {
newSubscriptionProductUrl: string;
onboardingUrl: string;
noThanksUrl: string;
dismissOptionKey: string;
experimentAssignment: Treatment;
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',
} ).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 === Treatment.A
2022-05-11 05:37:14 +00:00
? 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>
{ experimentAssignment === Treatment.A
2022-05-12 04:46:06 +00:00
? __( 'Create a subscription', 'woocommerce' )
: __(
'Create and connect your account',
'woocommerce'
) }
</h3>
<p>
{ experimentAssignment === Treatment.A
? __(
2022-05-12 04:46:06 +00:00
'Add a name, price and image to your subscription product and then publish it.',
'woocommerce'
)
: __(
'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>
{ experimentAssignment === Treatment.A
2022-05-12 04:46:06 +00:00
? __( 'Create and connect your account', 'woocommerce' )
: __(
'Provide a few business details',
'woocommerce'
) }
</h3>
<p>
{ experimentAssignment === Treatment.A
? __(
2022-05-12 04:46:06 +00:00
'To ensure safe and secure transactions, a WordPress.com account is required.',
'woocommerce'
)
: __(
'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>
{ experimentAssignment === Treatment.A
2022-05-12 04:46:06 +00:00
? __( 'Provide a few business details', 'woocommerce' )
: __( 'Create subscriptions', 'woocommerce' ) }
</h3>
<p>
{ experimentAssignment === Treatment.A
? __(
2022-05-12 04:46:06 +00:00
'Finally, well ask you to verify your business and payment details to enable deposits.',
'woocommerce'
)
: __(
'Finally, publish subscription products to offer on your store.',
'woocommerce'
) }
</p>
</div>
</div>
</>
);
const SubscriptionsPage = () => {
const [ hasError, setHasError ] = useState( false );
useEffect( () => {
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;