mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-04 08:47:23 +08:00
Merge remote-tracking branch 'origin/trunk' into PCP-3816-Create-payment-placeholder-page-in-new-settings-module
# Conflicts: # modules/ppcp-settings/resources/css/style.scss
This commit is contained in:
commit
6b9b024d64
55 changed files with 2943 additions and 1137 deletions
|
@ -15,3 +15,15 @@ $shadow-card: 0 3px 6px 0 rgba(0, 0, 0, 0.15);
|
|||
$shadow-selection-box: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
|
||||
$color-gradient-dark: #001435;
|
||||
$gradient-header: linear-gradient(87.03deg, #003087 -0.49%, #001E51 29.22%, $color-gradient-dark 100%);
|
||||
|
||||
$max-width-onboarding: 1024px;
|
||||
$max-width-onboarding-content: 662px;
|
||||
$max-width-settings: 938px;
|
||||
|
||||
#ppcp-settings-container {
|
||||
--max-width-settings: #{$max-width-settings};
|
||||
--max-width-onboarding: #{$max-width-onboarding};
|
||||
--max-width-onboarding-content: #{$max-width-onboarding-content};
|
||||
|
||||
--max-container-width: var(--max-width-settings);
|
||||
}
|
||||
|
|
|
@ -82,6 +82,10 @@
|
|||
&__checkbox-presentation {
|
||||
@include fake-input-field(2px);
|
||||
}
|
||||
&__additional-content{
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
gap: 16px;
|
||||
|
|
|
@ -1,20 +1,23 @@
|
|||
.ppcp-r {
|
||||
&-container {
|
||||
max-width: var(--max-container-width, none);
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
&-inner-container {
|
||||
width: 652px;
|
||||
max-width: 100%;
|
||||
margin: 0 auto;
|
||||
padding: 0 16px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding: 0 16px 72px;
|
||||
box-sizing: border-box;
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
padding-bottom: 36px;
|
||||
}
|
||||
}
|
||||
|
||||
&-container {
|
||||
max-width: 1024px;
|
||||
margin: 0 auto;
|
||||
|
||||
&--settings {
|
||||
max-width: 938px;
|
||||
}
|
||||
box-shadow: $shadow-card;
|
||||
}
|
||||
|
||||
&-card {
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
.ppcp-r-tabs {
|
||||
--wp-components-color-accent: #{$color-blueberry};
|
||||
--wp-admin-border-width-focus: 3px;
|
||||
|
||||
max-width: var(--max-container-width);
|
||||
margin: 0 auto;
|
||||
transition: max-width 0.2s;
|
||||
|
||||
.components-tab-panel__tabs {
|
||||
box-shadow: 0 -1px 0 0 $color-gray-400 inset;
|
||||
margin-bottom: 48px;
|
||||
gap: 12px;
|
||||
|
||||
.components-button {
|
||||
padding: 16px 20px;
|
||||
|
||||
&.is-active {
|
||||
background-color: #fff4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
@import './onboarding/step-welcome';
|
||||
@import './onboarding/step-business';
|
||||
@import './onboarding/step-products';
|
||||
|
||||
.ppcp-r-tabs.onboarding,
|
||||
.ppcp-r-container--onboarding {
|
||||
--max-container-width: var(--max-width-onboarding);
|
||||
|
||||
.ppcp-r-inner-container {
|
||||
max-width: var(--max-width-onboarding-content);
|
||||
}
|
||||
}
|
|
@ -1,12 +1,4 @@
|
|||
.ppcp-r-page-business {
|
||||
.ppcp-r-inner-container {
|
||||
width: 622px;
|
||||
padding-bottom: 84px;
|
||||
@media screen and (max-width: 480px) {
|
||||
padding-bottom: 42px;
|
||||
}
|
||||
}
|
||||
|
||||
.ppcp-r-payment-method-icons {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
|
|
@ -19,14 +19,6 @@
|
|||
}
|
||||
|
||||
.ppcp-r-page-products {
|
||||
.ppcp-r-inner-container {
|
||||
width: 622px;
|
||||
padding-bottom: 48px;
|
||||
@media screen and (max-width: 480px) {
|
||||
padding-bottom: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.ppcp-r-payment-method-icons {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
|
|
@ -1,11 +1,4 @@
|
|||
.ppcp-r-page-welcome {
|
||||
.ppcp-r-inner-container {
|
||||
padding-bottom: 72px;
|
||||
@media screen and (max-width: 480px) {
|
||||
padding-bottom: 36px;
|
||||
}
|
||||
}
|
||||
|
||||
.ppcp-r-welcome-features {
|
||||
margin: 0 0 32px 0;
|
||||
}
|
||||
|
|
|
@ -11,14 +11,11 @@
|
|||
@import './components/reusable-components/payment-method-icons';
|
||||
@import './components/reusable-components/settings-wrapper';
|
||||
@import './components/reusable-components/select-box';
|
||||
@import './components/reusable-components/tab-navigation';
|
||||
@import './components/reusable-components/navigation';
|
||||
@import './components/reusable-components/tabs';
|
||||
@import './components/reusable-components/fields';
|
||||
@import './components/reusable-components/title-badge';
|
||||
@import './components/reusable-components/payment-method-item';
|
||||
@import './components/screens/onboarding/step-welcome';
|
||||
@import './components/screens/onboarding/step-business';
|
||||
@import './components/screens/onboarding/step-products';
|
||||
@import './components/screens/onboarding';
|
||||
@import './components/screens/dashboard/tab-dashboard';
|
||||
@import './components/screens/dashboard/tab-payment-methods';
|
||||
}
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
export const PAGE_ONBOARDING = 'onboarding';
|
||||
export const PAGE_SETTINGS = 'settings';
|
||||
|
||||
const Container = ( { isCard = true, page, children } ) => {
|
||||
let className = 'ppcp-r-container';
|
||||
|
||||
|
|
|
@ -3,27 +3,35 @@ import { __ } from '@wordpress/i18n';
|
|||
|
||||
const Navigation = ( {
|
||||
setStep,
|
||||
setCompleted,
|
||||
currentStep,
|
||||
stepperOrder,
|
||||
canProceeedCallback = () => true,
|
||||
} ) => {
|
||||
const setNextStep = ( nextStep ) => {
|
||||
let newStep = currentStep + nextStep;
|
||||
if ( newStep > stepperOrder.length - 1 ) {
|
||||
newStep = currentStep;
|
||||
const navigateBy = ( stepDirection ) => {
|
||||
let newStep = currentStep + stepDirection;
|
||||
|
||||
if ( isNaN( newStep ) || newStep < 0 ) {
|
||||
console.warn( 'Invalid next step:', newStep );
|
||||
newStep = 0;
|
||||
}
|
||||
|
||||
if ( newStep >= stepperOrder.length ) {
|
||||
setCompleted( true );
|
||||
} else {
|
||||
setStep( newStep );
|
||||
}
|
||||
setStep( newStep );
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="ppcp-r-navigation">
|
||||
<Button variant="tertiary" onClick={ () => setNextStep( -1 ) }>
|
||||
<Button variant="tertiary" onClick={ () => navigateBy( -1 ) }>
|
||||
{ __( 'Back', 'woocommerce-paypal-payments' ) }
|
||||
</Button>
|
||||
<Button
|
||||
variant="primary"
|
||||
disabled={ ! canProceeedCallback() }
|
||||
onClick={ () => setNextStep( 1 ) }
|
||||
onClick={ () => navigateBy( 1 ) }
|
||||
>
|
||||
{ __( 'Next', 'woocommerce-paypal-payments' ) }
|
||||
</Button>
|
||||
|
|
|
@ -1,56 +1,47 @@
|
|||
import { useCallback, useEffect, useState } from '@wordpress/element';
|
||||
import { TabPanel } from '@wordpress/components';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import TabDashboard from '../Screens/Dashboard/TabDashboard';
|
||||
import TabPaymentMethods from '../Screens/Dashboard/TabPaymentMethods';
|
||||
import TabSettings from '../Screens/Dashboard/TabSettings';
|
||||
import TabStyling from '../Screens/Dashboard/TabStyling';
|
||||
import { getQuery, updateQueryString } from '@woocommerce/navigation';
|
||||
|
||||
const TAB_DASHBOARD = 'TabDashboard';
|
||||
const TAB_PAYMENT_METHODS = 'TabPaymentMethods';
|
||||
const TAB_SETTINGS = 'TabSettings';
|
||||
const TAB_STYLING = 'TabStyling';
|
||||
const TabNavigation = ( { tabs } ) => {
|
||||
const { panel } = getQuery();
|
||||
|
||||
const TabNavigation = () => {
|
||||
const tabComponents = {
|
||||
[ TAB_DASHBOARD ]: TabDashboard,
|
||||
[ TAB_PAYMENT_METHODS ]: TabPaymentMethods,
|
||||
[ TAB_SETTINGS ]: TabSettings,
|
||||
[ TAB_STYLING ]: TabStyling,
|
||||
const isValidTab = ( tabsList, checkTab ) => {
|
||||
return tabsList.some( ( tab ) => tab.name === checkTab );
|
||||
};
|
||||
|
||||
const getValidInitialPanel = () => {
|
||||
if ( ! panel || ! isValidTab( tabs, panel ) ) {
|
||||
return tabs[ 0 ].name;
|
||||
}
|
||||
return panel;
|
||||
};
|
||||
|
||||
const [ activePanel, setActivePanel ] = useState( getValidInitialPanel );
|
||||
|
||||
const updateActivePanel = useCallback(
|
||||
( tabName ) => {
|
||||
if ( isValidTab( tabs, tabName ) ) {
|
||||
setActivePanel( tabName );
|
||||
} else {
|
||||
console.warn( `Invalid tab name: ${ tabName }` );
|
||||
}
|
||||
},
|
||||
[ tabs ]
|
||||
);
|
||||
|
||||
useEffect( () => {
|
||||
updateQueryString( { panel: activePanel }, '/', getQuery() );
|
||||
}, [ activePanel ] );
|
||||
|
||||
return (
|
||||
<TabPanel
|
||||
className="my-tab-panel"
|
||||
activeClass="active-tab"
|
||||
tabs={ [
|
||||
{
|
||||
name: TAB_DASHBOARD,
|
||||
title: __( 'Dashboard', 'woocommerce-paypal-payments' ),
|
||||
className: 'ppcp-r-tab-dashboard',
|
||||
},
|
||||
{
|
||||
name: TAB_PAYMENT_METHODS,
|
||||
title: __(
|
||||
'Payment Methods',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
className: 'ppcp-r-tab-payment-methods',
|
||||
},
|
||||
{
|
||||
name: TAB_SETTINGS,
|
||||
title: __( 'Settings', 'woocommerce-paypal-payments' ),
|
||||
className: 'ppcp-r-tab-settings',
|
||||
},
|
||||
{
|
||||
name: TAB_STYLING,
|
||||
title: __( 'Styling', 'woocommerce-paypal-payments' ),
|
||||
className: 'ppcp-r-tab-styling',
|
||||
},
|
||||
] }
|
||||
className={ `ppcp-r-tabs ${ activePanel }` }
|
||||
initialTabName={ activePanel }
|
||||
onSelect={ updateActivePanel }
|
||||
tabs={ tabs }
|
||||
>
|
||||
{ ( tab ) => {
|
||||
const Component = tabComponents[ tab.name ];
|
||||
return <Component />;
|
||||
return tab.component || <>{ tab.title ?? tab.name }</>;
|
||||
} }
|
||||
</TabPanel>
|
||||
);
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
import TabNavigation from '../../ReusableComponents/TabNavigation';
|
||||
import Container from '../../ReusableComponents/Container';
|
||||
import { PAGE_SETTINGS } from '../../ReusableComponents/Container';
|
||||
|
||||
const Dashboard = () => {
|
||||
return (
|
||||
<Container isCard={ false } page={ PAGE_SETTINGS }>
|
||||
<TabNavigation />
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
||||
export default Dashboard;
|
|
@ -1,44 +1,36 @@
|
|||
import Container, {
|
||||
PAGE_ONBOARDING,
|
||||
} from '../../ReusableComponents/Container.js';
|
||||
import StepWelcome from './StepWelcome.js';
|
||||
import StepBusiness from './StepBusiness.js';
|
||||
import StepProducts from './StepProducts.js';
|
||||
import { useState } from '@wordpress/element';
|
||||
import Container from '../../ReusableComponents/Container';
|
||||
import { useOnboardingStep } from '../../../data';
|
||||
import { getSteps } from './availableSteps';
|
||||
|
||||
const getCurrentStep = ( requestedStep, steps ) => {
|
||||
const isValidStep = ( step ) =>
|
||||
typeof step === 'number' &&
|
||||
Number.isInteger( step ) &&
|
||||
step >= 0 &&
|
||||
step < steps.length;
|
||||
|
||||
const safeCurrentStep = isValidStep( requestedStep ) ? requestedStep : 0;
|
||||
return steps[ safeCurrentStep ];
|
||||
};
|
||||
|
||||
const Onboarding = () => {
|
||||
const [ step, setStep ] = useState( 0 );
|
||||
const { step, setStep, setCompleted, flags } = useOnboardingStep();
|
||||
const steps = getSteps( flags );
|
||||
|
||||
const CurrentStepComponent = getCurrentStep( step, steps );
|
||||
|
||||
return (
|
||||
<Container page={ PAGE_ONBOARDING }>
|
||||
<Container page="onboarding">
|
||||
<div className="ppcp-r-card">
|
||||
<Stepper currentStep={ step } setStep={ setStep } />
|
||||
<CurrentStepComponent
|
||||
setStep={ setStep }
|
||||
currentStep={ step }
|
||||
setCompleted={ setCompleted }
|
||||
stepperOrder={ steps }
|
||||
/>
|
||||
</div>
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
||||
const Stepper = ( { currentStep, setStep } ) => {
|
||||
const stepperOrder = [ StepWelcome, StepBusiness, StepProducts ];
|
||||
|
||||
const renderSteps = () => {
|
||||
return stepperOrder.map( ( Step, index ) => {
|
||||
return (
|
||||
<div
|
||||
key={ index }
|
||||
style={ index !== currentStep ? { display: 'none' } : {} }
|
||||
>
|
||||
<Step
|
||||
setStep={ setStep }
|
||||
currentStep={ currentStep }
|
||||
stepperOrder={ stepperOrder }
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
} );
|
||||
};
|
||||
|
||||
return <>{ renderSteps() }</>;
|
||||
};
|
||||
|
||||
export default Onboarding;
|
||||
|
|
|
@ -1,16 +1,35 @@
|
|||
import OnboardingHeader from '../../ReusableComponents/OnboardingHeader.js';
|
||||
import SelectBoxWrapper from '../../ReusableComponents/SelectBoxWrapper.js';
|
||||
import SelectBox from '../../ReusableComponents/SelectBox.js';
|
||||
import OnboardingHeader from '../../ReusableComponents/OnboardingHeader';
|
||||
import SelectBoxWrapper from '../../ReusableComponents/SelectBoxWrapper';
|
||||
import SelectBox from '../../ReusableComponents/SelectBox';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import PaymentMethodIcons from '../../ReusableComponents/PaymentMethodIcons';
|
||||
import { useState } from '@wordpress/element';
|
||||
import { useOnboardingStepBusiness } from '../../../data';
|
||||
import Navigation from '../../ReusableComponents/Navigation';
|
||||
import { BUSINESS_TYPES } from '../../../data/constants';
|
||||
|
||||
const StepBusiness = ( { setStep, currentStep, stepperOrder } ) => {
|
||||
const [ businessCategory, setBusinessCategory ] = useState( null );
|
||||
const BUSINESS_RADIO_GROUP_NAME = 'business';
|
||||
const CASUAL_SELLER_CHECKBOX_VALUE = 'casual_seller';
|
||||
const BUSINESS_CHECKBOX_VALUE = 'business';
|
||||
const BUSINESS_RADIO_GROUP_NAME = 'business';
|
||||
|
||||
const StepBusiness = ( {
|
||||
setStep,
|
||||
currentStep,
|
||||
stepperOrder,
|
||||
setCompleted,
|
||||
} ) => {
|
||||
const { isCasualSeller, setIsCasualSeller } = useOnboardingStepBusiness();
|
||||
|
||||
const handleSellerTypeChange = ( value ) => {
|
||||
setIsCasualSeller( BUSINESS_TYPES.CASUAL_SELLER === value );
|
||||
};
|
||||
|
||||
const getCurrentValue = () => {
|
||||
if ( isCasualSeller === null ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return isCasualSeller
|
||||
? BUSINESS_TYPES.CASUAL_SELLER
|
||||
: BUSINESS_TYPES.BUSINESS;
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="ppcp-r-page-business">
|
||||
|
@ -33,13 +52,10 @@ const StepBusiness = ( { setStep, currentStep, stepperOrder } ) => {
|
|||
) }
|
||||
icon="icon-business-casual-seller.svg"
|
||||
name={ BUSINESS_RADIO_GROUP_NAME }
|
||||
value={ CASUAL_SELLER_CHECKBOX_VALUE }
|
||||
changeCallback={ setBusinessCategory }
|
||||
currentValue={ businessCategory }
|
||||
checked={
|
||||
businessCategory ===
|
||||
{ CASUAL_SELLER_CHECKBOX_VALUE }
|
||||
}
|
||||
value={ BUSINESS_TYPES.CASUAL_SELLER }
|
||||
changeCallback={ handleSellerTypeChange }
|
||||
currentValue={ getCurrentValue() }
|
||||
checked={ isCasualSeller === true }
|
||||
type="radio"
|
||||
>
|
||||
<PaymentMethodIcons
|
||||
|
@ -64,12 +80,10 @@ const StepBusiness = ( { setStep, currentStep, stepperOrder } ) => {
|
|||
) }
|
||||
icon="icon-business-business.svg"
|
||||
name={ BUSINESS_RADIO_GROUP_NAME }
|
||||
value={ BUSINESS_CHECKBOX_VALUE }
|
||||
currentValue={ businessCategory }
|
||||
changeCallback={ setBusinessCategory }
|
||||
checked={
|
||||
businessCategory === { BUSINESS_CHECKBOX_VALUE }
|
||||
}
|
||||
value={ BUSINESS_TYPES.BUSINESS }
|
||||
changeCallback={ handleSellerTypeChange }
|
||||
currentValue={ getCurrentValue() }
|
||||
checked={ isCasualSeller === false }
|
||||
type="radio"
|
||||
>
|
||||
<PaymentMethodIcons
|
||||
|
@ -91,7 +105,8 @@ const StepBusiness = ( { setStep, currentStep, stepperOrder } ) => {
|
|||
setStep={ setStep }
|
||||
currentStep={ currentStep }
|
||||
stepperOrder={ stepperOrder }
|
||||
canProceeedCallback={ () => businessCategory !== null }
|
||||
setCompleted={ setCompleted }
|
||||
canProceeedCallback={ () => isCasualSeller !== null }
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -3,14 +3,18 @@ import Navigation from '../../ReusableComponents/Navigation';
|
|||
import { __ } from '@wordpress/i18n';
|
||||
import SelectBox from '../../ReusableComponents/SelectBox';
|
||||
import SelectBoxWrapper from '../../ReusableComponents/SelectBoxWrapper';
|
||||
import { useState } from '@wordpress/element';
|
||||
import { useOnboardingStepProducts } from '../../../data';
|
||||
import { PRODUCT_TYPES } from '../../../data/constants';
|
||||
|
||||
const StepProducts = ( { setStep, currentStep, stepperOrder } ) => {
|
||||
const [ products, setProducts ] = useState( [] );
|
||||
const PRODUCTS_CHECKBOX_GROUP_NAME = 'products';
|
||||
const VIRTUAL_CHECKBOX_VALUE = 'virtual';
|
||||
const PHYSICAL_CHECKBOX_VALUE = 'physical';
|
||||
const SUBSCRIPTIONS_CHECKBOX_VALUE = 'subscriptions';
|
||||
const PRODUCTS_CHECKBOX_GROUP_NAME = 'products';
|
||||
|
||||
const StepProducts = ( {
|
||||
setStep,
|
||||
currentStep,
|
||||
stepperOrder,
|
||||
setCompleted,
|
||||
} ) => {
|
||||
const { products, toggleProduct } = useOnboardingStepProducts();
|
||||
|
||||
return (
|
||||
<div className="ppcp-r-page-products">
|
||||
|
@ -30,8 +34,8 @@ const StepProducts = ( { setStep, currentStep, stepperOrder } ) => {
|
|||
) }
|
||||
icon="icon-product-virtual.svg"
|
||||
name={ PRODUCTS_CHECKBOX_GROUP_NAME }
|
||||
value={ VIRTUAL_CHECKBOX_VALUE }
|
||||
changeCallback={ setProducts }
|
||||
value={ PRODUCT_TYPES.VIRTUAL }
|
||||
changeCallback={ toggleProduct }
|
||||
currentValue={ products }
|
||||
type="checkbox"
|
||||
>
|
||||
|
@ -73,8 +77,8 @@ const StepProducts = ( { setStep, currentStep, stepperOrder } ) => {
|
|||
) }
|
||||
icon="icon-product-physical.svg"
|
||||
name={ PRODUCTS_CHECKBOX_GROUP_NAME }
|
||||
value={ PHYSICAL_CHECKBOX_VALUE }
|
||||
changeCallback={ setProducts }
|
||||
value={ PRODUCT_TYPES.PHYSICAL }
|
||||
changeCallback={ toggleProduct }
|
||||
currentValue={ products }
|
||||
type="checkbox"
|
||||
>
|
||||
|
@ -101,14 +105,17 @@ const StepProducts = ( { setStep, currentStep, stepperOrder } ) => {
|
|||
) }
|
||||
icon="icon-product-subscription.svg"
|
||||
name={ PRODUCTS_CHECKBOX_GROUP_NAME }
|
||||
value={ SUBSCRIPTIONS_CHECKBOX_VALUE }
|
||||
changeCallback={ setProducts }
|
||||
value={ PRODUCT_TYPES.SUBSCRIPTIONS }
|
||||
changeCallback={ toggleProduct }
|
||||
currentValue={ products }
|
||||
type="checkbox"
|
||||
>
|
||||
<a href="#">
|
||||
<a
|
||||
target="__blank"
|
||||
href="https://woocommerce.com/document/woocommerce-paypal-payments/#subscriptions-faq"
|
||||
>
|
||||
{ __(
|
||||
'WooCommerce Subscriptions - TODO missing link',
|
||||
'WooCommerce Subscriptions',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
</a>
|
||||
|
@ -118,6 +125,7 @@ const StepProducts = ( { setStep, currentStep, stepperOrder } ) => {
|
|||
setStep={ setStep }
|
||||
currentStep={ currentStep }
|
||||
stepperOrder={ stepperOrder }
|
||||
setCompleted={ setCompleted }
|
||||
canProceeedCallback={ () => products.length > 0 }
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
import OnboardingHeader from '../../ReusableComponents/OnboardingHeader.js';
|
||||
import OnboardingHeader from '../../ReusableComponents/OnboardingHeader';
|
||||
import { __, sprintf } from '@wordpress/i18n';
|
||||
import { Button, TextControl } from '@wordpress/components';
|
||||
import PaymentMethodIcons from '../../ReusableComponents/PaymentMethodIcons';
|
||||
import SettingsToggleBlock from '../../ReusableComponents/SettingsToggleBlock';
|
||||
import Separator from '../../ReusableComponents/Separator';
|
||||
import { useOnboardingDetails } from '../../../data';
|
||||
import { useOnboardingStepWelcome, useManualConnect } from '../../../data';
|
||||
|
||||
import DataStoreControl from '../../ReusableComponents/DataStoreControl';
|
||||
|
||||
const StepWelcome = ( { setStep, currentStep } ) => {
|
||||
const StepWelcome = ( { setStep, currentStep, setCompleted } ) => {
|
||||
return (
|
||||
<div className="ppcp-r-page-welcome">
|
||||
<OnboardingHeader
|
||||
|
@ -37,7 +38,7 @@ const StepWelcome = ( { setStep, currentStep } ) => {
|
|||
className="ppcp-r-page-welcome-or-separator"
|
||||
text={ __( 'or', 'woocommerce-paypal-payments' ) }
|
||||
/>
|
||||
<WelcomeForm />
|
||||
<WelcomeForm setCompleted={ setCompleted } />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -74,7 +75,7 @@ const WelcomeFeatures = () => {
|
|||
);
|
||||
};
|
||||
|
||||
const WelcomeForm = () => {
|
||||
const WelcomeForm = ( { setCompleted } ) => {
|
||||
const {
|
||||
isSandboxMode,
|
||||
setSandboxMode,
|
||||
|
@ -84,15 +85,35 @@ const WelcomeForm = () => {
|
|||
setClientId,
|
||||
clientSecret,
|
||||
setClientSecret,
|
||||
} = useOnboardingDetails();
|
||||
} = useOnboardingStepWelcome();
|
||||
|
||||
const { connectManual } = useManualConnect();
|
||||
|
||||
const handleConnect = async () => {
|
||||
try {
|
||||
const res = await connectManual(
|
||||
clientId,
|
||||
clientSecret,
|
||||
isSandboxMode
|
||||
);
|
||||
if ( ! res.success ) {
|
||||
throw new Error( 'Request failed.' );
|
||||
}
|
||||
|
||||
setCompleted( true );
|
||||
} catch ( exc ) {
|
||||
console.error( exc );
|
||||
alert( 'Connection failed.' );
|
||||
}
|
||||
};
|
||||
|
||||
const advancedUsersDescription = sprintf(
|
||||
// translators: %s: Link to PayPal REST application guide
|
||||
__(
|
||||
'For advanced users: Connect a custom PayPal REST app for full control over your integration. For more information on creating a PayPal REST application, <a href="%s">click here</a>.',
|
||||
'For advanced users: Connect a custom PayPal REST app for full control over your integration. For more information on creating a PayPal REST application, <a target="_blank" href="%s">click here</a>.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
'#'
|
||||
'https://woocommerce.com/document/woocommerce-paypal-payments/#manual-credential-input '
|
||||
);
|
||||
|
||||
return (
|
||||
|
@ -116,7 +137,7 @@ const WelcomeForm = () => {
|
|||
<Separator className="ppcp-r-page-welcome-mode-separator" />
|
||||
<SettingsToggleBlock
|
||||
label={ __(
|
||||
'Manually Connect - TODO missing link',
|
||||
'Manually Connect',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
description={ advancedUsersDescription }
|
||||
|
@ -125,24 +146,38 @@ const WelcomeForm = () => {
|
|||
>
|
||||
<DataStoreControl
|
||||
control={ TextControl }
|
||||
label={ __(
|
||||
'Sandbox Client ID',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
label={
|
||||
isSandboxMode
|
||||
? __(
|
||||
'Sandbox Client ID',
|
||||
'woocommerce-paypal-payments'
|
||||
)
|
||||
: __(
|
||||
'Live Client ID',
|
||||
'woocommerce-paypal-payments'
|
||||
)
|
||||
}
|
||||
value={ clientId }
|
||||
onChange={ setClientId }
|
||||
/>
|
||||
<DataStoreControl
|
||||
control={ TextControl }
|
||||
label={ __(
|
||||
'Sandbox Secret Key',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
label={
|
||||
isSandboxMode
|
||||
? __(
|
||||
'Sandbox Secret Key',
|
||||
'woocommerce-paypal-payments'
|
||||
)
|
||||
: __(
|
||||
'Live Secret Key',
|
||||
'woocommerce-paypal-payments'
|
||||
)
|
||||
}
|
||||
value={ clientSecret }
|
||||
onChange={ setClientSecret }
|
||||
type="password"
|
||||
/>
|
||||
<Button variant="secondary">
|
||||
<Button variant="secondary" onClick={ handleConnect }>
|
||||
{ __( 'Connect Account', 'woocommerce-paypal-payments' ) }
|
||||
</Button>
|
||||
</SettingsToggleBlock>
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
import StepWelcome from './StepWelcome';
|
||||
import StepBusiness from './StepBusiness';
|
||||
import StepProducts from './StepProducts';
|
||||
|
||||
export const getSteps = ( flags ) => {
|
||||
const allSteps = [ StepWelcome, StepBusiness, StepProducts ];
|
||||
|
||||
if ( ! flags.canUseCasualSelling ) {
|
||||
return allSteps.filter( ( step ) => step !== StepBusiness );
|
||||
}
|
||||
|
||||
return allSteps;
|
||||
};
|
|
@ -1,10 +1,23 @@
|
|||
import TabNavigation from '../ReusableComponents/TabNavigation';
|
||||
import { getSettingsTabs } from './tabs';
|
||||
import { useOnboardingStep } from '../../data';
|
||||
import Onboarding from './Onboarding/Onboarding';
|
||||
import { useState } from '@wordpress/element';
|
||||
import Dashboard from './Dashboard/Dashboard';
|
||||
|
||||
const Settings = () => {
|
||||
const [ onboarded, setOnboarded ] = useState( true );
|
||||
return <>{ onboarded ? <Dashboard /> : <Onboarding /> }</>;
|
||||
const onboardingProgress = useOnboardingStep();
|
||||
|
||||
if ( ! onboardingProgress.isReady ) {
|
||||
// TODO: Use better loading state indicator.
|
||||
return <div>Loading...</div>;
|
||||
}
|
||||
|
||||
if ( ! onboardingProgress.completed ) {
|
||||
return <Onboarding />;
|
||||
}
|
||||
|
||||
const tabs = getSettingsTabs( onboardingProgress );
|
||||
|
||||
return <TabNavigation tabs={ tabs }></TabNavigation>;
|
||||
};
|
||||
|
||||
export default Settings;
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
import { __ } from '@wordpress/i18n';
|
||||
import TabDashboard from './Dashboard/TabDashboard';
|
||||
import TabPaymentMethods from './Dashboard/TabPaymentMethods';
|
||||
import TabSettings from './Dashboard/TabSettings';
|
||||
import TabStyling from './Dashboard/TabStyling';
|
||||
|
||||
export const getSettingsTabs = () => {
|
||||
const tabs = [];
|
||||
|
||||
tabs.push( {
|
||||
name: 'dashboard',
|
||||
title: __( 'Dashboard', 'woocommerce-paypal-payments' ),
|
||||
component: <TabDashboard />,
|
||||
} );
|
||||
|
||||
tabs.push( {
|
||||
name: 'payment-methods',
|
||||
title: __( 'Payment Methods', 'woocommerce-paypal-payments' ),
|
||||
component: <TabPaymentMethods />,
|
||||
} );
|
||||
|
||||
tabs.push( {
|
||||
name: 'settings',
|
||||
title: __( 'Settings', 'woocommerce-paypal-payments' ),
|
||||
component: <TabSettings />,
|
||||
} );
|
||||
|
||||
tabs.push( {
|
||||
name: 'styling',
|
||||
title: __( 'Styling', 'woocommerce-paypal-payments' ),
|
||||
component: <TabStyling />,
|
||||
} );
|
||||
|
||||
return tabs;
|
||||
};
|
|
@ -1,2 +1,13 @@
|
|||
export const NAMESPACE = '/wc/v3/wc_paypal';
|
||||
export const STORE_NAME = 'wc/paypal';
|
||||
|
||||
export const BUSINESS_TYPES = {
|
||||
CASUAL_SELLER: 'casual_seller',
|
||||
BUSINESS: 'business',
|
||||
};
|
||||
|
||||
export const PRODUCT_TYPES = {
|
||||
VIRTUAL: 'virtual',
|
||||
PHYSICAL: 'physical',
|
||||
SUBSCRIPTIONS: 'subscriptions',
|
||||
};
|
||||
|
|
|
@ -1,12 +1,18 @@
|
|||
export default {
|
||||
RESET_ONBOARDING: 'RESET_ONBOARDING',
|
||||
|
||||
// Transient data.
|
||||
SET_IS_SAVING_ONBOARDING_DETAILS: 'SET_IS_SAVING_ONBOARDING_DETAILS',
|
||||
SET_ONBOARDING_IS_READY: 'SET_ONBOARDING_IS_READY',
|
||||
SET_IS_SAVING_ONBOARDING: 'SET_IS_SAVING_ONBOARDING',
|
||||
|
||||
// Persistent data.
|
||||
SET_ONBOARDING_COMPLETED: 'SET_ONBOARDING_COMPLETED',
|
||||
SET_ONBOARDING_DETAILS: 'SET_ONBOARDING_DETAILS',
|
||||
SET_ONBOARDING_STEP: 'SET_ONBOARDING_STEP',
|
||||
SET_SANDBOX_MODE: 'SET_SANDBOX_MODE',
|
||||
SET_MANUAL_CONNECTION_MODE: 'SET_MANUAL_CONNECTION_MODE',
|
||||
SET_CLIENT_ID: 'SET_CLIENT_ID',
|
||||
SET_CLIENT_SECRET: 'SET_CLIENT_SECRET',
|
||||
SET_IS_CASUAL_SELLER: 'SET_IS_CASUAL_SELLER',
|
||||
SET_PRODUCTS: 'SET_PRODUCTS',
|
||||
};
|
||||
|
|
|
@ -3,6 +3,28 @@ import { apiFetch } from '@wordpress/data-controls';
|
|||
import ACTION_TYPES from './action-types';
|
||||
import { NAMESPACE, STORE_NAME } from '../constants';
|
||||
|
||||
/**
|
||||
* Special. Resets all values in the onboarding store to initial defaults.
|
||||
*
|
||||
* @return {{type: string}} The action.
|
||||
*/
|
||||
export const resetOnboarding = () => {
|
||||
return { type: ACTION_TYPES.RESET_ONBOARDING };
|
||||
};
|
||||
|
||||
/**
|
||||
* Non-persistent. Marks the onboarding details as "ready", i.e., fully initialized.
|
||||
*
|
||||
* @param {boolean} isReady
|
||||
* @return {{type: string, isReady}} The action.
|
||||
*/
|
||||
export const setIsReady = ( isReady ) => {
|
||||
return {
|
||||
type: ACTION_TYPES.SET_ONBOARDING_IS_READY,
|
||||
isReady,
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Non-persistent. Changes the "saving" flag.
|
||||
*
|
||||
|
@ -11,7 +33,7 @@ import { NAMESPACE, STORE_NAME } from '../constants';
|
|||
*/
|
||||
export const setIsSaving = ( isSaving ) => {
|
||||
return {
|
||||
type: ACTION_TYPES.SET_IS_SAVING_ONBOARDING_DETAILS,
|
||||
type: ACTION_TYPES.SET_IS_SAVING_ONBOARDING,
|
||||
isSaving,
|
||||
};
|
||||
};
|
||||
|
@ -19,7 +41,7 @@ export const setIsSaving = ( isSaving ) => {
|
|||
/**
|
||||
* Persistent. Set the full onboarding details, usually during app initialization.
|
||||
*
|
||||
* @param {Object} payload
|
||||
* @param {{data: {}, flags?: {}}} payload
|
||||
* @return {{type: string, payload}} The action.
|
||||
*/
|
||||
export const setOnboardingDetails = ( payload ) => {
|
||||
|
@ -29,6 +51,19 @@ export const setOnboardingDetails = ( payload ) => {
|
|||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Persistent.Set the "onboarding completed" flag which shows or hides the wizard.
|
||||
*
|
||||
* @param {boolean} completed
|
||||
* @return {{type: string, payload}} The action.
|
||||
*/
|
||||
export const setCompleted = ( completed ) => {
|
||||
return {
|
||||
type: ACTION_TYPES.SET_ONBOARDING_COMPLETED,
|
||||
completed,
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Persistent. Sets the onboarding wizard to a new step.
|
||||
*
|
||||
|
@ -94,6 +129,32 @@ export const setClientSecret = ( clientSecret ) => {
|
|||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Persistent. Sets the "isCasualSeller" value.
|
||||
*
|
||||
* @param {boolean} isCasualSeller
|
||||
* @return {{type: string, isCasualSeller}} The action.
|
||||
*/
|
||||
export const setIsCasualSeller = ( isCasualSeller ) => {
|
||||
return {
|
||||
type: ACTION_TYPES.SET_IS_CASUAL_SELLER,
|
||||
isCasualSeller,
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Persistent. Sets the "products" array.
|
||||
*
|
||||
* @param {string[]} products
|
||||
* @return {{type: string, products}} The action.
|
||||
*/
|
||||
export const setProducts = ( products ) => {
|
||||
return {
|
||||
type: ACTION_TYPES.SET_PRODUCTS,
|
||||
products,
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Saves the persistent details to the WP database.
|
||||
*
|
||||
|
|
|
@ -1,14 +1,19 @@
|
|||
import { useSelect, useDispatch } from '@wordpress/data';
|
||||
import { STORE_NAME } from '../constants';
|
||||
import apiFetch from '@wordpress/api-fetch';
|
||||
import { NAMESPACE, PRODUCT_TYPES, STORE_NAME } from '../constants';
|
||||
import { getFlags } from './selectors';
|
||||
|
||||
export const useOnboardingDetails = () => {
|
||||
const useOnboardingDetails = () => {
|
||||
const {
|
||||
persist,
|
||||
setOnboardingStep,
|
||||
setCompleted,
|
||||
setSandboxMode,
|
||||
setManualConnectionMode,
|
||||
persist,
|
||||
setClientId,
|
||||
setClientSecret,
|
||||
setIsCasualSeller,
|
||||
setProducts,
|
||||
} = useDispatch( STORE_NAME );
|
||||
|
||||
// Transient accessors.
|
||||
|
@ -16,7 +21,24 @@ export const useOnboardingDetails = () => {
|
|||
return select( STORE_NAME ).getTransientData().isSaving;
|
||||
}, [] );
|
||||
|
||||
const isReady = useSelect( ( select ) => {
|
||||
return select( STORE_NAME ).getTransientData().isReady;
|
||||
} );
|
||||
|
||||
// Read-only flags.
|
||||
const flags = useSelect( ( select ) => {
|
||||
return select( STORE_NAME ).getFlags();
|
||||
} );
|
||||
|
||||
// Persistent accessors.
|
||||
const step = useSelect( ( select ) => {
|
||||
return select( STORE_NAME ).getPersistentData().step || 0;
|
||||
} );
|
||||
|
||||
const completed = useSelect( ( select ) => {
|
||||
return select( STORE_NAME ).getPersistentData().completed;
|
||||
} );
|
||||
|
||||
const clientId = useSelect( ( select ) => {
|
||||
return select( STORE_NAME ).getPersistentData().clientId;
|
||||
}, [] );
|
||||
|
@ -25,10 +47,6 @@ export const useOnboardingDetails = () => {
|
|||
return select( STORE_NAME ).getPersistentData().clientSecret;
|
||||
}, [] );
|
||||
|
||||
const onboardingStep = useSelect( ( select ) => {
|
||||
return select( STORE_NAME ).getPersistentData().step || 0;
|
||||
}, [] );
|
||||
|
||||
const isSandboxMode = useSelect( ( select ) => {
|
||||
return select( STORE_NAME ).getPersistentData().useSandbox;
|
||||
}, [] );
|
||||
|
@ -37,26 +55,112 @@ export const useOnboardingDetails = () => {
|
|||
return select( STORE_NAME ).getPersistentData().useManualConnection;
|
||||
}, [] );
|
||||
|
||||
const isCasualSeller = useSelect( ( select ) => {
|
||||
return select( STORE_NAME ).getPersistentData().isCasualSeller;
|
||||
}, [] );
|
||||
|
||||
const products = useSelect( ( select ) => {
|
||||
return select( STORE_NAME ).getPersistentData().products || [];
|
||||
}, [] );
|
||||
|
||||
const toggleProduct = ( list ) => {
|
||||
const validProducts = list.filter( ( item ) =>
|
||||
Object.values( PRODUCT_TYPES ).includes( item )
|
||||
);
|
||||
return setDetailAndPersist( setProducts, validProducts );
|
||||
};
|
||||
|
||||
const setDetailAndPersist = async ( setter, value ) => {
|
||||
setter( value );
|
||||
await persist();
|
||||
};
|
||||
|
||||
return {
|
||||
onboardingStep,
|
||||
isSaving,
|
||||
isReady,
|
||||
step,
|
||||
setStep: ( value ) => setDetailAndPersist( setOnboardingStep, value ),
|
||||
completed,
|
||||
setCompleted: ( state ) => setDetailAndPersist( setCompleted, state ),
|
||||
isSandboxMode,
|
||||
setSandboxMode: ( state ) =>
|
||||
setDetailAndPersist( setSandboxMode, state ),
|
||||
isManualConnectionMode,
|
||||
setManualConnectionMode: ( state ) =>
|
||||
setDetailAndPersist( setManualConnectionMode, state ),
|
||||
clientId,
|
||||
setClientId: ( value ) => setDetailAndPersist( setClientId, value ),
|
||||
clientSecret,
|
||||
setClientSecret: ( value ) =>
|
||||
setDetailAndPersist( setClientSecret, value ),
|
||||
setOnboardingStep: ( step ) =>
|
||||
setDetailAndPersist( setOnboardingStep, step ),
|
||||
setSandboxMode: ( state ) =>
|
||||
setDetailAndPersist( setSandboxMode, state ),
|
||||
setManualConnectionMode: ( state ) =>
|
||||
setDetailAndPersist( setManualConnectionMode, state ),
|
||||
isCasualSeller,
|
||||
setIsCasualSeller: ( value ) =>
|
||||
setDetailAndPersist( setIsCasualSeller, value ),
|
||||
products,
|
||||
toggleProduct,
|
||||
flags,
|
||||
};
|
||||
};
|
||||
|
||||
export const useOnboardingStepWelcome = () => {
|
||||
const {
|
||||
isSaving,
|
||||
isSandboxMode,
|
||||
setSandboxMode,
|
||||
isManualConnectionMode,
|
||||
setManualConnectionMode,
|
||||
clientId,
|
||||
setClientId,
|
||||
clientSecret,
|
||||
setClientSecret,
|
||||
} = useOnboardingDetails();
|
||||
|
||||
return {
|
||||
isSaving,
|
||||
isSandboxMode,
|
||||
setSandboxMode,
|
||||
isManualConnectionMode,
|
||||
setManualConnectionMode,
|
||||
clientId,
|
||||
setClientId,
|
||||
clientSecret,
|
||||
setClientSecret,
|
||||
};
|
||||
};
|
||||
|
||||
export const useOnboardingStepBusiness = () => {
|
||||
const { isCasualSeller, setIsCasualSeller } = useOnboardingDetails();
|
||||
|
||||
return { isCasualSeller, setIsCasualSeller };
|
||||
};
|
||||
|
||||
export const useOnboardingStepProducts = () => {
|
||||
const { products, toggleProduct } = useOnboardingDetails();
|
||||
|
||||
return { products, toggleProduct };
|
||||
};
|
||||
|
||||
export const useOnboardingStep = () => {
|
||||
const { isReady, step, setStep, completed, setCompleted, flags } =
|
||||
useOnboardingDetails();
|
||||
|
||||
return { isReady, step, setStep, completed, setCompleted, flags };
|
||||
};
|
||||
|
||||
export const useManualConnect = () => {
|
||||
const connectManual = async ( clientId, clientSecret, isSandboxMode ) => {
|
||||
return await apiFetch( {
|
||||
path: `${ NAMESPACE }/connect_manual`,
|
||||
method: 'POST',
|
||||
data: {
|
||||
clientId,
|
||||
clientSecret,
|
||||
useSandbox: isSandboxMode,
|
||||
},
|
||||
} );
|
||||
};
|
||||
|
||||
return {
|
||||
connectManual,
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,13 +1,26 @@
|
|||
import ACTION_TYPES from './action-types';
|
||||
|
||||
const defaultState = {
|
||||
isReady: false,
|
||||
isSaving: false,
|
||||
|
||||
// Data persisted to the server.
|
||||
data: {
|
||||
completed: false,
|
||||
step: 0,
|
||||
useSandbox: false,
|
||||
useManualConnection: false,
|
||||
clientId: '',
|
||||
clientSecret: '',
|
||||
isCasualSeller: null, // null value will uncheck both options in the UI.
|
||||
products: [],
|
||||
},
|
||||
|
||||
// Read only values, provided by the server.
|
||||
flags: {
|
||||
canUseCasualSelling: false,
|
||||
canUseVaulting: false,
|
||||
canUseCardPayments: false,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -35,20 +48,36 @@ export const onboardingReducer = (
|
|||
};
|
||||
|
||||
switch ( type ) {
|
||||
// Reset store to initial state.
|
||||
case ACTION_TYPES.RESET_ONBOARDING:
|
||||
return setPersistent( defaultState.data );
|
||||
|
||||
// Transient data.
|
||||
case ACTION_TYPES.SET_IS_SAVING_ONBOARDING_DETAILS:
|
||||
case ACTION_TYPES.SET_ONBOARDING_IS_READY:
|
||||
return setTransient( { isReady: action.isReady } );
|
||||
|
||||
case ACTION_TYPES.SET_IS_SAVING_ONBOARDING:
|
||||
return setTransient( { isSaving: action.isSaving } );
|
||||
|
||||
// Persistent data.
|
||||
case ACTION_TYPES.SET_ONBOARDING_DETAILS:
|
||||
const newState = setPersistent( action.payload.data );
|
||||
|
||||
if ( action.payload.flags ) {
|
||||
newState.flags = { ...newState.flags, ...action.payload.flags };
|
||||
}
|
||||
|
||||
return newState;
|
||||
|
||||
case ACTION_TYPES.SET_ONBOARDING_COMPLETED:
|
||||
return setPersistent( { completed: action.completed } );
|
||||
|
||||
case ACTION_TYPES.SET_CLIENT_ID:
|
||||
return setPersistent( { clientId: action.clientId } );
|
||||
|
||||
case ACTION_TYPES.SET_CLIENT_SECRET:
|
||||
return setPersistent( { clientSecret: action.clientSecret } );
|
||||
|
||||
case ACTION_TYPES.SET_ONBOARDING_DETAILS:
|
||||
return setPersistent( action.payload );
|
||||
|
||||
case ACTION_TYPES.SET_ONBOARDING_STEP:
|
||||
return setPersistent( { step: action.step } );
|
||||
|
||||
|
@ -60,6 +89,12 @@ export const onboardingReducer = (
|
|||
useManualConnection: action.useManualConnection,
|
||||
} );
|
||||
|
||||
case ACTION_TYPES.SET_IS_CASUAL_SELLER:
|
||||
return setPersistent( { isCasualSeller: action.isCasualSeller } );
|
||||
|
||||
case ACTION_TYPES.SET_PRODUCTS:
|
||||
return setPersistent( { products: action.products } );
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import { dispatch } from '@wordpress/data';
|
|||
import { __ } from '@wordpress/i18n';
|
||||
import { apiFetch } from '@wordpress/data-controls';
|
||||
import { NAMESPACE } from '../constants';
|
||||
import { setOnboardingDetails } from './actions';
|
||||
import { setIsReady, setOnboardingDetails } from './actions';
|
||||
|
||||
/**
|
||||
* Retrieve settings from the site's REST API.
|
||||
|
@ -13,6 +13,7 @@ export function* getPersistentData() {
|
|||
try {
|
||||
const result = yield apiFetch( { path } );
|
||||
yield setOnboardingDetails( result );
|
||||
yield setIsReady( true );
|
||||
} catch ( e ) {
|
||||
yield dispatch( 'core/notices' ).createErrorNotice(
|
||||
__(
|
||||
|
|
|
@ -13,6 +13,10 @@ export const getPersistentData = ( state ) => {
|
|||
};
|
||||
|
||||
export const getTransientData = ( state ) => {
|
||||
const { data, ...transientState } = getOnboardingState( state );
|
||||
const { data, flags, ...transientState } = getOnboardingState( state );
|
||||
return transientState || EMPTY_OBJ;
|
||||
};
|
||||
|
||||
export const getFlags = ( state ) => {
|
||||
return getOnboardingState( state ).flags || EMPTY_OBJ;
|
||||
};
|
||||
|
|
|
@ -27,4 +27,32 @@ export const initStore = () => {
|
|||
} );
|
||||
|
||||
register( store );
|
||||
|
||||
/* eslint-disable no-console */
|
||||
// Provide a debug tool to inspect the Redux store via the JS console.
|
||||
if ( window.ppcpSettings?.debug && console?.groupCollapsed ) {
|
||||
window.ppcpSettings.dumpStore = () => {
|
||||
const storeSelector = `wp.data.select('${ STORE_NAME }')`;
|
||||
console.group( `[STORE] ${ storeSelector }` );
|
||||
|
||||
const storeState = wp.data.select( STORE_NAME );
|
||||
Object.keys( selectors ).forEach( ( selector ) => {
|
||||
console.groupCollapsed( `[SELECTOR] .${ selector }()` );
|
||||
console.table( storeState[ selector ]() );
|
||||
console.groupEnd();
|
||||
} );
|
||||
|
||||
console.groupEnd();
|
||||
};
|
||||
window.ppcpSettings.resetStore = () => {
|
||||
wp.data.dispatch( STORE_NAME ).resetOnboarding();
|
||||
wp.data.dispatch( STORE_NAME ).persist();
|
||||
};
|
||||
window.ppcpSettings.startOnboarding = () => {
|
||||
wp.data.dispatch( STORE_NAME ).setCompleted( false );
|
||||
wp.data.dispatch( STORE_NAME ).setOnboardingStep( 0 );
|
||||
wp.data.dispatch( STORE_NAME ).persist();
|
||||
};
|
||||
}
|
||||
/* eslint-enable no-console */
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue