diff --git a/assets/js/blocks/reviews/reviews-by-product/block.tsx b/assets/js/blocks/reviews/reviews-by-product/block.tsx new file mode 100644 index 00000000000..60992c9eba7 --- /dev/null +++ b/assets/js/blocks/reviews/reviews-by-product/block.tsx @@ -0,0 +1,182 @@ +/** + * 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 ProductControl from '@woocommerce/editor-components/product-control'; +import { commentContent, Icon } from '@wordpress/icons'; + +/** + * Internal dependencies + */ +import EditorContainerBlock from '../editor-container-block.js'; +import NoReviewsPlaceholder from './no-reviews-placeholder'; +import { + getBlockControls, + getSharedReviewContentControls, + getSharedReviewListControls, +} from '../edit-utils.js'; +import type { ReviewsByProductEditorProps, SearchListItemProps } from './types'; + +const ReviewsByProductEditor = ( { + attributes, + debouncedSpeak, + setAttributes, +}: ReviewsByProductEditorProps ) => { + const { editMode, productId } = attributes; + + const renderProductControlItem = ( args: SearchListItemProps ) => { + return ( + + ); + }; + + const getInspectorControls = () => { + return ( + + + { + const id = value[ 0 ] ? value[ 0 ].id : 0; + setAttributes( { productId: id } ); + } } + renderItem={ renderProductControlItem } + isCompact={ true } + /> + + + { getSharedReviewContentControls( + attributes, + setAttributes + ) } + + + { getSharedReviewListControls( attributes, setAttributes ) } + + + ); + }; + + const renderEditMode = () => { + const onDone = () => { + setAttributes( { editMode: false } ); + debouncedSpeak( + __( + 'Showing Reviews by Product block preview.', + 'woo-gutenberg-products-block' + ) + ); + }; + + return ( + + } + label={ __( + 'Reviews by Product', + 'woo-gutenberg-products-block' + ) } + className="wc-block-reviews-by-product" + > + { __( + 'Show reviews of your product to build trust', + 'woo-gutenberg-products-block' + ) } +
+ { + const id = value[ 0 ] ? value[ 0 ].id : 0; + setAttributes( { productId: id } ); + } } + queryArgs={ { + orderby: 'comment_count', + order: 'desc', + } } + renderItem={ renderProductControlItem } + /> + +
+
+ ); + }; + + if ( ! productId || editMode ) { + return renderEditMode(); + } + + const buttonTitle = __( + 'Edit selected product', + 'woo-gutenberg-products-block' + ); + + return ( + <> + { getBlockControls( editMode, setAttributes, buttonTitle ) } + { getInspectorControls() } + + } + name={ __( + 'Reviews by Product', + 'woo-gutenberg-products-block' + ) } + noReviewsPlaceholder={ NoReviewsPlaceholder } + /> + + ); +}; + +export default withSpokenMessages( ReviewsByProductEditor ); diff --git a/assets/js/blocks/reviews/reviews-by-product/edit.tsx b/assets/js/blocks/reviews/reviews-by-product/edit.tsx index 3c9155a69a3..e241189c5f7 100644 --- a/assets/js/blocks/reviews/reviews-by-product/edit.tsx +++ b/assets/js/blocks/reviews/reviews-by-product/edit.tsx @@ -1,184 +1,22 @@ /** * 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 ProductControl from '@woocommerce/editor-components/product-control'; -import { commentContent, Icon } from '@wordpress/icons'; +import { useBlockProps } from '@wordpress/block-editor'; /** * Internal dependencies */ -import EditorContainerBlock from '../editor-container-block.js'; -import NoReviewsPlaceholder from './no-reviews-placeholder.js'; -import { - getBlockControls, - getSharedReviewContentControls, - getSharedReviewListControls, -} from '../edit-utils.js'; -import { ReviewsByProductEditorProps } from './types'; +import Block from './block'; +import type { ReviewsByProductEditorProps } from './types'; -const ReviewsByProductEditor = ( { - attributes, - debouncedSpeak, - setAttributes, -}: ReviewsByProductEditorProps ) => { - const { editMode, productId } = attributes; - - const renderProductControlItem = ( args ) => { - const { item = 0 } = args; - - return ( - - ); - }; - - const getInspectorControls = () => { - return ( - - - { - const id = value[ 0 ] ? value[ 0 ].id : 0; - setAttributes( { productId: id } ); - } } - renderItem={ renderProductControlItem } - isCompact={ true } - /> - - - { getSharedReviewContentControls( - attributes, - setAttributes - ) } - - - { getSharedReviewListControls( attributes, setAttributes ) } - - - ); - }; - - const renderEditMode = () => { - const onDone = () => { - setAttributes( { editMode: false } ); - debouncedSpeak( - __( - 'Showing Reviews by Product block preview.', - 'woo-gutenberg-products-block' - ) - ); - }; - - return ( - - } - label={ __( - 'Reviews by Product', - 'woo-gutenberg-products-block' - ) } - className="wc-block-reviews-by-product" - > - { __( - 'Show reviews of your product to build trust', - 'woo-gutenberg-products-block' - ) } -
- { - const id = value[ 0 ] ? value[ 0 ].id : 0; - setAttributes( { productId: id } ); - } } - queryArgs={ { - orderby: 'comment_count', - order: 'desc', - } } - renderItem={ renderProductControlItem } - /> - -
-
- ); - }; - - if ( ! productId || editMode ) { - return renderEditMode(); - } - - const buttonTitle = __( - 'Edit selected product', - 'woo-gutenberg-products-block' - ); +export const Edit = ( + props: unknown & ReviewsByProductEditorProps +): JSX.Element => { + const blockProps = useBlockProps(); return ( - <> - { getBlockControls( editMode, setAttributes, buttonTitle ) } - { getInspectorControls() } - - } - name={ __( - 'Reviews by Product', - 'woo-gutenberg-products-block' - ) } - noReviewsPlaceholder={ NoReviewsPlaceholder } - /> - +
+ +
); }; - -export default withSpokenMessages( ReviewsByProductEditor ); diff --git a/assets/js/blocks/reviews/reviews-by-product/index.js b/assets/js/blocks/reviews/reviews-by-product/index.tsx similarity index 94% rename from assets/js/blocks/reviews/reviews-by-product/index.js rename to assets/js/blocks/reviews/reviews-by-product/index.tsx index ff6d152d41b..c9927088dc7 100644 --- a/assets/js/blocks/reviews/reviews-by-product/index.js +++ b/assets/js/blocks/reviews/reviews-by-product/index.tsx @@ -8,7 +8,7 @@ import { Icon, commentContent } from '@wordpress/icons'; * Internal dependencies */ import '../editor.scss'; -import Editor from './edit'; +import { Edit } from './edit'; import sharedAttributes from '../attributes'; import save from '../save.js'; import { example } from '../example'; @@ -64,9 +64,7 @@ registerBlockType( 'woocommerce/reviews-by-product', { * * @param {Object} props Props to pass to block. */ - edit( props ) { - return ; - }, + edit: Edit, /** * Save the props to post content. diff --git a/assets/js/blocks/reviews/reviews-by-product/no-reviews-placeholder.js b/assets/js/blocks/reviews/reviews-by-product/no-reviews-placeholder.tsx similarity index 80% rename from assets/js/blocks/reviews/reviews-by-product/no-reviews-placeholder.js rename to assets/js/blocks/reviews/reviews-by-product/no-reviews-placeholder.tsx index 9d17ee9e350..85301538094 100644 --- a/assets/js/blocks/reviews/reviews-by-product/no-reviews-placeholder.js +++ b/assets/js/blocks/reviews/reviews-by-product/no-reviews-placeholder.tsx @@ -3,13 +3,21 @@ */ import { __, sprintf } from '@wordpress/i18n'; import { Placeholder, Spinner } from '@wordpress/components'; -import PropTypes from 'prop-types'; import ErrorPlaceholder from '@woocommerce/editor-components/error-placeholder'; import { Icon, commentContent } from '@wordpress/icons'; import { withProduct } from '@woocommerce/block-hocs'; import { decodeEntities } from '@wordpress/html-entities'; +/** + * Internal dependencies + */ +import type { NoReviewsPlaceholderProps } from './types'; -const NoReviewsPlaceholder = ( { error, getProduct, isLoading, product } ) => { +const NoReviewsPlaceholder = ( { + error, + getProduct, + isLoading, + product, +}: NoReviewsPlaceholderProps ) => { const renderApiError = () => ( { ); }; -NoReviewsPlaceholder.propTypes = { - // from withProduct - error: PropTypes.object, - isLoading: PropTypes.bool, - product: PropTypes.shape( { - name: PropTypes.node, - review_count: PropTypes.number, - } ), -}; - export default withProduct( NoReviewsPlaceholder ); diff --git a/assets/js/blocks/reviews/reviews-by-product/types.ts b/assets/js/blocks/reviews/reviews-by-product/types.ts index 297d7f62fbe..7fc268ca592 100644 --- a/assets/js/blocks/reviews/reviews-by-product/types.ts +++ b/assets/js/blocks/reviews/reviews-by-product/types.ts @@ -1,6 +1,8 @@ /** * External dependencies */ +import { ErrorObject } from '@woocommerce/editor-components/error-placeholder'; +import { renderItemArgs } from '@woocommerce/editor-components/search-list-control/types'; import { BlockEditProps } from '@wordpress/blocks'; interface ReviewByProductAttributes { @@ -13,3 +15,17 @@ export interface ReviewsByProductEditorProps attributes: ReviewByProductAttributes; debouncedSpeak: ( message: string ) => void; } + +export interface NoReviewsPlaceholderProps { + error: ErrorObject; + getProduct: () => void; + isLoading: boolean; + product?: { + name: string; + }; +} + +export interface SearchListItemProps extends renderItemArgs { + name: string; + reviewCount: number; +}