2022-04-07 19:56:20 +00:00
|
|
|
/**
|
|
|
|
* External dependencies
|
|
|
|
*/
|
|
|
|
import classnames from 'classnames';
|
2022-04-22 20:21:34 +00:00
|
|
|
import { useEffect, useState } from '@wordpress/element';
|
2022-04-08 17:28:43 +00:00
|
|
|
import { EllipsisMenu } from '@woocommerce/components';
|
|
|
|
import { recordEvent } from '@woocommerce/tracks';
|
|
|
|
import { useDispatch, useSelect } from '@wordpress/data';
|
2022-04-22 20:21:34 +00:00
|
|
|
import { OPTIONS_STORE_NAME, WCDataSelector, WEEK } from '@woocommerce/data';
|
2022-04-07 19:56:20 +00:00
|
|
|
import { Button, Card, CardHeader } from '@wordpress/components';
|
|
|
|
import { Text } from '@woocommerce/experimental';
|
2022-04-08 17:28:43 +00:00
|
|
|
import {
|
|
|
|
CustomerFeedbackModal,
|
|
|
|
CustomerFeedbackSimple,
|
|
|
|
} from '@woocommerce/customer-effort-score';
|
2022-04-07 19:56:20 +00:00
|
|
|
import { __ } from '@wordpress/i18n';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Internal dependencies
|
|
|
|
*/
|
2022-05-16 13:03:46 +00:00
|
|
|
import './completed-header.scss';
|
2022-04-07 19:56:20 +00:00
|
|
|
import HeaderImage from './completed-celebration-header.svg';
|
|
|
|
|
|
|
|
type TaskListCompletedHeaderProps = {
|
2022-04-08 17:28:43 +00:00
|
|
|
hideTasks: () => void;
|
2022-04-07 19:56:20 +00:00
|
|
|
keepTasks: () => void;
|
2022-05-16 13:03:46 +00:00
|
|
|
enableCES: boolean;
|
2022-04-07 19:56:20 +00:00
|
|
|
};
|
|
|
|
|
2022-04-08 17:28:43 +00:00
|
|
|
const ADMIN_INSTALL_TIMESTAMP_OPTION_NAME =
|
|
|
|
'woocommerce_admin_install_timestamp';
|
|
|
|
const SHOWN_FOR_ACTIONS_OPTION_NAME = 'woocommerce_ces_shown_for_actions';
|
|
|
|
const CES_ACTION = 'store_setup';
|
2022-05-16 13:03:46 +00:00
|
|
|
const ALLOW_TRACKING_OPTION_NAME = 'woocommerce_allow_tracking';
|
2022-04-08 17:28:43 +00:00
|
|
|
|
|
|
|
function getStoreAgeInWeeks( adminInstallTimestamp: number ) {
|
|
|
|
if ( adminInstallTimestamp === 0 ) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Date.now() is ms since Unix epoch, adminInstallTimestamp is in
|
|
|
|
// seconds since Unix epoch.
|
|
|
|
const storeAgeInMs = Date.now() - adminInstallTimestamp * 1000;
|
|
|
|
const storeAgeInWeeks = Math.round( storeAgeInMs / WEEK );
|
|
|
|
|
|
|
|
return storeAgeInWeeks;
|
|
|
|
}
|
|
|
|
|
2022-05-16 13:03:46 +00:00
|
|
|
export const TaskListCompletedHeader: React.FC< TaskListCompletedHeaderProps > = ( {
|
2022-04-07 19:56:20 +00:00
|
|
|
hideTasks,
|
|
|
|
keepTasks,
|
2022-05-16 13:03:46 +00:00
|
|
|
enableCES,
|
2022-04-07 19:56:20 +00:00
|
|
|
} ) => {
|
2022-04-08 17:28:43 +00:00
|
|
|
const { updateOptions } = useDispatch( OPTIONS_STORE_NAME );
|
|
|
|
const [ showCesModal, setShowCesModal ] = useState( false );
|
2022-05-16 13:03:46 +00:00
|
|
|
const [ hasSubmittedScore, setHasSubmittedScore ] = useState( false );
|
2022-04-08 17:28:43 +00:00
|
|
|
const [ score, setScore ] = useState( NaN );
|
2022-04-22 20:21:34 +00:00
|
|
|
const [ hideCES, setHideCES ] = useState( false );
|
2022-05-16 13:03:46 +00:00
|
|
|
const { storeAgeInWeeks, cesShownForActions, showCES } = useSelect(
|
2022-04-22 20:21:34 +00:00
|
|
|
( select: WCDataSelector ) => {
|
2022-05-16 13:03:46 +00:00
|
|
|
const { getOption, hasFinishedResolution } = select(
|
|
|
|
OPTIONS_STORE_NAME
|
|
|
|
);
|
2022-04-08 17:28:43 +00:00
|
|
|
|
2022-05-16 13:03:46 +00:00
|
|
|
if ( enableCES ) {
|
|
|
|
const allowTracking = getOption( ALLOW_TRACKING_OPTION_NAME );
|
2022-04-22 20:21:34 +00:00
|
|
|
const adminInstallTimestamp: number =
|
|
|
|
getOption( ADMIN_INSTALL_TIMESTAMP_OPTION_NAME ) || 0;
|
2022-05-16 13:03:46 +00:00
|
|
|
const cesActions = getOption< string[] >(
|
|
|
|
SHOWN_FOR_ACTIONS_OPTION_NAME
|
|
|
|
);
|
|
|
|
const loadingOptions =
|
|
|
|
! hasFinishedResolution( 'getOption', [
|
|
|
|
SHOWN_FOR_ACTIONS_OPTION_NAME,
|
|
|
|
] ) ||
|
|
|
|
! hasFinishedResolution( 'getOption', [
|
|
|
|
ADMIN_INSTALL_TIMESTAMP_OPTION_NAME,
|
|
|
|
] );
|
2022-04-22 20:21:34 +00:00
|
|
|
return {
|
|
|
|
storeAgeInWeeks: getStoreAgeInWeeks(
|
|
|
|
adminInstallTimestamp
|
|
|
|
),
|
2022-05-16 13:03:46 +00:00
|
|
|
cesShownForActions: cesActions,
|
|
|
|
showCES:
|
|
|
|
! loadingOptions &&
|
|
|
|
allowTracking &&
|
|
|
|
! ( cesActions || [] ).includes( 'store_setup' ),
|
|
|
|
loading: loadingOptions,
|
2022-04-22 20:21:34 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
return {};
|
2022-04-08 18:37:22 +00:00
|
|
|
}
|
2022-04-22 20:21:34 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
useEffect( () => {
|
2022-05-16 13:03:46 +00:00
|
|
|
if ( hasSubmittedScore ) {
|
2022-04-22 20:21:34 +00:00
|
|
|
setTimeout( () => {
|
|
|
|
setHideCES( true );
|
|
|
|
}, 1200 );
|
|
|
|
}
|
2022-05-16 13:03:46 +00:00
|
|
|
}, [ hasSubmittedScore ] );
|
2022-04-08 17:28:43 +00:00
|
|
|
|
2022-04-21 19:40:48 +00:00
|
|
|
const submitScore = ( recordedScore: number, comments?: string ) => {
|
|
|
|
recordEvent( 'ces_feedback', {
|
|
|
|
action: CES_ACTION,
|
|
|
|
score: recordedScore,
|
|
|
|
comments: comments || '',
|
|
|
|
store_age: storeAgeInWeeks,
|
|
|
|
} );
|
|
|
|
updateOptions( {
|
|
|
|
[ SHOWN_FOR_ACTIONS_OPTION_NAME ]: [
|
|
|
|
CES_ACTION,
|
2022-05-10 12:48:43 +00:00
|
|
|
...( cesShownForActions || [] ),
|
2022-04-21 19:40:48 +00:00
|
|
|
],
|
|
|
|
} );
|
2022-05-16 13:03:46 +00:00
|
|
|
setHasSubmittedScore( true );
|
2022-04-21 19:40:48 +00:00
|
|
|
};
|
|
|
|
|
2022-04-08 18:37:22 +00:00
|
|
|
const recordScore = ( recordedScore: number ) => {
|
|
|
|
if ( recordedScore > 2 ) {
|
2022-04-21 19:40:48 +00:00
|
|
|
setScore( recordedScore );
|
|
|
|
submitScore( recordedScore );
|
2022-04-08 17:28:43 +00:00
|
|
|
} else {
|
2022-04-08 18:37:22 +00:00
|
|
|
setScore( recordedScore );
|
2022-04-08 17:28:43 +00:00
|
|
|
setShowCesModal( true );
|
2022-04-08 18:37:22 +00:00
|
|
|
recordEvent( 'ces_view', {
|
|
|
|
action: CES_ACTION,
|
|
|
|
store_age: storeAgeInWeeks,
|
|
|
|
} );
|
2022-04-08 17:28:43 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-04-08 18:37:22 +00:00
|
|
|
const recordModalScore = ( recordedScore: number, comments: string ) => {
|
2022-04-08 17:28:43 +00:00
|
|
|
setShowCesModal( false );
|
2022-04-21 19:40:48 +00:00
|
|
|
submitScore( recordedScore, comments );
|
2022-04-08 17:28:43 +00:00
|
|
|
};
|
2022-04-07 19:56:20 +00:00
|
|
|
|
|
|
|
return (
|
|
|
|
<>
|
|
|
|
<div
|
|
|
|
className={ classnames(
|
|
|
|
'woocommerce-task-dashboard__container two-column-experiment'
|
|
|
|
) }
|
|
|
|
>
|
|
|
|
<Card
|
|
|
|
size="large"
|
|
|
|
className="woocommerce-task-card woocommerce-homescreen-card completed"
|
|
|
|
>
|
|
|
|
<CardHeader size="medium">
|
|
|
|
<div className="wooocommerce-task-card__header">
|
2022-04-25 14:35:46 +00:00
|
|
|
<img
|
|
|
|
src={ HeaderImage }
|
|
|
|
alt="Completed"
|
|
|
|
className="wooocommerce-task-card__finished-header-image"
|
|
|
|
/>
|
2022-04-07 19:56:20 +00:00
|
|
|
|
2022-05-16 13:03:46 +00:00
|
|
|
<Text size="title" as="h2" lineHeight={ 1.4 }>
|
2022-04-07 19:56:20 +00:00
|
|
|
{ __(
|
|
|
|
"You've completed store setup",
|
|
|
|
'woocommerce'
|
|
|
|
) }
|
2022-05-16 13:03:46 +00:00
|
|
|
</Text>
|
2022-04-07 19:56:20 +00:00
|
|
|
<Text
|
|
|
|
variant="subtitle.small"
|
|
|
|
as="p"
|
|
|
|
size="13"
|
|
|
|
lineHeight="16px"
|
|
|
|
className="wooocommerce-task-card__header-subtitle"
|
|
|
|
>
|
|
|
|
{ __(
|
|
|
|
'Congratulations! Take a moment to celebrate and look out for the first sale.',
|
|
|
|
'woocommerce'
|
|
|
|
) }
|
|
|
|
</Text>
|
|
|
|
<div className="woocommerce-task-card__header-menu">
|
|
|
|
<EllipsisMenu
|
|
|
|
label={ __(
|
|
|
|
'Task List Options',
|
|
|
|
'woocommerce'
|
|
|
|
) }
|
|
|
|
renderContent={ () => (
|
|
|
|
<div className="woocommerce-task-card__section-controls">
|
|
|
|
<Button
|
|
|
|
onClick={ () => keepTasks() }
|
|
|
|
>
|
|
|
|
{ __(
|
|
|
|
'Show setup task list',
|
|
|
|
'woocommerce'
|
|
|
|
) }
|
|
|
|
</Button>
|
|
|
|
<Button
|
|
|
|
onClick={ () => hideTasks() }
|
|
|
|
>
|
|
|
|
{ __(
|
|
|
|
'Hide this',
|
|
|
|
'woocommerce'
|
|
|
|
) }
|
|
|
|
</Button>
|
|
|
|
</div>
|
|
|
|
) }
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</CardHeader>
|
2022-05-16 13:03:46 +00:00
|
|
|
{ showCES && ! hideCES && ! hasSubmittedScore && (
|
2022-04-07 19:56:20 +00:00
|
|
|
<CustomerFeedbackSimple
|
|
|
|
label={ __(
|
|
|
|
'How was your experience?',
|
|
|
|
'woocommerce'
|
|
|
|
) }
|
2022-05-16 13:03:46 +00:00
|
|
|
onSelect={ recordScore }
|
2022-04-07 19:56:20 +00:00
|
|
|
/>
|
|
|
|
) }
|
2022-05-16 13:03:46 +00:00
|
|
|
{ hasSubmittedScore && ! hideCES && (
|
|
|
|
<div className="wooocommerce-task-card__header-ces-feedback">
|
|
|
|
<Text
|
|
|
|
variant="subtitle.small"
|
|
|
|
as="p"
|
|
|
|
size="13"
|
|
|
|
lineHeight="16px"
|
|
|
|
>
|
|
|
|
🙌{ ' ' }
|
|
|
|
{ __(
|
|
|
|
'We appreciate your feedback!',
|
|
|
|
'woocommerce'
|
|
|
|
) }
|
|
|
|
</Text>
|
|
|
|
</div>
|
|
|
|
) }
|
2022-04-07 19:56:20 +00:00
|
|
|
</Card>
|
|
|
|
</div>
|
2022-04-08 17:28:43 +00:00
|
|
|
{ showCesModal ? (
|
|
|
|
<CustomerFeedbackModal
|
|
|
|
label={ __( 'How was your experience?', 'woocommerce' ) }
|
|
|
|
defaultScore={ score }
|
|
|
|
recordScoreCallback={ recordModalScore }
|
2022-04-21 19:40:48 +00:00
|
|
|
onCloseModal={ () => {
|
|
|
|
setScore( NaN );
|
|
|
|
setShowCesModal( false );
|
|
|
|
} }
|
2022-04-08 17:28:43 +00:00
|
|
|
/>
|
|
|
|
) : null }
|
2022-04-07 19:56:20 +00:00
|
|
|
</>
|
|
|
|
);
|
|
|
|
};
|