Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A4A: Show Vendor link on the Marketplace. #101646

Open
wants to merge 3 commits into
base: trunk
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import useReferralDevSite from '../hooks/use-referral-dev-site';
import useShoppingCart from '../hooks/use-shopping-cart';
import { getClientReferralQueryArgs } from '../lib/get-client-referral-query-args';
import useSubmitForm from '../products-overview-v2/hooks/use-submit-form';
import { getVendorInfo } from '../products-overview-v2/lib/get-vendor-info';
import NoticeSummary from './notice-summary';
import PendingPaymentPopover from './pending-payment-popover';
import PricingSummary from './pricing-summary';
Expand Down Expand Up @@ -281,6 +282,7 @@ function Checkout( { isClient, referralBlogId }: Props ) {
key={ `product-info-${ items.product_id }-${ items.quantity }` }
product={ items }
isAutomatedReferrals={ isAutomatedReferrals }
vendor={ getVendorInfo( items.slug ) }
/>
) )
) }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
import { useTranslate, numberFormatCompact, formatCurrency } from 'i18n-calypso';
import wpcomIcon from 'calypso/assets/images/icons/wordpress-logo.svg';
import pressableIcon from 'calypso/assets/images/pressable/pressable-icon.svg';
import { VendorInfo } from 'calypso/components/jetpack/jetpack-lightbox/types';
import { useLicenseLightboxData } from 'calypso/jetpack-cloud/sections/partner-portal/license-lightbox/hooks/use-license-lightbox-data';
import getProductIcon from 'calypso/my-sites/plans/jetpack-plans/product-store/utils/get-product-icon';
import { useDispatch } from 'calypso/state';
import { recordTracksEvent } from 'calypso/state/analytics/actions';
import getPressablePlan from '../pressable-overview/lib/get-pressable-plan';
import type { ShoppingCartItem } from '../types';

