From ec7e7f9423edfb93431470f70b52c9e2a7a45d77 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Tue, 12 Nov 2024 12:10:53 +0200 Subject: [PATCH] tailwindify notices and errors hide country selector only when semrush limited reached fix order --- .../SEMrushRelatedKeyphrasesModalContent.js | 135 +++++++++--------- .../components/MaxRelatedKeyphrases.js | 31 ++++ .../UserMessage/components/RequestEmpty.js | 23 +++ .../UserMessage/components/RequestFailed.js | 23 +++ .../components/RequestLimitReached.js | 50 +++++++ .../elements/UserMessage/components/index.js | 4 + .../elements/UserMessage/docs/component.md | 1 + .../src/elements/UserMessage/docs/index.js | 1 + .../src/elements/UserMessage/index.js | 33 +++++ .../src/elements/UserMessage/stories.js | 24 ++++ .../src/index.js | 1 + 11 files changed, 262 insertions(+), 64 deletions(-) create mode 100644 packages/related-keyphrase-suggestions/src/elements/UserMessage/components/MaxRelatedKeyphrases.js create mode 100644 packages/related-keyphrase-suggestions/src/elements/UserMessage/components/RequestEmpty.js create mode 100644 packages/related-keyphrase-suggestions/src/elements/UserMessage/components/RequestFailed.js create mode 100644 packages/related-keyphrase-suggestions/src/elements/UserMessage/components/RequestLimitReached.js create mode 100644 packages/related-keyphrase-suggestions/src/elements/UserMessage/components/index.js create mode 100644 packages/related-keyphrase-suggestions/src/elements/UserMessage/docs/component.md create mode 100644 packages/related-keyphrase-suggestions/src/elements/UserMessage/docs/index.js create mode 100644 packages/related-keyphrase-suggestions/src/elements/UserMessage/index.js create mode 100644 packages/related-keyphrase-suggestions/src/elements/UserMessage/stories.js diff --git a/packages/js/src/components/SEMrushRelatedKeyphrasesModalContent.js b/packages/js/src/components/SEMrushRelatedKeyphrasesModalContent.js index 18c703a1ffd..fc12640450a 100644 --- a/packages/js/src/components/SEMrushRelatedKeyphrasesModalContent.js +++ b/packages/js/src/components/SEMrushRelatedKeyphrasesModalContent.js @@ -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"; @@ -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 ; - } - +export function getUserMessage( requestLimitReached, isSuccess, response, requestHasData, maxRelatedKeyphrases ) { if ( requestLimitReached ) { - return ; + return "requestLimitReached"; } if ( ! isSuccess && hasError( response ) ) { - return ; + return "requestFailed"; } if ( ! requestHasData ) { - return

{ __( "Sorry, there's no data available for that keyphrase/country combination.", "wordpress-seo" ) }

