2023-10-06 08:17:56 +00:00
|
|
|
/**
|
|
|
|
* External dependencies
|
|
|
|
*/
|
|
|
|
import { useQuery } from '@woocommerce/navigation';
|
2023-11-21 12:43:48 +00:00
|
|
|
import { useContext } from '@wordpress/element';
|
|
|
|
import { __ } from '@wordpress/i18n';
|
2023-10-06 08:17:56 +00:00
|
|
|
|
2023-10-04 16:59:34 +00:00
|
|
|
/**
|
|
|
|
* Internal dependencies
|
|
|
|
*/
|
|
|
|
import './search-results.scss';
|
2023-10-06 08:17:56 +00:00
|
|
|
import { Product, ProductType, SearchResultType } from '../product-list/types';
|
|
|
|
import Products from '../products/products';
|
2023-11-21 12:43:48 +00:00
|
|
|
import NoResults from '../product-list-content/no-results';
|
|
|
|
import { MarketplaceContext } from '../../contexts/marketplace-context';
|
|
|
|
import {
|
|
|
|
MARKETPLACE_ITEMS_PER_PAGE,
|
|
|
|
MARKETPLACE_SEARCH_RESULTS_PER_PAGE,
|
|
|
|
} from '~/marketplace/components/constants';
|
2023-10-04 16:59:34 +00:00
|
|
|
|
|
|
|
export interface SearchResultProps {
|
|
|
|
products: Product[];
|
2023-10-06 08:17:56 +00:00
|
|
|
type: SearchResultType;
|
2023-10-04 16:59:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export default function SearchResults( props: SearchResultProps ): JSX.Element {
|
2023-10-17 16:32:23 +00:00
|
|
|
const extensionList = props.products.filter(
|
2023-10-04 16:59:34 +00:00
|
|
|
( product ) => product.type === ProductType.extension
|
|
|
|
);
|
2023-10-17 16:32:23 +00:00
|
|
|
const themeList = props.products.filter(
|
2023-10-04 16:59:34 +00:00
|
|
|
( product ) => product.type === ProductType.theme
|
|
|
|
);
|
2023-11-21 12:43:48 +00:00
|
|
|
const marketplaceContextValue = useContext( MarketplaceContext );
|
|
|
|
const { isLoading } = marketplaceContextValue;
|
2023-10-04 16:59:34 +00:00
|
|
|
|
2023-10-06 08:17:56 +00:00
|
|
|
const query = useQuery();
|
|
|
|
const showCategorySelector = query.section ? true : false;
|
2023-11-21 06:48:59 +00:00
|
|
|
const searchTerm = query.term ? query.term : '';
|
2023-10-06 08:17:56 +00:00
|
|
|
|
2023-11-21 12:43:48 +00:00
|
|
|
type Overrides = {
|
|
|
|
categorySelector?: boolean;
|
|
|
|
showAllButton?: boolean;
|
|
|
|
perPage?: number;
|
|
|
|
};
|
2023-10-17 16:32:23 +00:00
|
|
|
|
2023-11-21 12:43:48 +00:00
|
|
|
function productsComponent(
|
|
|
|
products: Product[],
|
|
|
|
type: ProductType,
|
|
|
|
overrides: {
|
|
|
|
categorySelector?: boolean;
|
|
|
|
showAllButton?: boolean;
|
|
|
|
perPage?: number;
|
|
|
|
} = {}
|
|
|
|
) {
|
|
|
|
return (
|
|
|
|
<Products
|
|
|
|
products={ products }
|
|
|
|
type={ type }
|
|
|
|
categorySelector={
|
|
|
|
overrides.categorySelector ?? showCategorySelector
|
|
|
|
}
|
|
|
|
searchTerm={ searchTerm }
|
|
|
|
showAllButton={ overrides.showAllButton ?? true }
|
|
|
|
perPage={ overrides.perPage ?? MARKETPLACE_ITEMS_PER_PAGE }
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
function extensionsComponent( overrides: Overrides = {} ) {
|
|
|
|
return productsComponent(
|
|
|
|
extensionList,
|
|
|
|
ProductType.extension,
|
|
|
|
overrides
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
function themesComponent( overrides: Overrides = {} ) {
|
|
|
|
return productsComponent( themeList, ProductType.theme, overrides );
|
|
|
|
}
|
2023-10-17 16:32:23 +00:00
|
|
|
|
|
|
|
const content = () => {
|
|
|
|
if ( query?.section === SearchResultType.extension ) {
|
2023-11-21 12:43:48 +00:00
|
|
|
return extensionsComponent( { showAllButton: false } );
|
2023-10-17 16:32:23 +00:00
|
|
|
}
|
|
|
|
|
2023-11-21 12:43:48 +00:00
|
|
|
if ( query?.section === SearchResultType.theme ) {
|
|
|
|
return themesComponent( { showAllButton: false } );
|
|
|
|
}
|
|
|
|
|
|
|
|
// Components can handle their isLoading state. So we can put them both on the page.
|
|
|
|
if ( isLoading ) {
|
2023-10-17 16:32:23 +00:00
|
|
|
return (
|
|
|
|
<>
|
2023-11-21 12:43:48 +00:00
|
|
|
{ extensionsComponent() }
|
|
|
|
{ themesComponent() }
|
2023-10-17 16:32:23 +00:00
|
|
|
</>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2023-11-21 12:43:48 +00:00
|
|
|
// If we did finish loading items, and there are no results, show the no results component.
|
|
|
|
if (
|
|
|
|
! isLoading &&
|
|
|
|
extensionList.length === 0 &&
|
|
|
|
themeList.length === 0
|
|
|
|
) {
|
|
|
|
return (
|
|
|
|
<NoResults
|
|
|
|
type={ SearchResultType.all }
|
|
|
|
showHeading={ true }
|
|
|
|
heading={ __(
|
|
|
|
'No extensions or themes found…',
|
|
|
|
'woocommerce'
|
|
|
|
) }
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( themeList.length === 0 && extensionList.length > 0 ) {
|
|
|
|
return extensionsComponent( {
|
|
|
|
categorySelector: true,
|
|
|
|
showAllButton: false,
|
|
|
|
perPage: MARKETPLACE_ITEMS_PER_PAGE,
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( extensionList.length === 0 && themeList.length > 0 ) {
|
|
|
|
return themesComponent( {
|
|
|
|
categorySelector: true,
|
|
|
|
showAllButton: false,
|
|
|
|
perPage: MARKETPLACE_ITEMS_PER_PAGE,
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we're done loading, we can put these components on the page.
|
2023-10-17 16:32:23 +00:00
|
|
|
return (
|
|
|
|
<>
|
2023-11-21 12:43:48 +00:00
|
|
|
{ extensionsComponent( {
|
|
|
|
perPage: MARKETPLACE_SEARCH_RESULTS_PER_PAGE,
|
|
|
|
} ) }
|
|
|
|
{ themesComponent( {
|
|
|
|
perPage: MARKETPLACE_SEARCH_RESULTS_PER_PAGE,
|
|
|
|
} ) }
|
2023-10-17 16:32:23 +00:00
|
|
|
</>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
2023-10-04 16:59:34 +00:00
|
|
|
return (
|
|
|
|
<div className="woocommerce-marketplace__search-results">
|
2023-10-17 16:32:23 +00:00
|
|
|
{ content() }
|
2023-10-04 16:59:34 +00:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|