diff --git a/plugins/woocommerce-admin/changelogs/add-7636-header-cards b/plugins/woocommerce-admin/changelogs/add-7636-header-cards new file mode 100644 index 00000000000..618f66e076b --- /dev/null +++ b/plugins/woocommerce-admin/changelogs/add-7636-header-cards @@ -0,0 +1,4 @@ +Significance: minor +Type: Add + +Add header cards for all tasks in Tasklist UI experiment #7838 diff --git a/plugins/woocommerce-admin/client/two-column-tasks/headers/appearance.js b/plugins/woocommerce-admin/client/two-column-tasks/headers/appearance.js index 8849cddb6dd..c71d0c4115a 100644 --- a/plugins/woocommerce-admin/client/two-column-tasks/headers/appearance.js +++ b/plugins/woocommerce-admin/client/two-column-tasks/headers/appearance.js @@ -1,5 +1,47 @@ -const AppearanceHeader = ( task ) => { - return
{ task.id } Header
; +/** + * External dependencies + */ +import { Button } from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import TimerImage from './timer.svg'; +import PersonalizeMyStore from './illustrations/personalize-my-store.js'; + +const AppearanceHeader = ( { task, goToTask } ) => { + return ( +
+ +
+

{ __( 'Personalize my store', 'woocommerce-admin' ) }

+

+ { __( + 'Add your logo, create a homepage, and start designing your store', + 'woocommerce-admin' + ) } +

+ +

+ Timer{ ' ' } + { task.time } +

+
+
+ ); }; export default AppearanceHeader; diff --git a/plugins/woocommerce-admin/client/two-column-tasks/headers/illustrations/add-products.js b/plugins/woocommerce-admin/client/two-column-tasks/headers/illustrations/add-products.js new file mode 100644 index 00000000000..b9545be7961 --- /dev/null +++ b/plugins/woocommerce-admin/client/two-column-tasks/headers/illustrations/add-products.js @@ -0,0 +1,791 @@ +export default ( props ) => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); diff --git a/plugins/woocommerce-admin/client/two-column-tasks/headers/illustrations/add-tax-rates.js b/plugins/woocommerce-admin/client/two-column-tasks/headers/illustrations/add-tax-rates.js new file mode 100644 index 00000000000..3a1bfa0dfd8 --- /dev/null +++ b/plugins/woocommerce-admin/client/two-column-tasks/headers/illustrations/add-tax-rates.js @@ -0,0 +1,136 @@ +export default ( props ) => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + +); diff --git a/plugins/woocommerce-admin/client/two-column-tasks/headers/illustrations/get-more-sales.js b/plugins/woocommerce-admin/client/two-column-tasks/headers/illustrations/get-more-sales.js new file mode 100644 index 00000000000..2a2f42503c7 --- /dev/null +++ b/plugins/woocommerce-admin/client/two-column-tasks/headers/illustrations/get-more-sales.js @@ -0,0 +1,101 @@ +export default ( props ) => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); diff --git a/plugins/woocommerce-admin/client/two-column-tasks/headers/illustrations/get-paid.js b/plugins/woocommerce-admin/client/two-column-tasks/headers/illustrations/get-paid.js new file mode 100644 index 00000000000..426ea03528e --- /dev/null +++ b/plugins/woocommerce-admin/client/two-column-tasks/headers/illustrations/get-paid.js @@ -0,0 +1,84 @@ +export default ( props ) => ( + + + + + + + + + + + + + + + + + +); diff --git a/plugins/woocommerce-admin/client/two-column-tasks/headers/illustrations/personalize-my-store.js b/plugins/woocommerce-admin/client/two-column-tasks/headers/illustrations/personalize-my-store.js new file mode 100644 index 00000000000..e71b2907e02 --- /dev/null +++ b/plugins/woocommerce-admin/client/two-column-tasks/headers/illustrations/personalize-my-store.js @@ -0,0 +1,267 @@ +export default ( props ) => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); diff --git a/plugins/woocommerce-admin/client/two-column-tasks/headers/illustrations/setup_complete.svg b/plugins/woocommerce-admin/client/two-column-tasks/headers/illustrations/setup_complete.svg new file mode 100644 index 00000000000..4be1cdecd22 --- /dev/null +++ b/plugins/woocommerce-admin/client/two-column-tasks/headers/illustrations/setup_complete.svg @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/woocommerce-admin/client/two-column-tasks/headers/illustrations/shipping.js b/plugins/woocommerce-admin/client/two-column-tasks/headers/illustrations/shipping.js new file mode 100644 index 00000000000..9be69a2ae76 --- /dev/null +++ b/plugins/woocommerce-admin/client/two-column-tasks/headers/illustrations/shipping.js @@ -0,0 +1,112 @@ +export default ( props ) => ( + + + + + + + + + + + + + + + + + + + + + + + + + + +); diff --git a/plugins/woocommerce-admin/client/two-column-tasks/headers/marketing.js b/plugins/woocommerce-admin/client/two-column-tasks/headers/marketing.js index c767491a0aa..26629a13eb5 100644 --- a/plugins/woocommerce-admin/client/two-column-tasks/headers/marketing.js +++ b/plugins/woocommerce-admin/client/two-column-tasks/headers/marketing.js @@ -1,5 +1,47 @@ -const MarketingHeader = ( task ) => { - return
{ task.id } Header
; +/** + * External dependencies + */ +import { Button } from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import TimerImage from './timer.svg'; +import GetMoreSales from './illustrations/get-more-sales.js'; + +const MarketingHeader = ( { task, goToTask } ) => { + return ( +
+ +
+

{ __( 'Get more sales', 'woocommerce-admin' ) }

+

+ { __( + 'Add tools to grow your store such as email, social, and in-person selling', + 'woocommerce-admin' + ) } +

+ +

+ Timer{ ' ' } + { task.time } +

+
+
+ ); }; export default MarketingHeader; diff --git a/plugins/woocommerce-admin/client/two-column-tasks/headers/payments.js b/plugins/woocommerce-admin/client/two-column-tasks/headers/payments.js index b940423e288..422cba1da40 100644 --- a/plugins/woocommerce-admin/client/two-column-tasks/headers/payments.js +++ b/plugins/woocommerce-admin/client/two-column-tasks/headers/payments.js @@ -1,5 +1,47 @@ -const PaymentsHeader = ( task ) => { - return
{ task.id } Header
; +/** + * External dependencies + */ +import { Button } from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import TimerImage from './timer.svg'; +import GetPaid from './illustrations/get-paid'; + +const PaymentsHeader = ( { task, goToTask } ) => { + return ( +
+ +
+

{ __( 'Choose payment methods', 'woocommerce-admin' ) }

+

+ { __( + 'Choose payment providers and enable payment methods at checkout', + 'woocommerce-admin' + ) } +

+ +

+ Timer{ ' ' } + { task.time } +

+
+
+ ); }; export default PaymentsHeader; diff --git a/plugins/woocommerce-admin/client/two-column-tasks/headers/products.js b/plugins/woocommerce-admin/client/two-column-tasks/headers/products.js index 667d63c8644..f02afc77179 100644 --- a/plugins/woocommerce-admin/client/two-column-tasks/headers/products.js +++ b/plugins/woocommerce-admin/client/two-column-tasks/headers/products.js @@ -1,5 +1,46 @@ -const ProductsHeader = ( task ) => { - return
{ task.id } Header
; +/** + * External dependencies + */ +import { Button } from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import TimerImage from './timer.svg'; +import AddProducts from './illustrations/add-products.js'; + +const ProductsHeader = ( { task, goToTask } ) => { + return ( +
+ +
+

{ __( 'Add products to start selling' ) }

+

+ { __( + 'Add your first products and see them shine on your store! You can add your products manually or import them.' + ) } +

+ +

+ Timer{ ' ' } + { task.time } +

+
+
+ ); }; export default ProductsHeader; diff --git a/plugins/woocommerce-admin/client/two-column-tasks/headers/shipping.js b/plugins/woocommerce-admin/client/two-column-tasks/headers/shipping.js index 5e81bda0241..cb81e3c3921 100644 --- a/plugins/woocommerce-admin/client/two-column-tasks/headers/shipping.js +++ b/plugins/woocommerce-admin/client/two-column-tasks/headers/shipping.js @@ -1,5 +1,52 @@ -const ShippingHeader = ( task ) => { - return
{ task.id } Header
; +/** + * External dependencies + */ +import { Button } from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import TimerImage from './timer.svg'; +import Shipping from './illustrations/shipping.js'; + +const ShippingHeader = ( { task, goToTask } ) => { + return ( +
+ +
+

+ { __( + 'Set up shipping for your store', + 'woocommerce-admin' + ) } +

+

+ { __( + 'Configure shipping zones and rates', + 'woocommerce-admin' + ) } +

+ +

+ Timer{ ' ' } + { task.time } +

+
+
+ ); }; export default ShippingHeader; diff --git a/plugins/woocommerce-admin/client/two-column-tasks/headers/tax.js b/plugins/woocommerce-admin/client/two-column-tasks/headers/tax.js index 7f8d34d5024..c2d4c213bd6 100644 --- a/plugins/woocommerce-admin/client/two-column-tasks/headers/tax.js +++ b/plugins/woocommerce-admin/client/two-column-tasks/headers/tax.js @@ -1,5 +1,44 @@ -const TaxHeader = ( task ) => { - return
{ task.id } Header
; +/** + * External dependencies + */ +import { Button } from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import TimerImage from './timer.svg'; +import AddTaxRates from './illustrations/add-tax-rates.js'; + +const TaxHeader = ( { task, goToTask } ) => { + return ( +
+ +
+

+ { __( 'Next up, add your tax rates', 'woocommerce-admin' ) } +

+

{ task.content }

+ +

+ Timer{ ' ' } + { task.time } +

+
+
+ ); }; export default TaxHeader; diff --git a/plugins/woocommerce-admin/client/two-column-tasks/headers/timer.svg b/plugins/woocommerce-admin/client/two-column-tasks/headers/timer.svg new file mode 100644 index 00000000000..5869c627bf7 --- /dev/null +++ b/plugins/woocommerce-admin/client/two-column-tasks/headers/timer.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/plugins/woocommerce-admin/client/two-column-tasks/headers/woocommerce-payments.js b/plugins/woocommerce-admin/client/two-column-tasks/headers/woocommerce-payments.js new file mode 100644 index 00000000000..010ab0e7bf0 --- /dev/null +++ b/plugins/woocommerce-admin/client/two-column-tasks/headers/woocommerce-payments.js @@ -0,0 +1,99 @@ +/** + * External dependencies + */ +import { Button } from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; +import apiFetch from '@wordpress/api-fetch'; +import { useDispatch } from '@wordpress/data'; +import { useState } from '@wordpress/element'; +import { WC_ADMIN_NAMESPACE } from '@woocommerce/data'; +import { Link } from '@woocommerce/components'; +import interpolateComponents from 'interpolate-components'; + +/** + * Internal dependencies + */ +import TimerImage from './timer.svg'; +import GetPaid from './illustrations/get-paid'; + +const connect = ( createNotice, setIsBusy ) => { + const errorMessage = __( + 'There was an error connecting to WooCommerce Payments. Please try again or connect later in store settings.', + 'woocommerce-admin' + ); + setIsBusy( true ); + apiFetch( { + path: WC_ADMIN_NAMESPACE + '/plugins/connect-wcpay', + method: 'POST', + } ) + .then( ( response ) => { + window.location = response.connectUrl; + } ) + .catch( () => { + createNotice( 'error', errorMessage ); + setIsBusy( false ); + } ); +}; + +const WoocommercePaymentsHeader = ( { task, trackClick } ) => { + const { createNotice } = useDispatch( 'core/notices' ); + const [ isBusy, setIsBusy ] = useState( false ); + const onClick = () => { + trackClick(); + connect( createNotice, setIsBusy ); + }; + + return ( +
+ +
+

{ __( "It's time to get paid", 'woocommerce-admin' ) }

+

+ { __( + "You're only one step away from getting paid. Verify your business details to start managing transactions with WooCommerce Payments.", + 'woocommerce-admin' + ) } +

+

+ { interpolateComponents( { + mixedString: __( + 'By clicking "Verify Details", you agree to the {{link}}Terms of Service{{/link}}', + 'woocommerce-admin' + ), + components: { + link: ( + + ), + }, + } ) } +

+ +

+ Timer{ ' ' } + { __( '2 minutes' ) } +

+
+
+ ); +}; + +export default WoocommercePaymentsHeader; diff --git a/plugins/woocommerce-admin/client/two-column-tasks/style.scss b/plugins/woocommerce-admin/client/two-column-tasks/style.scss index e4c861f148e..fd00817b771 100644 --- a/plugins/woocommerce-admin/client/two-column-tasks/style.scss +++ b/plugins/woocommerce-admin/client/two-column-tasks/style.scss @@ -7,6 +7,24 @@ max-width: none; width: 100%; } + + .wooocommerce-task-card__header-container { + display: flex; + position: relative; + border-bottom: 1px solid $studio-gray-5; + } + + .wooocommerce-task-card__header { + width: 100%; + flex: 1; + } + + .woocommerce-ellipsis-menu.setup { + position: absolute; + top: 20px; + right: 16px; + } + .woocommerce-task-card.is-loading { .woocommerce-card__body { border-top: 1px solid $studio-gray-5; @@ -86,7 +104,8 @@ justify-content: space-between; ul li.complete .woocommerce-task-list__item-title { - font-weight: normal; + font-weight: 600; + color: $gray-600; } // Single column mode @@ -179,7 +198,55 @@ @include single-column; } + .woocommerce-task-header__contents-container { + padding: 20px 24px; + position: relative; + flex: 1; + overflow: hidden; + width: 100%; + } + .svg-background { + position: absolute; + z-index: 0; + + @include breakpoint( '<1280px' ) { + display: none; + } + + .admin-theme-color { + fill: var(--wp-admin-theme-color); + } + + .admin-theme-color-darker-10 { + fill: var(--wp-admin-theme-color-darker-10); + } + + .admin-theme-color-darker-20 { + fill: var(--wp-admin-theme-color-darker-20); + } + } + + .woocommerce-task-header__contents { + max-width: 500px; + p, + span { + color: $gray-600; + } + + // This is required in order to have svg image as background. + position: relative; + z-index: 1; + } + + .woocommerce-task-header__timer { + display: flex; + align-items: center; + line-height: 22px; + img { + margin-right: 6px; + } + } } .woocommerce-task-dashboard__body .woocommerce-task-dismiss-modal { diff --git a/plugins/woocommerce-admin/client/two-column-tasks/task-headers.js b/plugins/woocommerce-admin/client/two-column-tasks/task-headers.js index 402e9238e9b..c652134ddfc 100644 --- a/plugins/woocommerce-admin/client/two-column-tasks/task-headers.js +++ b/plugins/woocommerce-admin/client/two-column-tasks/task-headers.js @@ -7,6 +7,7 @@ import AppearanceHeader from './headers/appearance'; import ShippingHeader from './headers/shipping'; import ProductsHeader from './headers/products'; import PaymentsHeader from './headers/payments'; +import WoocommercePaymentsHeader from './headers/woocommerce-payments'; export default { tax: TaxHeader, @@ -15,4 +16,5 @@ export default { appearance: AppearanceHeader, payments: PaymentsHeader, products: ProductsHeader, + 'woocommerce-payments': WoocommercePaymentsHeader, }; diff --git a/plugins/woocommerce-admin/client/two-column-tasks/task-list.js b/plugins/woocommerce-admin/client/two-column-tasks/task-list.js index 6897711b443..90b2f0343c3 100644 --- a/plugins/woocommerce-admin/client/two-column-tasks/task-list.js +++ b/plugins/woocommerce-admin/client/two-column-tasks/task-list.js @@ -2,8 +2,8 @@ * External dependencies */ import { __ } from '@wordpress/i18n'; -import { useEffect, useRef, useState } from '@wordpress/element'; -import { Button, Card, CardHeader } from '@wordpress/components'; +import { useEffect, useRef, useState, createElement } from '@wordpress/element'; +import { Button, Card } from '@wordpress/components'; import { useSelect, useDispatch } from '@wordpress/data'; import { EllipsisMenu } from '@woocommerce/components'; import { updateQueryString } from '@woocommerce/navigation'; @@ -20,6 +20,12 @@ import taskHeaders from './task-headers'; import DismissModal from './dissmiss-modal'; import TaskListCompleted from './completed'; +// Temporary experiment titles which differs from current task titles. +const experimentTaskTitles = { + marketing: __( 'Get more sales', 'woocommerce-admin' ), + 'woocommerce-payments': __( 'Set up payments', 'woocommerce-admin' ), +}; + export const TaskList = ( { query, taskListId, @@ -40,7 +46,7 @@ export const TaskList = ( { }; } ); const { hideTaskList } = useDispatch( ONBOARDING_STORE_NAME ); - const [ headerContent, setHeaderContent ] = useState( '' ); + const [ headerData, setHeaderData ] = useState( {} ); const [ activeTaskId, setActiveTaskId ] = useState( '' ); const [ showDismissModal, setShowDismissModal ] = useState( false ); @@ -115,6 +121,7 @@ export const TaskList = ( { return (
(
@@ -141,27 +148,45 @@ export const TaskList = ( { ( listTask ) => listTask.isComplete === false ); + // If nothing is selected, default to the last task since everything is completed. if ( ! selectedHeaderCard ) { - selectedHeaderCard = visibleTasks[ 0 ]; + selectedHeaderCard = visibleTasks[ visibleTasks.length - 1 ]; } - const onTaskSelected = ( task ) => { - if ( task !== selectedHeaderCard ) { - recordEvent( `${ eventName }_click`, { - task_name: task.id, - } ); + const goToTask = ( task ) => { + trackClick( task ); + updateQueryString( { task: task.id } ); + }; - updateQueryString( { task: task.id } ); - } + const showTaskHeader = ( task ) => { if ( taskHeaders[ task.id ] ) { - setHeaderContent( taskHeaders[ task.id ]( task ) ); + setHeaderData( { + task, + goToTask: () => goToTask( task ), + trackClick: () => trackClick( task ), + } ); setActiveTaskId( task.id ); } }; + const trackClick = ( task ) => { + recordEvent( `${ eventName }_click`, { + task_name: task.id, + } ); + }; + + const onTaskSelected = ( task ) => { + if ( task.id === 'woocommerce-payments' ) { + // With WCPay, we have to show the header content for user to read t&c first. + showTaskHeader( task ); + } else { + goToTask( task ); + } + }; + useEffect( () => { if ( selectedHeaderCard ) { - onTaskSelected( selectedHeaderCard ); + showTaskHeader( selectedHeaderCard ); } }, [ selectedHeaderCard ] ); @@ -199,12 +224,16 @@ export const TaskList = ( { size="large" className="woocommerce-task-card woocommerce-homescreen-card" > - +
- { headerContent } + { headerData?.task && + createElement( + taskHeaders[ headerData.task.id ], + headerData + ) }
{ renderMenu() } - +
{ visibleTasks.map( ( task, index ) => { ++index; @@ -219,7 +248,10 @@ export const TaskList = ( { { @@ -232,7 +264,6 @@ export const TaskList = ( { } action={ task.action } actionLabel={ task.actionLabel } - additionalInfo={ task.additionalInfo } showActionButton={ task.showActionButton } /> ); diff --git a/plugins/woocommerce-admin/src/Features/OnboardingTasks/Tasks/Payments.php b/plugins/woocommerce-admin/src/Features/OnboardingTasks/Tasks/Payments.php index 5d1a6917907..035df1cf587 100644 --- a/plugins/woocommerce-admin/src/Features/OnboardingTasks/Tasks/Payments.php +++ b/plugins/woocommerce-admin/src/Features/OnboardingTasks/Tasks/Payments.php @@ -27,7 +27,8 @@ class Payments { ( ! WooCommercePayments::is_requested() || ! WooCommercePayments::is_installed() || - ! WooCommercePayments::is_supported() + ! WooCommercePayments::is_supported() || + WooCommercePayments::is_connected() ), 'time' => __( '2 minutes', 'woocommerce-admin' ), ); diff --git a/plugins/woocommerce-admin/src/Features/OnboardingTasks/Tasks/WooCommercePayments.php b/plugins/woocommerce-admin/src/Features/OnboardingTasks/Tasks/WooCommercePayments.php index 2e141a3020e..c75d3ff6419 100644 --- a/plugins/woocommerce-admin/src/Features/OnboardingTasks/Tasks/WooCommercePayments.php +++ b/plugins/woocommerce-admin/src/Features/OnboardingTasks/Tasks/WooCommercePayments.php @@ -27,7 +27,8 @@ class WooCommercePayments { 'is_complete' => self::is_connected(), 'can_view' => self::is_requested() && self::is_installed() && - self::is_supported(), + self::is_supported() && + ! self::is_connected(), 'time' => __( '2 minutes', 'woocommerce-admin' ), 'additional_info' => __( 'By setting up, you are agreeing to the Terms of Service',