| 1 |
/** |
| 2 |
* WordPress dependencies |
| 3 |
*/ |
| 4 |
import { __ } from '@wordpress/i18n'; |
| 5 |
|
| 6 |
/** |
| 7 |
* Internal dependencies |
| 8 |
*/ |
| 9 |
import { useRecommendationsStore } from '../recommendations-store'; |
| 10 |
import { ParselyRecommendationsFetcher } from './parsely-recommendations-fetcher'; |
| 11 |
import { ParselyRecommendationsList } from './parsely-recommendations-list'; |
| 12 |
import { ParselyRecommendationsTitle } from './parsely-recommendations-title'; |
| 13 |
|
| 14 |
interface ParselyRecommendationsProps { |
| 15 |
imagestyle: string; |
| 16 |
isEditMode: boolean; |
| 17 |
limit: number; |
| 18 |
openlinksinnewtab: boolean; |
| 19 |
showimages: boolean; |
| 20 |
sort: string; |
| 21 |
title: string; |
| 22 |
} |
| 23 |
|
| 24 |
export function ParselyRecommendations( { |
| 25 |
imagestyle, |
| 26 |
isEditMode, |
| 27 |
limit, |
| 28 |
openlinksinnewtab, |
| 29 |
showimages, |
| 30 |
sort, |
| 31 |
title, |
| 32 |
} : Readonly<ParselyRecommendationsProps> ): React.JSX.Element { |
| 33 |
const { |
| 34 |
state: { error, isLoaded, recommendations }, |
| 35 |
} = useRecommendationsStore(); |
| 36 |
|
| 37 |
function getErrorMessage() { |
| 38 |
let message = `${ __( 'Error:', 'wp-parsely' ) } ${ JSON.stringify( error ) }`; |
| 39 |
const httpError = message.includes( '"errors":{"http_request_failed"' ) || |
| 40 |
( typeof error === 'object' && error?.code === 'fetch_error' ) || |
| 41 |
( typeof error === 'object' && error?.code === 'offline_error' ); |
| 42 |
|
| 43 |
if ( httpError ) { |
| 44 |
message = __( 'The Parse.ly Recommendations API is not accessible. You may be offline.', 'wp-parsely' ); |
| 45 |
} else if ( error.message === 'Forbidden' && error.data?.status === 403 && error.code === 403 ) { |
| 46 |
message = __( 'Access denied. Please verify that your Site ID is valid.', 'wp-parsely' ); |
| 47 |
} else if ( message.startsWith( 'Error: {"code":"parsely_site_id_not_set"' ) ) { |
| 48 |
message = __( 'To use this Block, a Parse.ly Site ID must be set in the plugin\'s options', 'wp-parsely' ); |
| 49 |
} else if ( typeof error === 'object' && error?.code === 'rest_no_route' ) { |
| 50 |
message = __( 'The REST route is unavailable. To use it, wp_parsely_api_related_endpoint_enabled should be true.', 'wp-parsely' ); |
| 51 |
} |
| 52 |
|
| 53 |
return message; |
| 54 |
} |
| 55 |
|
| 56 |
// Show error messages within the WordPress Block Editor when needed. |
| 57 |
let errorMessage; |
| 58 |
if ( isLoaded && isEditMode ) { |
| 59 |
if ( error ) { |
| 60 |
errorMessage = getErrorMessage(); |
| 61 |
} else if ( Array.isArray( recommendations ) && ! recommendations?.length ) { |
| 62 |
errorMessage = __( 'No recommendations found.', 'wp-parsely' ); |
| 63 |
} |
| 64 |
} |
| 65 |
|
| 66 |
return ( |
| 67 |
<> |
| 68 |
<ParselyRecommendationsFetcher |
| 69 |
limit={ limit } |
| 70 |
sort={ sort } |
| 71 |
isEditMode={ isEditMode } |
| 72 |
/> |
| 73 |
{ ! isLoaded && ( |
| 74 |
<span className="parsely-recommendations-loading">{ __( 'Loading…', 'wp-parsely' ) }</span> |
| 75 |
) } |
| 76 |
{ errorMessage && ( |
| 77 |
<span className="parsely-recommendations-error">{ errorMessage }</span> |
| 78 |
) } |
| 79 |
{ isLoaded && !! recommendations?.length && ( |
| 80 |
<> |
| 81 |
<ParselyRecommendationsTitle title={ title } /> |
| 82 |
<ParselyRecommendationsList |
| 83 |
imagestyle={ imagestyle } |
| 84 |
openlinksinnewtab={ openlinksinnewtab } |
| 85 |
recommendations={ recommendations } |
| 86 |
showimages={ showimages } |
| 87 |
/> |
| 88 |
</> |
| 89 |
) } |
| 90 |
</> |
| 91 |
); |
| 92 |
} |
| 93 |
|