; + return "requestEmpty"; + } + + if ( maxRelatedKeyphrases ) { + return "maxRelatedKeyphrases"; } } @@ -95,6 +86,9 @@ export default function RelatedKeyphraseModalContent( props ) { setRequestLimitReached, isPending, isRtl, + userLocale, + requestHasData, + isSuccess, } = props; const isPremium = getL10nObject().isPremium; @@ -103,47 +97,54 @@ export default function RelatedKeyphraseModalContent( props ) { "&db=" + encodeURIComponent( countryCode ); return ( - - { ! requestLimitReached && ( - - { ! isPremium && } - { isPremium && hasMaximumRelatedKeyphrases( relatedKeyphrases ) && } - - - ) } - - { getUserMessage( props ) } - - - { response?.results?.rows &&

- - { sprintf( + + + { ! isPremium && } + + { ! requestLimitReached && } + + + + + { response?.results?.rows &&

+ + { sprintf( /* translators: %s expands to Semrush */ - __( "Get more insights at %s", "wordpress-seo" ), - "Semrush" - ) } - -

} -
- -
+ __( "Get more insights at %s", "wordpress-seo" ), + "Semrush" + ) } + +

} + ); } @@ -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 = { @@ -174,4 +178,7 @@ RelatedKeyphraseModalContent.defaultProps = { lastRequestKeyphrase: "", isRtl: false, isPending: false, + requestHasData: false, + isSuccess: false, + userLocale: "en", }; diff --git a/packages/related-keyphrase-suggestions/src/elements/UserMessage/components/MaxRelatedKeyphrases.js b/packages/related-keyphrase-suggestions/src/elements/UserMessage/components/MaxRelatedKeyphrases.js new file mode 100644 index 00000000000..1163519f1e6 --- /dev/null +++ b/packages/related-keyphrase-suggestions/src/elements/UserMessage/components/MaxRelatedKeyphrases.js @@ -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 ( + + { 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", + ) } + + ); +}; + +MaxRelatedKeyphrases.propTypes = { + className: PropTypes.string, +}; diff --git a/packages/related-keyphrase-suggestions/src/elements/UserMessage/components/RequestEmpty.js b/packages/related-keyphrase-suggestions/src/elements/UserMessage/components/RequestEmpty.js new file mode 100644 index 00000000000..d75b3574a4b --- /dev/null +++ b/packages/related-keyphrase-suggestions/src/elements/UserMessage/components/RequestEmpty.js @@ -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 ( + + { __( "Sorry, there's no data available for that keyphrase/country combination.", "wordpress-seo" ) } + + ); +}; + +RequestEmpty.propTypes = { + className: PropTypes.string, +}; diff --git a/packages/related-keyphrase-suggestions/src/elements/UserMessage/components/RequestFailed.js b/packages/related-keyphrase-suggestions/src/elements/UserMessage/components/RequestFailed.js new file mode 100644 index 00000000000..42f66b153e0 --- /dev/null +++ b/packages/related-keyphrase-suggestions/src/elements/UserMessage/components/RequestFailed.js @@ -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 ( + + { __( "We've encountered a problem trying to get related keyphrases. Please try again later.", "wordpress-seo" ) } + + ); +}; + +RequestFailed.propTypes = { + className: PropTypes.string, +}; diff --git a/packages/related-keyphrase-suggestions/src/elements/UserMessage/components/RequestLimitReached.js b/packages/related-keyphrase-suggestions/src/elements/UserMessage/components/RequestLimitReached.js new file mode 100644 index 00000000000..d64203e3a4a --- /dev/null +++ b/packages/related-keyphrase-suggestions/src/elements/UserMessage/components/RequestLimitReached.js @@ -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 ( + +
+ { 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 && } +
+
+ ); +}; + +RequestLimitReached.propTypes = { + upsellLink: PropTypes.string, + className: PropTypes.string, +}; diff --git a/packages/related-keyphrase-suggestions/src/elements/UserMessage/components/index.js b/packages/related-keyphrase-suggestions/src/elements/UserMessage/components/index.js new file mode 100644 index 00000000000..2206a1aa9f7 --- /dev/null +++ b/packages/related-keyphrase-suggestions/src/elements/UserMessage/components/index.js @@ -0,0 +1,4 @@ +export { MaxRelatedKeyphrases } from "./MaxRelatedKeyphrases"; +export { RequestFailed } from "./RequestFailed"; +export { RequestEmpty } from "./RequestEmpty"; +export { RequestLimitReached } from "./RequestLimitReached"; diff --git a/packages/related-keyphrase-suggestions/src/elements/UserMessage/docs/component.md b/packages/related-keyphrase-suggestions/src/elements/UserMessage/docs/component.md new file mode 100644 index 00000000000..c4d4735d2ce --- /dev/null +++ b/packages/related-keyphrase-suggestions/src/elements/UserMessage/docs/component.md @@ -0,0 +1 @@ +The alert to display to the user related to the related keyphrases suggestions request or action. \ No newline at end of file diff --git a/packages/related-keyphrase-suggestions/src/elements/UserMessage/docs/index.js b/packages/related-keyphrase-suggestions/src/elements/UserMessage/docs/index.js new file mode 100644 index 00000000000..a01392a1542 --- /dev/null +++ b/packages/related-keyphrase-suggestions/src/elements/UserMessage/docs/index.js @@ -0,0 +1 @@ +export { default as component } from "./component.md"; diff --git a/packages/related-keyphrase-suggestions/src/elements/UserMessage/index.js b/packages/related-keyphrase-suggestions/src/elements/UserMessage/index.js new file mode 100644 index 00000000000..641baaa1ee5 --- /dev/null +++ b/packages/related-keyphrase-suggestions/src/elements/UserMessage/index.js @@ -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 ; + case "requestFailed": + return ; + case "requestEmpty": + return ; + case "maxRelatedKeyphrases": + return ; + default: + return null; + } +}; + +UserMessage.propTypes = { + variant: PropTypes.oneOf( [ "requestLimitReached", "requestFailed", "requestEmpty", "maxRelatedKeyphrases" ] ), + upsellLink: PropTypes.string, + className: PropTypes.string, +}; diff --git a/packages/related-keyphrase-suggestions/src/elements/UserMessage/stories.js b/packages/related-keyphrase-suggestions/src/elements/UserMessage/stories.js new file mode 100644 index 00000000000..20a1c14eaca --- /dev/null +++ b/packages/related-keyphrase-suggestions/src/elements/UserMessage/stories.js @@ -0,0 +1,24 @@ +import React from "react"; +import { UserMessage } from "."; +import { component } from "./docs"; + +export const Factory = { + parameters: { + controls: { disable: false }, + }, + render: ( 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 }, + }, + }, +}; diff --git a/packages/related-keyphrase-suggestions/src/index.js b/packages/related-keyphrase-suggestions/src/index.js index 63111b68ad3..a76fc2fa99e 100644 --- a/packages/related-keyphrase-suggestions/src/index.js +++ b/packages/related-keyphrase-suggestions/src/index.js @@ -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";