This repository has been archived by the owner on Jun 7, 2022. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Create Customers Report page * Hide date range filter if dateRangeFilter.show is false * Rename dateRangeFilter.show to showDatePicker in filters config * Add correct key 'average_order_value' * Fix customers autocompleter not working
- Loading branch information
Showing
10 changed files
with
331 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
/** @format */ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { __ } from '@wordpress/i18n'; | ||
|
||
export const showDatePicker = false; | ||
|
||
export const filters = [ | ||
{ | ||
label: __( 'Show', 'wc-admin' ), | ||
staticParams: [], | ||
param: 'filter', | ||
showFilters: () => true, | ||
filters: [ { label: __( 'All Registered Customers', 'wc-admin' ), value: 'all' } ], | ||
}, | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/** @format */ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { Component, Fragment } from '@wordpress/element'; | ||
import PropTypes from 'prop-types'; | ||
|
||
/** | ||
* WooCommerce dependencies | ||
*/ | ||
import { ReportFilters } from '@woocommerce/components'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { filters, showDatePicker } from './config'; | ||
import CustomersReportTable from './table'; | ||
|
||
export default class CustomersReport extends Component { | ||
render() { | ||
const { query, path } = this.props; | ||
|
||
return ( | ||
<Fragment> | ||
<ReportFilters | ||
query={ query } | ||
path={ path } | ||
filters={ filters } | ||
showDatePicker={ showDatePicker } | ||
/> | ||
<CustomersReportTable query={ query } /> | ||
</Fragment> | ||
); | ||
} | ||
} | ||
|
||
CustomersReport.propTypes = { | ||
query: PropTypes.object.isRequired, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
/** @format */ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { __ } from '@wordpress/i18n'; | ||
import { Component } from '@wordpress/element'; | ||
import { format as formatDate } from '@wordpress/date'; | ||
|
||
/** | ||
* WooCommerce dependencies | ||
*/ | ||
import { getDateFormatsForInterval, getIntervalForQuery } from '@woocommerce/date'; | ||
import { formatCurrency, getCurrencyFormatDecimal } from '@woocommerce/currency'; | ||
import { Link } from '@woocommerce/components'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import ReportTable from 'analytics/components/report-table'; | ||
import { numberFormat } from 'lib/number'; | ||
|
||
export default class CustomersReportTable extends Component { | ||
constructor() { | ||
super(); | ||
|
||
this.getHeadersContent = this.getHeadersContent.bind( this ); | ||
this.getRowsContent = this.getRowsContent.bind( this ); | ||
} | ||
|
||
getHeadersContent() { | ||
return [ | ||
{ | ||
label: __( 'Name', 'wc-admin' ), | ||
key: 'name', | ||
required: true, | ||
isLeftAligned: true, | ||
isSortable: true, | ||
}, | ||
{ | ||
label: __( 'Username', 'wc-admin' ), | ||
key: 'username', | ||
hiddenByDefault: true, | ||
}, | ||
{ | ||
label: __( 'Sign Up', 'wc-admin' ), | ||
key: 'date_sign_up', | ||
defaultSort: true, | ||
isSortable: true, | ||
}, | ||
{ | ||
label: __( 'Email', 'wc-admin' ), | ||
key: 'email', | ||
}, | ||
{ | ||
label: __( 'Orders', 'wc-admin' ), | ||
key: 'orders_count', | ||
isSortable: true, | ||
isNumeric: true, | ||
}, | ||
{ | ||
label: __( 'Lifetime Spend', 'wc-admin' ), | ||
key: 'total_spend', | ||
isSortable: true, | ||
isNumeric: true, | ||
}, | ||
{ | ||
label: __( 'AOV', 'wc-admin' ), | ||
screenReaderLabel: __( 'Average Order Value', 'wc-admin' ), | ||
key: 'average_order_value', | ||
isNumeric: true, | ||
}, | ||
{ | ||
label: __( 'Last Active', 'wc-admin' ), | ||
key: 'date_last_active', | ||
isSortable: true, | ||
}, | ||
{ | ||
label: __( 'Country', 'wc-admin' ), | ||
key: 'country', | ||
}, | ||
{ | ||
label: __( 'City', 'wc-admin' ), | ||
key: 'city', | ||
hiddenByDefault: true, | ||
}, | ||
{ | ||
label: __( 'Postal Code', 'wc-admin' ), | ||
key: 'postal_code', | ||
hiddenByDefault: true, | ||
}, | ||
]; | ||
} | ||
|
||
getRowsContent( customers ) { | ||
const { query } = this.props; | ||
const currentInterval = getIntervalForQuery( query ); | ||
const formats = getDateFormatsForInterval( currentInterval ); | ||
|
||
return customers.map( customer => { | ||
const { | ||
average_order_value, | ||
id, | ||
city, | ||
country, | ||
date_last_active, | ||
date_sign_up, | ||
email, | ||
name, | ||
orders_count, | ||
postal_code, | ||
username, | ||
total_spend, | ||
} = customer; | ||
|
||
const customerNameLink = ( | ||
<Link href={ 'user-edit.php?user_id=' + id } type="wp-admin"> | ||
{ name } | ||
</Link> | ||
); | ||
|
||
return [ | ||
{ | ||
display: customerNameLink, | ||
value: name, | ||
}, | ||
{ | ||
display: username, | ||
value: username, | ||
}, | ||
{ | ||
display: formatDate( formats.tableFormat, date_sign_up ), | ||
value: date_sign_up, | ||
}, | ||
{ | ||
display: <a href={ 'mailto:' + email }>{ email }</a>, | ||
value: email, | ||
}, | ||
{ | ||
display: numberFormat( orders_count ), | ||
value: orders_count, | ||
}, | ||
{ | ||
display: formatCurrency( total_spend ), | ||
value: getCurrencyFormatDecimal( total_spend ), | ||
}, | ||
{ | ||
display: average_order_value, | ||
value: getCurrencyFormatDecimal( average_order_value ), | ||
}, | ||
{ | ||
display: formatDate( formats.tableFormat, date_last_active ), | ||
value: date_last_active, | ||
}, | ||
{ | ||
display: country, | ||
value: country, | ||
}, | ||
{ | ||
display: city, | ||
value: city, | ||
}, | ||
{ | ||
display: postal_code, | ||
value: postal_code, | ||
}, | ||
]; | ||
} ); | ||
} | ||
|
||
render() { | ||
const { query } = this.props; | ||
|
||
return ( | ||
<ReportTable | ||
compareBy="customers" | ||
endpoint="customers" | ||
getHeadersContent={ this.getHeadersContent } | ||
getRowsContent={ this.getRowsContent } | ||
itemIdField="id" | ||
query={ query } | ||
title={ __( 'Registered Customers', 'wc-admin' ) } | ||
/> | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
62 changes: 62 additions & 0 deletions
62
packages/components/src/search/autocompleters/customers.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/** @format */ | ||
/** | ||
* External dependencies | ||
*/ | ||
import apiFetch from '@wordpress/api-fetch'; | ||
|
||
/** | ||
* WooCommerce dependencies | ||
*/ | ||
import { stringifyQuery } from '@woocommerce/navigation'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { computeSuggestionMatch } from './utils'; | ||
|
||
/** | ||
* A customer completer. | ||
* See https://github.com/WordPress/gutenberg/tree/master/packages/components/src/autocomplete#the-completer-interface | ||
* | ||
* @type {Completer} | ||
*/ | ||
export default { | ||
name: 'customers', | ||
className: 'woocommerce-search__customers-result', | ||
options( search ) { | ||
let payload = ''; | ||
if ( search ) { | ||
const query = { | ||
search, | ||
per_page: 10, | ||
}; | ||
payload = stringifyQuery( query ); | ||
} | ||
return apiFetch( { path: `/wc/v3/customers${ payload }` } ); | ||
}, | ||
isDebounced: true, | ||
getOptionKeywords( customer ) { | ||
return [ customer.name ]; | ||
}, | ||
getOptionLabel( customer, query ) { | ||
const match = computeSuggestionMatch( customer.name, query ) || {}; | ||
return [ | ||
<span key="name" className="woocommerce-search__result-name" aria-label={ customer.name }> | ||
{ match.suggestionBeforeMatch } | ||
<strong className="components-form-token-field__suggestion-match"> | ||
{ match.suggestionMatch } | ||
</strong> | ||
{ match.suggestionAfterMatch } | ||
</span>, | ||
]; | ||
}, | ||
// This is slightly different than gutenberg/Autocomplete, we don't support different methods | ||
// of replace/insertion, so we can just return the value. | ||
getOptionCompletion( customer ) { | ||
const value = { | ||
id: customer.id, | ||
label: customer.name, | ||
}; | ||
return value; | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.