Add core profiler user profile page (#38328)
This commit is contained in:
parent
6d4014042b
commit
4547922f3f
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: patch
|
||||||
|
Type: add
|
||||||
|
|
||||||
|
Add onKeyDown and readOnlyWhenClosed options to experimentalSelectControl
|
|
@ -105,4 +105,6 @@ Name | Type | Default | Description
|
||||||
`onInputChange` | Function | `() => null` | A callback that fires when the user input has changed
|
`onInputChange` | Function | `() => null` | A callback that fires when the user input has changed
|
||||||
`onRemove` | Function | `() => null` | A callback that fires when a selected item has been removed
|
`onRemove` | Function | `() => null` | A callback that fires when a selected item has been removed
|
||||||
`onSelect` | Function | `() => null` | A callback that fires when an item has been selected
|
`onSelect` | Function | `() => null` | A callback that fires when an item has been selected
|
||||||
`selected` | Array or Item | `undefined` | An array of selected items or a single selected item
|
`selected` | Array or Item | `undefined` | An array of selected items or a single selected item\
|
||||||
|
`onKeyDown` | Function | `() => null` | A callback that fires when a key is pressed
|
||||||
|
`readOnlyWhenClosed` | Boolean | `false` | Whether the input should be read-only when the menu is closed
|
||||||
|
|
|
@ -58,6 +58,7 @@ export type SelectControlProps< ItemType > = {
|
||||||
) => void;
|
) => void;
|
||||||
onRemove?: ( item: ItemType ) => void;
|
onRemove?: ( item: ItemType ) => void;
|
||||||
onSelect?: ( selected: ItemType ) => void;
|
onSelect?: ( selected: ItemType ) => void;
|
||||||
|
onKeyDown?: ( e: KeyboardEvent ) => void;
|
||||||
onFocus?: ( data: { inputValue: string } ) => void;
|
onFocus?: ( data: { inputValue: string } ) => void;
|
||||||
stateReducer?: (
|
stateReducer?: (
|
||||||
state: UseComboboxState< ItemType | null >,
|
state: UseComboboxState< ItemType | null >,
|
||||||
|
@ -70,6 +71,8 @@ export type SelectControlProps< ItemType > = {
|
||||||
inputProps?: GetInputPropsOptions;
|
inputProps?: GetInputPropsOptions;
|
||||||
suffix?: JSX.Element | null;
|
suffix?: JSX.Element | null;
|
||||||
showToggleButton?: boolean;
|
showToggleButton?: boolean;
|
||||||
|
readOnlyWhenClosed?: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a feature already implemented in downshift@7.0.0 through the
|
* This is a feature already implemented in downshift@7.0.0 through the
|
||||||
* reducer. In order for us to use it this prop is added temporarily until
|
* reducer. In order for us to use it this prop is added temporarily until
|
||||||
|
@ -118,6 +121,7 @@ function SelectControl< ItemType = DefaultItemType >( {
|
||||||
onRemove = () => null,
|
onRemove = () => null,
|
||||||
onSelect = () => null,
|
onSelect = () => null,
|
||||||
onFocus = () => null,
|
onFocus = () => null,
|
||||||
|
onKeyDown = () => null,
|
||||||
stateReducer = ( state, actionAndChanges ) => actionAndChanges.changes,
|
stateReducer = ( state, actionAndChanges ) => actionAndChanges.changes,
|
||||||
placeholder,
|
placeholder,
|
||||||
selected,
|
selected,
|
||||||
|
@ -126,6 +130,7 @@ function SelectControl< ItemType = DefaultItemType >( {
|
||||||
inputProps = {},
|
inputProps = {},
|
||||||
suffix = <SuffixIcon icon={ chevronDown } />,
|
suffix = <SuffixIcon icon={ chevronDown } />,
|
||||||
showToggleButton = false,
|
showToggleButton = false,
|
||||||
|
readOnlyWhenClosed = true,
|
||||||
__experimentalOpenMenuOnFocus = false,
|
__experimentalOpenMenuOnFocus = false,
|
||||||
}: SelectControlProps< ItemType > ) {
|
}: SelectControlProps< ItemType > ) {
|
||||||
const [ isFocused, setIsFocused ] = useState( false );
|
const [ isFocused, setIsFocused ] = useState( false );
|
||||||
|
@ -247,7 +252,7 @@ function SelectControl< ItemType = DefaultItemType >( {
|
||||||
onRemove( item );
|
onRemove( item );
|
||||||
};
|
};
|
||||||
|
|
||||||
const isReadOnly = ! isOpen && ! isFocused;
|
const isReadOnly = readOnlyWhenClosed && ! isOpen && ! isFocused;
|
||||||
|
|
||||||
const selectedItemTags = multiple ? (
|
const selectedItemTags = multiple ? (
|
||||||
<SelectedItems
|
<SelectedItems
|
||||||
|
@ -305,6 +310,7 @@ function SelectControl< ItemType = DefaultItemType >( {
|
||||||
setIsFocused( false );
|
setIsFocused( false );
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
onKeyDown,
|
||||||
placeholder,
|
placeholder,
|
||||||
disabled,
|
disabled,
|
||||||
...inputProps,
|
...inputProps,
|
||||||
|
|
|
@ -5,6 +5,10 @@ import { setLocaleData } from '@wordpress/i18n';
|
||||||
import { registerStore } from '@wordpress/data';
|
import { registerStore } from '@wordpress/data';
|
||||||
import 'regenerator-runtime/runtime';
|
import 'regenerator-runtime/runtime';
|
||||||
|
|
||||||
|
// Mock the config module to avoid errors like:
|
||||||
|
// Core Error: Could not find config value for key ${ key }. Please make sure that if you need it then it has a default value assigned in config/_shared.json.
|
||||||
|
jest.mock( '@automattic/calypso-config' );
|
||||||
|
|
||||||
// Due to the dependency @wordpress/compose which introduces the use of
|
// Due to the dependency @wordpress/compose which introduces the use of
|
||||||
// ResizeObserver this global mock is required for some tests to work.
|
// ResizeObserver this global mock is required for some tests to work.
|
||||||
global.ResizeObserver = require( 'resize-observer-polyfill' );
|
global.ResizeObserver = require( 'resize-observer-polyfill' );
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
.woocommerce-profiler-choice-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
padding: $gap-large $gap;
|
||||||
|
border: 1px solid $gray-200;
|
||||||
|
border-radius: 2px;
|
||||||
|
width: 100%;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&[data-selected] {
|
||||||
|
border: 2px solid var(--wp-admin-theme-color);
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus-visible {
|
||||||
|
border: 2px solid var(--wp-admin-theme-color);
|
||||||
|
padding: $gap-large $gap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.woocommerce-profiler-choice {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.woocommerce-profiler-choice-input {
|
||||||
|
opacity: 0;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 20px;
|
||||||
|
color: $gray-900;
|
||||||
|
display: flex;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
input + label::before {
|
||||||
|
content: '';
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
border: 1px solid $gray-600;
|
||||||
|
border-radius: 16px;
|
||||||
|
margin-right: $gap;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[data-selected] + label::before {
|
||||||
|
border-color: var(--wp-admin-theme-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
input[data-selected] + label::after {
|
||||||
|
background-color: var(--wp-admin-theme-color);
|
||||||
|
align-self: center;
|
||||||
|
border-radius: 50%;
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
left: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.woocommerce-profiler-choice-sub-options {
|
||||||
|
margin-top: $gap-large;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
> div {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import './choice.scss';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
className?: string;
|
||||||
|
selected: boolean;
|
||||||
|
title: string;
|
||||||
|
name: string;
|
||||||
|
value: string;
|
||||||
|
onChange: ( value: string ) => void;
|
||||||
|
subOptionsComponent?: React.ReactNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Choice = ( {
|
||||||
|
className,
|
||||||
|
selected,
|
||||||
|
title,
|
||||||
|
name,
|
||||||
|
value,
|
||||||
|
onChange,
|
||||||
|
subOptionsComponent = null,
|
||||||
|
}: Props ) => {
|
||||||
|
const changeHandler = () => {
|
||||||
|
onChange( value );
|
||||||
|
};
|
||||||
|
const inputId = 'woocommerce-' + value.replace( /_/g, '-' );
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
role="radio"
|
||||||
|
className={ classNames(
|
||||||
|
'woocommerce-profiler-choice-container',
|
||||||
|
className
|
||||||
|
) }
|
||||||
|
onClick={ changeHandler }
|
||||||
|
onKeyDown={ ( e ) => {
|
||||||
|
if ( e.key === 'Enter' ) {
|
||||||
|
changeHandler();
|
||||||
|
}
|
||||||
|
} }
|
||||||
|
data-selected={ selected ? selected : null }
|
||||||
|
tabIndex={ 0 }
|
||||||
|
>
|
||||||
|
<div className="woocommerce-profiler-choice">
|
||||||
|
<input
|
||||||
|
className="woocommerce-profiler-choice-input"
|
||||||
|
id={ inputId }
|
||||||
|
name={ name }
|
||||||
|
type="radio"
|
||||||
|
value={ value }
|
||||||
|
checked={ !! selected }
|
||||||
|
onChange={ changeHandler }
|
||||||
|
data-selected={ selected ? selected : null }
|
||||||
|
// Stop the input from being focused when the parent div is clicked
|
||||||
|
tabIndex={ -1 }
|
||||||
|
></input>
|
||||||
|
<label htmlFor={ inputId } className="choice__title">
|
||||||
|
{ title }
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
{ selected && subOptionsComponent && (
|
||||||
|
<div className="woocommerce-profiler-choice-sub-options">
|
||||||
|
{ subOptionsComponent }
|
||||||
|
</div>
|
||||||
|
) }
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
|
@ -1,7 +1,11 @@
|
||||||
.woocommerce-profiler-heading {
|
.woocommerce-profiler-heading {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
margin-bottom: 48px;
|
margin-bottom: 48px;
|
||||||
width: 100%;
|
|
||||||
max-width: 550px;
|
max-width: 550px;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
.woocommerce-profiler-heading__title {
|
.woocommerce-profiler-heading__title {
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
|
@ -31,4 +35,30 @@
|
||||||
color: $gray-800;
|
color: $gray-800;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.woocommerce-profiler__stepper-heading {
|
||||||
|
margin-top: 72px;
|
||||||
|
|
||||||
|
.woocommerce-profiler-heading__title {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
.woocommerce-profiler-heading__subtitle {
|
||||||
|
margin: 12px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: #{ ($break-mobile) }) {
|
||||||
|
margin-top: 52px 0 40px;
|
||||||
|
|
||||||
|
.woocommerce-profiler-heading__title {
|
||||||
|
font-size: 32px;
|
||||||
|
line-height: 40px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.woocommerce-profiler-heading__subtitle {
|
||||||
|
text-align: left;
|
||||||
|
font-size: 16px;
|
||||||
|
color: $gray-700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
|
||||||
|
.woocommerce-experimental-select-control {
|
||||||
|
&:hover,
|
||||||
|
ul:hover,
|
||||||
|
.woocommerce-experimental-select-control__input:hover,
|
||||||
|
.components-popover:hover,
|
||||||
|
.woocommerce-experimental-select-control__combo-box-wrapper:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.has-selected-items {
|
||||||
|
.woocommerce-experimental-select-control__combox-box {
|
||||||
|
position: absolute;
|
||||||
|
width: 0;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.woocommerce-experimental-select-control__combox-box .woocommerce-experimental-select-control__input {
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.components-popover.woocommerce-experimental-select-control__popover-menu {
|
||||||
|
padding-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.woocommerce-experimental-select-control__selected-item {
|
||||||
|
background: $gray-100;
|
||||||
|
padding: 2px 5px 2px 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.woocommerce-tag .woocommerce-tag__text {
|
||||||
|
background: none !important;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 16px;
|
||||||
|
padding: 0 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.woocommerce-experimental-select-control__combo-box-wrapper {
|
||||||
|
transition: box-shadow 0.25s linear;
|
||||||
|
border: 1px solid #bbb;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.woocommerce-experimental-select-control__popover-menu {
|
||||||
|
border: none;
|
||||||
|
left: 0 !important;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.woocommerce-experimental-select-control__popover-menu-container {
|
||||||
|
overflow-y: initial;
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.components-popover {
|
||||||
|
transform: none !important;
|
||||||
|
|
||||||
|
.components-popover__content {
|
||||||
|
transform: none;
|
||||||
|
width: 100%;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
|
||||||
|
border-radius: 2px;
|
||||||
|
overflow-x: hidden !important;
|
||||||
|
|
||||||
|
ul li {
|
||||||
|
&:hover {
|
||||||
|
background-color: #eff2fd !important;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.components-base-control__field {
|
||||||
|
margin-bottom: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.components-checkbox-control__label {
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: normal !important;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.components-checkbox-control__input-container {
|
||||||
|
border: 1px solid #757575;
|
||||||
|
border-radius: 2px;
|
||||||
|
height: 20px !important;
|
||||||
|
padding: 1px;
|
||||||
|
width: 20px !important;
|
||||||
|
|
||||||
|
.components-checkbox-control__input[type='checkbox'] {
|
||||||
|
border: none;
|
||||||
|
height: 16px !important;
|
||||||
|
width: 16px !important;
|
||||||
|
&:checked {
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
svg {
|
||||||
|
height: 20px;
|
||||||
|
top: -1px;
|
||||||
|
width: 22px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import { __ } from '@wordpress/i18n';
|
||||||
|
import {
|
||||||
|
__experimentalSelectControl as SelectControl,
|
||||||
|
selectControlStateChangeTypes,
|
||||||
|
} from '@woocommerce/components';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import { renderMenu } from './render-menu';
|
||||||
|
import './multiple-selector.scss';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
options: Array< { label: string; value: string } >;
|
||||||
|
onSelect: (
|
||||||
|
selectedOptions: Array< { label: string; value: string } >
|
||||||
|
) => void;
|
||||||
|
selectedOptions?: Array< { label: string; value: string } >;
|
||||||
|
placeholder?: string;
|
||||||
|
onOpenClose?: ( isOpen: boolean ) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const MultipleSelector = ( {
|
||||||
|
options,
|
||||||
|
onSelect,
|
||||||
|
selectedOptions = [],
|
||||||
|
placeholder = __( 'Select platforms', 'woocommerce' ),
|
||||||
|
onOpenClose = () => {},
|
||||||
|
}: Props ) => {
|
||||||
|
return (
|
||||||
|
<SelectControl
|
||||||
|
label=""
|
||||||
|
multiple
|
||||||
|
__experimentalOpenMenuOnFocus
|
||||||
|
readOnlyWhenClosed={ false }
|
||||||
|
items={ options }
|
||||||
|
getFilteredItems={ ( allItems ) => allItems }
|
||||||
|
selected={ selectedOptions }
|
||||||
|
inputProps={ {
|
||||||
|
'aria-readonly': true,
|
||||||
|
'aria-label': __(
|
||||||
|
'Use up and down arrow keys to navigate',
|
||||||
|
'woocommerce'
|
||||||
|
),
|
||||||
|
} }
|
||||||
|
onKeyDown={ ( e ) => {
|
||||||
|
if ( e.key.length <= 1 ) {
|
||||||
|
e.preventDefault();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} }
|
||||||
|
placeholder={ selectedOptions.length ? '' : placeholder }
|
||||||
|
stateReducer={ ( state, actionAndChanges ) => {
|
||||||
|
const { changes, type } = actionAndChanges;
|
||||||
|
switch ( type ) {
|
||||||
|
case selectControlStateChangeTypes.ControlledPropUpdatedSelectedItem:
|
||||||
|
return {
|
||||||
|
...changes,
|
||||||
|
inputValue: state.inputValue,
|
||||||
|
};
|
||||||
|
case selectControlStateChangeTypes.ItemClick:
|
||||||
|
return {
|
||||||
|
...changes,
|
||||||
|
isOpen: true,
|
||||||
|
inputValue: state.inputValue,
|
||||||
|
highlightedIndex: state.highlightedIndex,
|
||||||
|
};
|
||||||
|
default:
|
||||||
|
return changes;
|
||||||
|
}
|
||||||
|
} }
|
||||||
|
onSelect={ ( item ) => {
|
||||||
|
if ( ! item ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const exist = selectedOptions.find(
|
||||||
|
( existingItem ) => existingItem.value === item.value
|
||||||
|
);
|
||||||
|
const updatedPlatforms = exist
|
||||||
|
? selectedOptions.filter(
|
||||||
|
( existingItem ) =>
|
||||||
|
existingItem.value !== item.value
|
||||||
|
)
|
||||||
|
: [ ...selectedOptions, item ];
|
||||||
|
onSelect( updatedPlatforms );
|
||||||
|
} }
|
||||||
|
onRemove={ ( item ) =>
|
||||||
|
onSelect( selectedOptions.filter( ( i ) => i !== item ) )
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{ renderMenu( { selectedOptions, onOpenClose } ) }
|
||||||
|
</SelectControl>
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1,62 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import { CheckboxControl } from '@wordpress/components';
|
||||||
|
import { useEffect } from '@wordpress/element';
|
||||||
|
import {
|
||||||
|
__experimentalSelectControlMenu as Menu,
|
||||||
|
__experimentalSelectControlMenuItem as MenuItem,
|
||||||
|
} from '@woocommerce/components';
|
||||||
|
import { ChildrenProps } from '@woocommerce/components/build-types/experimental-select-control/types';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
selectedOptions: Array< { label: string; value: string } >;
|
||||||
|
onOpenClose: ( isOpen: boolean ) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const renderMenu =
|
||||||
|
( { selectedOptions, onOpenClose }: Props ) =>
|
||||||
|
( {
|
||||||
|
items,
|
||||||
|
highlightedIndex,
|
||||||
|
isOpen,
|
||||||
|
getItemProps,
|
||||||
|
getMenuProps,
|
||||||
|
}: ChildrenProps< {
|
||||||
|
label: string;
|
||||||
|
value: string;
|
||||||
|
} > ) => {
|
||||||
|
useEffect( () => {
|
||||||
|
onOpenClose( isOpen );
|
||||||
|
}, [ isOpen ] );
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Menu
|
||||||
|
isOpen={ isOpen }
|
||||||
|
getMenuProps={ getMenuProps }
|
||||||
|
scrollIntoViewOnOpen={ true }
|
||||||
|
>
|
||||||
|
{ items.map( ( item, menuIndex ) => {
|
||||||
|
const isSelected = selectedOptions.includes( item );
|
||||||
|
return (
|
||||||
|
<MenuItem
|
||||||
|
key={ `${ item.value }` }
|
||||||
|
index={ menuIndex }
|
||||||
|
item={ item }
|
||||||
|
getItemProps={ getItemProps }
|
||||||
|
isActive={ highlightedIndex === menuIndex }
|
||||||
|
activeStyle={ {
|
||||||
|
backgroundColor: '#f6f7f7',
|
||||||
|
} }
|
||||||
|
>
|
||||||
|
<CheckboxControl
|
||||||
|
onChange={ () => {} }
|
||||||
|
checked={ isSelected }
|
||||||
|
label={ item.label }
|
||||||
|
/>
|
||||||
|
</MenuItem>
|
||||||
|
);
|
||||||
|
} ) }
|
||||||
|
</Menu>
|
||||||
|
);
|
||||||
|
};
|
|
@ -22,7 +22,12 @@ import { initializeExPlat } from '@woocommerce/explat';
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import { IntroOptIn } from './pages/IntroOptIn';
|
import { IntroOptIn } from './pages/IntroOptIn';
|
||||||
import { UserProfile } from './pages/UserProfile';
|
import {
|
||||||
|
UserProfile,
|
||||||
|
BusinessChoice,
|
||||||
|
SellingOnlineAnswer,
|
||||||
|
SellingPlatform,
|
||||||
|
} from './pages/UserProfile';
|
||||||
import { BusinessInfo } from './pages/BusinessInfo';
|
import { BusinessInfo } from './pages/BusinessInfo';
|
||||||
import { BusinessLocation } from './pages/BusinessLocation';
|
import { BusinessLocation } from './pages/BusinessLocation';
|
||||||
import { getCountryStateOptions } from './services/country';
|
import { getCountryStateOptions } from './services/country';
|
||||||
|
@ -76,9 +81,22 @@ export type ExtensionsEvent = {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO: add types as we develop the pages
|
||||||
|
export type OnboardingProfile = {
|
||||||
|
business_choice: BusinessChoice;
|
||||||
|
selling_online_answer: SellingOnlineAnswer | null;
|
||||||
|
selling_platforms: SellingPlatform[] | null;
|
||||||
|
skip?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
export type CoreProfilerStateMachineContext = {
|
export type CoreProfilerStateMachineContext = {
|
||||||
optInDataSharing: boolean;
|
optInDataSharing: boolean;
|
||||||
userProfile: { foo: { bar: 'qux' }; skipped: false } | { skipped: true };
|
userProfile: {
|
||||||
|
businessChoice?: BusinessChoice;
|
||||||
|
sellingOnlineAnswer?: SellingOnlineAnswer | null;
|
||||||
|
sellingPlatforms?: SellingPlatform[] | null;
|
||||||
|
skipped?: boolean;
|
||||||
|
};
|
||||||
geolocatedLocation: {
|
geolocatedLocation: {
|
||||||
location: string;
|
location: string;
|
||||||
};
|
};
|
||||||
|
@ -126,6 +144,36 @@ const handleCountries = assign( {
|
||||||
},
|
},
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
const getOnboardingProfileOption = async () =>
|
||||||
|
resolveSelect( OPTIONS_STORE_NAME ).getOption(
|
||||||
|
'woocommerce_onboarding_profile'
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleOnboardingProfileOption = assign( {
|
||||||
|
userProfile: (
|
||||||
|
_context,
|
||||||
|
event: DoneInvokeEvent< OnboardingProfile | undefined >
|
||||||
|
) => {
|
||||||
|
if ( ! event.data ) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const {
|
||||||
|
business_choice: businessChoice,
|
||||||
|
selling_online_answer: sellingOnlineAnswer,
|
||||||
|
selling_platforms: sellingPlatforms,
|
||||||
|
...rest
|
||||||
|
} = event.data;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...rest,
|
||||||
|
businessChoice,
|
||||||
|
sellingOnlineAnswer,
|
||||||
|
sellingPlatforms,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
} );
|
||||||
|
|
||||||
const redirectToWooHome = () => {
|
const redirectToWooHome = () => {
|
||||||
navigateTo( { url: getNewPath( {}, '/', {} ) } );
|
navigateTo( { url: getNewPath( {}, '/', {} ) } );
|
||||||
};
|
};
|
||||||
|
@ -148,6 +196,35 @@ const recordTracksIntroViewed = () => {
|
||||||
} );
|
} );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const recordTracksUserProfileViewed = () => {
|
||||||
|
recordEvent( 'storeprofiler_step_view', {
|
||||||
|
step: 'user_profile',
|
||||||
|
wc_version: getSetting( 'wcVersion' ),
|
||||||
|
} );
|
||||||
|
};
|
||||||
|
|
||||||
|
const recordTracksUserProfileCompleted = (
|
||||||
|
_context: CoreProfilerStateMachineContext,
|
||||||
|
event: Extract< UserProfileEvent, { type: 'USER_PROFILE_COMPLETED' } >
|
||||||
|
) => {
|
||||||
|
recordEvent( 'storeprofiler_step_complete', {
|
||||||
|
step: 'user_profile',
|
||||||
|
wc_version: getSetting( 'wcVersion' ),
|
||||||
|
} );
|
||||||
|
|
||||||
|
recordEvent( 'storeprofiler_user_profile', {
|
||||||
|
business_choice: event.payload.userProfile.businessChoice,
|
||||||
|
selling_online_answer: event.payload.userProfile.sellingOnlineAnswer,
|
||||||
|
selling_platforms: event.payload.userProfile.sellingPlatforms
|
||||||
|
? event.payload.userProfile.sellingPlatforms.join()
|
||||||
|
: null,
|
||||||
|
} );
|
||||||
|
};
|
||||||
|
|
||||||
|
const recordTracksUserProfileSkipped = () => {
|
||||||
|
recordEvent( 'storeprofiler_user_profile_skip' );
|
||||||
|
};
|
||||||
|
|
||||||
const recordTracksSkipBusinessLocationViewed = () => {
|
const recordTracksSkipBusinessLocationViewed = () => {
|
||||||
recordEvent( 'storeprofiler_step_view', {
|
recordEvent( 'storeprofiler_step_view', {
|
||||||
step: 'skip_business_location',
|
step: 'skip_business_location',
|
||||||
|
@ -183,6 +260,22 @@ const updateTrackingOption = (
|
||||||
} );
|
} );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const updateOnboardingProfileOption = (
|
||||||
|
context: CoreProfilerStateMachineContext
|
||||||
|
) => {
|
||||||
|
const { businessChoice, sellingOnlineAnswer, sellingPlatforms, ...rest } =
|
||||||
|
context.userProfile;
|
||||||
|
|
||||||
|
return dispatch( OPTIONS_STORE_NAME ).updateOptions( {
|
||||||
|
woocommerce_onboarding_profile: {
|
||||||
|
...rest,
|
||||||
|
business_choice: businessChoice,
|
||||||
|
selling_online_answer: sellingOnlineAnswer,
|
||||||
|
selling_platforms: sellingPlatforms,
|
||||||
|
},
|
||||||
|
} );
|
||||||
|
};
|
||||||
|
|
||||||
const updateBusinessLocation = ( countryAndState: string ) => {
|
const updateBusinessLocation = ( countryAndState: string ) => {
|
||||||
return dispatch( OPTIONS_STORE_NAME ).updateOptions( {
|
return dispatch( OPTIONS_STORE_NAME ).updateOptions( {
|
||||||
woocommerce_default_country: countryAndState,
|
woocommerce_default_country: countryAndState,
|
||||||
|
@ -238,10 +331,14 @@ const coreProfilerMachineActions = {
|
||||||
recordTracksIntroCompleted,
|
recordTracksIntroCompleted,
|
||||||
recordTracksIntroSkipped,
|
recordTracksIntroSkipped,
|
||||||
recordTracksIntroViewed,
|
recordTracksIntroViewed,
|
||||||
|
recordTracksUserProfileCompleted,
|
||||||
|
recordTracksUserProfileSkipped,
|
||||||
|
recordTracksUserProfileViewed,
|
||||||
recordTracksSkipBusinessLocationViewed,
|
recordTracksSkipBusinessLocationViewed,
|
||||||
recordTracksSkipBusinessLocationCompleted,
|
recordTracksSkipBusinessLocationCompleted,
|
||||||
assignOptInDataSharing,
|
assignOptInDataSharing,
|
||||||
handleCountries,
|
handleCountries,
|
||||||
|
handleOnboardingProfileOption,
|
||||||
redirectToWooHome,
|
redirectToWooHome,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -249,6 +346,7 @@ const coreProfilerMachineServices = {
|
||||||
getAllowTrackingOption,
|
getAllowTrackingOption,
|
||||||
getCountries,
|
getCountries,
|
||||||
getExtensions,
|
getExtensions,
|
||||||
|
getOnboardingProfileOption,
|
||||||
};
|
};
|
||||||
export const coreProfilerStateMachineDefinition = createMachine( {
|
export const coreProfilerStateMachineDefinition = createMachine( {
|
||||||
id: 'coreProfiler',
|
id: 'coreProfiler',
|
||||||
|
@ -296,7 +394,7 @@ export const coreProfilerStateMachineDefinition = createMachine( {
|
||||||
introOptIn: {
|
introOptIn: {
|
||||||
on: {
|
on: {
|
||||||
INTRO_COMPLETED: {
|
INTRO_COMPLETED: {
|
||||||
target: 'userProfile',
|
target: 'preUserProfile',
|
||||||
actions: [
|
actions: [
|
||||||
'assignOptInDataSharing',
|
'assignOptInDataSharing',
|
||||||
'updateTrackingOption',
|
'updateTrackingOption',
|
||||||
|
@ -328,10 +426,25 @@ export const coreProfilerStateMachineDefinition = createMachine( {
|
||||||
component: IntroOptIn,
|
component: IntroOptIn,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
preUserProfile: {
|
||||||
|
invoke: {
|
||||||
|
src: 'getOnboardingProfileOption',
|
||||||
|
onDone: [
|
||||||
|
{
|
||||||
|
actions: [ 'handleOnboardingProfileOption' ],
|
||||||
|
target: 'userProfile',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
onError: {
|
||||||
|
target: 'userProfile',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
userProfile: {
|
userProfile: {
|
||||||
|
entry: [ 'recordTracksUserProfileViewed' ],
|
||||||
on: {
|
on: {
|
||||||
USER_PROFILE_COMPLETED: {
|
USER_PROFILE_COMPLETED: {
|
||||||
target: 'preBusinessInfo',
|
target: 'postUserProfile',
|
||||||
actions: [
|
actions: [
|
||||||
assign( {
|
assign( {
|
||||||
userProfile: ( context, event: UserProfileEvent ) =>
|
userProfile: ( context, event: UserProfileEvent ) =>
|
||||||
|
@ -340,7 +453,7 @@ export const coreProfilerStateMachineDefinition = createMachine( {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
USER_PROFILE_SKIPPED: {
|
USER_PROFILE_SKIPPED: {
|
||||||
target: 'preBusinessInfo',
|
target: 'postUserProfile',
|
||||||
actions: [
|
actions: [
|
||||||
assign( {
|
assign( {
|
||||||
userProfile: ( context, event: UserProfileEvent ) =>
|
userProfile: ( context, event: UserProfileEvent ) =>
|
||||||
|
@ -349,11 +462,36 @@ export const coreProfilerStateMachineDefinition = createMachine( {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
exit: actions.choose( [
|
||||||
|
{
|
||||||
|
cond: ( _context, event ) =>
|
||||||
|
event.type === 'USER_PROFILE_COMPLETED',
|
||||||
|
actions: 'recordTracksUserProfileCompleted',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
cond: ( _context, event ) =>
|
||||||
|
event.type === 'USER_PROFILE_SKIPPED',
|
||||||
|
actions: 'recordTracksUserProfileSkipped',
|
||||||
|
},
|
||||||
|
] ),
|
||||||
meta: {
|
meta: {
|
||||||
progress: 40,
|
progress: 40,
|
||||||
component: UserProfile,
|
component: UserProfile,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
postUserProfile: {
|
||||||
|
invoke: {
|
||||||
|
src: ( context ) => {
|
||||||
|
return updateOnboardingProfileOption( context );
|
||||||
|
},
|
||||||
|
onDone: {
|
||||||
|
target: 'preBusinessInfo',
|
||||||
|
},
|
||||||
|
onError: {
|
||||||
|
target: 'preBusinessInfo',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
preBusinessInfo: {
|
preBusinessInfo: {
|
||||||
always: [
|
always: [
|
||||||
// immediately transition to businessInfo without any events as long as geolocation parallel has completed
|
// immediately transition to businessInfo without any events as long as geolocation parallel has completed
|
||||||
|
|
|
@ -41,6 +41,7 @@ export const BusinessLocation = ( {
|
||||||
<Navigation percentage={ navigationProgress } />
|
<Navigation percentage={ navigationProgress } />
|
||||||
<div className="woocommerce-profiler-page__content woocommerce-profiler-business-location__content">
|
<div className="woocommerce-profiler-page__content woocommerce-profiler-business-location__content">
|
||||||
<Heading
|
<Heading
|
||||||
|
className="woocommerce-profiler__stepper-heading"
|
||||||
title={ __(
|
title={ __(
|
||||||
'Where is your business located?',
|
'Where is your business located?',
|
||||||
'woocommerce'
|
'woocommerce'
|
||||||
|
@ -74,9 +75,9 @@ export const BusinessLocation = ( {
|
||||||
showAllOnFocus
|
showAllOnFocus
|
||||||
isSearchable
|
isSearchable
|
||||||
/>
|
/>
|
||||||
<div className="woocommerce-profiler-go-to-mystore__button-container">
|
<div className="woocommerce-profiler-button-container woocommerce-profiler-go-to-mystore__button-container">
|
||||||
<Button
|
<Button
|
||||||
className="woocommerce-profiler-go-to-mystore__button"
|
className="woocommerce-profiler-button"
|
||||||
variant="primary"
|
variant="primary"
|
||||||
disabled={ ! storeCountry.key }
|
disabled={ ! storeCountry.key }
|
||||||
onClick={ () => {
|
onClick={ () => {
|
||||||
|
|
|
@ -1,41 +1,299 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import { __ } from '@wordpress/i18n';
|
||||||
|
import { Button } from '@wordpress/components';
|
||||||
|
import { useState } from '@wordpress/element';
|
||||||
|
import { SelectControl } from '@woocommerce/components';
|
||||||
|
import { Icon, chevronDown } from '@wordpress/icons';
|
||||||
|
import classnames from 'classnames';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import { UserProfileEvent } from '../index';
|
import { UserProfileEvent, CoreProfilerStateMachineContext } from '../index';
|
||||||
|
import { Navigation } from '../components/navigation/navigation';
|
||||||
|
import { Heading } from '../components/heading/heading';
|
||||||
|
import { Choice } from '../components/choice/choice';
|
||||||
|
import { MultipleSelector } from '../components/multiple-selector/multiple-selector';
|
||||||
|
|
||||||
|
const businessOptions = [
|
||||||
|
{
|
||||||
|
title: __( "I'm just starting my business", 'woocommerce' ),
|
||||||
|
value: 'im_just_starting_my_business' as const,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: __( "I'm already selling", 'woocommerce' ),
|
||||||
|
value: 'im_already_selling' as const,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: __( "I'm setting up a store for a client", 'woocommerce' ),
|
||||||
|
value: 'im_setting_up_a_store_for_a_client' as const,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const sellingOnlineOptions = [
|
||||||
|
{
|
||||||
|
label: __( "Yes, I'm selling online", 'woocommerce' ),
|
||||||
|
value: 'yes_im_selling_online' as const,
|
||||||
|
key: 'yes_im_selling_online' as const,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: __( "No, I'm selling offline", 'woocommerce' ),
|
||||||
|
value: 'no_im_selling_offline' as const,
|
||||||
|
key: 'no_im_selling_offline' as const,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: __( "I'm selling both online and offline", 'woocommerce' ),
|
||||||
|
value: 'im_selling_both_online_and_offline' as const,
|
||||||
|
key: 'im_selling_both_online_and_offline' as const,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const platformOptions = [
|
||||||
|
{
|
||||||
|
label: __( 'Amazon', 'woocommerce' ),
|
||||||
|
value: 'amazon' as const,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: __( 'Adobe Commerce', 'woocommerce' ),
|
||||||
|
value: 'adobe_commerce' as const,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: __( 'Big Cartel', 'woocommerce' ),
|
||||||
|
value: 'big_cartel' as const,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: __( 'Big Commerce', 'woocommerce' ),
|
||||||
|
value: 'big_commerce' as const,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: __( 'Ebay', 'woocommerce' ),
|
||||||
|
value: 'ebay' as const,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: __( 'Ecwid', 'woocommerce' ),
|
||||||
|
value: 'ecwid' as const,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: __( 'Etsy', 'woocommerce' ),
|
||||||
|
value: 'etsy' as const,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: __( 'Facebook Marketplace', 'woocommerce' ),
|
||||||
|
value: 'facebook_marketplace' as const,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: __( 'Google Shopping', 'woocommerce' ),
|
||||||
|
value: 'google_shopping' as const,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: __( 'Pinterest', 'woocommerce' ),
|
||||||
|
value: 'pinterest' as const,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: __( 'Shopify', 'woocommerce' ),
|
||||||
|
value: 'shopify' as const,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: __( 'Square', 'woocommerce' ),
|
||||||
|
value: 'square' as const,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: __( 'Squarespace', 'woocommerce' ),
|
||||||
|
value: 'squarespace' as const,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: __( 'Wix', 'woocommerce' ),
|
||||||
|
value: 'wix' as const,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: __( 'WordPress', 'woocommerce' ),
|
||||||
|
value: 'wordpress' as const,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export type BusinessChoice = typeof businessOptions[ 0 ][ 'value' ];
|
||||||
|
export type SellingOnlineAnswer = typeof sellingOnlineOptions[ 0 ][ 'value' ];
|
||||||
|
export type SellingPlatform = typeof platformOptions[ 0 ][ 'value' ];
|
||||||
|
|
||||||
export const UserProfile = ( {
|
export const UserProfile = ( {
|
||||||
sendEvent,
|
sendEvent,
|
||||||
|
navigationProgress,
|
||||||
|
context,
|
||||||
}: {
|
}: {
|
||||||
sendEvent: ( event: UserProfileEvent ) => void;
|
sendEvent: ( event: UserProfileEvent ) => void;
|
||||||
|
navigationProgress: number;
|
||||||
|
context: CoreProfilerStateMachineContext;
|
||||||
} ) => {
|
} ) => {
|
||||||
|
const [ businessChoice, setBusinessChoice ] = useState< BusinessChoice >(
|
||||||
|
context.userProfile.businessChoice || 'im_just_starting_my_business'
|
||||||
|
);
|
||||||
|
const [ sellingOnlineAnswer, setSellingOnlineAnswer ] =
|
||||||
|
useState< SellingOnlineAnswer | null >(
|
||||||
|
context.userProfile.sellingOnlineAnswer || null
|
||||||
|
);
|
||||||
|
const [ sellingPlatforms, setSellingPlatforms ] =
|
||||||
|
useState< Array< SellingPlatform > | null >(
|
||||||
|
context.userProfile.sellingPlatforms || null
|
||||||
|
);
|
||||||
|
const [ isPlatformDropdownOpen, setIsPlatformDropdownOpen ] =
|
||||||
|
useState( false );
|
||||||
|
|
||||||
|
const renderAlreadySellingOptions = () => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="woocommerce-profiler-selling-online-question">
|
||||||
|
<p className="woocommerce-profiler-question-label">
|
||||||
|
{ __( 'Are you selling online?', 'woocommerce' ) }
|
||||||
|
</p>
|
||||||
|
<SelectControl
|
||||||
|
className="woocommerce-profiler-select-control__selling-online-question"
|
||||||
|
instanceId={ 1 }
|
||||||
|
label={ __( 'Select an option', 'woocommerce' ) }
|
||||||
|
autoComplete="new-password" // disable autocomplete and autofill
|
||||||
|
options={ sellingOnlineOptions }
|
||||||
|
excludeSelectedOptions={ false }
|
||||||
|
help={ <Icon icon={ chevronDown } /> }
|
||||||
|
onChange={ (
|
||||||
|
selectedOptionKey: typeof sellingOnlineAnswer
|
||||||
|
) => {
|
||||||
|
setSellingOnlineAnswer( selectedOptionKey );
|
||||||
|
} }
|
||||||
|
multiple={ false }
|
||||||
|
selected={ sellingOnlineAnswer }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{ sellingOnlineAnswer &&
|
||||||
|
[
|
||||||
|
'yes_im_selling_online',
|
||||||
|
'im_selling_both_online_and_offline',
|
||||||
|
].includes( sellingOnlineAnswer ) && (
|
||||||
|
<div className="woocommerce-profiler-selling-platform">
|
||||||
|
<p className="woocommerce-profiler-question-label">
|
||||||
|
{ __(
|
||||||
|
'Which platform(s) are you currently using?',
|
||||||
|
'woocommerce'
|
||||||
|
) }
|
||||||
|
</p>
|
||||||
|
<MultipleSelector
|
||||||
|
options={ platformOptions }
|
||||||
|
selectedOptions={ platformOptions.filter(
|
||||||
|
( option ) =>
|
||||||
|
sellingPlatforms?.includes(
|
||||||
|
option.value
|
||||||
|
)
|
||||||
|
) }
|
||||||
|
onSelect={ ( items ) => {
|
||||||
|
setSellingPlatforms(
|
||||||
|
items.map(
|
||||||
|
( item ) =>
|
||||||
|
item.value as SellingPlatform
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} }
|
||||||
|
onOpenClose={ setIsPlatformDropdownOpen }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) }
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onContinue = () => {
|
||||||
|
sendEvent( {
|
||||||
|
type: 'USER_PROFILE_COMPLETED',
|
||||||
|
payload: {
|
||||||
|
userProfile: {
|
||||||
|
businessChoice,
|
||||||
|
sellingOnlineAnswer:
|
||||||
|
businessChoice === 'im_already_selling'
|
||||||
|
? sellingOnlineAnswer
|
||||||
|
: null,
|
||||||
|
sellingPlatforms:
|
||||||
|
businessChoice === 'im_already_selling'
|
||||||
|
? sellingPlatforms
|
||||||
|
: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} );
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div
|
||||||
<div data-testid="core-profiler-user-profile">User Profile</div>
|
className="woocommerce-profiler-user-profile"
|
||||||
<button
|
data-testid="core-profiler-user-profile"
|
||||||
onClick={ () =>
|
>
|
||||||
sendEvent( {
|
<Navigation
|
||||||
type: 'USER_PROFILE_COMPLETED',
|
percentage={ navigationProgress }
|
||||||
payload: {
|
skipText={ __( 'Skip this setup', 'woocommerce' ) }
|
||||||
userProfile: {
|
onSkip={ () =>
|
||||||
foo: { bar: 'qux' },
|
|
||||||
skipped: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} )
|
|
||||||
}
|
|
||||||
>
|
|
||||||
Next
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
onClick={ () =>
|
|
||||||
sendEvent( {
|
sendEvent( {
|
||||||
type: 'USER_PROFILE_SKIPPED',
|
type: 'USER_PROFILE_SKIPPED',
|
||||||
payload: { userProfile: { skipped: true } },
|
payload: { userProfile: { skipped: true } },
|
||||||
} )
|
} )
|
||||||
}
|
}
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
className={ classnames(
|
||||||
|
'woocommerce-profiler-page__content woocommerce-profiler-user-profile__content',
|
||||||
|
{
|
||||||
|
'is-platform-selector-open': isPlatformDropdownOpen,
|
||||||
|
}
|
||||||
|
) }
|
||||||
>
|
>
|
||||||
Skip
|
<Heading
|
||||||
</button>
|
className="woocommerce-profiler__stepper-heading"
|
||||||
</>
|
title={ __(
|
||||||
|
'Which one of these best describes you?',
|
||||||
|
'woocommerce'
|
||||||
|
) }
|
||||||
|
subTitle={ __(
|
||||||
|
'Let us know where you are in your commerce journey so that we can tailor your Woo experience for you.',
|
||||||
|
'woocommerce'
|
||||||
|
) }
|
||||||
|
/>
|
||||||
|
<form className="woocommerce-user-profile-choices">
|
||||||
|
<fieldset>
|
||||||
|
<legend className="screen-reader-text">
|
||||||
|
{ __(
|
||||||
|
'Which one of these best describes you?',
|
||||||
|
'woocommerce'
|
||||||
|
) }
|
||||||
|
</legend>
|
||||||
|
{ businessOptions.map( ( { title, value } ) => {
|
||||||
|
return (
|
||||||
|
<Choice
|
||||||
|
key={ value }
|
||||||
|
name="user-profile-choice"
|
||||||
|
title={ title }
|
||||||
|
selected={ businessChoice === value }
|
||||||
|
value={ value }
|
||||||
|
onChange={ ( _value ) => {
|
||||||
|
setBusinessChoice(
|
||||||
|
_value as BusinessChoice
|
||||||
|
);
|
||||||
|
} }
|
||||||
|
subOptionsComponent={
|
||||||
|
value === 'im_already_selling'
|
||||||
|
? renderAlreadySellingOptions()
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
} ) }
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
<div className="woocommerce-profiler-button-container">
|
||||||
|
<Button
|
||||||
|
className="woocommerce-profiler-button"
|
||||||
|
variant="primary"
|
||||||
|
onClick={ onContinue }
|
||||||
|
>
|
||||||
|
{ __( 'Continue', 'woocommerce' ) }
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,129 @@
|
||||||
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import { render, screen, fireEvent } from '@testing-library/react';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import { UserProfile } from '../UserProfile';
|
||||||
|
import { CoreProfilerStateMachineContext } from '../..';
|
||||||
|
|
||||||
|
describe( 'UserProfile', () => {
|
||||||
|
let props: {
|
||||||
|
sendEvent: jest.Mock;
|
||||||
|
navigationProgress: number;
|
||||||
|
context: Pick< CoreProfilerStateMachineContext, 'userProfile' >;
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach( () => {
|
||||||
|
props = {
|
||||||
|
sendEvent: jest.fn(),
|
||||||
|
navigationProgress: 0,
|
||||||
|
context: {
|
||||||
|
userProfile: {
|
||||||
|
businessChoice: 'im_just_starting_my_business',
|
||||||
|
sellingOnlineAnswer: null,
|
||||||
|
sellingPlatforms: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
} );
|
||||||
|
|
||||||
|
it( 'should render user profile page', () => {
|
||||||
|
// @ts-ignore
|
||||||
|
render( <UserProfile { ...props } /> );
|
||||||
|
expect(
|
||||||
|
screen.getByText( /Which one of these best describes you?/i, {
|
||||||
|
selector: 'h1',
|
||||||
|
} )
|
||||||
|
).toBeInTheDocument();
|
||||||
|
expect(
|
||||||
|
screen.getByRole( 'button', {
|
||||||
|
name: /Continue/i,
|
||||||
|
} )
|
||||||
|
).toBeInTheDocument();
|
||||||
|
} );
|
||||||
|
|
||||||
|
it( 'should show online selling question when choosing "im_already_selling"', () => {
|
||||||
|
// @ts-ignore
|
||||||
|
render( <UserProfile { ...props } /> );
|
||||||
|
const radioInput = screen.getByLabelText< HTMLInputElement >(
|
||||||
|
"I'm already selling"
|
||||||
|
); // Replace with the label of your radio button
|
||||||
|
|
||||||
|
// Perform the radio button selection
|
||||||
|
fireEvent.click( radioInput );
|
||||||
|
|
||||||
|
// Assert the expected behavior
|
||||||
|
expect( radioInput.checked ).toBe( true );
|
||||||
|
|
||||||
|
const onlineSellingQuestion = screen.getByText(
|
||||||
|
/Are you selling online?/i
|
||||||
|
);
|
||||||
|
expect( onlineSellingQuestion ).toBeInTheDocument();
|
||||||
|
} );
|
||||||
|
|
||||||
|
it( 'should show online selling question when choosing "Yes, I\'m selling online"', () => {
|
||||||
|
render(
|
||||||
|
// @ts-ignore
|
||||||
|
<UserProfile
|
||||||
|
{ ...{
|
||||||
|
...props,
|
||||||
|
context: {
|
||||||
|
userProfile: {
|
||||||
|
businessChoice: 'im_already_selling',
|
||||||
|
sellingOnlineAnswer: 'yes_im_selling_online',
|
||||||
|
sellingPlatforms: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
const platformSelector = screen.getByLabelText( /Select an option/i );
|
||||||
|
expect( platformSelector ).toBeInTheDocument();
|
||||||
|
} );
|
||||||
|
|
||||||
|
it( 'should call sendEvent with USER_PROFILE_COMPLETED event when button is clicked', () => {
|
||||||
|
render(
|
||||||
|
// @ts-ignore
|
||||||
|
<UserProfile { ...props } />
|
||||||
|
);
|
||||||
|
screen
|
||||||
|
.getByRole( 'button', {
|
||||||
|
name: /Continue/i,
|
||||||
|
} )
|
||||||
|
.click();
|
||||||
|
expect( props.sendEvent ).toHaveBeenCalledWith( {
|
||||||
|
type: 'USER_PROFILE_COMPLETED',
|
||||||
|
payload: {
|
||||||
|
userProfile: {
|
||||||
|
businessChoice: 'im_just_starting_my_business',
|
||||||
|
sellingOnlineAnswer: null,
|
||||||
|
sellingPlatforms: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
|
||||||
|
it( 'should call sendEvent with USER_PROFILE_SKIPPED event when skip button is clicked', () => {
|
||||||
|
render(
|
||||||
|
// @ts-ignore
|
||||||
|
<UserProfile { ...props } />
|
||||||
|
);
|
||||||
|
screen
|
||||||
|
.getByRole( 'button', {
|
||||||
|
name: /Skip this setup/i,
|
||||||
|
} )
|
||||||
|
.click();
|
||||||
|
expect( props.sendEvent ).toHaveBeenCalledWith( {
|
||||||
|
type: 'USER_PROFILE_SKIPPED',
|
||||||
|
payload: {
|
||||||
|
userProfile: {
|
||||||
|
skipped: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
} );
|
|
@ -19,6 +19,85 @@
|
||||||
@include breakpoint( '<782px' ) {
|
@include breakpoint( '<782px' ) {
|
||||||
padding: 0 20px;
|
padding: 0 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.woocommerce-profiler-button-container {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 404px;
|
||||||
|
@include breakpoint( '<782px' ) {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 20px;
|
||||||
|
padding: 0 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.woocommerce-profiler-button {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 10px 16px;
|
||||||
|
height: 48px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.woocommerce-select-control__option {
|
||||||
|
font-size: 13px;
|
||||||
|
height: 40px;
|
||||||
|
min-height: initial;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: #eff2fd;
|
||||||
|
color: $gray-900;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.woocommerce-select-control__listbox {
|
||||||
|
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
margin-top: 8px;
|
||||||
|
top: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.woocommerce-select-control__control {
|
||||||
|
height: 40px;
|
||||||
|
padding: 12px;
|
||||||
|
border: 1px solid #bbb;
|
||||||
|
|
||||||
|
label,
|
||||||
|
.woocommerce-select-control__control-input {
|
||||||
|
font-size: 13px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.components-base-control__label {
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 16px;
|
||||||
|
color: $gray-700;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.with-value {
|
||||||
|
.woocommerce-select-control__control-input {
|
||||||
|
margin: 0;
|
||||||
|
color: $gray-900;
|
||||||
|
}
|
||||||
|
|
||||||
|
.components-base-control__label {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-active {
|
||||||
|
border: 1px solid var(--wp-admin-theme-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#woocommerce-select-control__listbox-0 {
|
||||||
|
top: 40px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.woocommerce-profiler-select-control__country {
|
||||||
|
max-width: 404px;
|
||||||
|
margin: auto auto 32px auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Intro opt-in page
|
// Intro opt-in page
|
||||||
|
@ -117,6 +196,11 @@
|
||||||
max-width: 514px;
|
max-width: 514px;
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.woocommerce-select-control__control-input {
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 16px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
|
@ -124,38 +208,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.woocommerce-profiler-select-control__country {
|
|
||||||
max-width: 400px;
|
|
||||||
margin: auto auto 32px auto;
|
|
||||||
.woocommerce-select-control__option {
|
|
||||||
font-size: 13px;
|
|
||||||
&:hover {
|
|
||||||
background: #eff2fd;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.woocommerce-select-control__listbox {
|
|
||||||
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
margin-top: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.woocommerce-select-control__control {
|
// Business location page
|
||||||
height: 40px;
|
|
||||||
padding: 12px;
|
|
||||||
border: 1px solid #bbb;
|
|
||||||
label,
|
|
||||||
input {
|
|
||||||
font-size: 13px;
|
|
||||||
color: var(--wp-components-color-foreground, #757575);
|
|
||||||
}
|
|
||||||
&.is-active {
|
|
||||||
border: 1px solid #3858e9;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#woocommerce-select-control__listbox-0 {
|
|
||||||
top: 40px !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.woocommerce-profiler-business-location {
|
.woocommerce-profiler-business-location {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
@ -169,42 +223,6 @@
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.woocommerce-profiler-heading {
|
|
||||||
margin-top: 72px;
|
|
||||||
@include breakpoint( '<782px' ) {
|
|
||||||
margin-top: 52px;
|
|
||||||
margin-bottom: 40px;
|
|
||||||
h1 {
|
|
||||||
font-size: 32px;
|
|
||||||
line-height: 40px;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
h2 {
|
|
||||||
text-align: left;
|
|
||||||
font-size: 16px;
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.woocommerce-profiler-go-to-mystore__button-container {
|
|
||||||
width: 100%;
|
|
||||||
max-width: 400px;
|
|
||||||
@include breakpoint( '<782px' ) {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 20px;
|
|
||||||
padding: 0 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.woocommerce-profiler-go-to-mystore__button {
|
|
||||||
display: flex;
|
|
||||||
width: 100%;
|
|
||||||
justify-content: center;
|
|
||||||
padding: 10px 16px;
|
|
||||||
height: 48px;
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
.components-base-control__field {
|
.components-base-control__field {
|
||||||
height: 40px;
|
height: 40px;
|
||||||
}
|
}
|
||||||
|
@ -232,6 +250,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Loader page
|
||||||
.woocommerce-profiler-loader {
|
.woocommerce-profiler-loader {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@ -283,3 +302,45 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// User profile page
|
||||||
|
.woocommerce-profiler-user-profile {
|
||||||
|
.woocommerce-profiler-user-profile__content {
|
||||||
|
min-height: 630px;
|
||||||
|
|
||||||
|
&.is-platform-selector-open {
|
||||||
|
padding-bottom: 145px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.woocommerce-user-profile-choices {
|
||||||
|
margin-bottom: 32px;
|
||||||
|
max-width: 404px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.woocommerce-profiler-heading__title {
|
||||||
|
max-width: 480px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.woocommerce-user-profile-choices fieldset {
|
||||||
|
display: flex;
|
||||||
|
gap: 18px;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.woocommerce-profiler-choice-sub-options {
|
||||||
|
.woocommerce-profiler-question-label {
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: $gray-900;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 11px;
|
||||||
|
line-height: 16px;
|
||||||
|
margin: 0 0 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.woocommerce-profiler-selling-platform {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1955,7 +1955,7 @@ Object {
|
||||||
class="woocommerce-profiler-page__content woocommerce-profiler-business-location__content"
|
class="woocommerce-profiler-page__content woocommerce-profiler-business-location__content"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="woocommerce-profiler-heading"
|
class="woocommerce-profiler-heading woocommerce-profiler__stepper-heading"
|
||||||
>
|
>
|
||||||
<h1
|
<h1
|
||||||
class="woocommerce-profiler-heading__title"
|
class="woocommerce-profiler-heading__title"
|
||||||
|
@ -2032,10 +2032,10 @@ Object {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="woocommerce-profiler-go-to-mystore__button-container"
|
class="woocommerce-profiler-button-container woocommerce-profiler-go-to-mystore__button-container"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
class="components-button woocommerce-profiler-go-to-mystore__button is-primary"
|
class="components-button woocommerce-profiler-button is-primary"
|
||||||
disabled=""
|
disabled=""
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
|
@ -2107,7 +2107,7 @@ Object {
|
||||||
class="woocommerce-profiler-page__content woocommerce-profiler-business-location__content"
|
class="woocommerce-profiler-page__content woocommerce-profiler-business-location__content"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="woocommerce-profiler-heading"
|
class="woocommerce-profiler-heading woocommerce-profiler__stepper-heading"
|
||||||
>
|
>
|
||||||
<h1
|
<h1
|
||||||
class="woocommerce-profiler-heading__title"
|
class="woocommerce-profiler-heading__title"
|
||||||
|
@ -2184,10 +2184,10 @@ Object {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="woocommerce-profiler-go-to-mystore__button-container"
|
class="woocommerce-profiler-button-container woocommerce-profiler-go-to-mystore__button-container"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
class="components-button woocommerce-profiler-go-to-mystore__button is-primary"
|
class="components-button woocommerce-profiler-button is-primary"
|
||||||
disabled=""
|
disabled=""
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
|
@ -3033,16 +3033,179 @@ Object {
|
||||||
class="woocommerce-profile-wizard__container woocommerce-profile-wizard__step-userProfile"
|
class="woocommerce-profile-wizard__container woocommerce-profile-wizard__step-userProfile"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
class="woocommerce-profiler-user-profile"
|
||||||
data-testid="core-profiler-user-profile"
|
data-testid="core-profiler-user-profile"
|
||||||
>
|
>
|
||||||
User Profile
|
<div
|
||||||
|
class="woocommerce-profiler-navigation-container"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="woocommerce-profiler-progress-bar progress-bar"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="woocommerce-profiler-progress-bar__container"
|
||||||
|
style="background-color: transparent;"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="woocommerce-profiler-progress-bar__filler"
|
||||||
|
style="width: 40%; display: inherit;"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="woocommerce-profiler-navigation"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="woocommerce-profiler-navigation-col-left"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="woologo"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
class="wc-icon wc-icon__woo-logo"
|
||||||
|
preserveAspectRatio="xMidYMid"
|
||||||
|
version="1.1"
|
||||||
|
viewBox="0 0 256 153"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="m23.759 0h208.38c13.187 0 23.863 10.675 23.863 23.863v79.542c0 13.187-10.675 23.863-23.863 23.863h-74.727l10.257 25.118-45.109-25.118h-98.695c-13.187 0-23.863-10.675-23.863-23.863v-79.542c-0.10466-13.083 10.571-23.863 23.758-23.863z"
|
||||||
|
fill="#7f54b3"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="m14.578 21.75c1.4569-1.9772 3.6423-3.0179 6.5561-3.226 5.3073-0.41626 8.3252 2.0813 9.0537 7.4927 3.226 21.75 6.7642 40.169 10.511 55.259l22.79-43.395c2.0813-3.9545 4.6829-6.0358 7.8049-6.2439 4.5789-0.3122 7.3886 2.6016 8.5333 8.7415 2.6016 13.841 5.9317 25.6 9.8862 35.59 2.7057-26.433 7.2846-45.476 13.737-57.236 1.561-2.9138 3.8504-4.3707 6.8683-4.5789 2.3935-0.20813 4.5789 0.52033 6.5561 2.0813 1.9772 1.561 3.0179 3.5382 3.226 5.9317 0.10406 1.8732-0.20813 3.4341-1.0407 4.9951-4.0585 7.4927-7.3886 20.085-10.094 37.567-2.6016 16.963-3.5382 30.179-2.9138 39.649 0.20813 2.6016-0.20813 4.8911-1.2488 6.8683-1.2488 2.2894-3.122 3.5382-5.5154 3.7463-2.7057 0.20813-5.5154-1.0406-8.2211-3.8504-9.678-9.8862-17.379-24.663-22.998-44.332-6.7642 13.32-11.759 23.311-14.985 29.971-6.1398 11.759-11.343 17.795-15.714 18.107-2.8098 0.20813-5.2033-2.1854-7.2846-7.1805-5.3073-13.633-11.031-39.961-17.171-78.985-0.41626-2.7057 0.20813-5.0992 1.665-6.9724zm223.64 16.338c-3.7463-6.5561-9.2618-10.511-16.65-12.072-1.9772-0.41626-3.8504-0.62439-5.6195-0.62439-9.9902 0-18.107 5.2033-24.455 15.61-5.4114 8.8455-8.1171 18.628-8.1171 29.346 0 8.013 1.665 14.881 4.9951 20.605 3.7463 6.5561 9.2618 10.511 16.65 12.072 1.9772 0.41626 3.8504 0.62439 5.6195 0.62439 10.094 0 18.211-5.2033 24.455-15.61 5.4114-8.9496 8.1171-18.732 8.1171-29.45 0.10406-8.1171-1.665-14.881-4.9951-20.501zm-13.112 28.826c-1.4569 6.8683-4.0585 11.967-7.9089 15.402-3.0179 2.7057-5.8276 3.8504-8.4293 3.3301-2.4976-0.52033-4.5789-2.7057-6.1398-6.7642-1.2488-3.226-1.8732-6.452-1.8732-9.4699 0-2.6016 0.20813-5.2033 0.72846-7.5967 0.93659-4.2667 2.7057-8.4293 5.5154-12.384 3.4341-5.0992 7.0764-7.1805 10.823-6.452 2.4976 0.52033 4.5789 2.7057 6.1398 6.7642 1.2488 3.226 1.8732 6.452 1.8732 9.4699 0 2.7057-0.20813 5.3073-0.72846 7.7008zm-52.033-28.826c-3.7463-6.5561-9.3659-10.511-16.65-12.072-1.9772-0.41626-3.8504-0.62439-5.6195-0.62439-9.9902 0-18.107 5.2033-24.455 15.61-5.4114 8.8455-8.1171 18.628-8.1171 29.346 0 8.013 1.665 14.881 4.9951 20.605 3.7463 6.5561 9.2618 10.511 16.65 12.072 1.9772 0.41626 3.8504 0.62439 5.6195 0.62439 10.094 0 18.211-5.2033 24.455-15.61 5.4114-8.9496 8.1171-18.732 8.1171-29.45 0-8.1171-1.665-14.881-4.9951-20.501zm-13.216 28.826c-1.4569 6.8683-4.0585 11.967-7.9089 15.402-3.0179 2.7057-5.8276 3.8504-8.4293 3.3301-2.4976-0.52033-4.5789-2.7057-6.1398-6.7642-1.2488-3.226-1.8732-6.452-1.8732-9.4699 0-2.6016 0.20813-5.2033 0.72846-7.5967 0.93658-4.2667 2.7057-8.4293 5.5154-12.384 3.4341-5.0992 7.0764-7.1805 10.823-6.452 2.4976 0.52033 4.5789 2.7057 6.1398 6.7642 1.2488 3.226 1.8732 6.452 1.8732 9.4699 0.10406 2.7057-0.20813 5.3073-0.72846 7.7008z"
|
||||||
|
fill="#fff"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="woocommerce-profiler-navigation-col-right"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
class="components-button woocommerce-profiler-navigation-skip-link is-link"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
Skip this setup
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="woocommerce-profiler-page__content woocommerce-profiler-user-profile__content"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="woocommerce-profiler-heading woocommerce-profiler__stepper-heading"
|
||||||
|
>
|
||||||
|
<h1
|
||||||
|
class="woocommerce-profiler-heading__title"
|
||||||
|
>
|
||||||
|
Which one of these best describes you?
|
||||||
|
</h1>
|
||||||
|
<h2
|
||||||
|
class="woocommerce-profiler-heading__subtitle"
|
||||||
|
>
|
||||||
|
Let us know where you are in your commerce journey so that we can tailor your Woo experience for you.
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<form
|
||||||
|
class="woocommerce-user-profile-choices"
|
||||||
|
>
|
||||||
|
<fieldset>
|
||||||
|
<legend
|
||||||
|
class="screen-reader-text"
|
||||||
|
>
|
||||||
|
Which one of these best describes you?
|
||||||
|
</legend>
|
||||||
|
<div
|
||||||
|
class="woocommerce-profiler-choice-container"
|
||||||
|
data-selected="true"
|
||||||
|
role="radio"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="woocommerce-profiler-choice"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
checked=""
|
||||||
|
class="woocommerce-profiler-choice-input"
|
||||||
|
data-selected="true"
|
||||||
|
id="woocommerce-im-just-starting-my-business"
|
||||||
|
name="user-profile-choice"
|
||||||
|
tabindex="-1"
|
||||||
|
type="radio"
|
||||||
|
value="im_just_starting_my_business"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
class="choice__title"
|
||||||
|
for="woocommerce-im-just-starting-my-business"
|
||||||
|
>
|
||||||
|
I'm just starting my business
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="woocommerce-profiler-choice-container"
|
||||||
|
role="radio"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="woocommerce-profiler-choice"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
class="woocommerce-profiler-choice-input"
|
||||||
|
id="woocommerce-im-already-selling"
|
||||||
|
name="user-profile-choice"
|
||||||
|
tabindex="-1"
|
||||||
|
type="radio"
|
||||||
|
value="im_already_selling"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
class="choice__title"
|
||||||
|
for="woocommerce-im-already-selling"
|
||||||
|
>
|
||||||
|
I'm already selling
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="woocommerce-profiler-choice-container"
|
||||||
|
role="radio"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="woocommerce-profiler-choice"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
class="woocommerce-profiler-choice-input"
|
||||||
|
id="woocommerce-im-setting-up-a-store-for-a-client"
|
||||||
|
name="user-profile-choice"
|
||||||
|
tabindex="-1"
|
||||||
|
type="radio"
|
||||||
|
value="im_setting_up_a_store_for_a_client"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
class="choice__title"
|
||||||
|
for="woocommerce-im-setting-up-a-store-for-a-client"
|
||||||
|
>
|
||||||
|
I'm setting up a store for a client
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
<div
|
||||||
|
class="woocommerce-profiler-button-container"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
class="components-button woocommerce-profiler-button is-primary"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
Continue
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button>
|
|
||||||
Next
|
|
||||||
</button>
|
|
||||||
<button>
|
|
||||||
Skip
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>,
|
</body>,
|
||||||
|
@ -3051,16 +3214,179 @@ Object {
|
||||||
class="woocommerce-profile-wizard__container woocommerce-profile-wizard__step-userProfile"
|
class="woocommerce-profile-wizard__container woocommerce-profile-wizard__step-userProfile"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
class="woocommerce-profiler-user-profile"
|
||||||
data-testid="core-profiler-user-profile"
|
data-testid="core-profiler-user-profile"
|
||||||
>
|
>
|
||||||
User Profile
|
<div
|
||||||
|
class="woocommerce-profiler-navigation-container"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="woocommerce-profiler-progress-bar progress-bar"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="woocommerce-profiler-progress-bar__container"
|
||||||
|
style="background-color: transparent;"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="woocommerce-profiler-progress-bar__filler"
|
||||||
|
style="width: 40%; display: inherit;"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="woocommerce-profiler-navigation"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="woocommerce-profiler-navigation-col-left"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="woologo"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
class="wc-icon wc-icon__woo-logo"
|
||||||
|
preserveAspectRatio="xMidYMid"
|
||||||
|
version="1.1"
|
||||||
|
viewBox="0 0 256 153"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="m23.759 0h208.38c13.187 0 23.863 10.675 23.863 23.863v79.542c0 13.187-10.675 23.863-23.863 23.863h-74.727l10.257 25.118-45.109-25.118h-98.695c-13.187 0-23.863-10.675-23.863-23.863v-79.542c-0.10466-13.083 10.571-23.863 23.758-23.863z"
|
||||||
|
fill="#7f54b3"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="m14.578 21.75c1.4569-1.9772 3.6423-3.0179 6.5561-3.226 5.3073-0.41626 8.3252 2.0813 9.0537 7.4927 3.226 21.75 6.7642 40.169 10.511 55.259l22.79-43.395c2.0813-3.9545 4.6829-6.0358 7.8049-6.2439 4.5789-0.3122 7.3886 2.6016 8.5333 8.7415 2.6016 13.841 5.9317 25.6 9.8862 35.59 2.7057-26.433 7.2846-45.476 13.737-57.236 1.561-2.9138 3.8504-4.3707 6.8683-4.5789 2.3935-0.20813 4.5789 0.52033 6.5561 2.0813 1.9772 1.561 3.0179 3.5382 3.226 5.9317 0.10406 1.8732-0.20813 3.4341-1.0407 4.9951-4.0585 7.4927-7.3886 20.085-10.094 37.567-2.6016 16.963-3.5382 30.179-2.9138 39.649 0.20813 2.6016-0.20813 4.8911-1.2488 6.8683-1.2488 2.2894-3.122 3.5382-5.5154 3.7463-2.7057 0.20813-5.5154-1.0406-8.2211-3.8504-9.678-9.8862-17.379-24.663-22.998-44.332-6.7642 13.32-11.759 23.311-14.985 29.971-6.1398 11.759-11.343 17.795-15.714 18.107-2.8098 0.20813-5.2033-2.1854-7.2846-7.1805-5.3073-13.633-11.031-39.961-17.171-78.985-0.41626-2.7057 0.20813-5.0992 1.665-6.9724zm223.64 16.338c-3.7463-6.5561-9.2618-10.511-16.65-12.072-1.9772-0.41626-3.8504-0.62439-5.6195-0.62439-9.9902 0-18.107 5.2033-24.455 15.61-5.4114 8.8455-8.1171 18.628-8.1171 29.346 0 8.013 1.665 14.881 4.9951 20.605 3.7463 6.5561 9.2618 10.511 16.65 12.072 1.9772 0.41626 3.8504 0.62439 5.6195 0.62439 10.094 0 18.211-5.2033 24.455-15.61 5.4114-8.9496 8.1171-18.732 8.1171-29.45 0.10406-8.1171-1.665-14.881-4.9951-20.501zm-13.112 28.826c-1.4569 6.8683-4.0585 11.967-7.9089 15.402-3.0179 2.7057-5.8276 3.8504-8.4293 3.3301-2.4976-0.52033-4.5789-2.7057-6.1398-6.7642-1.2488-3.226-1.8732-6.452-1.8732-9.4699 0-2.6016 0.20813-5.2033 0.72846-7.5967 0.93659-4.2667 2.7057-8.4293 5.5154-12.384 3.4341-5.0992 7.0764-7.1805 10.823-6.452 2.4976 0.52033 4.5789 2.7057 6.1398 6.7642 1.2488 3.226 1.8732 6.452 1.8732 9.4699 0 2.7057-0.20813 5.3073-0.72846 7.7008zm-52.033-28.826c-3.7463-6.5561-9.3659-10.511-16.65-12.072-1.9772-0.41626-3.8504-0.62439-5.6195-0.62439-9.9902 0-18.107 5.2033-24.455 15.61-5.4114 8.8455-8.1171 18.628-8.1171 29.346 0 8.013 1.665 14.881 4.9951 20.605 3.7463 6.5561 9.2618 10.511 16.65 12.072 1.9772 0.41626 3.8504 0.62439 5.6195 0.62439 10.094 0 18.211-5.2033 24.455-15.61 5.4114-8.9496 8.1171-18.732 8.1171-29.45 0-8.1171-1.665-14.881-4.9951-20.501zm-13.216 28.826c-1.4569 6.8683-4.0585 11.967-7.9089 15.402-3.0179 2.7057-5.8276 3.8504-8.4293 3.3301-2.4976-0.52033-4.5789-2.7057-6.1398-6.7642-1.2488-3.226-1.8732-6.452-1.8732-9.4699 0-2.6016 0.20813-5.2033 0.72846-7.5967 0.93658-4.2667 2.7057-8.4293 5.5154-12.384 3.4341-5.0992 7.0764-7.1805 10.823-6.452 2.4976 0.52033 4.5789 2.7057 6.1398 6.7642 1.2488 3.226 1.8732 6.452 1.8732 9.4699 0.10406 2.7057-0.20813 5.3073-0.72846 7.7008z"
|
||||||
|
fill="#fff"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="woocommerce-profiler-navigation-col-right"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
class="components-button woocommerce-profiler-navigation-skip-link is-link"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
Skip this setup
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="woocommerce-profiler-page__content woocommerce-profiler-user-profile__content"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="woocommerce-profiler-heading woocommerce-profiler__stepper-heading"
|
||||||
|
>
|
||||||
|
<h1
|
||||||
|
class="woocommerce-profiler-heading__title"
|
||||||
|
>
|
||||||
|
Which one of these best describes you?
|
||||||
|
</h1>
|
||||||
|
<h2
|
||||||
|
class="woocommerce-profiler-heading__subtitle"
|
||||||
|
>
|
||||||
|
Let us know where you are in your commerce journey so that we can tailor your Woo experience for you.
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<form
|
||||||
|
class="woocommerce-user-profile-choices"
|
||||||
|
>
|
||||||
|
<fieldset>
|
||||||
|
<legend
|
||||||
|
class="screen-reader-text"
|
||||||
|
>
|
||||||
|
Which one of these best describes you?
|
||||||
|
</legend>
|
||||||
|
<div
|
||||||
|
class="woocommerce-profiler-choice-container"
|
||||||
|
data-selected="true"
|
||||||
|
role="radio"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="woocommerce-profiler-choice"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
checked=""
|
||||||
|
class="woocommerce-profiler-choice-input"
|
||||||
|
data-selected="true"
|
||||||
|
id="woocommerce-im-just-starting-my-business"
|
||||||
|
name="user-profile-choice"
|
||||||
|
tabindex="-1"
|
||||||
|
type="radio"
|
||||||
|
value="im_just_starting_my_business"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
class="choice__title"
|
||||||
|
for="woocommerce-im-just-starting-my-business"
|
||||||
|
>
|
||||||
|
I'm just starting my business
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="woocommerce-profiler-choice-container"
|
||||||
|
role="radio"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="woocommerce-profiler-choice"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
class="woocommerce-profiler-choice-input"
|
||||||
|
id="woocommerce-im-already-selling"
|
||||||
|
name="user-profile-choice"
|
||||||
|
tabindex="-1"
|
||||||
|
type="radio"
|
||||||
|
value="im_already_selling"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
class="choice__title"
|
||||||
|
for="woocommerce-im-already-selling"
|
||||||
|
>
|
||||||
|
I'm already selling
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="woocommerce-profiler-choice-container"
|
||||||
|
role="radio"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="woocommerce-profiler-choice"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
class="woocommerce-profiler-choice-input"
|
||||||
|
id="woocommerce-im-setting-up-a-store-for-a-client"
|
||||||
|
name="user-profile-choice"
|
||||||
|
tabindex="-1"
|
||||||
|
type="radio"
|
||||||
|
value="im_setting_up_a_store_for_a_client"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
class="choice__title"
|
||||||
|
for="woocommerce-im-setting-up-a-store-for-a-client"
|
||||||
|
>
|
||||||
|
I'm setting up a store for a client
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
<div
|
||||||
|
class="woocommerce-profiler-button-container"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
class="components-button woocommerce-profiler-button is-primary"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
Continue
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button>
|
|
||||||
Next
|
|
||||||
</button>
|
|
||||||
<button>
|
|
||||||
Skip
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>,
|
</div>,
|
||||||
"debug": [Function],
|
"debug": [Function],
|
||||||
|
|
|
@ -14,14 +14,16 @@ import { createMachine } from 'xstate';
|
||||||
*/
|
*/
|
||||||
import { CoreProfilerController } from '../';
|
import { CoreProfilerController } from '../';
|
||||||
|
|
||||||
jest.mock( '@automattic/calypso-config' );
|
|
||||||
|
|
||||||
// mock out the external dependencies which we don't want to test here
|
// mock out the external dependencies which we don't want to test here
|
||||||
const actionOverrides = {
|
const actionOverrides = {
|
||||||
updateTrackingOption: jest.fn(),
|
updateTrackingOption: jest.fn(),
|
||||||
|
updateOnboardingProfileOption: jest.fn(),
|
||||||
recordTracksIntroCompleted: jest.fn(),
|
recordTracksIntroCompleted: jest.fn(),
|
||||||
recordTracksIntroSkipped: jest.fn(),
|
recordTracksIntroSkipped: jest.fn(),
|
||||||
recordTracksIntroViewed: jest.fn(),
|
recordTracksIntroViewed: jest.fn(),
|
||||||
|
recordTracksUserProfileCompleted: jest.fn(),
|
||||||
|
recordTracksUserProfileSkipped: jest.fn(),
|
||||||
|
recordTracksUserProfileViewed: jest.fn(),
|
||||||
recordTracksSkipBusinessLocationViewed: jest.fn(),
|
recordTracksSkipBusinessLocationViewed: jest.fn(),
|
||||||
recordTracksSkipBusinessLocationCompleted: jest.fn(),
|
recordTracksSkipBusinessLocationCompleted: jest.fn(),
|
||||||
redirectToWooHome: jest.fn(),
|
redirectToWooHome: jest.fn(),
|
||||||
|
@ -34,6 +36,7 @@ const servicesOverrides = {
|
||||||
.mockResolvedValue( [
|
.mockResolvedValue( [
|
||||||
{ code: 'US', name: 'United States', states: [] },
|
{ code: 'US', name: 'United States', states: [] },
|
||||||
] ),
|
] ),
|
||||||
|
getOnboardingProfileOption: jest.fn().mockResolvedValue( {} ),
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: minor
|
||||||
|
Type: add
|
||||||
|
|
||||||
|
Add core profiler user profile page
|
Loading…
Reference in New Issue