mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-07 19:54:15 +08:00
Merge pull request #2898 from woocommerce/PCP-3914-finish-production-login-logic
Add all options to the ISU login logic (3914)
This commit is contained in:
commit
4d2c9fce10
39 changed files with 1427 additions and 332 deletions
|
@ -0,0 +1,68 @@
|
|||
import {
|
||||
Children,
|
||||
isValidElement,
|
||||
cloneElement,
|
||||
useMemo,
|
||||
createContext,
|
||||
useContext,
|
||||
} from '@wordpress/element';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { CommonHooks } from '../../data';
|
||||
import SpinnerOverlay from './SpinnerOverlay';
|
||||
|
||||
// Create context to track the busy state across nested wrappers
|
||||
const BusyContext = createContext( false );
|
||||
|
||||
/**
|
||||
* Wraps interactive child elements and modifies their behavior based on the global `isBusy` state.
|
||||
* Allows custom processing of child props via the `onBusy` callback.
|
||||
*
|
||||
* @param {Object} props - Component properties.
|
||||
* @param {Children} props.children - Child components to wrap.
|
||||
* @param {boolean} props.enabled - Enables or disables the busy-state logic.
|
||||
* @param {boolean} props.busySpinner - Allows disabling the spinner in busy-state.
|
||||
* @param {string} props.className - Additional class names for the wrapper.
|
||||
* @param {Function} props.onBusy - Callback to process child props when busy.
|
||||
*/
|
||||
const BusyStateWrapper = ( {
|
||||
children,
|
||||
enabled = true,
|
||||
busySpinner = true,
|
||||
className = '',
|
||||
onBusy = () => ( { disabled: true } ),
|
||||
} ) => {
|
||||
const { isBusy } = CommonHooks.useBusyState();
|
||||
const hasBusyParent = useContext( BusyContext );
|
||||
|
||||
const isBusyComponent = isBusy && enabled;
|
||||
const showSpinner = busySpinner && isBusyComponent && ! hasBusyParent;
|
||||
|
||||
const wrapperClassName = classNames( 'ppcp-r-busy-wrapper', className, {
|
||||
'ppcp--is-loading': isBusyComponent,
|
||||
} );
|
||||
|
||||
const memoizedChildren = useMemo(
|
||||
() =>
|
||||
Children.map( children, ( child ) =>
|
||||
isValidElement( child )
|
||||
? cloneElement(
|
||||
child,
|
||||
isBusyComponent ? onBusy( child.props ) : {}
|
||||
)
|
||||
: child
|
||||
),
|
||||
[ children, isBusyComponent, onBusy ]
|
||||
);
|
||||
|
||||
return (
|
||||
<BusyContext.Provider value={ isBusyComponent }>
|
||||
<div className={ wrapperClassName }>
|
||||
{ showSpinner && <SpinnerOverlay /> }
|
||||
{ memoizedChildren }
|
||||
</div>
|
||||
</BusyContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export default BusyStateWrapper;
|
|
@ -0,0 +1 @@
|
|||
export { default as openSignup } from './Icons/open-signup';
|
|
@ -0,0 +1,12 @@
|
|||
/**
|
||||
* WordPress dependencies
|
||||
*/
|
||||
import { SVG, Path } from '@wordpress/primitives';
|
||||
|
||||
const openSignup = (
|
||||
<SVG xmlns="http://www.w3.org/2000/svg" viewBox="0 0 25 24">
|
||||
<Path d="M12.4999 12.75V18.75C12.4999 18.9489 12.4209 19.1397 12.2803 19.2803C12.1396 19.421 11.9488 19.5 11.7499 19.5C11.551 19.5 11.3603 19.421 11.2196 19.2803C11.0789 19.1397 10.9999 18.9489 10.9999 18.75V14.5613L4.78055 20.7806C4.71087 20.8503 4.62815 20.9056 4.5371 20.9433C4.44606 20.981 4.34847 21.0004 4.24993 21.0004C4.15138 21.0004 4.0538 20.981 3.96276 20.9433C3.87171 20.9056 3.78899 20.8503 3.7193 20.7806C3.64962 20.7109 3.59435 20.6282 3.55663 20.5372C3.51892 20.4461 3.49951 20.3485 3.49951 20.25C3.49951 20.1515 3.51892 20.0539 3.55663 19.9628C3.59435 19.8718 3.64962 19.7891 3.7193 19.7194L9.93868 13.5H5.74993C5.55102 13.5 5.36025 13.421 5.2196 13.2803C5.07895 13.1397 4.99993 12.9489 4.99993 12.75C4.99993 12.5511 5.07895 12.3603 5.2196 12.2197C5.36025 12.079 5.55102 12 5.74993 12H11.7499C11.9488 12 12.1396 12.079 12.2803 12.2197C12.4209 12.3603 12.4999 12.5511 12.4999 12.75ZM19.9999 3H7.99993C7.6021 3 7.22057 3.15804 6.93927 3.43934C6.65796 3.72064 6.49993 4.10218 6.49993 4.5V9C6.49993 9.19891 6.57895 9.38968 6.7196 9.53033C6.86025 9.67098 7.05102 9.75 7.24993 9.75C7.44884 9.75 7.63961 9.67098 7.78026 9.53033C7.92091 9.38968 7.99993 9.19891 7.99993 9V4.5H19.9999V16.5H15.4999C15.301 16.5 15.1103 16.579 14.9696 16.7197C14.8289 16.8603 14.7499 17.0511 14.7499 17.25C14.7499 17.4489 14.8289 17.6397 14.9696 17.7803C15.1103 17.921 15.301 18 15.4999 18H19.9999C20.3978 18 20.7793 17.842 21.0606 17.5607C21.3419 17.2794 21.4999 16.8978 21.4999 16.5V4.5C21.4999 4.10218 21.3419 3.72064 21.0606 3.43934C20.7793 3.15804 20.3978 3 19.9999 3Z" />
|
||||
</SVG>
|
||||
);
|
||||
|
||||
export default openSignup;
|
|
@ -1,23 +1,17 @@
|
|||
import { ToggleControl } from '@wordpress/components';
|
||||
import { useRef } from '@wordpress/element';
|
||||
|
||||
import SpinnerOverlay from './SpinnerOverlay';
|
||||
|
||||
const SettingsToggleBlock = ( {
|
||||
isToggled,
|
||||
setToggled,
|
||||
isLoading = false,
|
||||
disabled = false,
|
||||
...props
|
||||
} ) => {
|
||||
const toggleRef = useRef( null );
|
||||
const blockClasses = [ 'ppcp-r-toggle-block' ];
|
||||
|
||||
if ( isLoading ) {
|
||||
blockClasses.push( 'ppcp--is-loading' );
|
||||
}
|
||||
|
||||
const handleLabelClick = () => {
|
||||
if ( ! toggleRef.current || isLoading ) {
|
||||
if ( ! toggleRef.current || disabled ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -52,13 +46,12 @@ const SettingsToggleBlock = ( {
|
|||
ref={ toggleRef }
|
||||
checked={ isToggled }
|
||||
onChange={ ( newState ) => setToggled( newState ) }
|
||||
disabled={ isLoading }
|
||||
disabled={ disabled }
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{ props.children && isToggled && (
|
||||
<div className="ppcp-r-toggle-block__toggled-content">
|
||||
{ isLoading && <SpinnerOverlay /> }
|
||||
{ props.children }
|
||||
</div>
|
||||
) }
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
import { Spinner } from '@wordpress/components';
|
||||
|
||||
const SpinnerOverlay = () => {
|
||||
const SpinnerOverlay = ( { message = '' } ) => {
|
||||
return (
|
||||
<div className="ppcp-r-spinner-overlay">
|
||||
{ message && (
|
||||
<span className="ppcp-r-spinner-overlay__message">
|
||||
{ message }
|
||||
</span>
|
||||
) }
|
||||
<Spinner />
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,96 +1,118 @@
|
|||
import { __, sprintf } from '@wordpress/i18n';
|
||||
import { Button, TextControl } from '@wordpress/components';
|
||||
import { useRef, useMemo } from '@wordpress/element';
|
||||
import { useDispatch } from '@wordpress/data';
|
||||
import { store as noticesStore } from '@wordpress/notices';
|
||||
import {
|
||||
useRef,
|
||||
useState,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useCallback,
|
||||
} from '@wordpress/element';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import SettingsToggleBlock from '../../../ReusableComponents/SettingsToggleBlock';
|
||||
import Separator from '../../../ReusableComponents/Separator';
|
||||
import DataStoreControl from '../../../ReusableComponents/DataStoreControl';
|
||||
import { CommonHooks } from '../../../../data';
|
||||
import { openPopup } from '../../../../utils/window';
|
||||
import {
|
||||
useSandboxConnection,
|
||||
useManualConnection,
|
||||
} from '../../../../hooks/useHandleConnections';
|
||||
|
||||
import ConnectionButton from './ConnectionButton';
|
||||
import BusyStateWrapper from '../../../ReusableComponents/BusyStateWrapper';
|
||||
|
||||
const FORM_ERRORS = {
|
||||
noClientId: __(
|
||||
'Please enter your Client ID',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
noClientSecret: __(
|
||||
'Please enter your Secret Key',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
invalidClientId: __(
|
||||
'Please enter a valid Client ID',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
};
|
||||
|
||||
const AdvancedOptionsForm = () => {
|
||||
const [ clientValid, setClientValid ] = useState( false );
|
||||
const [ secretValid, setSecretValid ] = useState( false );
|
||||
|
||||
const AdvancedOptionsForm = ( { setCompleted } ) => {
|
||||
const { isBusy } = CommonHooks.useBusyState();
|
||||
const { isSandboxMode, setSandboxMode, connectViaSandbox } =
|
||||
CommonHooks.useSandbox();
|
||||
const { isSandboxMode, setSandboxMode } = useSandboxConnection();
|
||||
const {
|
||||
handleConnectViaIdAndSecret,
|
||||
isManualConnectionMode,
|
||||
setManualConnectionMode,
|
||||
clientId,
|
||||
setClientId,
|
||||
clientSecret,
|
||||
setClientSecret,
|
||||
connectViaIdAndSecret,
|
||||
} = CommonHooks.useManualConnection();
|
||||
} = useManualConnection();
|
||||
|
||||
const { createSuccessNotice, createErrorNotice } =
|
||||
useDispatch( noticesStore );
|
||||
const refClientId = useRef( null );
|
||||
const refClientSecret = useRef( null );
|
||||
|
||||
const isValidClientId = useMemo( () => {
|
||||
return /^A[\w-]{79}$/.test( clientId );
|
||||
}, [ clientId ] );
|
||||
const validateManualConnectionForm = useCallback( () => {
|
||||
const checks = [
|
||||
{
|
||||
ref: refClientId,
|
||||
valid: () => clientId,
|
||||
errorMessage: FORM_ERRORS.noClientId,
|
||||
},
|
||||
{
|
||||
ref: refClientId,
|
||||
valid: () => clientValid,
|
||||
errorMessage: FORM_ERRORS.invalidClientId,
|
||||
},
|
||||
{
|
||||
ref: refClientSecret,
|
||||
valid: () => clientSecret && secretValid,
|
||||
errorMessage: FORM_ERRORS.noClientSecret,
|
||||
},
|
||||
];
|
||||
|
||||
const isFormValid = useMemo( () => {
|
||||
return isValidClientId && clientId && clientSecret;
|
||||
}, [ isValidClientId, clientId, clientSecret ] );
|
||||
for ( const { ref, valid, errorMessage } of checks ) {
|
||||
if ( valid() ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const handleServerError = ( res, genericMessage ) => {
|
||||
console.error( 'Connection error', res );
|
||||
createErrorNotice( res?.message ?? genericMessage );
|
||||
};
|
||||
|
||||
const handleServerSuccess = () => {
|
||||
createSuccessNotice(
|
||||
__( 'Connected to PayPal', 'woocommerce-paypal-payments' )
|
||||
);
|
||||
setCompleted( true );
|
||||
};
|
||||
|
||||
const handleSandboxConnect = async () => {
|
||||
const res = await connectViaSandbox();
|
||||
|
||||
if ( ! res.success || ! res.data ) {
|
||||
handleServerError(
|
||||
res,
|
||||
__(
|
||||
'Could not generate a Sandbox login link.',
|
||||
'woocommerce-paypal-payments'
|
||||
)
|
||||
);
|
||||
return;
|
||||
ref?.current?.focus();
|
||||
throw new Error( errorMessage );
|
||||
}
|
||||
}, [ clientId, clientSecret, clientValid, secretValid ] );
|
||||
|
||||
const connectionUrl = res.data;
|
||||
const popup = openPopup( connectionUrl );
|
||||
const handleManualConnect = useCallback(
|
||||
() =>
|
||||
handleConnectViaIdAndSecret( {
|
||||
validation: validateManualConnectionForm,
|
||||
} ),
|
||||
[ handleConnectViaIdAndSecret, validateManualConnectionForm ]
|
||||
);
|
||||
|
||||
if ( ! popup ) {
|
||||
createErrorNotice(
|
||||
__(
|
||||
'Popup blocked. Please allow popups for this site to connect to PayPal.',
|
||||
'woocommerce-paypal-payments'
|
||||
)
|
||||
);
|
||||
}
|
||||
};
|
||||
useEffect( () => {
|
||||
setClientValid( ! clientId || /^A[\w-]{79}$/.test( clientId ) );
|
||||
setSecretValid( clientSecret && clientSecret.length > 0 );
|
||||
}, [ clientId, clientSecret ] );
|
||||
|
||||
const handleManualConnect = async () => {
|
||||
const res = await connectViaIdAndSecret();
|
||||
const clientIdLabel = useMemo(
|
||||
() =>
|
||||
isSandboxMode
|
||||
? __( 'Sandbox Client ID', 'woocommerce-paypal-payments' )
|
||||
: __( 'Live Client ID', 'woocommerce-paypal-payments' ),
|
||||
[ isSandboxMode ]
|
||||
);
|
||||
|
||||
if ( res.success ) {
|
||||
handleServerSuccess();
|
||||
} else {
|
||||
handleServerError(
|
||||
res,
|
||||
__(
|
||||
'Could not connect to PayPal. Please make sure your Client ID and Secret Key are correct.',
|
||||
'woocommerce-paypal-payments'
|
||||
)
|
||||
);
|
||||
}
|
||||
};
|
||||
const secretKeyLabel = useMemo(
|
||||
() =>
|
||||
isSandboxMode
|
||||
? __( 'Sandbox Secret Key', 'woocommerce-paypal-payments' )
|
||||
: __( 'Live Secret Key', 'woocommerce-paypal-payments' ),
|
||||
[ isSandboxMode ]
|
||||
);
|
||||
|
||||
const advancedUsersDescription = sprintf(
|
||||
// translators: %s: Link to PayPal REST application guide
|
||||
|
@ -103,88 +125,84 @@ const AdvancedOptionsForm = ( { setCompleted } ) => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<SettingsToggleBlock
|
||||
label={ __(
|
||||
'Enable Sandbox Mode',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
description={ __(
|
||||
'Activate Sandbox mode to safely test PayPal with sample data. Once your store is ready to go live, you can easily switch to your production account.',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
isToggled={ !! isSandboxMode }
|
||||
setToggled={ setSandboxMode }
|
||||
isLoading={ isBusy }
|
||||
>
|
||||
<Button onClick={ handleSandboxConnect } variant="secondary">
|
||||
{ __( 'Connect Account', 'woocommerce-paypal-payments' ) }
|
||||
</Button>
|
||||
</SettingsToggleBlock>
|
||||
<Separator withLine={ false } />
|
||||
<SettingsToggleBlock
|
||||
label={
|
||||
__( 'Manually Connect', 'woocommerce-paypal-payments' ) +
|
||||
( isBusy ? ' ...' : '' )
|
||||
}
|
||||
description={ advancedUsersDescription }
|
||||
isToggled={ !! isManualConnectionMode }
|
||||
setToggled={ setManualConnectionMode }
|
||||
isLoading={ isBusy }
|
||||
>
|
||||
<DataStoreControl
|
||||
control={ TextControl }
|
||||
ref={ refClientId }
|
||||
label={
|
||||
isSandboxMode
|
||||
? __(
|
||||
'Sandbox Client ID',
|
||||
'woocommerce-paypal-payments'
|
||||
)
|
||||
: __(
|
||||
'Live Client ID',
|
||||
'woocommerce-paypal-payments'
|
||||
)
|
||||
}
|
||||
value={ clientId }
|
||||
onChange={ setClientId }
|
||||
className={
|
||||
clientId && ! isValidClientId ? 'has-error' : ''
|
||||
}
|
||||
/>
|
||||
{ clientId && ! isValidClientId && (
|
||||
<p className="client-id-error">
|
||||
{ __(
|
||||
'Please enter a valid Client ID',
|
||||
<BusyStateWrapper>
|
||||
<SettingsToggleBlock
|
||||
label={ __(
|
||||
'Enable Sandbox Mode',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
description={ __(
|
||||
'Activate Sandbox mode to safely test PayPal with sample data. Once your store is ready to go live, you can easily switch to your production account.',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
isToggled={ !! isSandboxMode }
|
||||
setToggled={ setSandboxMode }
|
||||
>
|
||||
<ConnectionButton
|
||||
title={ __(
|
||||
'Connect Account',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
</p>
|
||||
) }
|
||||
<DataStoreControl
|
||||
control={ TextControl }
|
||||
ref={ refClientSecret }
|
||||
label={
|
||||
isSandboxMode
|
||||
? __(
|
||||
'Sandbox Secret Key',
|
||||
'woocommerce-paypal-payments'
|
||||
)
|
||||
: __(
|
||||
'Live Secret Key',
|
||||
'woocommerce-paypal-payments'
|
||||
)
|
||||
}
|
||||
value={ clientSecret }
|
||||
onChange={ setClientSecret }
|
||||
type="password"
|
||||
/>
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={ handleManualConnect }
|
||||
disabled={ ! isFormValid }
|
||||
showIcon={ false }
|
||||
variant="secondary"
|
||||
className="small-button"
|
||||
isSandbox={
|
||||
true /* This button always connects to sandbox */
|
||||
}
|
||||
/>
|
||||
</SettingsToggleBlock>
|
||||
</BusyStateWrapper>
|
||||
<Separator withLine={ false } />
|
||||
<BusyStateWrapper
|
||||
onBusy={ ( props ) => ( {
|
||||
disabled: true,
|
||||
label: props.label + ' ...',
|
||||
} ) }
|
||||
>
|
||||
<SettingsToggleBlock
|
||||
label={ __(
|
||||
'Manually Connect',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
description={ advancedUsersDescription }
|
||||
isToggled={ !! isManualConnectionMode }
|
||||
setToggled={ setManualConnectionMode }
|
||||
>
|
||||
{ __( 'Connect Account', 'woocommerce-paypal-payments' ) }
|
||||
</Button>
|
||||
</SettingsToggleBlock>
|
||||
<DataStoreControl
|
||||
control={ TextControl }
|
||||
ref={ refClientId }
|
||||
label={ clientIdLabel }
|
||||
value={ clientId }
|
||||
onChange={ setClientId }
|
||||
className={ classNames( {
|
||||
'has-error': ! clientValid,
|
||||
} ) }
|
||||
/>
|
||||
{ clientValid || (
|
||||
<p className="client-id-error">
|
||||
{ FORM_ERRORS.invalidClientId }
|
||||
</p>
|
||||
) }
|
||||
<DataStoreControl
|
||||
control={ TextControl }
|
||||
ref={ refClientSecret }
|
||||
label={ secretKeyLabel }
|
||||
value={ clientSecret }
|
||||
onChange={ setClientSecret }
|
||||
type="password"
|
||||
/>
|
||||
<Button
|
||||
variant="secondary"
|
||||
className="small-button"
|
||||
onClick={ handleManualConnect }
|
||||
>
|
||||
{ __(
|
||||
'Connect Account',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
</Button>
|
||||
</SettingsToggleBlock>
|
||||
</BusyStateWrapper>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
import { Button } from '@wordpress/components';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { CommonHooks } from '../../../../data';
|
||||
import { openSignup } from '../../../ReusableComponents/Icons';
|
||||
import {
|
||||
useProductionConnection,
|
||||
useSandboxConnection,
|
||||
} from '../../../../hooks/useHandleConnections';
|
||||
import BusyStateWrapper from '../../../ReusableComponents/BusyStateWrapper';
|
||||
|
||||
const ConnectionButton = ( {
|
||||
title,
|
||||
isSandbox = false,
|
||||
variant = 'primary',
|
||||
showIcon = true,
|
||||
className = '',
|
||||
} ) => {
|
||||
const { handleSandboxConnect } = useSandboxConnection();
|
||||
const { handleProductionConnect } = useProductionConnection();
|
||||
const buttonClassName = classNames( 'ppcp-r-connection-button', className, {
|
||||
'sandbox-mode': isSandbox,
|
||||
'live-mode': ! isSandbox,
|
||||
} );
|
||||
|
||||
const handleConnectClick = async () => {
|
||||
if ( isSandbox ) {
|
||||
await handleSandboxConnect();
|
||||
} else {
|
||||
await handleProductionConnect();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<BusyStateWrapper>
|
||||
<Button
|
||||
className={ buttonClassName }
|
||||
variant={ variant }
|
||||
icon={ showIcon ? openSignup : null }
|
||||
onClick={ handleConnectClick }
|
||||
>
|
||||
<span className="button-title">{ title }</span>
|
||||
</Button>
|
||||
</BusyStateWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default ConnectionButton;
|
|
@ -6,6 +6,7 @@ import classNames from 'classnames';
|
|||
|
||||
import { OnboardingHooks } from '../../../../data';
|
||||
import useIsScrolled from '../../../../hooks/useIsScrolled';
|
||||
import BusyStateWrapper from '../../../ReusableComponents/BusyStateWrapper';
|
||||
|
||||
const Navigation = ( { stepDetails, onNext, onPrev, onExit } ) => {
|
||||
const { title, isFirst, percentage, showNext, canProceed } = stepDetails;
|
||||
|
@ -20,7 +21,11 @@ const Navigation = ( { stepDetails, onNext, onPrev, onExit } ) => {
|
|||
return (
|
||||
<div className={ className }>
|
||||
<div className="ppcp-r-navigation">
|
||||
<div className="ppcp-r-navigation--left">
|
||||
<BusyStateWrapper
|
||||
className="ppcp-r-navigation--left"
|
||||
busySpinner={ false }
|
||||
enabled={ ! isFirst }
|
||||
>
|
||||
<Button
|
||||
variant="link"
|
||||
onClick={ isFirst ? onExit : onPrev }
|
||||
|
@ -31,7 +36,7 @@ const Navigation = ( { stepDetails, onNext, onPrev, onExit } ) => {
|
|||
{ title }
|
||||
</span>
|
||||
</Button>
|
||||
</div>
|
||||
</BusyStateWrapper>
|
||||
{ ! isFirst &&
|
||||
NextButton( { showNext, isDisabled, onNext, onExit } ) }
|
||||
<ProgressBar percent={ percentage } />
|
||||
|
@ -42,7 +47,10 @@ const Navigation = ( { stepDetails, onNext, onPrev, onExit } ) => {
|
|||
|
||||
const NextButton = ( { showNext, isDisabled, onNext, onExit } ) => {
|
||||
return (
|
||||
<div className="ppcp-r-navigation--right">
|
||||
<BusyStateWrapper
|
||||
className="ppcp-r-navigation--right"
|
||||
busySpinner={ false }
|
||||
>
|
||||
<Button variant="link" onClick={ onExit }>
|
||||
{ __( 'Save and exit', 'woocommerce-paypal-payments' ) }
|
||||
</Button>
|
||||
|
@ -55,7 +63,7 @@ const NextButton = ( { showNext, isDisabled, onNext, onExit } ) => {
|
|||
{ __( 'Continue', 'woocommerce-paypal-payments' ) }
|
||||
</Button>
|
||||
) }
|
||||
</div>
|
||||
</BusyStateWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -6,8 +6,7 @@ import Navigation from './Components/Navigation';
|
|||
import { useEffect } from '@wordpress/element';
|
||||
|
||||
const Onboarding = () => {
|
||||
const { step, setStep, setCompleted, flags } = OnboardingHooks.useSteps();
|
||||
|
||||
const { step, setStep, flags } = OnboardingHooks.useSteps();
|
||||
const Steps = getSteps( flags );
|
||||
const currentStep = getCurrentStep( step, Steps );
|
||||
|
||||
|
@ -45,7 +44,6 @@ const Onboarding = () => {
|
|||
<currentStep.StepComponent
|
||||
setStep={ setStep }
|
||||
currentStep={ step }
|
||||
setCompleted={ setCompleted }
|
||||
stepperOrder={ Steps }
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -1,28 +1,9 @@
|
|||
import { __ } from '@wordpress/i18n';
|
||||
import { Button, Icon } from '@wordpress/components';
|
||||
|
||||
import OnboardingHeader from '../../ReusableComponents/OnboardingHeader';
|
||||
import ConnectionButton from './Components/ConnectionButton';
|
||||
|
||||
const StepCompleteSetup = ( { setCompleted } ) => {
|
||||
const ButtonIcon = () => (
|
||||
<Icon
|
||||
icon={ () => (
|
||||
<svg
|
||||
width="25"
|
||||
height="24"
|
||||
viewBox="0 0 25 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M12.4999 12.75V18.75C12.4999 18.9489 12.4209 19.1397 12.2803 19.2803C12.1396 19.421 11.9488 19.5 11.7499 19.5C11.551 19.5 11.3603 19.421 11.2196 19.2803C11.0789 19.1397 10.9999 18.9489 10.9999 18.75V14.5613L4.78055 20.7806C4.71087 20.8503 4.62815 20.9056 4.5371 20.9433C4.44606 20.981 4.34847 21.0004 4.24993 21.0004C4.15138 21.0004 4.0538 20.981 3.96276 20.9433C3.87171 20.9056 3.78899 20.8503 3.7193 20.7806C3.64962 20.7109 3.59435 20.6282 3.55663 20.5372C3.51892 20.4461 3.49951 20.3485 3.49951 20.25C3.49951 20.1515 3.51892 20.0539 3.55663 19.9628C3.59435 19.8718 3.64962 19.7891 3.7193 19.7194L9.93868 13.5H5.74993C5.55102 13.5 5.36025 13.421 5.2196 13.2803C5.07895 13.1397 4.99993 12.9489 4.99993 12.75C4.99993 12.5511 5.07895 12.3603 5.2196 12.2197C5.36025 12.079 5.55102 12 5.74993 12H11.7499C11.9488 12 12.1396 12.079 12.2803 12.2197C12.4209 12.3603 12.4999 12.5511 12.4999 12.75ZM19.9999 3H7.99993C7.6021 3 7.22057 3.15804 6.93927 3.43934C6.65796 3.72064 6.49993 4.10218 6.49993 4.5V9C6.49993 9.19891 6.57895 9.38968 6.7196 9.53033C6.86025 9.67098 7.05102 9.75 7.24993 9.75C7.44884 9.75 7.63961 9.67098 7.78026 9.53033C7.92091 9.38968 7.99993 9.19891 7.99993 9V4.5H19.9999V16.5H15.4999C15.301 16.5 15.1103 16.579 14.9696 16.7197C14.8289 16.8603 14.7499 17.0511 14.7499 17.25C14.7499 17.4489 14.8289 17.6397 14.9696 17.7803C15.1103 17.921 15.301 18 15.4999 18H19.9999C20.3978 18 20.7793 17.842 21.0606 17.5607C21.3419 17.2794 21.4999 16.8978 21.4999 16.5V4.5C21.4999 4.10218 21.3419 3.72064 21.0606 3.43934C20.7793 3.15804 20.3978 3 19.9999 3Z"
|
||||
fill="white"
|
||||
/>
|
||||
</svg>
|
||||
) }
|
||||
/>
|
||||
);
|
||||
|
||||
const StepCompleteSetup = () => {
|
||||
return (
|
||||
<div className="ppcp-r-page-products">
|
||||
<OnboardingHeader
|
||||
|
@ -37,18 +18,12 @@ const StepCompleteSetup = ( { setCompleted } ) => {
|
|||
/>
|
||||
<div className="ppcp-r-inner-container">
|
||||
<div className="ppcp-r-onboarding-header__description">
|
||||
<Button
|
||||
variant="primary"
|
||||
icon={ ButtonIcon }
|
||||
onClick={ () => {
|
||||
setCompleted( true );
|
||||
} }
|
||||
>
|
||||
{ __(
|
||||
<ConnectionButton
|
||||
title={ __(
|
||||
'Connect to PayPal',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
</Button>
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -9,9 +9,11 @@ import AccordionSection from '../../ReusableComponents/AccordionSection';
|
|||
|
||||
import AdvancedOptionsForm from './Components/AdvancedOptionsForm';
|
||||
import { CommonHooks } from '../../../data';
|
||||
import BusyStateWrapper from '../../ReusableComponents/BusyStateWrapper';
|
||||
|
||||
const StepWelcome = ( { setStep, currentStep, setCompleted } ) => {
|
||||
const StepWelcome = ( { setStep, currentStep } ) => {
|
||||
const { storeCountry, storeCurrency } = CommonHooks.useWooSettings();
|
||||
|
||||
return (
|
||||
<div className="ppcp-r-page-welcome">
|
||||
<OnboardingHeader
|
||||
|
@ -33,16 +35,18 @@ const StepWelcome = ( { setStep, currentStep, setCompleted } ) => {
|
|||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
</p>
|
||||
<Button
|
||||
className="ppcp-r-button-activate-paypal"
|
||||
variant="primary"
|
||||
onClick={ () => setStep( currentStep + 1 ) }
|
||||
>
|
||||
{ __(
|
||||
'Activate PayPal Payments',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
</Button>
|
||||
<BusyStateWrapper>
|
||||
<Button
|
||||
className="ppcp-r-button-activate-paypal"
|
||||
variant="primary"
|
||||
onClick={ () => setStep( currentStep + 1 ) }
|
||||
>
|
||||
{ __(
|
||||
'Activate PayPal Payments',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
</Button>
|
||||
</BusyStateWrapper>
|
||||
</div>
|
||||
<Separator className="ppcp-r-page-welcome-mode-separator" />
|
||||
<WelcomeDocs
|
||||
|
@ -61,7 +65,7 @@ const StepWelcome = ( { setStep, currentStep, setCompleted } ) => {
|
|||
className="onboarding-advanced-options"
|
||||
id="advanced-options"
|
||||
>
|
||||
<AdvancedOptionsForm setCompleted={ setCompleted } />
|
||||
<AdvancedOptionsForm />
|
||||
</AccordionSection>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,20 +1,37 @@
|
|||
import { useMemo } from '@wordpress/element';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { OnboardingHooks } from '../../data';
|
||||
import SpinnerOverlay from '../ReusableComponents/SpinnerOverlay';
|
||||
|
||||
import Onboarding from './Onboarding/Onboarding';
|
||||
import SettingsScreen from './SettingsScreen';
|
||||
|
||||
const Settings = () => {
|
||||
const onboardingProgress = OnboardingHooks.useSteps();
|
||||
|
||||
if ( ! onboardingProgress.isReady ) {
|
||||
// TODO: Use better loading state indicator.
|
||||
return <div>Loading...</div>;
|
||||
}
|
||||
const wrapperClass = classNames( 'ppcp-r-app', {
|
||||
loading: ! onboardingProgress.isReady,
|
||||
} );
|
||||
|
||||
if ( ! onboardingProgress.completed ) {
|
||||
return <Onboarding />;
|
||||
}
|
||||
const Content = useMemo( () => {
|
||||
if ( ! onboardingProgress.isReady ) {
|
||||
return (
|
||||
<SpinnerOverlay
|
||||
message={ __( 'Loading…', 'woocommerce-paypal-payments' ) }
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return <SettingsScreen />;
|
||||
if ( ! onboardingProgress.completed ) {
|
||||
return <Onboarding />;
|
||||
}
|
||||
|
||||
return <SettingsScreen />;
|
||||
}, [ onboardingProgress ] );
|
||||
|
||||
return <div className={ wrapperClass }>{ Content }</div>;
|
||||
};
|
||||
|
||||
export default Settings;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue