@automattic/wpcom-checkout
Version:
Functions and components used by WordPress.com checkout.
805 lines (798 loc) • 49.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CouponLineItem = exports.LineItem = exports.NonProductLineItem = void 0;
exports.LineItemPrice = LineItemPrice;
exports.LineItemSublabelAndPrice = LineItemSublabelAndPrice;
exports.LineItemBillingInterval = LineItemBillingInterval;
const tslib_1 = require("tslib");
const jsx_runtime_1 = require("react/jsx-runtime");
const calypso_products_1 = require("@automattic/calypso-products");
const components_1 = require("@automattic/components");
const composite_checkout_1 = require("@automattic/composite-checkout");
const number_formatters_1 = require("@automattic/number-formatters");
const styled_1 = tslib_1.__importDefault(require("@emotion/styled"));
const i18n_calypso_1 = require("i18n-calypso");
const react_1 = require("react");
const checkout_labels_1 = require("./checkout-labels");
const introductory_offer_1 = require("./introductory-offer");
const is_wpcom_product_renewal_1 = require("./is-wpcom-product-renewal");
const join_classes_1 = require("./join-classes");
const loading_card_1 = require("./loading-card");
const partner_coupon_1 = require("./partner-coupon");
const partner_logo_ionos_1 = tslib_1.__importDefault(require("./partner-logo-ionos"));
exports.NonProductLineItem = (0, styled_1.default)(WPNonProductLineItem) `
display: flex;
flex-wrap: wrap;
justify-content: space-between;
font-weight: ${({ theme, total }) => (total ? theme.weights.bold : theme.weights.normal)};
color: ${({ theme, total }) => total ? theme.colors.textColorDark : theme.colors.textColorLight};
font-size: ${({ total }) => (total ? '1.2em' : '1.1em')};
line-height: 1em;
padding: ${({ total, tax, subtotal, coupon }) => total || subtotal || tax || coupon ? '0' : '20px 0'};
position: relative;
margin-bottom: 8px;
&:last-child {
margin-bottom: 0;
}
.checkout-line-item__price {
position: relative;
}
`;
exports.LineItem = (0, styled_1.default)(CheckoutLineItem) `
display: flex;
flex-wrap: wrap;
justify-content: space-between;
padding: 16px 0;
font-weight: ${({ theme }) => theme.weights.normal};
color: ${({ theme }) => theme.colors.textColorDark};
font-size: ${({ shouldShowComparison }) => (shouldShowComparison ? '20px' : '1.1em')};
position: relative;
.checkout-line-item__price {
position: relative;
${({ shouldShowComparison }) => shouldShowComparison &&
`
display: flex;
`}
}
`;
exports.CouponLineItem = (0, styled_1.default)(WPCouponLineItem) `
.jetpack-partner-logo {
padding-bottom: 20px;
}
`;
const GiftBadge = styled_1.default.span `
color: #234929;
background-color: #b8e6bf;
margin-bottom: 0.1em;
padding: 0.1em 0.8em;
border-radius: 5px;
display: inline-block;
font-size: small;
`;
const LineItemMeta = styled_1.default.div `
color: ${(props) => props.theme.colors.textColorLight};
font-size: 14px;
overflow-wrap: anywhere;
width: 100%;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
flex-direction: row;
align-content: center;
gap: 2px 10px;
`;
const UpgradeCreditInformationLineItem = (0, styled_1.default)(LineItemMeta) `
justify-content: flex-start;
gap: 4px;
.gridicon {
fill: ${(props) => props.theme.colors.textColorLight};
}
`;
const UpgradeCreditPopover = (0, styled_1.default)(components_1.Popover) `
&.popover .popover__inner {
color: ${(props) => props.theme.colors.textColorOnDarkBackground};
background: ${(props) => props.theme.colors.textColorDark};
text-align: start;
border-radius: 4px;
min-height: 32px;
width: 300px;
align-items: center;
font-style: normal;
padding: 8px 10px;
overflow-wrap: break-word;
}
`;
const DiscountCallout = styled_1.default.div `
color: ${(props) => props.theme.colors.discount};
display: block;
`;
const NotApplicableCallout = styled_1.default.div `
color: ${(props) => props.theme.colors.textColorLight};
display: block;
`;
const LineItemTitle = styled_1.default.div `
word-break: break-word;
font-weight: ${({ theme }) => theme.weights.bold};
flex: 1;
display: flex;
gap: 0.5em;
font-size: inherit;
`;
const LineItemSublabelTitle = styled_1.default.div `
flex: 1;
`;
const LineItemPriceWrapper = styled_1.default.span `
display: flex;
flex: 0 0 auto;
gap: 4px;
margin-left: 12px;
font-size: inherit;
.rtl & {
margin-right: 12px;
margin-left: 0;
}
`;
const DeleteButtonWrapper = styled_1.default.div `
width: 100%;
display: inherit;
justify-content: inherit;
`;
const DeleteButton = (0, styled_1.default)(composite_checkout_1.Button) `
width: auto;
font-size: 0.75rem;
color: ${(props) => props.theme.colors.textColorLight};
`;
function LineItemPrice({ actualAmount, crossedOutAmount, }) {
return ((0, jsx_runtime_1.jsxs)(LineItemPriceWrapper, { children: [crossedOutAmount && (0, jsx_runtime_1.jsx)("s", { children: crossedOutAmount }), (0, jsx_runtime_1.jsx)("span", { children: actualAmount })] }));
}
function WPNonProductLineItem({ lineItem, className = null, isSummary, hasDeleteButton, removeProductFromCart, createUserAndSiteBeforeTransaction, isPwpoUser, }) {
const label = lineItem.label;
const actualAmountDisplay = lineItem.formattedAmount;
const { formStatus } = (0, composite_checkout_1.useFormStatus)();
const isDisabled = formStatus !== composite_checkout_1.FormStatus.READY;
const [isModalVisible, setIsModalVisible] = (0, react_1.useState)(false);
const translate = (0, i18n_calypso_1.useTranslate)();
const modalCopy = returnModalCopy(lineItem.type, translate, createUserAndSiteBeforeTransaction || false, isPwpoUser || false);
/* eslint-disable wpcalypso/jsx-classname-namespace */
return ((0, jsx_runtime_1.jsxs)("div", { className: (0, join_classes_1.joinClasses)([className, 'checkout-line-item']), "data-e2e-product-slug": lineItem.id, "data-product-type": lineItem.type, children: [(0, jsx_runtime_1.jsx)(LineItemTitle, { isSummary: isSummary, children: label }), (0, jsx_runtime_1.jsx)("span", { className: "checkout-line-item__price", children: (0, jsx_runtime_1.jsx)(LineItemPrice, { actualAmount: actualAmountDisplay }) }), hasDeleteButton && removeProductFromCart && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(DeleteButtonWrapper, { children: (0, jsx_runtime_1.jsx)(DeleteButton, { className: "checkout-line-item__remove-product", buttonType: "text-button", "aria-label": String(translate('Remove %s from cart', {
args: label,
})), disabled: isDisabled, onClick: () => {
setIsModalVisible(true);
}, children: translate('Remove from cart') }) }), (0, jsx_runtime_1.jsx)(composite_checkout_1.CheckoutModal, { isVisible: isModalVisible, closeModal: () => {
setIsModalVisible(false);
}, secondaryAction: () => {
setIsModalVisible(false);
}, primaryAction: () => {
removeProductFromCart();
}, secondaryButtonCTA: String('Cancel'), title: modalCopy.title, copy: modalCopy.description })] }))] }));
/* eslint-enable wpcalypso/jsx-classname-namespace */
}
function WPCouponLineItem({ lineItem, className, isSummary, hasDeleteButton, removeProductFromCart, createUserAndSiteBeforeTransaction, isPwpoUser, hasPartnerCoupon, }) {
return ((0, jsx_runtime_1.jsxs)("div", { className: (0, join_classes_1.joinClasses)([className, 'coupon-line-item']), "data-partner-coupon": !!hasPartnerCoupon, children: [(0, jsx_runtime_1.jsx)(exports.NonProductLineItem, { lineItem: lineItem, isSummary: isSummary, hasDeleteButton: hasDeleteButton, removeProductFromCart: removeProductFromCart, createUserAndSiteBeforeTransaction: createUserAndSiteBeforeTransaction, isPwpoUser: isPwpoUser }), !!hasPartnerCoupon && (0, jsx_runtime_1.jsx)(PartnerLogo, {})] }));
}
function EmailMeta({ product, isRenewal }) {
const translate = (0, i18n_calypso_1.useTranslate)();
if (isRenewal) {
let numberOfMailboxes = null;
if ((0, calypso_products_1.isGSuiteOrExtraLicenseProductSlug)(product.product_slug)) {
numberOfMailboxes = product.volume ?? null;
}
if ((0, calypso_products_1.isGoogleWorkspaceProductSlug)(product.product_slug) || (0, calypso_products_1.isTitanMail)(product)) {
numberOfMailboxes = product.current_quantity ?? null;
}
if (numberOfMailboxes === null) {
return null;
}
return ((0, jsx_runtime_1.jsx)(LineItemMeta, { children: translate('%(numberOfMailboxes)d mailbox for %(domainName)s', '%(numberOfMailboxes)d mailboxes for %(domainName)s', {
args: {
numberOfMailboxes,
domainName: product.meta,
},
count: numberOfMailboxes,
}) }));
}
let mailboxes = [];
if ((0, calypso_products_1.isGoogleWorkspaceProductSlug)(product.product_slug) ||
(0, calypso_products_1.isGSuiteOrExtraLicenseProductSlug)(product.product_slug)) {
mailboxes = product.extra?.google_apps_users ?? [];
}
if ((0, calypso_products_1.isTitanMail)(product)) {
mailboxes = product.extra?.email_users ?? [];
}
return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: mailboxes.map((mailbox, index) => {
return ((0, jsx_runtime_1.jsxs)(LineItemMeta, { children: [(0, jsx_runtime_1.jsx)("div", { children: mailbox.email }, mailbox.email), index === 0 && (0, jsx_runtime_1.jsx)(GSuiteDiscountCallout, { product: product })] }, mailbox.email));
}) }));
}
function returnModalCopyForProduct(product, translate, hasBundledDomainInCart, hasMarketplaceProductsInCart, createUserAndSiteBeforeTransaction, isPwpoUser) {
const productType = getProductTypeForModalCopy(product, hasBundledDomainInCart, hasMarketplaceProductsInCart, isPwpoUser);
const isRenewal = (0, is_wpcom_product_renewal_1.isWpComProductRenewal)(product);
return returnModalCopy(productType, translate, createUserAndSiteBeforeTransaction, isRenewal, product);
}
function getProductTypeForModalCopy(product, hasBundledDomainInCart, hasMarketplaceProductsInCart, isPwpoUser) {
if (product.is_gift_purchase) {
return 'gift purchase';
}
if ((0, calypso_products_1.isWpComPlan)(product.product_slug)) {
if (hasMarketplaceProductsInCart) {
return 'plan with marketplace dependencies';
}
if (hasBundledDomainInCart && !isPwpoUser) {
return 'plan with domain dependencies';
}
return 'plan';
}
if ((0, calypso_products_1.isDomainRegistration)(product)) {
return 'domain';
}
return product.product_slug;
}
function returnModalCopy(productType, translate, createUserAndSiteBeforeTransaction, isRenewal = false, product) {
const domainNameString = product ? product.meta : translate('your selected domain');
switch (productType) {
case 'gift purchase':
return {
title: String(translate('You are about to remove your gift from the cart')),
description: String(translate('When you press Continue, all gift products in the cart will be removed, and your gift will not be given.')),
};
case 'plan with marketplace dependencies':
if (isRenewal) {
return {
title: String(translate('You are about to remove your plan renewal from the cart')),
description: String(translate("Some of your other product(s) depend on your plan to be renewed. When you press Continue, the plan renewal will be removed from the cart and your plan will keep its current expiry date. When the plan expires these product(s) will stop working even if they haven't expired yet.")),
};
}
return {
title: String(translate('You are about to remove your plan from the cart')),
description: String(translate('Since some of your other product(s) depend on your plan to be purchased, they will also be removed from the cart. When you press Continue, these product(s) along with your new plan will be removed from the cart, and your site will continue to run on its current plan.')),
};
case 'plan with domain dependencies': {
if (isRenewal) {
return {
title: String(translate('You are about to remove your plan renewal from the cart')),
description: String(translate('When you press Continue, your plan renewal will be removed from the cart and your plan will keep its current expiry date.')),
};
}
const title = String(translate('You are about to remove your plan from the cart'));
let description = '';
if (createUserAndSiteBeforeTransaction) {
description = String(translate('When you press Continue, your plan will be removed from the cart. Your site will be created with the free plan when you complete payment for the other product(s) in your cart.'));
}
else {
description = String(translate('Since some of your other product(s) depend on your plan to be purchased, they will also be removed from the cart. When you press Continue, these product(s) will be removed along with your new plan in the cart, and your site will continue to run with its current plan.'));
}
return { title, description };
}
case 'plan':
if (isRenewal) {
return {
title: String(translate('You are about to remove your plan renewal from the cart')),
description: String(translate('When you press Continue, your plan renewal will be removed from the cart and your plan will keep its current expiry date.')),
};
}
return {
title: String(translate('You are about to remove your plan from the cart')),
description: String(createUserAndSiteBeforeTransaction
? translate('When you press Continue, your plan will be removed from the cart.')
: translate('When you press Continue, your plan will be removed from the cart and your site will continue to run with its current plan.')),
};
case 'domain':
if (isRenewal) {
return {
title: String(translate('You are about to remove your domain renewal from the cart')),
description: String(translate('When you press Continue, your domain renewal will be removed from the cart and your domain will keep its current expiry date.')),
};
}
return {
title: String(translate('You are about to remove %(domainName)s from the cart', {
args: { domainName: domainNameString },
})),
description: String(translate('When you press Continue, %(domainName)s will be removed from the cart and will become available for anyone to register.', {
args: { domainName: domainNameString },
})),
};
case 'coupon':
return {
title: String(translate('You are about to remove your coupon from the cart')),
description: String(translate('When you press Continue, you will need to confirm your payment details.')),
};
default:
if (isRenewal) {
return {
title: String(translate('You are about to remove your renewal from the cart')),
description: String(translate('When you press Continue, your renewal will be removed from the cart and your product will keep its current expiry date.')),
};
}
return {
title: String(translate('You are about to remove your product from the cart')),
description: String(createUserAndSiteBeforeTransaction
? translate('When you press Continue, your product will be removed from the cart.')
: translate('When you press Continue, your product will be removed from the cart and your site will continue to run without it.')),
};
}
}
function getHasRemoveFromCartModal({ product, hasBundledDomainsInCart, hasMarketplaceProductsInCart, isPwpoUser = false, }) {
const productType = getProductTypeForModalCopy(product, hasBundledDomainsInCart, hasMarketplaceProductsInCart, isPwpoUser);
const isRenewal = (0, is_wpcom_product_renewal_1.isWpComProductRenewal)(product);
switch (productType) {
case 'gift purchase':
return true;
case 'plan with marketplace dependencies':
return true;
case 'plan with domain dependencies': {
if (isRenewal) {
return false;
}
return true;
}
case 'plan':
return false;
case 'domain':
return false;
case 'coupon':
return true;
default:
return false;
}
}
function JetpackSearchMeta({ product }) {
return (0, jsx_runtime_1.jsx)(ProductTier, { product: product });
}
function ProductTier({ product }) {
const translate = (0, i18n_calypso_1.useTranslate)();
if ((0, calypso_products_1.isJetpackSearch)(product) && product.price_tier_transform_quantity_divide_by) {
const currentQuantity = product.current_quantity || 1;
let units_used;
if (product.price_tier_transform_quantity_round === 'down') {
units_used = Math.floor(currentQuantity / product.price_tier_transform_quantity_divide_by);
}
else {
units_used = Math.ceil(currentQuantity / product.price_tier_transform_quantity_divide_by);
}
const purchaseQuantityDividedByThousand = (units_used * product.price_tier_transform_quantity_divide_by) / 1000;
return ((0, jsx_runtime_1.jsx)(LineItemMeta, { children: translate('Up to %(purchaseQuantityDividedByThousand)sk records and/or requests per month', { args: { purchaseQuantityDividedByThousand } }) }));
}
return null;
}
function LineItemSublabelAndPrice({ product, shouldShowComparison, compareToPrice, }) {
const translate = (0, i18n_calypso_1.useTranslate)();
const productSlug = product.product_slug;
const price = (0, number_formatters_1.formatCurrency)(product.item_original_subtotal_integer, product.currency, {
isSmallestUnit: true,
stripZeros: true,
});
if ((0, calypso_products_1.isP2Plus)(product)) {
// This is the price for one item for products with a quantity (eg. seats in a license).
const itemPrice = (0, number_formatters_1.formatCurrency)(product.item_original_cost_for_quantity_one_integer, product.currency, { isSmallestUnit: true, stripZeros: true });
const members = product?.current_quantity || 1;
const p2Options = {
args: {
itemPrice,
members,
},
count: members,
};
return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: translate('Monthly subscription: %(itemPrice)s x %(members)s member', 'Monthly subscription: %(itemPrice)s x %(members)s members', p2Options) }));
}
if ((0, calypso_products_1.isTieredVolumeSpaceAddon)(product)) {
const productQuantity = product?.quantity ?? 1;
const currentQuantity = product?.current_quantity ?? 1;
const spaceQuantity = productQuantity > 1 ? productQuantity - currentQuantity : currentQuantity;
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [translate('%(quantity)s GB extra space, %(price)s per year', {
args: { quantity: spaceQuantity, price },
}), (0, jsx_runtime_1.jsx)("br", {}), translate('Total extra space after purchase: %(totalSpace)s GB', {
args: { totalSpace: product.is_renewal ? currentQuantity : productQuantity },
})] }));
}
if ((0, calypso_products_1.isGoogleWorkspaceProductSlug)(productSlug) ||
(0, calypso_products_1.isGSuiteOrExtraLicenseProductSlug)(productSlug) ||
(0, calypso_products_1.isTitanMail)(product)) {
if (product.months_per_bill_period === 12 || product.months_per_bill_period === null) {
const billingInterval = GetBillingIntervalLabel({ product });
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(checkout_labels_1.DefaultLineItemSublabel, { product: product }), ": ", billingInterval, (0, jsx_runtime_1.jsx)(LineItemExpiryDates, { product: product })] }));
}
if (product.months_per_bill_period === 1) {
const billingInterval = translate('billed monthly');
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(checkout_labels_1.DefaultLineItemSublabel, { product: product }), ": ", billingInterval, (0, jsx_runtime_1.jsx)(LineItemExpiryDates, { product: product })] }));
}
return (0, jsx_runtime_1.jsx)(checkout_labels_1.DefaultLineItemSublabel, { product: product });
}
if ((0, calypso_products_1.isDIFMProduct)(product)) {
const numberOfExtraPages = product.quantity && product.price_tier_maximum_units
? product.quantity - product.price_tier_maximum_units
: 0;
if (numberOfExtraPages > 0) {
const costOfExtraPages = (0, number_formatters_1.formatCurrency)(product.item_original_cost_integer - product.item_original_cost_for_quantity_one_integer, product.currency, {
stripZeros: true,
isSmallestUnit: true,
});
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [translate('Service: %(productCost)s one-time fee', {
args: {
productCost: (0, number_formatters_1.formatCurrency)(product.item_original_cost_for_quantity_one_integer, product.currency, { isSmallestUnit: true, stripZeros: true }),
},
}), (0, jsx_runtime_1.jsx)("br", {}), translate('%(numberOfExtraPages)d Extra Page: %(costOfExtraPages)s one-time fee', '%(numberOfExtraPages)d Extra Pages: %(costOfExtraPages)s one-time fee', {
args: {
numberOfExtraPages,
costOfExtraPages,
},
count: numberOfExtraPages,
})] }));
}
}
const isDomainRegistration = product.is_domain_registration;
const isDomainMapping = productSlug === 'domain_map';
const isDomainTransfer = productSlug === 'domain_transfer';
if (((isDomainRegistration || isDomainMapping) && product.months_per_bill_period === 12) ||
(isDomainTransfer && product.volume === 100)) {
const premiumLabel = product.extra?.premium ? translate('Premium') : '';
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [premiumLabel, " ", (0, jsx_runtime_1.jsx)(checkout_labels_1.DefaultLineItemSublabel, { product: product }), !product.is_included_for_100yearplan && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [": ", GetBillingIntervalLabel({ product })] })), (0, jsx_runtime_1.jsx)(LineItemExpiryDates, { product: product })] }));
}
if (isDomainTransfer) {
const premiumLabel = product.extra?.premium ? translate('Premium') : '';
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [premiumLabel, " ", (0, jsx_runtime_1.jsx)(checkout_labels_1.DefaultLineItemSublabel, { product: product }), ":", ' ', translate('billed annually'), " ", price] }));
}
if (shouldShowComparison && compareToPrice) {
const monthlyPrice = (0, number_formatters_1.formatCurrency)(compareToPrice, product.currency, {
isSmallestUnit: true,
stripZeros: true,
});
const showCrossedOutPrice = product.item_original_subtotal_integer / (product.months_per_bill_period ?? 1) !==
compareToPrice;
if ((0, calypso_products_1.isMonthlyProduct)(product)) {
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(LineItemSublabelTitle, { children: translate('Billed every month') }), showCrossedOutPrice && ((0, jsx_runtime_1.jsxs)("s", { children: [monthlyPrice, " ", translate('/month')] }))] }));
}
if ((0, calypso_products_1.isYearly)(product)) {
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(LineItemSublabelTitle, { children: translate('Billed every year') }), showCrossedOutPrice && ((0, jsx_runtime_1.jsxs)("s", { children: [monthlyPrice, " ", translate('/month')] }))] }));
}
if ((0, calypso_products_1.isBiennially)(product)) {
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(LineItemSublabelTitle, { children: translate('Billed every 2 years') }), showCrossedOutPrice && ((0, jsx_runtime_1.jsxs)("s", { children: [monthlyPrice, " ", translate('/month')] }))] }));
}
if ((0, calypso_products_1.isTriennially)(product)) {
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(LineItemSublabelTitle, { children: translate('Billed every 3 years') }), showCrossedOutPrice && ((0, jsx_runtime_1.jsxs)("s", { children: [monthlyPrice, " ", translate('/month')] }))] }));
}
}
const shouldRenderBasicTermSublabel = (0, calypso_products_1.isPlan)(product) || (0, calypso_products_1.isAddOn)(product) || (0, calypso_products_1.isJetpackProductSlug)(productSlug);
if (shouldRenderBasicTermSublabel && (0, calypso_products_1.isMonthlyProduct)(product)) {
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(checkout_labels_1.DefaultLineItemSublabel, { product: product }), ":", ' ', translate('%(price)s per month', { args: { price } }), (0, jsx_runtime_1.jsx)(LineItemExpiryDates, { product: product })] }));
}
if (shouldRenderBasicTermSublabel && (0, calypso_products_1.isYearly)(product)) {
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(checkout_labels_1.DefaultLineItemSublabel, { product: product }), ":", ' ', translate('%(price)s per year', { args: { price } }), (0, jsx_runtime_1.jsx)(LineItemExpiryDates, { product: product })] }));
}
if (shouldRenderBasicTermSublabel && (0, calypso_products_1.isBiennially)(product)) {
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(checkout_labels_1.DefaultLineItemSublabel, { product: product }), ":", ' ', translate('%(price)s per two years', { args: { price } }), (0, jsx_runtime_1.jsx)(LineItemExpiryDates, { product: product })] }));
}
if (shouldRenderBasicTermSublabel && (0, calypso_products_1.isTriennially)(product)) {
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(checkout_labels_1.DefaultLineItemSublabel, { product: product }), ":", ' ', translate('%(price)s per three years', { args: { price } }), (0, jsx_runtime_1.jsx)(LineItemExpiryDates, { product: product })] }));
}
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(checkout_labels_1.DefaultLineItemSublabel, { product: product }), (0, jsx_runtime_1.jsx)(LineItemExpiryDates, { product: product })] }));
}
function getApproximateDifferenceInMonths(dateFrom, dateTo) {
return Math.abs(dateTo.getMonth() - dateFrom.getMonth() + 12 * (dateTo.getFullYear() - dateFrom.getFullYear()));
}
function LineItemExpiryDates({ product }) {
const translate = (0, i18n_calypso_1.useTranslate)();
// We only currently show the expiry date for renewals when the current
// subscription is more than 9 months away from expiration (to help
// prevent accidental renewals), although it should be accurate for
// other cart items as well.
if (!product.is_renewal) {
return null;
}
if (!product.subscription_current_expiry_date) {
return null;
}
const expiryTimestamp = new Date(product.subscription_current_expiry_date);
const minNumberOfMonths = 10;
if (getApproximateDifferenceInMonths(expiryTimestamp, new Date()) < minNumberOfMonths) {
return null;
}
const expiryDate = product.subscription_current_expiry_date
? formatDate(product.subscription_current_expiry_date)
: undefined;
const postRenewExpiry = product.subscription_post_purchase_expiry_date
? formatDate(product.subscription_post_purchase_expiry_date)
: undefined;
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [expiryDate && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("br", {}), translate('Currently expires on %(expiryDate)s', { args: { expiryDate } }), ' '] })), postRenewExpiry && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("br", {}), translate('After purchase, will expire on %(postRenewExpiry)s', {
args: { postRenewExpiry },
})] }))] }));
}
function formatDate(isoDate) {
// This somewhat mimics `moment.format('ll')` (used here formerly) without
// needing the deprecated `moment` package.
return new Date(Date.parse(isoDate)).toLocaleDateString('en-US', {
weekday: undefined,
month: 'short',
day: 'numeric',
year: 'numeric',
});
}
function GetBillingIntervalLabel({ product }) {
const translate = (0, i18n_calypso_1.useTranslate)();
if (product.volume > 1) {
return translate('billed %(total_years)s years, then annually', {
args: { total_years: product.volume },
});
}
return translate('billed annually');
}
function LineItemBillingInterval({ product }) {
const translate = (0, i18n_calypso_1.useTranslate)();
if ((0, calypso_products_1.isDIFMProduct)(product)) {
return (0, jsx_runtime_1.jsx)("span", { children: translate('One-time fee') });
}
if (product.is_included_for_100yearplan) {
return null;
}
if ((0, calypso_products_1.isMonthlyProduct)(product)) {
return (0, jsx_runtime_1.jsx)("span", { children: translate('Renews every month') });
}
if ((0, calypso_products_1.isYearly)(product)) {
return (0, jsx_runtime_1.jsx)("span", { children: translate('Renews every year') });
}
if ((0, calypso_products_1.isBiennially)(product)) {
return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: translate('Renews every two years') });
}
if ((0, calypso_products_1.isTriennially)(product)) {
return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: translate('Renews every three years') });
}
}
function isCouponApplied({ coupon_savings_integer = 0 }) {
return coupon_savings_integer > 0;
}
const UpgradeCreditHelpIconLink = () => {
const [isPopoverOpen, setIsPopoverOpen] = (0, react_1.useState)(false);
const translate = (0, i18n_calypso_1.useTranslate)();
const ref = (0, react_1.useRef)(null);
function toggleIsPopoverOpen() {
setIsPopoverOpen((isPopoverOpen) => !isPopoverOpen);
}
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("span", { ref: ref, onMouseEnter: () => setIsPopoverOpen(true), onMouseLeave: () => setIsPopoverOpen(false), onTouchStart: toggleIsPopoverOpen, children: (0, jsx_runtime_1.jsx)(components_1.Gridicon, { icon: "help-outline", size: 18 }) }), (0, jsx_runtime_1.jsx)(UpgradeCreditPopover, { autoPosition: true, context: ref.current, isVisible: isPopoverOpen, hideArrow: true, children: translate('Upgrade now and we’ll automatically apply the remaining credit from your current plan. Remember, upgrade credit can only be used toward plan upgrades for the same website.') })] }));
};
function hasUpgradeCredit(product) {
return (product.cost_overrides?.some((override) => override.override_code === 'recent-plan-proration') ?? false);
}
function UpgradeCreditInformation({ product }) {
const translate = (0, i18n_calypso_1.useTranslate)();
const origCost = product.item_original_subtotal_integer;
const finalCost = product.item_subtotal_integer;
const upgradeCredit = origCost - finalCost;
const planSlug = product.product_slug;
const isRenewal = product.is_renewal;
if (
// Do not display discount reason if there is an introductory offer.
product.introductory_offer_terms?.enabled ||
// Do not display discount reason for non-wpcom, non-jetpack products.
(!(0, calypso_products_1.isWpComPlan)(planSlug) && !(0, calypso_products_1.isJetpackProductSlug)(planSlug)) ||
// Do not display discount reason if there is no discount.
origCost <= finalCost ||
// Do not display discount reason if this is a renewal.
isRenewal ||
// Do not display discount reason if a coupon is applied.
isCouponApplied(product) ||
// Do not display upgrade credit if there is no upgrade credit.
!hasUpgradeCredit(product)) {
return null;
}
if ((0, calypso_products_1.isMonthlyProduct)(product)) {
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [translate('Upgrade Credit: %(upgradeCredit)s applied in first month only', {
comment: 'The upgrade credit is a pro rated balance of the previous plan which is to be applied' +
'as a deduction to the first year of next purchased plan. It will be applied once only in the first term',
args: {
upgradeCredit: (0, number_formatters_1.formatCurrency)(upgradeCredit, product.currency, {
isSmallestUnit: true,
stripZeros: true,
}),
},
}), (0, jsx_runtime_1.jsx)(UpgradeCreditHelpIconLink, {})] }));
}
if ((0, calypso_products_1.isYearly)(product)) {
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [translate('Upgrade Credit: %(upgradeCredit)s applied in first year only', {
comment: 'The upgrade credit is a pro rated balance of the previous plan which is to be applied' +
'as a deduction to the first year of next purchased plan. It will be applied once only in the first term',
args: {
upgradeCredit: (0, number_formatters_1.formatCurrency)(upgradeCredit, product.currency, {
isSmallestUnit: true,
stripZeros: true,
}),
},
}), (0, jsx_runtime_1.jsx)(UpgradeCreditHelpIconLink, {})] }));
}
if ((0, calypso_products_1.isBiennially)(product) || (0, calypso_products_1.isTriennially)(product)) {
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [translate('Upgrade Credit: %(discount)s applied in first term only', {
comment: 'The upgrade credit is a pro rated balance of the previous plan which is to be applied' +
'as a deduction to the first year of next purchased plan. It will be applied once only in the first term',
args: {
discount: (0, number_formatters_1.formatCurrency)(upgradeCredit, product.currency, {
isSmallestUnit: true,
stripZeros: true,
}),
},
}), (0, jsx_runtime_1.jsx)(UpgradeCreditHelpIconLink, {})] }));
}
return null;
}
function IntroductoryOfferCallout({ product, isStreamlinedPrice, }) {
const translate = (0, i18n_calypso_1.useTranslate)();
const introductoryOffer = (0, introductory_offer_1.getItemIntroductoryOfferDisplay)(translate, product, isStreamlinedPrice);
if (!introductoryOffer) {
return null;
}
if (!introductoryOffer.enabled) {
return (0, jsx_runtime_1.jsx)(NotApplicableCallout, { children: introductoryOffer.text });
}
return (0, jsx_runtime_1.jsx)(DiscountCallout, { children: introductoryOffer.text });
}
function JetpackAkismetSaleCouponCallout({ product }) {
const isJetpackOrAkismet = (0, calypso_products_1.isJetpackProductSlug)(product.product_slug) || (0, calypso_products_1.isAkismetProduct)(product);
const translate = (0, i18n_calypso_1.useTranslate)();
const hasIntroductoryOffer = product.introductory_offer_terms &&
!product.introductory_offer_terms.reason &&
product.introductory_offer_terms.enabled;
// If this is not a Jetpack or Akismet product or the product already has an intro offer,
// Skip this discount callout - we are re-using the intro offer callout for first-term sale coupons
if (!isJetpackOrAkismet || hasIntroductoryOffer || !product.is_sale_coupon_applied) {
return null;
}
const interval = product.bill_period === '31' ? 'month' : 'year';
const interval_count = interval === 'month' ? 1 : parseInt(product.bill_period) / 365;
const discountText = (0, introductory_offer_1.getIntroductoryOfferIntervalDisplay)({
translate,
intervalUnit: interval,
intervalCount: interval_count,
isFreeTrial: false,
isPriceIncrease: false,
context: '',
remainingRenewalsUsingOffer: 0,
});
return (0, jsx_runtime_1.jsx)(DiscountCallout, { children: discountText });
}
function PartnerLogo({ className }) {
const translate = (0, i18n_calypso_1.useTranslate)();
/* eslint-disable wpcalypso/jsx-classname-namespace */
return ((0, jsx_runtime_1.jsxs)(LineItemMeta, { className: (0, join_classes_1.joinClasses)([className, 'jetpack-partner-logo']), children: [(0, jsx_runtime_1.jsx)("div", { children: translate('Included in your IONOS plan') }), (0, jsx_runtime_1.jsx)("div", { className: "checkout-line-item__partner-logo-image", children: (0, jsx_runtime_1.jsx)(partner_logo_ionos_1.default, {}) })] }));
/* eslint-enable wpcalypso/jsx-classname-namespace */
}
function DomainDiscountCallout({ product }) {
const translate = (0, i18n_calypso_1.useTranslate)();
if (product.is_included_for_100yearplan) {
return (0, jsx_runtime_1.jsx)(DiscountCallout, { children: translate('Included with your plan') });
}
if (product.is_bundled) {
return (0, jsx_runtime_1.jsx)(DiscountCallout, { children: translate('Discount for first year') });
}
const isFreeDomainMapping = product.product_slug === 'domain_map' && product.item_subtotal_integer === 0;
if (isFreeDomainMapping) {
return (0, jsx_runtime_1.jsx)(DiscountCallout, { children: translate('Free with your plan') });
}
return null;
}
function GSuiteDiscountCallout({ product }) {
const translate = (0, i18n_calypso_1.useTranslate)();
if ((0, calypso_products_1.isGSuiteOrGoogleWorkspaceProductSlug)(product.product_slug) &&
product.item_original_subtotal_integer < product.item_original_subtotal_integer &&
product.is_sale_coupon_applied) {
return (0, jsx_runtime_1.jsx)(DiscountCallout, { children: translate('Discount for first year') });
}
return null;
}
function GiftBadgeWithText() {
const translate = (0, i18n_calypso_1.useTranslate)();
return (0, jsx_runtime_1.jsx)(GiftBadge, { children: translate('Gift') });
}
const MobileGiftWrapper = styled_1.default.div `
display: block;
width: 100%;
@media ( ${(props) => props.theme.breakpoints.tabletUp} ) {
display: none;
}
`;
const DesktopGiftWrapper = styled_1.default.div `
display: none;
@media ( ${(props) => props.theme.breakpoints.tabletUp} ) {
display: block;
}
`;
function CheckoutLineItem({ children, product, className, hasDeleteButton, removeProductFromCart, isRestorable = false, isSummary, createUserAndSiteBeforeTransaction, responseCart, restorableProducts, setRestorableProducts, isPwpoUser, onRemoveProduct, onRemoveProductClick, onRemoveProductCancel, isAkPro500Cart, shouldShowComparison, compareToPrice, }) {
const translate = (0, i18n_calypso_1.useTranslate)();
const hasBundledDomainsInCart = responseCart.products.some((product) => (product.is_domain_registration || product.product_slug === 'domain_transfer') &&
product.is_bundled);
const hasMarketplaceProductsInCart = responseCart.products.some((product) => product.extra.is_marketplace_product === true ||
product.product_slug.startsWith('wp_mp_theme'));
const { formStatus } = (0, composite_checkout_1.useFormStatus)();
const [isModalVisible, setIsModalVisible] = (0, react_1.useState)(false);
const [isPlaceholder, setIsPlaceholder] = (0, react_1.useState)(false);
const hasRemoveFromCartModal = getHasRemoveFromCartModal({
product,
hasBundledDomainsInCart,
hasMarketplaceProductsInCart,
isPwpoUser,
});
const modalCopy = returnModalCopyForProduct(product, translate, hasBundledDomainsInCart, hasMarketplaceProductsInCart, createUserAndSiteBeforeTransaction || false, isPwpoUser || false);
const isDisabled = formStatus !== composite_checkout_1.FormStatus.READY;
const isRenewal = (0, is_wpcom_product_renewal_1.isWpComProductRenewal)(product);
const productSlug = product?.product_slug;
const label = (0, checkout_labels_1.getLabel)(product);
const originalAmountInteger = isAkPro500Cart && product.quantity
? product.item_original_cost_for_quantity_one_integer
: product.item_original_subtotal_integer;
const originalAmountDisplay = (0, number_formatters_1.formatCurrency)(originalAmountInteger, product.currency, {
isSmallestUnit: true,
stripZeros: true,
});
const itemSubtotalInteger = isAkPro500Cart && product.quantity
? product.item_subtotal_integer / product.quantity
: product.item_subtotal_integer;
const actualAmountDisplay = (0, number_formatters_1.formatCurrency)(itemSubtotalInteger, product.currency, {
isSmallestUnit: true,
stripZeros: true,
});
let pricePerMonth = 0;
let originalPricePerMonth = 0;
if (shouldShowComparison) {
pricePerMonth = Math.round(product.item_subtotal_integer / (product.months_per_bill_period ?? 1));
originalPricePerMonth = product.item_original_monthly_cost_integer;
}
const monthlyAmountDisplay = (0, number_formatters_1.formatCurrency)(pricePerMonth, product.currency, {
isSmallestUnit: true,
stripZeros: true,
});
const originalMonthlyAmountDisplay = (0, number_formatters_1.formatCurrency)(originalPricePerMonth, product.currency, {
isSmallestUnit: true,
stripZeros: true,
});
const isDiscounted = Boolean(itemSubtotalInteger < originalAmountInteger && originalAmountDisplay);
const isEmail = (0, calypso_products_1.isGoogleWorkspaceProductSlug)(productSlug) ||
(0, calypso_products_1.isGSuiteOrExtraLicenseProductSlug)(productSlug) ||
(0, calypso_products_1.isTitanMail)(product);
const containsPartnerCoupon = (0, partner_coupon_1.getPartnerCoupon)({
coupon: responseCart.coupon,
});
const removeProductFromCartAndSetAsRestorable = async () => {
if (!(hasDeleteButton && removeProductFromCart)) {
return;
}
setIsPlaceholder(true);
let product_uuids_to_remove = [product.uuid];
// Gifts need to be all or nothing, to prevent leaving
// the site in a state where it requires other purchases
// in order to actually work correctly for the period of
// the gift (for example, gifting a plan renewal without
// a domain renewal would likely lead the site's domain
// to expire soon afterwards).
if (product.is_gift_purchase) {
product_uuids_to_remove = responseCart.products
.filter((cart_product) => cart_product.is_gift_purchase)
.map((cart_product) => cart_product.uuid);
}
await Promise.all(product_uuids_to_remove.map(removeProductFromCart)).catch(() => {
// Nothing needs to be done here. CartMessages will display the error to the user.
});
setRestorableProducts?.([...(restorableProducts || []), product]);
onRemoveProduct?.(label);
};
if (isPlaceholder) {
return ((0, jsx_runtime_1.jsxs)(loading_card_1.LoadingCard, { children: [(0, jsx_runtime_1.jsxs)(loading_card_1.LoadingRow, { children: [(0, jsx_runtime_1.jsx)(loading_card_1.LoadingCopy, { noMargin: true, width: "150px" }), (0, jsx_runtime_1.jsx)(loading_card_1.LoadingCopy, { noMargin: true, width: "45px" })] }), (0, jsx_runtime_1.jsx)(loading_card_1.LoadingCopy, { height: "35px", width: "225px" }), (0, jsx_runtime_1.jsx)(loading_card_1.LoadingCopy, { width: "100px" })] }));
}
return ((0, jsx_runtime_1.jsxs)("div", { className: (0, join_classes_1.joinClasses)([className, 'checkout-line-item']), "data-e2e-product-slug": productSlug, "data-product-type": (0, calypso_products_1.isPlan)(product) ? 'plan' : product.product_slug, children: [responseCart.is_gift_purchase && ((0, jsx_runtime_1.jsx)(MobileGiftWrapper, { children: (0, jsx_runtime_1.jsx)(GiftBadgeWithText, {}) })), (0, jsx_runtime_1.jsxs)(LineItemTitle, { isSummary: isSummary, children: [label, responseCart.is_gift_purchase && ((0, jsx_runtime_1.jsx)(DesktopGiftWrapper, { children: (0, jsx_runtime_1.jsx)(GiftBadgeWithText, {}) }))] }), (0, jsx_runtime_1.jsx)("span", { className: "checkout-line-item__price", children: shouldShowComparison ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(LineItemPrice, { actualAmount: monthlyAmountDisplay, crossedOutAmount: isDiscounted ? originalMonthlyAmountDisplay : undefined }), ' ', translate('/month')] })) : ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsx)(LineItemPrice, { actualAmount: actualAmountDisplay, crossedOutAmount: isDiscounted ? originalAmountDisplay : undefined }) })) }), !containsPartnerCoupon && ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(UpgradeCreditInformationLineItem, { children: (0, jsx_runtime_1.jsx)(UpgradeCreditInformation, { product: product }) }), (0, jsx_runtime_1.jsxs)(LineItemMeta, { children: [(0, jsx_runtime_1.jsx)(LineItemSublabelAndPrice, { product: product, shouldShowComparison: shouldShowComparison, compareToPrice: compareToPrice }), (0, jsx_runtime_1.jsx)(DomainDiscountCallout, { product: product }), (0, jsx_runtime_1.jsx)(IntroductoryOfferCallout, { product: product, isStreamlinedPrice: shouldShowComparison }), (0, jsx_runtime_1.jsx)(JetpackAkismetSaleCouponCallout, { product: product })] })] }) })), containsPartnerCoupon && ((0, jsx_runtime_1.jsx)(LineItemMeta, { children: (0, jsx_runtime_1.jsx)(LineItemSublabelAndPrice, { product: product }) })), (0, calypso_products_1.isJetpackSearch)(product) && (0, jsx_runtime_1.jsx)(JetpackSearchMeta, { product: product }), isEmail && (0, jsx_runtime_1.jsx)(EmailMeta, { product: product, isRenewal: isRenewal }), children, hasDeleteButton && removeProductFromCart && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(DeleteButtonWrapper, { children: (0, jsx_runtime_1.jsx)(DeleteButton, { className: "checkout-line-item__remove-product", buttonType: "text-button", "aria-label": String(translate('Remove %s from cart', {
args: label,
})), disabled: isDisabled, onClick: () => {
if (isRestorable) {
if (hasRemoveFromCartModal) {
setIsModalVisible(true);
}
else {
removeProductFromCartAndSetAsRestorable();
}
}
else {
setIsModalVisible(true);
}
onRemoveProductClick?.(label);
}, children: translate('Remove from cart') }) }), (0, jsx_runtime_1.jsx)(composite_checkout_1.CheckoutModal, { isVisible: isModalVisible, closeModal: () => {
setIsModalVisible(false);
}, primaryAction: removeProductFromCartAndSetAsRestorable, cancelAction: () => {
onRemoveProductCancel?.(label);
}, secondaryAction: () => {
onRemoveProductCancel?.(label);
}, secondaryButtonCTA: String(translate('Cancel')), title: modalCopy.title, copy: modalCopy.description })] }))] }));
}
//# sourceMappingURL=checkout-line-items.js.map