2018-07-09 15:46:31 +00:00
|
|
|
/** @format */
|
|
|
|
/**
|
|
|
|
* External dependencies
|
|
|
|
*/
|
2018-08-01 12:21:51 +00:00
|
|
|
import { __, sprintf } from '@wordpress/i18n';
|
2018-07-20 18:24:39 +00:00
|
|
|
import { Component, Fragment } from '@wordpress/element';
|
2018-12-12 13:35:56 +00:00
|
|
|
import { compose } from '@wordpress/compose';
|
2018-07-25 14:25:08 +00:00
|
|
|
import Gridicon from 'gridicons';
|
2018-08-01 12:21:51 +00:00
|
|
|
import interpolateComponents from 'interpolate-components';
|
2018-12-12 13:35:56 +00:00
|
|
|
import { noop, isNull } from 'lodash';
|
|
|
|
import PropTypes from 'prop-types';
|
2018-07-09 15:46:31 +00:00
|
|
|
|
|
|
|
/**
|
2018-12-12 13:35:56 +00:00
|
|
|
* WooCommerce dependencies
|
2018-07-09 15:46:31 +00:00
|
|
|
*/
|
2018-09-21 15:19:05 +00:00
|
|
|
import {
|
2018-12-12 13:35:56 +00:00
|
|
|
EmptyContent,
|
2018-09-21 15:19:05 +00:00
|
|
|
Gravatar,
|
|
|
|
Link,
|
|
|
|
ProductImage,
|
|
|
|
ReviewRating,
|
|
|
|
Section,
|
|
|
|
SplitButton,
|
|
|
|
} from '@woocommerce/components';
|
2018-07-09 15:46:31 +00:00
|
|
|
|
2018-12-12 13:35:56 +00:00
|
|
|
/**
|
|
|
|
* Internal dependencies
|
|
|
|
*/
|
|
|
|
import { ActivityCard, ActivityCardPlaceholder } from '../activity-card';
|
|
|
|
import ActivityHeader from '../activity-header';
|
2019-01-30 07:22:10 +00:00
|
|
|
import { QUERY_DEFAULTS } from 'wc-api/constants';
|
2018-12-12 13:35:56 +00:00
|
|
|
import sanitizeHTML from 'lib/sanitize-html';
|
|
|
|
import withSelect from 'wc-api/with-select';
|
2018-08-01 12:21:51 +00:00
|
|
|
|
2018-07-09 15:46:31 +00:00
|
|
|
class ReviewsPanel extends Component {
|
2018-08-01 12:21:51 +00:00
|
|
|
renderReview( review ) {
|
2018-12-12 13:35:56 +00:00
|
|
|
const product =
|
|
|
|
( review && review._embedded && review._embedded.up && review._embedded.up[ 0 ] ) || null;
|
|
|
|
|
|
|
|
if ( isNull( product ) ) {
|
|
|
|
return null;
|
|
|
|
}
|
2018-08-01 12:21:51 +00:00
|
|
|
|
|
|
|
const title = interpolateComponents( {
|
|
|
|
mixedString: sprintf(
|
|
|
|
__(
|
|
|
|
'{{productLink}}%s{{/productLink}} reviewed by {{authorLink}}%s{{/authorLink}}',
|
|
|
|
'wc-admin'
|
|
|
|
),
|
|
|
|
product.name,
|
|
|
|
review.reviewer
|
|
|
|
),
|
|
|
|
components: {
|
|
|
|
productLink: <Link href={ product.permalink } type="external" />,
|
|
|
|
authorLink: <Link href={ 'mailto:' + review.reviewer_email } type="external" />,
|
|
|
|
},
|
|
|
|
} );
|
|
|
|
|
|
|
|
const subtitle = (
|
2018-07-20 18:24:39 +00:00
|
|
|
<Fragment>
|
2018-08-01 12:21:51 +00:00
|
|
|
<ReviewRating review={ review } />
|
|
|
|
{ review.verified && (
|
|
|
|
<span className="woocommerce-review-activity-card__verified">
|
|
|
|
<Gridicon icon="checkmark" size={ 18 } />
|
|
|
|
{ __( 'Verified customer', 'wc-admin' ) }
|
|
|
|
</span>
|
|
|
|
) }
|
|
|
|
</Fragment>
|
|
|
|
);
|
2018-07-25 14:25:08 +00:00
|
|
|
|
2018-08-01 12:21:51 +00:00
|
|
|
const icon = (
|
|
|
|
<div className="woocommerce-review-activity-card__image-overlay">
|
|
|
|
<Gravatar user={ review.reviewer_email } size={ 24 } />
|
|
|
|
<ProductImage product={ product } />
|
|
|
|
</div>
|
|
|
|
);
|
2018-07-25 14:25:08 +00:00
|
|
|
|
2018-08-01 12:21:51 +00:00
|
|
|
const cardActions = () => {
|
|
|
|
const mainLabel =
|
|
|
|
'approved' === review.status ? __( 'Unapprove', 'wc-admin' ) : __( 'Approve', 'wc-admin' );
|
|
|
|
return (
|
2018-07-25 14:25:08 +00:00
|
|
|
<SplitButton
|
2018-08-01 12:21:51 +00:00
|
|
|
mainLabel={ mainLabel }
|
|
|
|
menuLabel={ __( 'Select an action', 'wc-admin' ) }
|
|
|
|
onClick={ noop }
|
2018-07-25 14:25:08 +00:00
|
|
|
controls={ [
|
|
|
|
{
|
2018-08-01 12:21:51 +00:00
|
|
|
label: __( 'Reply', 'wc-admin' ),
|
|
|
|
onClick: noop,
|
2018-07-25 14:25:08 +00:00
|
|
|
},
|
|
|
|
{
|
2018-08-01 12:21:51 +00:00
|
|
|
label: __( 'Spam', 'wc-admin' ),
|
|
|
|
onClick: noop,
|
2018-07-25 14:25:08 +00:00
|
|
|
},
|
|
|
|
{
|
2018-08-01 12:21:51 +00:00
|
|
|
label: __( 'Trash', 'wc-admin' ),
|
|
|
|
onClick: noop,
|
2018-07-25 14:25:08 +00:00
|
|
|
},
|
|
|
|
] }
|
|
|
|
/>
|
2018-08-01 12:21:51 +00:00
|
|
|
);
|
|
|
|
};
|
2018-07-25 14:25:08 +00:00
|
|
|
|
2018-08-01 12:21:51 +00:00
|
|
|
return (
|
|
|
|
<ActivityCard
|
|
|
|
className="woocommerce-review-activity-card"
|
|
|
|
key={ review.id }
|
|
|
|
title={ title }
|
|
|
|
subtitle={ subtitle }
|
|
|
|
date={ review.date_created }
|
|
|
|
icon={ icon }
|
|
|
|
actions={ cardActions() }
|
|
|
|
>
|
2018-12-12 13:35:56 +00:00
|
|
|
<span dangerouslySetInnerHTML={ sanitizeHTML( review.review ) } />
|
2018-08-01 12:21:51 +00:00
|
|
|
</ActivityCard>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
2018-12-12 13:35:56 +00:00
|
|
|
const { isError, isRequesting, reviews } = this.props;
|
|
|
|
|
|
|
|
if ( isError ) {
|
|
|
|
const title = __( 'There was an error getting your reviews. Please try again.', 'wc-admin' );
|
|
|
|
const actionLabel = __( 'Reload', 'wc-admin' );
|
|
|
|
const actionCallback = () => {
|
|
|
|
window.location.reload();
|
|
|
|
};
|
|
|
|
|
|
|
|
return (
|
|
|
|
<Fragment>
|
|
|
|
<EmptyContent
|
|
|
|
title={ title }
|
|
|
|
actionLabel={ actionLabel }
|
|
|
|
actionURL={ null }
|
|
|
|
actionCallback={ actionCallback }
|
|
|
|
/>
|
|
|
|
</Fragment>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2018-08-01 12:21:51 +00:00
|
|
|
return (
|
|
|
|
<Fragment>
|
|
|
|
<ActivityHeader title={ __( 'Reviews', 'wc-admin' ) } />
|
|
|
|
<Section>
|
2018-12-12 13:35:56 +00:00
|
|
|
{ isRequesting ? (
|
|
|
|
<ActivityCardPlaceholder
|
|
|
|
className="woocommerce-review-activity-card"
|
|
|
|
hasAction
|
|
|
|
hasDate
|
|
|
|
lines={ 2 }
|
|
|
|
/>
|
2018-08-01 12:21:51 +00:00
|
|
|
) : (
|
2018-12-12 13:35:56 +00:00
|
|
|
<Fragment>{ reviews.map( this.renderReview ) }</Fragment>
|
2018-08-01 12:21:51 +00:00
|
|
|
) }
|
|
|
|
</Section>
|
2018-07-20 18:24:39 +00:00
|
|
|
</Fragment>
|
|
|
|
);
|
2018-07-09 15:46:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-12 13:35:56 +00:00
|
|
|
ReviewsPanel.propTypes = {
|
|
|
|
reviews: PropTypes.array.isRequired,
|
|
|
|
isError: PropTypes.bool,
|
|
|
|
isRequesting: PropTypes.bool,
|
|
|
|
};
|
|
|
|
|
|
|
|
ReviewsPanel.defaultProps = {
|
|
|
|
reviews: [],
|
|
|
|
isError: false,
|
|
|
|
isRequesting: false,
|
|
|
|
};
|
|
|
|
|
|
|
|
export default compose(
|
|
|
|
withSelect( select => {
|
2018-12-15 12:38:54 +00:00
|
|
|
const { getReviews, getReviewsError, isGetReviewsRequesting } = select( 'wc-api' );
|
2018-12-12 13:35:56 +00:00
|
|
|
const reviewsQuery = {
|
|
|
|
page: 1,
|
|
|
|
per_page: QUERY_DEFAULTS.pageSize,
|
|
|
|
_embed: 1,
|
|
|
|
};
|
|
|
|
|
|
|
|
const reviews = getReviews( reviewsQuery );
|
2018-12-15 12:38:54 +00:00
|
|
|
const isError = Boolean( getReviewsError( reviewsQuery ) );
|
2018-12-12 13:35:56 +00:00
|
|
|
const isRequesting = isGetReviewsRequesting( reviewsQuery );
|
|
|
|
|
|
|
|
return { reviews, isError, isRequesting };
|
|
|
|
} )
|
|
|
|
)( ReviewsPanel );
|