Skip to content

Commit

Permalink
Store Dashboard: Refactor, Update widgets to use DashboardWidget (#22859
Browse files Browse the repository at this point in the history
)

* Move row component into DashboardWidget folder

* Add an empty `alt` for screen readers, this image is presentational only

* Switch placeholder screen to use responsive row group

* Clean up component: remove unnecessary arrow functions, remove setState on mount

* Remove unnecessary arrow functions

* Switch out BasicWidget placeholder for a div

* Move all setup components into setup folder

* Add a readme for the dashboard widgets

* Update no-orders view to use DashboardWidget

* Convert Reports widget to use DashboardWidget

* Use DashboardWidget & DashboardWidgetRow for processing orders & reviews

* Switch ShareWidget to use the DashboardWidget component

* Remove now-unused BasicWidget & WidgetGroup

* Fix responsive styles for orders/reviews widgets

* Image width should only apply to the reports widget

* Clean up duplicate import
  • Loading branch information
ryelle authored Mar 7, 2018
1 parent 4d73e71 commit 58a00b3
Show file tree
Hide file tree
Showing 29 changed files with 530 additions and 763 deletions.
20 changes: 10 additions & 10 deletions client/extensions/woocommerce/app/dashboard/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ import ManageExternalView from './manage-external-view';
import ManageNoOrdersView from './manage-no-orders-view';
import ManageOrdersView from './manage-orders-view';
import Placeholder from './placeholder';
import StoreLocationSetupView from './store-location-setup-view';
import StoreLocationSetupView from './setup/store-location';
import RequiredPagesSetupView from './required-pages-setup-view';
import RequiredPluginsInstallView from './required-plugins-install-view';
import SetupTasksView from './setup-tasks-view';
import SetupTasksView from './setup';
import MailChimp from 'woocommerce/app/settings/email/mailchimp/index.js';
import QuerySettingsGeneral from 'woocommerce/components/query-settings-general';
import warn from 'lib/warn';
Expand Down Expand Up @@ -77,27 +77,27 @@ class Dashboard extends Component {
redirectURL: false,
};

componentDidMount = () => {
componentDidMount() {
const { siteId } = this.props;

if ( siteId ) {
this.fetchStoreData();
}
};
}

componentDidUpdate = prevProps => {
componentDidUpdate( prevProps ) {
const { siteId } = this.props;
const oldSiteId = prevProps.siteId ? prevProps.siteId : null;

if ( siteId && oldSiteId !== siteId ) {
this.fetchStoreData();
}
};
}

// If the user 1) has set the store address in StoreLocationSetupView
// and 2) we have a redirectURL, don't render but go ahead and
// redirect (i.e. to the WooCommerce Setup Wizard in wp-admin)
shouldComponentUpdate = ( nextProps, nextState ) => {
shouldComponentUpdate( nextProps, nextState ) {
const { setStoreAddressDuringInitialSetup } = nextProps;
const { redirectURL } = nextState;

Expand All @@ -107,7 +107,7 @@ class Dashboard extends Component {
}

return true;
};
}

fetchStoreData = () => {
const { siteId, productsLoaded } = this.props;
Expand Down Expand Up @@ -242,7 +242,7 @@ class Dashboard extends Component {
);
};

render = () => {
render() {
const { className, isSetupComplete, loading, selectedSite, siteId } = this.props;

return (
Expand All @@ -255,7 +255,7 @@ class Dashboard extends Component {
<QuerySettingsGeneral siteId={ siteId } />
</Main>
);
};
}
}

function mapStateToProps( state ) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
/** @format */

/**
* External dependencies
*/

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { localize } from 'i18n-calypso';
Expand All @@ -12,10 +10,11 @@ import page from 'page';
/**
* Internal dependencies
*/
import BasicWidget from 'woocommerce/components/basic-widget';
import Button from 'components/button';
import DashboardWidget from 'woocommerce/components/dashboard-widget';
import DashboardWidgetRow from 'woocommerce/components/dashboard-widget/row';
import { getLink } from 'woocommerce/lib/nav-utils';
import ShareWidget from 'woocommerce/components/share-widget';
import WidgetGroup from 'woocommerce/components/widget-group';
import { recordTrack } from 'woocommerce/lib/analytics';

class ManageNoOrdersView extends Component {
Expand Down Expand Up @@ -49,10 +48,11 @@ class ManageNoOrdersView extends Component {
page.redirect( getLink( '/store/stats/orders/day/:site', site ) );
};
return (
<BasicWidget
buttonLabel={ translate( 'View stats' ) }
onButtonClick={ trackClick }
<DashboardWidget
className="dashboard__stats-widget"
image="/calypso/images/extensions/woocommerce/woocommerce-sample-graph.svg"
imagePosition="bottom"
imageFlush
title={ translate( 'Looking for stats?' ) }
>
<p>
Expand All @@ -61,7 +61,8 @@ class ManageNoOrdersView extends Component {
' Keep an eye on revenue, order totals, popular products, and more.'
) }
</p>
</BasicWidget>
<Button onClick={ trackClick }>{ translate( 'View stats' ) }</Button>
</DashboardWidget>
);
};

