diff --git a/client/components/mma/accountoverview/AccountOverview.tsx b/client/components/mma/accountoverview/AccountOverview.tsx index 527839b00..ad20e0215 100644 --- a/client/components/mma/accountoverview/AccountOverview.tsx +++ b/client/components/mma/accountoverview/AccountOverview.tsx @@ -45,7 +45,10 @@ import { isCancelled } from '../cancel/CancellationSummary'; import { PageContainer } from '../Page'; import { JsonResponseHandler } from '../shared/asyncComponents/DefaultApiResponseHandler'; import { DefaultLoadingView } from '../shared/asyncComponents/DefaultLoadingView'; +import { DownloadAppCtaVariation1 } from '../shared/DownloadAppCtaVariation1'; +import { DownloadFeastAppCtaWithImage } from '../shared/DownloadFeastAppCtaWithImage'; import type { IsFromAppProps } from '../shared/IsFromAppProps'; +import { NewspaperArchiveCta } from '../shared/NewspaperArchiveCta'; import { nonServiceableCountries } from '../shared/NonServiceableCountries'; import { PaymentFailureAlertIfApplicable } from '../shared/PaymentFailureAlertIfApplicable'; import { CancelledProductCard } from './CancelledProductCard'; @@ -166,6 +169,10 @@ const AccountOverviewPage = ({ isFromApp }: IsFromAppProps) => { isSpecificProductType(productDetail, PRODUCT_TYPES.digipack), ); + const hasDigitalPlusPrint = allActiveProductDetails.some((productDetail) => + isSpecificProductType(productDetail, PRODUCT_TYPES.tierthree), + ); + const hasNonServiceableCountry = nonServiceableCountries.includes( allActiveProductDetails.find(isProduct)?.billingCountry as string, ); @@ -290,6 +297,20 @@ const AccountOverviewPage = ({ isFromApp }: IsFromAppProps) => { ); })} + {hasDigitalPlusPrint && ( + <> +

+ Get the most out of your benefits +

+ + {featureSwitches.digitalArchiveCta && ( + + )} + + + + + )} ); }; diff --git a/client/components/mma/cancel/cancellationSaves/CancelAlternativeConfirmed.tsx b/client/components/mma/cancel/cancellationSaves/CancelAlternativeConfirmed.tsx index 0175f70c2..da97ae33b 100755 --- a/client/components/mma/cancel/cancellationSaves/CancelAlternativeConfirmed.tsx +++ b/client/components/mma/cancel/cancellationSaves/CancelAlternativeConfirmed.tsx @@ -23,7 +23,7 @@ import type { PaidSubscriptionPlan } from '@/shared/productResponse'; import { getMainPlan } from '@/shared/productResponse'; import { BenefitsSection } from '../../shared/benefits/BenefitsSection'; import { DownloadAppCta } from '../../shared/DownloadAppCta'; -import { DownloadFeastAppCta } from '../../shared/DownloadFeastAppCta'; +import { DownloadFeastAppCtaWithIcon } from '../../shared/DownloadFeastAppCtaWithIcon'; import { Heading } from '../../shared/Heading'; import type { CancellationContextInterface, @@ -324,7 +324,7 @@ export const CancelAlternativeConfirmed = () => { - +
; + +export const Default: StoryFn = () => ( + +); diff --git a/client/components/mma/shared/DownloadAppCtaVariation1.tsx b/client/components/mma/shared/DownloadAppCtaVariation1.tsx new file mode 100644 index 000000000..e3b5d6219 --- /dev/null +++ b/client/components/mma/shared/DownloadAppCtaVariation1.tsx @@ -0,0 +1,124 @@ +import type { SerializedStyles } from '@emotion/react'; +import { css } from '@emotion/react'; +import { + from, + space, + textSans15, + textSans17, + textSansBold17, + textSansBold20, + until, +} from '@guardian/source/foundations'; +import { androidAppUrl, iosAppUrl } from '@/shared/externalLinks'; +import { AndroidPlayStoreButton } from './assets/AndroidPlayStoreButton'; +import { AppleAppStoreButton } from './assets/AppleAppStoreButton'; + +interface DownloadAppCtaVariation1Props { + additionalCss?: SerializedStyles; +} + +const containerCss = css` + background-color: #e1eaf7; + h4 { + ${textSansBold17}; + margin: 0 ${space[5]}px 0 0; + } + p { + ${textSans15}; + margin: ${space[1]}px ${space[5]}px 0 0; + } + ${from.tablet} { + padding: ${space[6]}px 0 0 ${space[6]}px; + h4 { + ${textSansBold20}; + } + p { + ${textSans17}; + } + } +`; + +const inlineContentsCss = css` + display: flex; + flex-direction: column; + column-gap: ${space[3]}px; + ${from.tablet} { + flex-direction: row; + } +`; + +const copyContainerCss = css` + order: 2; + margin-top: ${space[4]}px; + padding: 0 ${space[3]}px ${space[5]}px; + ${from.tablet} { + order: 1; + margin: 0 0 ${space[6]}px; + padding: 0; + } +`; + +const appStoreBtnsContainerCss = css` + margin-top: ${space[4]}px; +`; + +const heroImageContainerCss = css` + align-items: flex-end; + background: linear-gradient(transparent, rgba(0, 0, 0, 0.1)); + display: flex; + flex-grow: 1; + order: 1; + ${from.tablet} { + background: none; + order: 2; + } +`; + +const heroImageCss = css` + margin: 0 auto; + max-width: 450px; + ${until.tablet} { + width: 100%; + } + ${from.tablet} { + max-width: 340px; + } +`; + +export const DownloadAppCtaVariation1 = ( + props: DownloadAppCtaVariation1Props, +) => { + return ( +
+
+
+

The Guardian News app

+

+ Never miss a story with unlimited access to our quality + news app, plus enjoy personalised recommendations and + offline reading. +

+
+ + +
+
+
+ +
+
+
+ ); +}; diff --git a/client/components/mma/shared/DownloadFeastAppCta.tsx b/client/components/mma/shared/DownloadFeastAppCtaWithIcon.tsx similarity index 92% rename from client/components/mma/shared/DownloadFeastAppCta.tsx rename to client/components/mma/shared/DownloadFeastAppCtaWithIcon.tsx index 6ef56b4aa..aedb0fac6 100644 --- a/client/components/mma/shared/DownloadFeastAppCta.tsx +++ b/client/components/mma/shared/DownloadFeastAppCtaWithIcon.tsx @@ -6,7 +6,7 @@ import { AndroidPlayStoreButton } from './assets/AndroidPlayStoreButton'; import { AppleAppStoreButton } from './assets/AppleAppStoreButton'; import { FeastAppIcon } from './assets/FeastAppIcon'; -interface DownloadFeastAppCtaProps { +interface DownloadFeastAppCtaWithIconProps { additionalCss?: SerializedStyles; } @@ -45,7 +45,9 @@ const appIconContainerCss = css` } `; -export const DownloadFeastAppCta = (props: DownloadFeastAppCtaProps) => { +export const DownloadFeastAppCtaWithIcon = ( + props: DownloadFeastAppCtaWithIconProps, +) => { return (
diff --git a/client/components/mma/shared/DownloadFeastAppCtaWithImage.stories.tsx b/client/components/mma/shared/DownloadFeastAppCtaWithImage.stories.tsx new file mode 100644 index 000000000..cf96a392f --- /dev/null +++ b/client/components/mma/shared/DownloadFeastAppCtaWithImage.stories.tsx @@ -0,0 +1,11 @@ +import type { Meta, StoryFn } from '@storybook/react'; +import { DownloadFeastAppCtaWithImage } from './DownloadFeastAppCtaWithImage'; + +export default { + title: 'Components/DownloadFeastAppCtaWithImage', + component: DownloadFeastAppCtaWithImage, +} as Meta; + +export const Default: StoryFn = () => ( + +); diff --git a/client/components/mma/shared/DownloadFeastAppCtaWithImage.tsx b/client/components/mma/shared/DownloadFeastAppCtaWithImage.tsx new file mode 100644 index 000000000..0fcc9652e --- /dev/null +++ b/client/components/mma/shared/DownloadFeastAppCtaWithImage.tsx @@ -0,0 +1,123 @@ +import type { SerializedStyles } from '@emotion/react'; +import { css } from '@emotion/react'; +import { + from, + space, + textSans15, + textSans17, + textSansBold17, + textSansBold20, + until, +} from '@guardian/source/foundations'; +import { androidFeastAppUrl, iosFeastAppUrl } from '@/shared/externalLinks'; +import { AndroidPlayStoreButton } from './assets/AndroidPlayStoreButton'; +import { AppleAppStoreButton } from './assets/AppleAppStoreButton'; + +interface DownloadFeastAppCtaWithImageProps { + additionalCss?: SerializedStyles; +} + +const containerCss = css` + background-color: #e1e5d5; + h4 { + ${textSansBold17}; + margin: 0 ${space[5]}px 0 0; + } + p { + ${textSans15}; + margin: ${space[1]}px ${space[5]}px 0 0; + } + ${from.tablet} { + padding: ${space[6]}px 0 0 ${space[6]}px; + h4 { + ${textSansBold20}; + } + p { + ${textSans17}; + } + } +`; + +const inlineContentsCss = css` + display: flex; + flex-direction: column; + column-gap: ${space[3]}px; + ${from.tablet} { + flex-direction: row; + } +`; + +const copyContainerCss = css` + order: 2; + margin-top: ${space[4]}px; + padding: 0 ${space[3]}px ${space[5]}px; + ${from.tablet} { + order: 1; + margin: 0 0 ${space[6]}px; + padding: 0; + } +`; + +const appStoreBtnsContainerCss = css` + margin-top: ${space[4]}px; +`; + +const heroImageContainerCss = css` + align-items: flex-end; + background: linear-gradient(transparent, rgba(0, 0, 0, 0.1)); + display: flex; + flex-grow: 1; + order: 1; + ${from.tablet} { + background: none; + order: 2; + } +`; + +const heroImageCss = css` + margin: 0 auto; + max-width: 450px; + ${until.tablet} { + width: 100%; + } + ${from.tablet} { + max-width: 340px; + } +`; + +export const DownloadFeastAppCtaWithImage = ( + props: DownloadFeastAppCtaWithImageProps, +) => { + return ( +
+
+
+

The Guardian Feast app

+

+ Discover thousands of recipes from the Guardian and + Observer in our ultimate cooking companion app. +

+
+ + +
+
+
+ +
+
+
+ ); +}; diff --git a/client/components/mma/shared/NewspaperArchiveCta.stories.tsx b/client/components/mma/shared/NewspaperArchiveCta.stories.tsx new file mode 100644 index 000000000..abb86a676 --- /dev/null +++ b/client/components/mma/shared/NewspaperArchiveCta.stories.tsx @@ -0,0 +1,11 @@ +import type { Meta, StoryFn } from '@storybook/react'; +import { NewspaperArchiveCta } from './NewspaperArchiveCta'; + +export default { + title: 'Components/NewpaperArchiveCta', + component: NewspaperArchiveCta, +} as Meta; + +export const Default: StoryFn = () => ( + +); diff --git a/client/components/mma/shared/NewspaperArchiveCta.tsx b/client/components/mma/shared/NewspaperArchiveCta.tsx new file mode 100644 index 000000000..b02cbc74b --- /dev/null +++ b/client/components/mma/shared/NewspaperArchiveCta.tsx @@ -0,0 +1,143 @@ +import type { SerializedStyles } from '@emotion/react'; +import { css } from '@emotion/react'; +import { + breakpoints, + from, + palette, + space, + textSans15, + textSans17, + textSansBold17, + textSansBold20, + until, +} from '@guardian/source/foundations'; +import { + LinkButton, + SvgArrowRightStraight, +} from '@guardian/source/react-components'; +import { trackEvent } from '@/client/utilities/analytics'; + +interface NewspaperArchiveCtaProps { + additionalCss?: SerializedStyles; +} + +const containerCss = css` + background-color: #1e3e72; + color: ${palette.neutral[100]}; + h4 { + ${textSansBold17}; + margin: 0 ${space[5]}px 0 0; + } + p { + ${textSans15}; + margin: ${space[1]}px ${space[5]}px 0 0; + } + ${from.tablet} { + padding: ${space[6]}px 0 0 ${space[6]}px; + h4 { + ${textSansBold20}; + } + p { + ${textSans17}; + } + } +`; + +const inlineContentsCss = css` + display: flex; + flex-direction: column; + column-gap: ${space[3]}px; + ${from.tablet} { + flex-direction: row; + } +`; + +const copyContainerCss = css` + order: 2; + margin-top: ${space[4]}px; + padding: 0 ${space[3]}px ${space[5]}px; + ${from.tablet} { + order: 1; + margin: 0 0 ${space[6]}px; + padding: 0; + } +`; + +const heroImageContainerCss = css` + background: linear-gradient(transparent, rgba(0, 0, 0, 0.1)); + display: flex; + align-items: flex-end; + justify-content: center; + flex-grow: 1; + order: 1; + ${from.tablet} { + background: none; + justify-content: flex-end; + order: 2; + } +`; + +const heroImageCss = css` + margin: 0 auto; + max-width: 450px; + ${until.tablet} { + width: 100%; + } + ${from.tablet} { + max-width: 340px; + } +`; + +export const NewspaperArchiveCta = (props: NewspaperArchiveCtaProps) => { + const onExploreBtnClick = () => + trackEvent({ + eventCategory: 'DigitalPlusPrintCta', + eventAction: 'digital_plus_print_cta_click', + eventLabel: 'newspaper_archive', + }); + + return ( +
+
+
+

The Guardian Newspaper archive

+

+ Journey through more than 200 years of the Guardian and + Observer and search through every page printed in our + newspapers. +

+ } + iconSide="right" + onClick={onExploreBtnClick} + size="small" + target="_blank" + rel="noopener noreferrer" + > + Explore the archive + +
+
+ + + + +
+
+
+ ); +}; diff --git a/shared/featureSwitches.ts b/shared/featureSwitches.ts index 9338f613b..1615b1d31 100644 --- a/shared/featureSwitches.ts +++ b/shared/featureSwitches.ts @@ -29,7 +29,8 @@ type FeatureSwitchName = | 'supporterPlusUpdateAmount' | 'digisubSave' | 'supporterplusCancellationOffer' - | 'contributionCancellationPause'; + | 'contributionCancellationPause' + | 'digitalArchiveCta'; export const featureSwitches: Record = { exampleFeature: false, @@ -38,4 +39,5 @@ export const featureSwitches: Record = { digisubSave: true, supporterplusCancellationOffer: true, contributionCancellationPause: true, + digitalArchiveCta: false, };