Skip to content

Commit

Permalink
tailwindify notices and errors
Browse files Browse the repository at this point in the history
hide country selector only when semrush limited reached

fix order
  • Loading branch information
vraja-pro committed Nov 12, 2024
1 parent 9d1cb6a commit ec7e7f9
Show file tree
Hide file tree
Showing 11 changed files with 262 additions and 64 deletions.
135 changes: 71 additions & 64 deletions packages/js/src/components/SEMrushRelatedKeyphrasesModalContent.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
/* External dependencies */
import { Fragment } from "@wordpress/element";
import { KeyphrasesTable } from "@yoast/related-keyphrase-suggestions";
import { KeyphrasesTable, UserMessage } from "@yoast/related-keyphrase-suggestions";
import { Root } from "@yoast/ui-library";
import { __, sprintf } from "@wordpress/i18n";
import PropTypes from "prop-types";
import { isEmpty } from "lodash";

/* Internal dependencies */
import SEMrushLoading from "./modals/SEMrushLoading";
import SEMrushLimitReached from "./modals/SEMrushLimitReached";
import SEMrushCountrySelector from "./modals/SEMrushCountrySelector";
import SEMrushUpsellAlert from "./modals/SEMrushUpsellAlert";
import SEMrushRequestFailed from "./modals/SEMrushRequestFailed";
import SEMrushMaxRelatedKeyphrases from "./modals/SEMrushMaxRelatedKeyphrases";
import getL10nObject from "../analysis/getL10nObject";
import { makeOutboundLink } from "@yoast/helpers";

Expand All @@ -28,35 +23,31 @@ export function hasError( response ) {
}