export default function ProductInfo( {
product,
isAutomatedReferrals,
vendor,
}: {
product: ShoppingCartItem;
isAutomatedReferrals?: boolean;
vendor?: VendorInfo | null;
} ) {
const translate = useTranslate();
const dispatch = useDispatch();

const { title, product: productInfo } = useLicenseLightboxData( product );

Expand Down Expand Up @@ -115,7 +121,28 @@ export default function ProductInfo( {
<div className="product-info__text-content">
<div className="product-info__header">
<label htmlFor={ productTitle } className="product-info__label">
{ productTitle }
<h3>{ productTitle }</h3>
{ vendor &&
translate( 'By {{a/}}', {
components: {
a: (
<a
href={ vendor.vendorUrl }
target="_blank"
rel="noopener noreferrer"
onClick={ () => {
dispatch(
recordTracksEvent( 'calypso_marketplace_products_overview_vendor_click', {
vendor: vendor.vendorName,
} )
);
} }
>
{ vendor.vendorName }
</a>
),
},
} ) }
Comment on lines +125 to +145
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can create a common component and reuse it wherever required, as it is being used in 2 places

<ProductVendorInfo /> or something similar

</label>
<span className="product-info__count">{ countInfo }</span>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,11 @@

.product-info__label {
@include heading-medium;

a {
text-decoration: underline;
color: var(--color-text);
}
}

.product-info__count {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { LICENSE_INFO_MODAL_ID } from 'calypso/jetpack-cloud/sections/partner-po
import LicenseLightbox from 'calypso/jetpack-cloud/sections/partner-portal/license-lightbox';
import { useDispatch } from 'calypso/state';
import { recordTracksEvent } from 'calypso/state/analytics/actions';
import { getVendorInfo } from '../lib/get-vendor-info';
import WooPaymentsCustomDescription from '../product-card/woopayments-custom-description';
import WooPaymentsCustomFooter from '../product-card/woopayments-custom-footer';
import WooPaymentsRevenueShareNotice from '../product-card/woopayments-revenue-share-notice';
Expand Down Expand Up @@ -119,6 +120,8 @@ function withProductLightbox< T >(
return undefined;
}, [ currentProduct.slug ] );

const vendor = getVendorInfo( currentProduct.slug );

return (
<>
<WrappedComponent
Expand All @@ -129,6 +132,7 @@ function withProductLightbox< T >(
/>
{ showLightbox && (
<LicenseLightbox
vendor={ vendor }
product={ currentProduct }
quantity={ quantity }
ctaLabel={ customCTALabel ?? ( ctaLightboxLabel as string ) }
Expand Down
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about we keep this info in useProductDescription as we are already using it show the description?

Something like:

const VENDOR_INFO_MAP: Record< string, VendorInfo > = {
	kestrel: {
		vendorName: 'Kestrel',
		vendorUrl: 'https://woocommerce.com/vendor/kestrel/',
	},
	'element-stark': {
		vendorName: 'Element Stark',
		vendorUrl: 'https://woocommerce.com/vendor/element-stark/',
	},
	storeapps: {
		vendorName: 'StoreApps',
		vendorUrl: 'https://woocommerce.com/vendor/storeapps/',
	},
	woocommerce: {
		vendorName: 'Woo',
		vendorUrl: 'https://woocommerce.com/',
	},
	jetpack: {
		vendorName: 'Jetpack',
		vendorUrl: 'https://jetpack.com/',
	},
	pressable: {
		vendorName: 'Pressable',
		vendorUrl: 'https://pressable.com/',
	},
	wpcom: {
		vendorName: 'WordPress.com',
		vendorUrl: 'https://wordpress.com/',
	},
};
case 'woocommerce-constellation':
  description = translate(
	  'A flexible, WooCommerce memberships platform to support publishers, purchasing clubs, online learning, associations, and more.'
  );
  vendor = VENDOR_INFO_MAP.kestrel;
break;

Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { VendorInfo } from 'calypso/components/jetpack/jetpack-lightbox/types';

const VENDOR_INFO_MAP: Record< string, VendorInfo > = {
kestrel: {
vendorName: 'Kestrel',
vendorUrl: 'https://woocommerce.com/vendor/kestrel/',
},
'element-stark': {
vendorName: 'Element Stark',
vendorUrl: 'https://woocommerce.com/vendor/element-stark/',
},
storeapps: {
vendorName: 'StoreApps',
vendorUrl: 'https://woocommerce.com/vendor/storeapps/',
},
woocommerce: {
vendorName: 'Woo',
vendorUrl: 'https://woocommerce.com/',
},
jetpack: {
vendorName: 'Jetpack',
vendorUrl: 'https://jetpack.com/',
},
pressable: {
vendorName: 'Pressable',
vendorUrl: 'https://pressable.com/',
},
wpcom: {
vendorName: 'WordPress.com',
vendorUrl: 'https://wordpress.com/',
},
};

const THIRD_PARTY_PRODUCT_MAP: Record< string, string > = {
'woocommerce-constellation': 'kestrel',
'woocommerce-dynamic-pricing': 'element-stark',
'woocommerce-rental-products': 'kestrel',
'woocommerce-smart-coupons': 'storeapps',
'woocommerce-variation-swatches-and-photos': 'element-stark',
};

export const getVendorInfo = ( productSlug: string ) => {
const thirdPartyVendor = THIRD_PARTY_PRODUCT_MAP[ productSlug ];

if ( thirdPartyVendor ) {
return VENDOR_INFO_MAP[ thirdPartyVendor ];
}

if ( productSlug.startsWith( 'woocommerce-' ) ) {
return VENDOR_INFO_MAP[ 'woocommerce' ];
}

if ( productSlug.startsWith( 'jetpack-' ) ) {
return VENDOR_INFO_MAP[ 'jetpack' ];
}

if ( productSlug.startsWith( 'wpcom-' ) ) {
return VENDOR_INFO_MAP[ 'wpcom' ];
}

if ( productSlug.startsWith( 'pressable-' ) ) {
return VENDOR_INFO_MAP[ 'pressable' ];
}

return null;
};
4 changes: 4 additions & 0 deletions client/components/jetpack/jetpack-lightbox/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export type VendorInfo = {
vendorName: string;
vendorUrl: string;
};
32 changes: 30 additions & 2 deletions client/components/jetpack/jetpack-product-info/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@ import isWooCommerceProduct from 'calypso/jetpack-cloud/sections/partner-portal/
import { PricingBreakdown } from 'calypso/my-sites/plans/jetpack-plans/product-store/pricing-breakdown';
import getProductIcon from 'calypso/my-sites/plans/jetpack-plans/product-store/utils/get-product-icon';
import { SelectorProduct } from 'calypso/my-sites/plans/jetpack-plans/types';
import { useDispatch } from 'calypso/state';
import { recordTracksEvent } from 'calypso/state/analytics/actions';
import JetpackProductInfoComingSoonList from './coming-soon-list';
import JetpackProductInfoFAQList from './faq-list';
import JetpackProductInfoProductList from './product-list';
import JetpackProductInfoRecommendationTags from './recommendation-tags';
import JetpackProductInfoRegularList from './regular-list';
import JetpackProductInfoSection from './section';
import type { VendorInfo } from '../jetpack-lightbox/types';

import './style.scss';

Expand All @@ -22,6 +25,7 @@ type JetpackProductInfoProps = {
siteId?: number;
title: TranslateResult;
customDescription?: ReactNode;
vendor?: VendorInfo | null;
};

const JetpackProductInfo: FunctionComponent< JetpackProductInfoProps > = ( {
Expand All @@ -31,6 +35,7 @@ const JetpackProductInfo: FunctionComponent< JetpackProductInfoProps > = ( {
siteId = null,
title,
customDescription,
vendor,
} ) => {
const {
alsoIncluded,
Expand All @@ -45,7 +50,7 @@ const JetpackProductInfo: FunctionComponent< JetpackProductInfoProps > = ( {
whatIsIncluded,
whatIsIncludedComingSoon,
} = product;

const dispatch = useDispatch();
const translate = useTranslate();
const icon = getProductIcon( { productSlug } );
const isWooCommerce = isWooCommerceProduct( productSlug );
Expand All @@ -63,7 +68,30 @@ const JetpackProductInfo: FunctionComponent< JetpackProductInfoProps > = ( {
<div className={ iconStyles }>
<img alt="" src={ icon } />
</div>
<h2>{ title }</h2>
<div className="jetpack-product-info__header-title">
<h2>{ title }</h2>
{ vendor &&
translate( 'By {{a/}}', {
components: {
a: (
<a
href={ vendor.vendorUrl }
target="_blank"
rel="noopener noreferrer"
onClick={ () => {
dispatch(
recordTracksEvent( 'calypso_marketplace_products_overview_vendor_click', {
vendor: vendor.vendorName,
} )
);
} }
>
{ vendor.vendorName }
</a>
),
},
} ) }
</div>
</div>
<div className="jetpack-product-info__description">{ lightboxDescription }</div>

Expand Down
5 changes: 5 additions & 0 deletions client/components/jetpack/jetpack-product-info/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@
font-weight: 700;
color: var(--studio-gray-100);
}

a {
text-decoration: underline;
color: var(--color-text);
}
}

.jetpack-product-info__product-icon {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import JetpackLightbox, {
JetpackLightboxMain,
} from 'calypso/components/jetpack/jetpack-lightbox';
import useMobileSidebar from 'calypso/components/jetpack/jetpack-lightbox/hooks/use-mobile-sidebar';
import { VendorInfo } from 'calypso/components/jetpack/jetpack-lightbox/types';
import JetpackProductInfo from 'calypso/components/jetpack/jetpack-product-info';
import { APIProductFamilyProduct } from 'calypso/state/partner-portal/types';
import { useLicenseLightboxData } from './hooks/use-license-lightbox-data';
Expand All @@ -32,6 +33,7 @@ export type LicenseLightBoxProps = {
fireCloseOnCTAClick?: boolean;
customDescription?: ReactNode;
customFooter?: ReactNode;
vendor?: VendorInfo | null;
};

const LicenseLightbox: FunctionComponent< LicenseLightBoxProps > = ( {
Expand All @@ -51,6 +53,7 @@ const LicenseLightbox: FunctionComponent< LicenseLightBoxProps > = ( {
fireCloseOnCTAClick = true,
customDescription,
customFooter,
vendor,
} ) => {
const isLargeScreen = useBreakpoint( '>782px' );
const { title, product: productInfo } = useLicenseLightboxData( product );
Expand All @@ -74,6 +77,7 @@ const LicenseLightbox: FunctionComponent< LicenseLightBoxProps > = ( {
<JetpackLightboxMain ref={ mainRef }>
{ productInfo && (
<JetpackProductInfo
vendor={ vendor }
title={ title }
product={ productInfo }
full={ isLargeScreen }
Expand Down
Loading