From 07cebb703194056447a8d401b53d4539cf6dfdfd Mon Sep 17 00:00:00 2001 From: Christos Date: Mon, 21 Oct 2024 12:48:28 +0300 Subject: [PATCH] Plans (state): Update plan-thank-you-card to utilise data-stores (#95316) * Plans (state): Remove getPlanDiscountedRawPrice, getSitePlanRawPrice, and isSitePlanDiscounted from Calypso state * Plans (state): Update plan-thank-you-card to utilise data-stores --- client/blocks/plan-thank-you-card/index.jsx | 139 -------------------- client/blocks/plan-thank-you-card/index.tsx | 78 +++++++++++ client/components/thank-you-card/index.jsx | 4 +- packages/components/src/index.ts | 1 + 4 files changed, 81 insertions(+), 141 deletions(-) delete mode 100644 client/blocks/plan-thank-you-card/index.jsx create mode 100644 client/blocks/plan-thank-you-card/index.tsx diff --git a/client/blocks/plan-thank-you-card/index.jsx b/client/blocks/plan-thank-you-card/index.jsx deleted file mode 100644 index 4387d9c69a37d..0000000000000 --- a/client/blocks/plan-thank-you-card/index.jsx +++ /dev/null @@ -1,139 +0,0 @@ -import { getPlan, getPlanClass } from '@automattic/calypso-products'; -import { ProductIcon } from '@automattic/components'; -import clsx from 'clsx'; -import { localize } from 'i18n-calypso'; -import PropTypes from 'prop-types'; -import { Component } from 'react'; -import { connect } from 'react-redux'; -import QuerySitePlans from 'calypso/components/data/query-site-plans'; -import QuerySites from 'calypso/components/data/query-sites'; -import ThankYouCard from 'calypso/components/thank-you-card'; -import getRawSite from 'calypso/state/selectors/get-raw-site'; -import { getCurrentPlan } from 'calypso/state/sites/plans/selectors'; - -import './style.scss'; - -class PlanThankYouCard extends Component { - getPlanClass() { - const { plan } = this.props; - if ( ! plan || ! plan.productSlug ) { - return ''; - } - - return getPlanClass( plan.productSlug ); - } - - renderPlanName() { - const { plan, translate } = this.props; - if ( ! plan ) { - return ''; - } - - return translate( '%(planName)s Plan', { - args: { planName: getPlan( plan.productSlug ).getTitle() }, - } ); - } - - renderPlanIcon() { - const { plan } = this.props; - if ( ! plan || ! plan.productSlug ) { - return null; - } - - return ; - } - - renderAction() { - const { action } = this.props; - if ( action ) { - return action; - } - - return null; - } - - renderDescription() { - const { description, translate } = this.props; - if ( description ) { - return description; - } - - return translate( "Now that we've taken care of the plan, it's time to see your new site." ); - } - - renderHeading() { - const { heading, translate } = this.props; - if ( heading ) { - return heading; - } - - return translate( 'Thank you for your purchase!' ); - } - - renderButtonText() { - const { buttonText, translate } = this.props; - if ( buttonText ) { - return buttonText; - } - - return translate( 'Visit Your Site' ); - } - - getButtonUrl() { - const { buttonUrl, siteUrl } = this.props; - if ( buttonUrl ) { - return buttonUrl; - } - - return siteUrl; - } - - render() { - const { siteId } = this.props; - const description = this.renderDescription(); - - return ( -
- - - - -
- ); - } -} - -PlanThankYouCard.propTypes = { - action: PropTypes.node, - buttonText: PropTypes.string, - buttonUrl: PropTypes.string, - /** - * Description can be either a string or object to allow either a bare - * string or a description that contains HTML and other components. - */ - description: PropTypes.oneOfType( [ PropTypes.string, PropTypes.object ] ), - heading: PropTypes.string, - plan: PropTypes.object, - siteId: PropTypes.number.isRequired, - siteUrl: PropTypes.string, - translate: PropTypes.func.isRequired, -}; - -export default connect( ( state, ownProps ) => { - const site = getRawSite( state, ownProps.siteId ); - const plan = getCurrentPlan( state, ownProps.siteId ); - - return { - plan, - siteUrl: site && site.URL, - }; -} )( localize( PlanThankYouCard ) ); diff --git a/client/blocks/plan-thank-you-card/index.tsx b/client/blocks/plan-thank-you-card/index.tsx new file mode 100644 index 0000000000000..dabe8d33183c7 --- /dev/null +++ b/client/blocks/plan-thank-you-card/index.tsx @@ -0,0 +1,78 @@ +import { getPlanClass } from '@automattic/calypso-products'; +import { ProductIcon } from '@automattic/components'; +import { Site, Plans } from '@automattic/data-stores'; +import clsx from 'clsx'; +import { localize, useTranslate } from 'i18n-calypso'; +import ThankYouCard from 'calypso/components/thank-you-card'; +import type { SupportedSlugs } from '@automattic/components'; + +import './style.scss'; + +interface Props { + action?: React.ReactNode; + buttonText?: string; + buttonUrl?: string; + description?: string | React.ReactNode; + heading?: string; + siteId?: number | string | null; +} + +const PlanThankYouCard = ( { + siteId, + action, + buttonText, + buttonUrl, + description, + heading, +}: Props ) => { + const translate = useTranslate(); + const { data: site } = Site.useSite( { siteIdOrSlug: siteId } ); + const { data: plans } = Plans.usePlans( { coupon: undefined } ); + const currentPlan = Plans.useCurrentPlan( { siteId } ); + + /** + * We could skip rendering and simplify the code checking on site, plans, and currentPlan: + * + * if ( ! site || ! plans || ! currentPlan ) { + * return null; + * } + */ + + const classes = clsx( + 'plan-thank-you-card', + currentPlan && getPlanClass( currentPlan.planSlug ) + ); + + const icon = currentPlan ? ( + + ) : null; + + const name = + currentPlan && plans?.[ currentPlan.planSlug ]?.productNameShort + ? translate( '%(planName)s Plan', { + args: { planName: plans[ currentPlan.planSlug ].productNameShort }, + } ) + : ''; + + return ( +
+ +
+ ); +}; + +export default localize( PlanThankYouCard ); diff --git a/client/components/thank-you-card/index.jsx b/client/components/thank-you-card/index.jsx index db1c4b5b74172..61ce8494eaee7 100644 --- a/client/components/thank-you-card/index.jsx +++ b/client/components/thank-you-card/index.jsx @@ -79,10 +79,10 @@ const ThankYouCard = ( { ThankYouCard.propTypes = { buttonText: PropTypes.string, buttonUrl: PropTypes.string, - description: PropTypes.string, + description: PropTypes.string | PropTypes.node, descriptionWithHTML: PropTypes.object, heading: PropTypes.string, - name: PropTypes.string, + name: PropTypes.string | PropTypes.node, icon: PropTypes.node, action: PropTypes.node, }; diff --git a/packages/components/src/index.ts b/packages/components/src/index.ts index 11d99ed7e7cca..b86c8014bab2c 100644 --- a/packages/components/src/index.ts +++ b/packages/components/src/index.ts @@ -13,6 +13,7 @@ export * from './forms'; export { default as Gridicon } from './gridicon'; export { default as Popover } from './popover'; export { default as ProductIcon } from './product-icon'; +export type { SupportedSlugs } from './product-icon/config'; export { default as ProgressBar } from './progress-bar'; export { default as CircularProgressBar } from './circular-progress-bar'; export { default as ResponsiveToolbarGroup } from './responsive-toolbar-group';