Expand All @@ -73,10 +74,7 @@ class ManageNoOrdersView extends Component {
} );
};
return (
<BasicWidget
buttonLabel={ translate( 'View & test your store' ) }
buttonLink={ site.URL }
onButtonClick={ trackClick }
<DashboardWidget
className="dashboard__view-and-test-widget"
title={ translate( 'Test all the things' ) }
>
Expand All @@ -92,21 +90,24 @@ class ManageNoOrdersView extends Component {
' a product to your cart, and attempt to check out using different addresses.'
) }
</p>
</BasicWidget>
<Button onClick={ trackClick } href={ site.URL }>
{ translate( 'View & test your store' ) }
</Button>
</DashboardWidget>
);
};

render = () => {
render() {
return (
<div className="dashboard__manage-no-orders">
{ this.renderShareWidget() }
<WidgetGroup>
<DashboardWidgetRow>
{ this.renderStatsWidget() }
{ this.renderViewAndTestWidget() }
</WidgetGroup>
</DashboardWidgetRow>
</div>
);
};
}
}

export default localize( ManageNoOrdersView );
117 changes: 65 additions & 52 deletions client/extensions/woocommerce/app/dashboard/manage-orders-view.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
/** @format */

/**
* External dependencies
*/

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import config from 'config';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import classNames from 'classnames';
import { localize } from 'i18n-calypso';

