/**
* External dependencies
*/
import { __, _n, sprintf } from '@wordpress/i18n';
import { InspectorControls } from '@wordpress/block-editor';
import {
Button,
PanelBody,
Placeholder,
withSpokenMessages,
} from '@wordpress/components';
import { SearchListItem } from '@woocommerce/editor-components/search-list-control';
import PropTypes from 'prop-types';
import ProductControl from '@woocommerce/editor-components/product-control';
import { Icon, commentContent } from '@wordpress/icons';
/**
* Internal dependencies
*/
import EditorContainerBlock from '../editor-container-block.js';
import NoReviewsPlaceholder from './no-reviews-placeholder.js';
import {
getBlockControls,
getSharedReviewContentControls,
getSharedReviewListControls,
} from '../edit-utils.js';
/**
* Component to handle edit mode of "Reviews by Product".
*
* @param {Object} props Incoming props for the component.
* @param {Object} props.attributes Incoming block attributes.
* @param {function(any):any} props.debouncedSpeak
* @param {function(any):any} props.setAttributes Setter for block attributes.
*/
const ReviewsByProductEditor = ( {
attributes,
debouncedSpeak,
setAttributes,
} ) => {
const { editMode, productId } = attributes;
const renderProductControlItem = ( args ) => {
const { item = 0 } = args;
return (
<SearchListItem
{ ...args }
countLabel={ sprintf(
/* translators: %d is the review count. */
_n(
'%d review',
'%d reviews',
item.review_count,
'woocommerce'
),
item.review_count
) }
aria-label={ sprintf(
/* translators: %1$s is the item name, and %2$d is the number of reviews for the item. */
_n(
'%1$s, has %2$d review',
'%1$s, has %2$d reviews',
item.review_count,
'woocommerce'
),
item.name,
item.review_count
) }
/>
);
};
const getInspectorControls = () => {
return (
<InspectorControls key="inspector">
<PanelBody
title={ __( 'Product', 'woocommerce' ) }
initialOpen={ false }
>
<ProductControl
selected={ attributes.productId || 0 }
onChange={ ( value = [] ) => {
const id = value[ 0 ] ? value[ 0 ].id : 0;
setAttributes( { productId: id } );
} }
renderItem={ renderProductControlItem }
isCompact={ true }
/>
</PanelBody>
<PanelBody
title={ __( 'Content', 'woocommerce' ) }
>
{ getSharedReviewContentControls(
attributes,
setAttributes
) }
</PanelBody>
<PanelBody
title={ __(
'List Settings',
'woocommerce'
) }
>
{ getSharedReviewListControls( attributes, setAttributes ) }
</PanelBody>
</InspectorControls>
);
};
const renderEditMode = () => {
const onDone = () => {
setAttributes( { editMode: false } );
debouncedSpeak(
__(
'Showing Reviews by Product block preview.',
'woocommerce'
)
);
};
return (
<Placeholder
icon={
<Icon
icon={ commentContent }
className="block-editor-block-icon"
/>
}
label={ __(
'Reviews by Product',
'woocommerce'
) }
className="wc-block-reviews-by-product"
>
{ __(
'Show reviews of your product to build trust',
'woocommerce'
) }
<div className="wc-block-reviews__selection">
<ProductControl
selected={ attributes.productId || 0 }
onChange={ ( value = [] ) => {
const id = value[ 0 ] ? value[ 0 ].id : 0;
setAttributes( { productId: id } );
} }
queryArgs={ {
orderby: 'comment_count',
order: 'desc',
} }
renderItem={ renderProductControlItem }
/>
<Button isPrimary onClick={ onDone }>
{ __( 'Done', 'woocommerce' ) }
</Button>
</div>
</Placeholder>
);
};
if ( ! productId || editMode ) {
return renderEditMode();
}
const buttonTitle = __(
'Edit selected product',
'woocommerce'
);
return (
<>
{ getBlockControls( editMode, setAttributes, buttonTitle ) }
{ getInspectorControls() }
<EditorContainerBlock
attributes={ attributes }
icon={
<Icon
icon={ commentContent }
className="block-editor-block-icon"
/>
}
name={ __(
'Reviews by Product',
'woocommerce'
) }
noReviewsPlaceholder={ NoReviewsPlaceholder }
/>
</>
);
};
ReviewsByProductEditor.propTypes = {
/**
* The attributes for this block.
*/
attributes: PropTypes.object.isRequired,
/**
* The register block name.
*/
name: PropTypes.string.isRequired,
/**
* A callback to update attributes.
*/
setAttributes: PropTypes.func.isRequired,
// from withSpokenMessages
debouncedSpeak: PropTypes.func.isRequired,
};
export default withSpokenMessages( ReviewsByProductEditor );