/**
* Gets a user message based on the passed props' values.
* Gets a user message variant.
*
* @param {Object} props The props to use.
* @param {boolean} requestLimitReached Whether the request limit has been reached.
* @param {boolean} isSuccess Whether the request was successful.
* @param {Object} response The response object.
* @param {boolean} requestHasData Whether the request has data.
* @param {boolean} maxRelatedKeyphrases Whether the maximum related keyphrases has been reached.
*
* @returns {wp.Element} The user message.
*/
export function getUserMessage( props ) {
const {
isPending,
requestLimitReached,
isSuccess,
response,
requestHasData,
} = props;

if ( isPending ) {
return <SEMrushLoading />;
}

export function getUserMessage( requestLimitReached, isSuccess, response, requestHasData, maxRelatedKeyphrases ) {
if ( requestLimitReached ) {
return <SEMrushLimitReached />;
return "requestLimitReached";
}

if ( ! isSuccess && hasError( response ) ) {
return <SEMrushRequestFailed />;
return "requestFailed";
}

if ( ! requestHasData ) {
return <p>{ __( "Sorry, there's no data available for that keyphrase/country combination.", "wordpress-seo" ) }</p>;
return "requestEmpty";
}

if ( maxRelatedKeyphrases ) {
return "maxRelatedKeyphrases";
}
}

Expand Down Expand Up @@ -95,6 +86,9 @@ export default function RelatedKeyphraseModalContent( props ) {
setRequestLimitReached,
isPending,
isRtl,
userLocale,
requestHasData,
isSuccess,
} = props;

const isPremium = getL10nObject().isPremium;
Expand All @@ -103,47 +97,54 @@ export default function RelatedKeyphraseModalContent( props ) {
"&db=" + encodeURIComponent( countryCode );

return (
<Fragment>
{ ! requestLimitReached && (
<Fragment>
{ ! isPremium && <SEMrushUpsellAlert /> }
{ isPremium && hasMaximumRelatedKeyphrases( relatedKeyphrases ) && <SEMrushMaxRelatedKeyphrases /> }
<SEMrushCountrySelector
countryCode={ countryCode }
setCountry={ setCountry }
newRequest={ newRequest }
keyphrase={ keyphrase }
setRequestFailed={ setRequestFailed }
setNoResultsFound={ setNoResultsFound }
setRequestSucceeded={ setRequestSucceeded }
setRequestLimitReached={ setRequestLimitReached }
response={ response }
lastRequestKeyphrase={ lastRequestKeyphrase }
/>
</Fragment>
) }

{ getUserMessage( props ) }
<Root context={ { isRtl } }>
<KeyphrasesTable
relatedKeyphrases={ relatedKeyphrases }
columnNames={ response?.results?.columnNames }
data={ response?.results?.rows }
isPending={ isPending }
renderButton={ renderAction }
/>
{ response?.results?.rows && <p className="yst-mb-0 yst-mt-2">
<GetMoreInsightsLink href={ url }>
{ sprintf(
<Root context={ { isRtl } }>

{ ! isPremium && <SEMrushUpsellAlert /> }

{ ! requestLimitReached && <SEMrushCountrySelector
countryCode={ countryCode }
setCountry={ setCountry }
newRequest={ newRequest }
keyphrase={ keyphrase }
setRequestFailed={ setRequestFailed }
setNoResultsFound={ setNoResultsFound }
setRequestSucceeded={ setRequestSucceeded }
setRequestLimitReached={ setRequestLimitReached }
response={ response }
lastRequestKeyphrase={ lastRequestKeyphrase }
userLocale={ userLocale }
isRtl={ isRtl }
/> }

<UserMessage
variant={ getUserMessage(
requestLimitReached,
isSuccess,
response,
requestHasData,
( isPremium && hasMaximumRelatedKeyphrases( relatedKeyphrases ) )
) }
upsellLink={ window.wpseoAdminL10n[ "shortlinks.semrush.prices" ] }
className="yst-my-2"
/>

<KeyphrasesTable
relatedKeyphrases={ relatedKeyphrases }
columnNames={ response?.results?.columnNames }
data={ response?.results?.rows }
isPending={ isPending }
renderButton={ renderAction }
/>
{ response?.results?.rows && <p className="yst-mb-0 yst-mt-2">
<GetMoreInsightsLink href={ url }>
{ sprintf(
/* translators: %s expands to Semrush */
__( "Get more insights at %s", "wordpress-seo" ),
"Semrush"
) }
</GetMoreInsightsLink>
</p> }
</Root>

</Fragment>
__( "Get more insights at %s", "wordpress-seo" ),
"Semrush"
) }
</GetMoreInsightsLink>
</p> }
</Root>
);
}

Expand All @@ -163,6 +164,9 @@ RelatedKeyphraseModalContent.propTypes = {
lastRequestKeyphrase: PropTypes.string,
isRtl: PropTypes.bool,
isPending: PropTypes.bool,
requestHasData: PropTypes.bool,
isSuccess: PropTypes.bool,
userLocale: PropTypes.string,
};

RelatedKeyphraseModalContent.defaultProps = {
Expand All @@ -174,4 +178,7 @@ RelatedKeyphraseModalContent.defaultProps = {
lastRequestKeyphrase: "",
isRtl: false,
isPending: false,
requestHasData: false,
isSuccess: false,
userLocale: "en",
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from "react";
import PropTypes from "prop-types";
import { __, sprintf } from "@wordpress/i18n";
import { Alert } from "@yoast/ui-library";

/**
* Display the message when reaching max related keyphrases.
*
* @param {string} [className=""] The class name for the alert.
*
* @returns {React.Component} The alert for max related keyphrases.
*/
export const MaxRelatedKeyphrases = ( { className = "" } ) => {
return (
<Alert variant="warning" className={ className }>
{ sprintf(
/* translators: %s: Expands to "Yoast SEO". */
__(
// eslint-disable-next-line max-len
"You've reached the maximum amount of 4 related keyphrases. You can change or remove related keyphrases in the %s metabox or sidebar.",
"wordpress-seo",
),
"Yoast SEO",
) }
</Alert>
);
};

MaxRelatedKeyphrases.propTypes = {
className: PropTypes.string,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from "react";
import PropTypes from "prop-types";
import { __ } from "@wordpress/i18n";
import { Alert } from "@yoast/ui-library";

/**
* Display the message for a empty request.
*
* @param {string} [className=""] The class name for the alert.
*
* @returns {React.Component} The message for a empty request.
*/
export const RequestEmpty = ( { className = "" } ) => {
return (
<Alert variant="info" className={ className }>
{ __( "Sorry, there's no data available for that keyphrase/country combination.", "wordpress-seo" ) }
</Alert>
);
};

RequestEmpty.propTypes = {
className: PropTypes.string,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from "react";
import PropTypes from "prop-types";
import { __ } from "@wordpress/i18n";
import { Alert } from "@yoast/ui-library";

/**
* Display the message for a failed request.
*
* @param {string} [className=""] The class name for the alert.
*
* @returns {React.Component} The message for a failed request.
*/
export const RequestFailed = ( { className = "" } ) => {
return (
<Alert variant="error" className={ className }>
{ __( "We've encountered a problem trying to get related keyphrases. Please try again later.", "wordpress-seo" ) }
</Alert>
);
};

RequestFailed.propTypes = {
className: PropTypes.string,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React from "react";
import PropTypes from "prop-types";
import { __, sprintf } from "@wordpress/i18n";
import { Alert, Button } from "@yoast/ui-library";
import { ArrowNarrowRightIcon } from "@heroicons/react/outline";

/**
* Display the message for a request that has reached the limit.
*
* @param {String} [upsellLink] The upsell link.
* @param {string} [className=""] The class name for the alert.
*
* @returns {React.Component} The message for limit reached.
*/
export const RequestLimitReached = ( { upsellLink, className = "" } ) => {
return (
<Alert variant="warning" className={ className }>
<div className="yst-flex yst-flex-col yst-items-start">
{ sprintf(
/* translators: %s : Expands to "Semrush". */
__( "You've reached your request limit for today. Check back tomorrow or upgrade your plan over at %s.", "wordpress-seo" ),
"Semrush",
) }

{ upsellLink && <Button
variant="upsell"
className="yst-mt-3 yst-gap-1.5"
as="a"
href={ upsellLink }
target="_blank"
>
{
sprintf(
/* translators: %s : Expands to "Semrush". */
__( "Upgrade your %s plan", "wordpress-seo" ),
"Semrush",
)
}
<ArrowNarrowRightIcon className="yst-w-4 yst-h-4 yst-text-amber-900" />

</Button> }
</div>
</Alert>
);
};

RequestLimitReached.propTypes = {
upsellLink: PropTypes.string,
className: PropTypes.string,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export { MaxRelatedKeyphrases } from "./MaxRelatedKeyphrases";
export { RequestFailed } from "./RequestFailed";
export { RequestEmpty } from "./RequestEmpty";
export { RequestLimitReached } from "./RequestLimitReached";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The alert to display to the user related to the related keyphrases suggestions request or action.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as component } from "./component.md";
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from "react";
import PropTypes from "prop-types";
import { RequestFailed, RequestLimitReached, RequestEmpty, MaxRelatedKeyphrases } from "./components";

/**
* Displays the user message following a request or action.
*
* @param {string} [variant] The type of message to display.
* @param {string} [upsellLink=""] The link to the upsell page.
* @param {string} [className=""] The class name for the button.
*
* @returns {React.Component} The user message.
*/
export const UserMessage = ( { variant, upsellLink = "", className = "" } ) => {
switch ( variant ) {
case "requestLimitReached":
return <RequestLimitReached upsellLink={ upsellLink } className={ className } />;
case "requestFailed":
return <RequestFailed className={ className } />;
case "requestEmpty":
return <RequestEmpty className={ className } />;
case "maxRelatedKeyphrases":
return <MaxRelatedKeyphrases className={ className } />;
default:
return null;
}
};

UserMessage.propTypes = {
variant: PropTypes.oneOf( [ "requestLimitReached", "requestFailed", "requestEmpty", "maxRelatedKeyphrases" ] ),
upsellLink: PropTypes.string,
className: PropTypes.string,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from "react";
import { UserMessage } from ".";
import { component } from "./docs";

export const Factory = {
parameters: {
controls: { disable: false },
},
render: ( args ) => <UserMessage { ...args } />,
};

export default {
title: "2) Elements/UserMessage",
component: UserMessage,
args: {
variant: "requestLimitReached",
upsellLink: "https://www.semrush.com/analytics/keywordoverview/?q=example&db=us",
},
parameters: {
docs: {
description: { component },
},
},
};
1 change: 1 addition & 0 deletions packages/related-keyphrase-suggestions/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export { DifficultyBullet } from "./elements/DifficultyBullet";
export { IntentBadge } from "./elements/IntentBadge";
export { TableButton } from "./elements/TableButton";
export { CountrySelector } from "./components/CountrySelector";
export { UserMessage } from "./elements/UserMessage";

0 comments on commit ec7e7f9

Please sign in to comment.