/**
* Internal dependencies
*/
import Button from 'components/button';
import DashboardWidget from 'woocommerce/components/dashboard-widget';
import DashboardWidgetRow from 'woocommerce/components/dashboard-widget/row';
import LabelsSetupNotice from 'woocommerce/woocommerce-services/components/labels-setup-notice';
import { fetchOrders } from 'woocommerce/state/sites/orders/actions';
import { fetchReviews } from 'woocommerce/state/sites/reviews/actions';
import formatCurrency from 'lib/format-currency';
import {
areOrdersLoading,
areOrdersLoaded,
Expand All @@ -30,9 +31,7 @@ import { getSelectedSiteWithFallback } from 'woocommerce/state/sites/selectors';
import { getLink } from 'woocommerce/lib/nav-utils';
import { getPaymentCurrencySettings } from 'woocommerce/state/sites/settings/general/selectors';
import { getTotalReviews } from 'woocommerce/state/sites/reviews/selectors';
import ProcessOrdersWidget from 'woocommerce/components/process-orders-widget';
import ShareWidget from 'woocommerce/components/share-widget';
import Card from 'components/card';
import QuerySettingsGeneral from 'woocommerce/components/query-settings-general';

class ManageOrdersView extends Component {
Expand Down Expand Up @@ -84,45 +83,60 @@ class ManageOrdersView extends Component {
}
};

shouldShowPendingReviews = () => {
return config.isEnabled( 'woocommerce/extension-reviews' ) && this.props.pendingReviews;
};

possiblyRenderProcessOrdersWidget = () => {
const { site, orders, ordersRevenue, currency } = this.props;
const { currency, orders, ordersRevenue, site, translate } = this.props;
if ( ! orders.length ) {
return null;
}
const currencyValue = ( currency && currency.value ) || '';
const orderCountPhrase = translate( '✨ New order', '✨ New orders', {
count: orders.length,
} );
const classes = classNames( 'dashboard__process-orders-container', {
'has-reviews': this.shouldShowPendingReviews(),
} );
return (
<ProcessOrdersWidget
className="dashboard__process-orders-widget"
site={ site }
orders={ orders }
ordersRevenue={ ordersRevenue }
currency={ currency }
/>
<DashboardWidgetRow className={ classes }>
<DashboardWidget className="dashboard__process-orders-total">
<span className="dashboard__process-orders-value">{ orders.length }</span>
<span className="dashboard__process-orders-label">{ orderCountPhrase }</span>
</DashboardWidget>
<DashboardWidget className="dashboard__process-orders-revenue">
<span className="dashboard__process-orders-value">
{ formatCurrency( ordersRevenue, currencyValue ) || ordersRevenue }
</span>
<span className="dashboard__process-orders-label">{ translate( '💰 Revenue' ) }</span>
</DashboardWidget>
<DashboardWidget className="dashboard__process-orders-action">
<Button href={ getLink( '/store/orders/:site', site ) }>
{ translate( 'Process orders' ) }
</Button>
</DashboardWidget>
</DashboardWidgetRow>
);
};

possiblyRenderReviewsWidget = () => {
const { site, pendingReviews, translate } = this.props;
if ( ! pendingReviews ) {
if ( ! this.shouldShowPendingReviews() ) {
return null;
}

const classes = classNames( 'card', 'dashboard__reviews-widget' );
const countText = translate( 'Pending review', 'Pending reviews', {
const { site, pendingReviews, translate } = this.props;
const countText = translate( '%d pending review', '%d pending reviews', {
args: [ pendingReviews ],
count: pendingReviews,
} );

return (
<div className={ classes }>
<div>
<span>{ pendingReviews }</span>
<span>{ countText }</span>
</div>
<div>
<Button href={ getLink( '/store/reviews/:site', site ) }>
{ translate( 'Moderate', { context: 'Product reviews widget moderation button' } ) }
</Button>
</div>
</div>
<DashboardWidget className="dashboard__reviews-widget" title={ countText } width="third">
<Button href={ getLink( '/store/reviews/:site', site ) }>
{ translate( 'Moderate', { context: 'Product reviews widget moderation button' } ) }
</Button>
</DashboardWidget>
);
};

Expand All @@ -138,7 +152,7 @@ class ManageOrdersView extends Component {
);
};

render = () => {
render() {
const { site, translate, orders, user } = this.props;
return (
<div className="dashboard__manage-has-orders">
Expand All @@ -156,34 +170,33 @@ class ManageOrdersView extends Component {

<LabelsSetupNotice />

<div className="dashboard__queue-widgets">
<DashboardWidgetRow>
{ this.possiblyRenderProcessOrdersWidget() }
{ config.isEnabled( 'woocommerce/extension-reviews' ) &&
this.possiblyRenderReviewsWidget() }
</div>
{ this.possiblyRenderReviewsWidget() }
</DashboardWidgetRow>

<DashboardWidget
className="dashboard__reports-widget"
image="/calypso/images/extensions/woocommerce/woocommerce-reports.svg"
imagePosition="right"
title={ translate( 'Reports' ) }
>
<p>
{ translate(
'See a detailed breakdown of how your store is doing on the stats screen.'
) }
</p>
<p>
<Button href={ getLink( '/store/stats/orders/day/:site', site ) }>
{ orders.length ? translate( 'View full reports' ) : translate( 'View reports' ) }
</Button>
</p>
</DashboardWidget>

<Card className="dashboard__reports-widget">
<div className="dashboard__reports-widget-content-wrapper">
<img src="/calypso/images/extensions/woocommerce/woocommerce-reports.svg" alt="" />
<div className="dashboard__reports-widget-content">
<h2>{ translate( 'Reports' ) }</h2>
<p>
{ translate(
'See a detailed breakdown of how your store is doing on the stats screen.'
) }
</p>
<p>
<Button href={ getLink( '/store/stats/orders/day/:site', site ) }>
{ orders.length ? translate( 'View full reports' ) : translate( 'View reports' ) }
</Button>
</p>
</div>
</div>
</Card>
{ this.possiblyRenderShareWidget() }
</div>
);
};
}
}

function mapStateToProps( state ) {
Expand Down
11 changes: 5 additions & 6 deletions client/extensions/woocommerce/app/dashboard/placeholder.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,18 @@ import React from 'react';
/**
* Internal dependencies
*/
import BasicWidget from 'woocommerce/components/basic-widget';
import WidgetGroup from 'woocommerce/components/widget-group';
import WidgetRow from 'woocommerce/components/dashboard-widget/row';

const DashboardPlaceholder = () => {
const loading = <BasicWidget title="…" className="dashboard__placeholder-small" />;
const loading = <div title="…" className="dashboard__placeholder-small dashboard-widget card" />;

return (
<div className="dashboard__placeholder">
<BasicWidget className="dashboard__placeholder-large card" />
<WidgetGroup>
<div className="dashboard__placeholder-large card dashboard-widget" />
<WidgetRow>
{ loading }
{ loading }
</WidgetGroup>
</WidgetRow>
</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { localize } from 'i18n-calypso';
*/
import { getSelectedSiteWithFallback } from 'woocommerce/state/sites/selectors';
import ProgressBar from 'components/progress-bar';
import SetupHeader from './setup-header';
import SetupHeader from './setup/header';
import { setUpStorePages } from 'woocommerce/state/sites/setup-choices/actions';

class RequiredPagesSetupView extends Component {
Expand All @@ -36,7 +36,7 @@ class RequiredPagesSetupView extends Component {
render = () => {
const { translate } = this.props;
return (
<div className="card dashboard__setup-wrapper">
<div className="card dashboard__setup-wrapper setup__wrapper">
<SetupHeader
imageSource={ '/calypso/images/extensions/woocommerce/woocommerce-store-creation.svg' }
imageWidth={ 160 }
Expand Down
Loading

0 comments on commit 58a00b3

Please sign in to comment.