diff --git a/support-frontend/assets/components/checkoutBenefits/benefitsCheckList.tsx b/support-frontend/assets/components/checkoutBenefits/benefitsCheckList.tsx index 67ceb634b8..6bdbbd6065 100644 --- a/support-frontend/assets/components/checkoutBenefits/benefitsCheckList.tsx +++ b/support-frontend/assets/components/checkoutBenefits/benefitsCheckList.tsx @@ -68,6 +68,9 @@ const listCss = (style: CheckListStyle) => css` } } `; +const opaqueCss = css` + opacity: 0; +`; export type BenefitsCheckListData = { isChecked: boolean; @@ -91,15 +94,13 @@ export type BenefitsCheckListProps = { function ChecklistItemIcon({ checked, style, - hideBullet, }: { checked: boolean; style: CheckListStyle; - hideBullet?: boolean; }): JSX.Element { const styleSize = style === 'standard' ? 'small' : 'xsmall'; return style === 'bullet' ? ( - + ) : checked ? ( ) : ( @@ -129,12 +130,13 @@ export function BenefitsCheckList({ item.maybeGreyedOut, ]} > -
- +
+
)} diff --git a/support-frontend/assets/components/checkoutBenefits/bulletSvg.tsx b/support-frontend/assets/components/checkoutBenefits/bulletSvg.tsx index b03de0420e..ba65b1e9c1 100644 --- a/support-frontend/assets/components/checkoutBenefits/bulletSvg.tsx +++ b/support-frontend/assets/components/checkoutBenefits/bulletSvg.tsx @@ -1,11 +1,6 @@ import { palette } from '@guardian/source/foundations'; -type BulletSvgProps = { - opacity?: number; -}; -export default function BulletSvg({ - opacity = 1, -}: BulletSvgProps): JSX.Element { +export default function BulletSvg(): JSX.Element { return ( - + ); } diff --git a/support-frontend/assets/helpers/abTests/abtestDefinitions.ts b/support-frontend/assets/helpers/abTests/abtestDefinitions.ts index 8ccb394c24..e22670fdb3 100644 --- a/support-frontend/assets/helpers/abTests/abtestDefinitions.ts +++ b/support-frontend/assets/helpers/abTests/abtestDefinitions.ts @@ -126,4 +126,28 @@ export const tests: Tests = { targetPage: pageUrlRegexes.contributions.allLandingPagesAndThankyouPages, excludeContributionsOnlyCountries: false, }, + benefitsReset: { + variants: [ + { + id: 'control', + }, + { + id: 'v1', + }, + { + id: 'v2', + }, + ], + audiences: { + ALL: { + offset: 0, + size: 1, + }, + }, + isActive: true, + referrerControlled: false, // ab-test name not needed to be in paramURL + seed: 4, + targetPage: pageUrlRegexes.contributions.allLandingPagesAndThankyouPages, + excludeContributionsOnlyCountries: true, + }, }; diff --git a/support-frontend/assets/helpers/productCatalog.ts b/support-frontend/assets/helpers/productCatalog.ts index 696b4fbe91..74abbfc248 100644 --- a/support-frontend/assets/helpers/productCatalog.ts +++ b/support-frontend/assets/helpers/productCatalog.ts @@ -12,6 +12,9 @@ export type { ActiveProductKey }; export const productCatalog = window.guardian.productCatalog; +export type SupporterPlusVariants = 'control' | 'v1' | 'v2'; +export type ContributionVariants = 'control' | 'v1' | 'v2Annual' | 'v2Monthly'; + type ProductBenefit = { copy: string; tooltip?: string; @@ -94,6 +97,10 @@ export function isProductKey(val: unknown): val is ActiveProductKey { return productKeys.includes(val as ActiveProductKey); } +const appBenefitControlV2 = { + copy: 'Unlimited access to the Guardian app', + tooltip: `Read beyond our 20 article-per-month limit, enjoy offline access and personalised recommendations, and access our full archive of journalism. Never miss a story with the Guardian News app – a beautiful, intuitive reading experience.`, +}; const appBenefit = { copy: 'Full access to the Guardian app', tooltip: `Read beyond our 20 article-per-month limit, enjoy offline access and personalised recommendations, and access our full archive of journalism. Never miss a story with the Guardian News app – a beautiful, intuitive reading experience.`, @@ -101,9 +108,21 @@ const appBenefit = { const addFreeBenefit = { copy: 'Ad-free reading on all your devices', }; + +const newsletterBenefitControl = { + copy: 'Exclusive newsletter for supporters, sent every week from the Guardian newsroom', +}; const newsletterBenefit = { copy: 'Regular dispatches from the newsroom to see the impact of your support', }; +const newsletterBenefitMonthlyV2 = { + copy: 'Give to the Guardian every month with Support', + hideBullet: true, +}; +const newsletterBenefitAnnualV2 = { + copy: 'Give to the Guardian every year with Support', + hideBullet: true, +}; const fewerAsksBenefit = { copy: 'Far fewer asks for support', tooltip: `You'll see far fewer financial support asks at the bottom of articles or in pop-up banners.`, @@ -118,6 +137,17 @@ const guardianWeeklyBenefit = { copy: 'Guardian Weekly print magazine delivered to your door every week ', tooltip: `Guardian Weekly is a beautifully concise magazine featuring a handpicked selection of in-depth articles, global news, long reads, opinion and more. Delivered to you every week, wherever you are in the world.`, }; +const newspaperArchiveBenefitUK = { + copy: `Unlimited access to the Guardian's 200-year newspaper archive`, + isNew: true, + tooltip: `Look back on more than 200 years of world history with the Guardian newspaper archive. Get digital access to every front page, article and advertisement, as it was printed in the UK, since 1821.`, +}; +const newspaperArchiveBenefitROW = { + copy: `Unlimited access to the Guardian's 200-year newspaper archive`, + isNew: true, + tooltip: `Look back on more than 200 years of world history with the Guardian newspaper archive. Get digital access to every front page, article and advertisement, as it was printed, since 1821.`, +}; + const feastBenefit = { copy: 'Unlimited access to the Guardian Feast app', isNew: true, @@ -133,6 +163,45 @@ const supporterPlusBenefits = [ partnerOffersBenefit, feastBenefit, ]; +const supporterPlusBenefitsList: Record< + SupporterPlusVariants, + ProductBenefit[] +> = { + control: [ + appBenefitControlV2, + addFreeBenefit, + newsletterBenefitControl, + fewerAsksBenefit, + partnerOffersBenefit, + feastBenefit, + ], + v1: supporterPlusBenefits, + v2: [ + appBenefitControlV2, + addFreeBenefit, + fewerAsksBenefit, + partnerOffersBenefit, + feastBenefit, + ], +}; + +const contributionBenefitsList: Record = + { + control: [newsletterBenefitControl], + v1: [newsletterBenefit], + v2Monthly: [newsletterBenefitMonthlyV2], + v2Annual: [newsletterBenefitAnnualV2], + }; + +const tierThreeBenefits = [guardianWeeklyBenefit]; +const tierThreeInclArchiveBenefitsUK = [ + guardianWeeklyBenefit, + newspaperArchiveBenefitUK, +]; +const tierThreeInclArchiveBenefitsROW = [ + guardianWeeklyBenefit, + newspaperArchiveBenefitROW, +]; const guardianAdLiteBenefits = [ { @@ -389,6 +458,58 @@ export const productCatalogDescription: Record< }, }; +function supporterPlusVariant(variant?: string): SupporterPlusVariants { + switch (variant) { + case 'v1': + case 'v2': + return variant; + default: + return 'control'; + } +} +function contributionVariant( + period: 'Monthly' | 'Annual', + variant?: string, +): ContributionVariants { + switch (variant) { + case 'v1': + return variant; + case 'v2': + return `v2${period}`; + default: + return 'control'; + } +} + +export function productCatalogDescriptionResetAndNewspaperArchive( + period: 'Monthly' | 'Annual', + resetVariant?: string, + countryGroupId?: CountryGroupId, +) { + const newsPaperArchiveBenefit = countryGroupId + ? countryGroupId === 'GBPCountries' + ? tierThreeInclArchiveBenefitsUK + : tierThreeInclArchiveBenefitsROW + : tierThreeBenefits; + + return { + ...productCatalogDescription, + SupporterPlus: { + ...productCatalogDescription.SupporterPlus, + benefits: supporterPlusBenefitsList[supporterPlusVariant(resetVariant)], + }, + Contribution: { + ...productCatalogDescription.Contribution, + benefits: + contributionBenefitsList[contributionVariant(period, resetVariant)], + }, + TierThree: { + ...productCatalogDescription.TierThree, + benefits: newsPaperArchiveBenefit, + }, + }; +} + export function productCatalogDescriptionNewBenefits( countryGroupId: CountryGroupId, ) { diff --git a/support-frontend/assets/pages/supporter-plus-landing/components/threeTierCard.tsx b/support-frontend/assets/pages/supporter-plus-landing/components/threeTierCard.tsx index 2de192133d..187139b017 100644 --- a/support-frontend/assets/pages/supporter-plus-landing/components/threeTierCard.tsx +++ b/support-frontend/assets/pages/supporter-plus-landing/components/threeTierCard.tsx @@ -210,6 +210,7 @@ export function ThreeTierCard({ price, promotion, ctaCopy, + lozengeText, abParticipations, }: ThreeTierCardProps): JSX.Element { const currency = currencies[currencyId]; @@ -227,7 +228,9 @@ export function ThreeTierCard({ {isRecommended && !isUserSelected && ( )}

{label}

@@ -301,6 +304,7 @@ export function ThreeTierCard({ isChecked: true, toolTip: benefit.tooltip, isNew: benefit.isNew, + hideBullet: benefit.hideBullet, }; })} style={'compact'} diff --git a/support-frontend/assets/pages/supporter-plus-landing/components/threeTierCards.tsx b/support-frontend/assets/pages/supporter-plus-landing/components/threeTierCards.tsx index 1a547a88f7..e1ffb10efd 100644 --- a/support-frontend/assets/pages/supporter-plus-landing/components/threeTierCards.tsx +++ b/support-frontend/assets/pages/supporter-plus-landing/components/threeTierCards.tsx @@ -17,6 +17,7 @@ export type ThreeTierCardsProps = { price: number; promotion?: Promotion; ctaCopy: string; + lozengeText?: string; }>; currencyId: IsoCurrency; countryGroupId: CountryGroupId; @@ -89,6 +90,7 @@ export function ThreeTierCards({ countryGroupId={countryGroupId} paymentFrequency={paymentFrequency} ctaCopy={cardContent.ctaCopy} + lozengeText={cardContent.lozengeText} abParticipations={abParticipations} /> ); diff --git a/support-frontend/assets/pages/supporter-plus-landing/twoStepPages/threeTierLanding.tsx b/support-frontend/assets/pages/supporter-plus-landing/twoStepPages/threeTierLanding.tsx index 6bf3cc45c0..109934d039 100644 --- a/support-frontend/assets/pages/supporter-plus-landing/twoStepPages/threeTierLanding.tsx +++ b/support-frontend/assets/pages/supporter-plus-landing/twoStepPages/threeTierLanding.tsx @@ -46,9 +46,8 @@ import { } from 'helpers/internationalisation/countryGroup'; import { currencies } from 'helpers/internationalisation/currency'; import { - productCatalogDescription as canonicalProductCatalogDescription, productCatalog, - productCatalogDescriptionNewBenefits, + productCatalogDescriptionResetAndNewspaperArchive, } from 'helpers/productCatalog'; import type { BillingPeriod } from 'helpers/productPrice/billingPeriods'; import type { Promotion } from 'helpers/productPrice/promotions'; @@ -374,11 +373,16 @@ export function ThreeTierLanding({ const selectedContributionRatePlan = contributionType === 'ANNUAL' ? 'Annual' : 'Monthly'; - const productCatalogDescription = ['v1', 'v2'].includes( + const inResetBenefits = abParticipations.benefitsReset; // all variants + const inNewsPaperArchiveBenefit = ['v1', 'v2'].includes( abParticipations.newspaperArchiveBenefit ?? '', - ) - ? productCatalogDescriptionNewBenefits(countryGroupId) - : canonicalProductCatalogDescription; + ); + const productCatalogDescription = + productCatalogDescriptionResetAndNewspaperArchive( + selectedContributionRatePlan, + inResetBenefits, + inNewsPaperArchiveBenefit ? countryGroupId : undefined, + ); /** * Tier 1: Contributions @@ -448,6 +452,9 @@ export function ThreeTierLanding({ urlSearchParamsProduct === 'SupporterPlus' || isCardUserSelected(tier2Pricing, promotionTier2?.discount?.amount), ctaCopy: 'Support', + lozengeText: ['control', 'v2'].includes(inResetBenefits ?? '') + ? 'Recommended' + : 'Highest impact', }; /**