From b19b2acf644f74ee3447cd1bbd81f34df3118b80 Mon Sep 17 00:00:00 2001 From: Abban Dunne Date: Wed, 11 Dec 2024 13:56:36 +0100 Subject: [PATCH] Add 2024 Thank You Banners --- banners/thank_you_2024/banner_ctrl.de.ts | 59 ++++ banners/thank_you_2024/banner_ctrl.en.ts | 59 ++++ banners/thank_you_2024/banner_ctrl.wpde.ts | 61 ++++ banners/thank_you_2024/banner_var.de.ts | 59 ++++ banners/thank_you_2024/banner_var.en.ts | 59 ++++ banners/thank_you_2024/banner_var.wpde.ts | 61 ++++ .../components/BannerCtrl.de.vue | 110 +++++++ .../components/BannerCtrl.en.vue | 110 +++++++ .../components/BannerVar.de.vue | 110 +++++++ .../components/BannerVar.en.vue | 110 +++++++ .../thank_you_2024/components/CloseButton.vue | 23 ++ .../components/FullPageBanner.vue | 57 ++++ .../thank_you_2024/components/MiniBanner.vue | 28 ++ .../thank_you_2024/components/ProgressBar.vue | 34 +++ .../thank_you_2024/components/StatsBox.vue | 53 ++++ .../content/ExecutiveDirectorsImage.vue | 11 + banners/thank_you_2024/content/ListTick.vue | 7 + .../content/MembershipBenefits.de.vue | 11 + .../content/MembershipBenefits.en.vue | 11 + .../content/win/FullPageBannerText.de.vue | 54 ++++ .../content/win/FullPageBannerText.en.vue | 53 ++++ .../content/win/MiniBannerText.de.vue | 18 ++ .../content/win/MiniBannerText.en.vue | 19 ++ banners/thank_you_2024/createTrackedURL.ts | 19 ++ banners/thank_you_2024/event_map.ts | 25 ++ banners/thank_you_2024/event_map.wpde.ts | 11 + banners/thank_you_2024/messages.de.ts | 21 ++ banners/thank_you_2024/messages.en.ts | 21 ++ banners/thank_you_2024/settings.ts | 14 + banners/thank_you_2024/styles/Banner.scss | 9 + .../thank_you_2024/styles/CloseButton.scss | 24 ++ .../styles/ExecutiveDirectors.scss | 41 +++ .../thank_you_2024/styles/FullPageBanner.scss | 269 ++++++++++++++++++ banners/thank_you_2024/styles/MiniBanner.scss | 122 ++++++++ .../thank_you_2024/styles/ProgressBar.scss | 161 +++++++++++ banners/thank_you_2024/styles/StatsBox.scss | 28 ++ .../thank_you_2024/styles/styles_wpde.scss | 9 + .../thank_you_2024/styles/styles_wporg.scss | 9 + .../styles/swatches/color_dark.scss | 63 ++++ .../styles/swatches/color_light.scss | 62 ++++ .../styles/swatches/skin_default.scss | 5 + .../styles/swatches/skin_wporg.scss | 21 ++ .../styles/variables/_breakpoints.scss | 37 +++ .../styles/variables/_fonts.scss | 9 + campaign_info.thank_you.toml | 119 ++++---- .../thank_you_2024/BannerCtrl.de.spec.ts | 162 +++++++++++ .../thank_you_2024/BannerCtrl.en.spec.ts | 162 +++++++++++ .../thank_you_2024/BannerVar.de.spec.ts | 162 +++++++++++ .../thank_you_2024/BannerVar.en.spec.ts | 162 +++++++++++ .../thank_you_2024/CloseButton.spec.ts | 21 ++ .../thank_you_2024/FullPageBanner.spec.ts | 52 ++++ .../banners/thank_you_2024/MiniBanner.spec.ts | 41 +++ .../thank_you_2024/ProgressBar.spec.ts | 35 +++ 53 files changed, 3017 insertions(+), 56 deletions(-) create mode 100644 banners/thank_you_2024/banner_ctrl.de.ts create mode 100644 banners/thank_you_2024/banner_ctrl.en.ts create mode 100644 banners/thank_you_2024/banner_ctrl.wpde.ts create mode 100644 banners/thank_you_2024/banner_var.de.ts create mode 100644 banners/thank_you_2024/banner_var.en.ts create mode 100644 banners/thank_you_2024/banner_var.wpde.ts create mode 100644 banners/thank_you_2024/components/BannerCtrl.de.vue create mode 100644 banners/thank_you_2024/components/BannerCtrl.en.vue create mode 100644 banners/thank_you_2024/components/BannerVar.de.vue create mode 100644 banners/thank_you_2024/components/BannerVar.en.vue create mode 100644 banners/thank_you_2024/components/CloseButton.vue create mode 100644 banners/thank_you_2024/components/FullPageBanner.vue create mode 100644 banners/thank_you_2024/components/MiniBanner.vue create mode 100644 banners/thank_you_2024/components/ProgressBar.vue create mode 100644 banners/thank_you_2024/components/StatsBox.vue create mode 100644 banners/thank_you_2024/content/ExecutiveDirectorsImage.vue create mode 100644 banners/thank_you_2024/content/ListTick.vue create mode 100644 banners/thank_you_2024/content/MembershipBenefits.de.vue create mode 100644 banners/thank_you_2024/content/MembershipBenefits.en.vue create mode 100644 banners/thank_you_2024/content/win/FullPageBannerText.de.vue create mode 100644 banners/thank_you_2024/content/win/FullPageBannerText.en.vue create mode 100644 banners/thank_you_2024/content/win/MiniBannerText.de.vue create mode 100644 banners/thank_you_2024/content/win/MiniBannerText.en.vue create mode 100644 banners/thank_you_2024/createTrackedURL.ts create mode 100644 banners/thank_you_2024/event_map.ts create mode 100644 banners/thank_you_2024/event_map.wpde.ts create mode 100644 banners/thank_you_2024/messages.de.ts create mode 100644 banners/thank_you_2024/messages.en.ts create mode 100644 banners/thank_you_2024/settings.ts create mode 100644 banners/thank_you_2024/styles/Banner.scss create mode 100644 banners/thank_you_2024/styles/CloseButton.scss create mode 100644 banners/thank_you_2024/styles/ExecutiveDirectors.scss create mode 100644 banners/thank_you_2024/styles/FullPageBanner.scss create mode 100644 banners/thank_you_2024/styles/MiniBanner.scss create mode 100644 banners/thank_you_2024/styles/ProgressBar.scss create mode 100644 banners/thank_you_2024/styles/StatsBox.scss create mode 100644 banners/thank_you_2024/styles/styles_wpde.scss create mode 100644 banners/thank_you_2024/styles/styles_wporg.scss create mode 100644 banners/thank_you_2024/styles/swatches/color_dark.scss create mode 100644 banners/thank_you_2024/styles/swatches/color_light.scss create mode 100644 banners/thank_you_2024/styles/swatches/skin_default.scss create mode 100644 banners/thank_you_2024/styles/swatches/skin_wporg.scss create mode 100644 banners/thank_you_2024/styles/variables/_breakpoints.scss create mode 100644 banners/thank_you_2024/styles/variables/_fonts.scss create mode 100644 test/banners/thank_you_2024/BannerCtrl.de.spec.ts create mode 100644 test/banners/thank_you_2024/BannerCtrl.en.spec.ts create mode 100644 test/banners/thank_you_2024/BannerVar.de.spec.ts create mode 100644 test/banners/thank_you_2024/BannerVar.en.spec.ts create mode 100644 test/banners/thank_you_2024/CloseButton.spec.ts create mode 100644 test/banners/thank_you_2024/FullPageBanner.spec.ts create mode 100644 test/banners/thank_you_2024/MiniBanner.spec.ts create mode 100644 test/banners/thank_you_2024/ProgressBar.spec.ts diff --git a/banners/thank_you_2024/banner_ctrl.de.ts b/banners/thank_you_2024/banner_ctrl.de.ts new file mode 100644 index 000000000..ded873dd2 --- /dev/null +++ b/banners/thank_you_2024/banner_ctrl.de.ts @@ -0,0 +1,59 @@ +import { createVueApp } from '@src/createVueApp'; + +import './styles/styles_wporg.scss'; + +import PageWPORG from '@src/page/PageWPORG'; +import { SkinFactory } from '@src/page/skin/SkinFactory'; +import { WindowSizeIssueChecker } from '@src/utils/SizeIssueChecker/WindowSizeIssueChecker'; +import { Translator } from '@src/Translator'; +import { WindowMediaWiki } from '@src/page/MediaWiki/WindowMediaWiki'; +import { UrlRuntimeEnvironment } from '@src/utils/RuntimeEnvironment'; +import { LocalImpressionCount } from '@src/utils/LocalImpressionCount'; +import { LegacyTrackerWPORG } from '@src/tracking/LegacyTrackerWPORG'; +import BannerConductor from '@src/components/BannerConductor/BannerConductor.vue'; +import { WindowResizeHandler } from '@src/utils/ResizeHandler'; +import Banner from './components/BannerCtrl.de.vue'; +import messages from './messages.de'; +import eventMappings from './event_map'; +import TranslationPlugin from '@src/TranslationPlugin'; +import { createTrackedURL, MEMBERSHIP_FORM_URL, SUBSCRIBE_URL, USE_OF_FUNDS_URL } from './createTrackedURL'; +import { createThankYouSettings } from './settings'; +import { IntegerDe } from '@src/utils/DynamicContent/formatters/IntegerDe'; +import { Locales } from '@src/domain/Locales'; +import { WindowTimer } from '@src/utils/Timer'; + +const translator = new Translator( messages ); +const mediaWiki = new WindowMediaWiki(); +const page = new PageWPORG( mediaWiki, ( new SkinFactory( mediaWiki ) ).getSkin(), new WindowSizeIssueChecker( 0 ) ); +const runtimeEnvironment = new UrlRuntimeEnvironment( window.location ); +const impressionCount = new LocalImpressionCount( page.getTracking().keyword, runtimeEnvironment ); +const tracker = new LegacyTrackerWPORG( mediaWiki, page.getTracking().keyword, eventMappings, runtimeEnvironment ); + +const app = createVueApp( BannerConductor, { + page, + bannerConfig: { + delay: 0, + transitionDuration: 0 + }, + bannerProps: { + settings: createThankYouSettings( new IntegerDe(), page.getCampaignParameters().thankYouCampaign ), + subscribeURL: createTrackedURL( SUBSCRIBE_URL, page.getTracking(), impressionCount, { locale: Locales.DE } ), + useOfFundsURL: createTrackedURL( USE_OF_FUNDS_URL, page.getTracking(), impressionCount, { locale: Locales.DE } ), + membershipWithAmountURL: createTrackedURL( MEMBERSHIP_FORM_URL, page.getTracking(), impressionCount, { + locale: Locales.DE, + interval: '1', + fee: '200', + type: 'sustaining' + } ), + membershipWithoutAmountURL: createTrackedURL( MEMBERSHIP_FORM_URL, page.getTracking(), impressionCount, { locale: Locales.DE, type: 'sustaining' } ) + }, + resizeHandler: new WindowResizeHandler(), + banner: Banner, + impressionCount +} ); + +app.use( TranslationPlugin, translator ); +app.provide( 'tracker', tracker ); +app.provide( 'timer', new WindowTimer() ); + +app.mount( page.getBannerContainer() ); diff --git a/banners/thank_you_2024/banner_ctrl.en.ts b/banners/thank_you_2024/banner_ctrl.en.ts new file mode 100644 index 000000000..f4b041c0e --- /dev/null +++ b/banners/thank_you_2024/banner_ctrl.en.ts @@ -0,0 +1,59 @@ +import { createVueApp } from '@src/createVueApp'; + +import './styles/styles_wporg.scss'; + +import PageWPORG from '@src/page/PageWPORG'; +import { SkinFactory } from '@src/page/skin/SkinFactory'; +import { WindowSizeIssueChecker } from '@src/utils/SizeIssueChecker/WindowSizeIssueChecker'; +import { Translator } from '@src/Translator'; +import { WindowMediaWiki } from '@src/page/MediaWiki/WindowMediaWiki'; +import { UrlRuntimeEnvironment } from '@src/utils/RuntimeEnvironment'; +import { LocalImpressionCount } from '@src/utils/LocalImpressionCount'; +import { LegacyTrackerWPORG } from '@src/tracking/LegacyTrackerWPORG'; +import BannerConductor from '@src/components/BannerConductor/BannerConductor.vue'; +import { WindowResizeHandler } from '@src/utils/ResizeHandler'; +import Banner from './components/BannerCtrl.en.vue'; +import messages from './messages.en'; +import eventMappings from './event_map'; +import TranslationPlugin from '@src/TranslationPlugin'; +import { createTrackedURL, MEMBERSHIP_FORM_URL, SUBSCRIBE_URL, USE_OF_FUNDS_URL } from './createTrackedURL'; +import { createThankYouSettings } from './settings'; +import { IntegerEn } from '@src/utils/DynamicContent/formatters/IntegerEn'; +import { Locales } from '@src/domain/Locales'; +import { WindowTimer } from '@src/utils/Timer'; + +const translator = new Translator( messages ); +const mediaWiki = new WindowMediaWiki(); +const page = new PageWPORG( mediaWiki, ( new SkinFactory( mediaWiki ) ).getSkin(), new WindowSizeIssueChecker( 0 ) ); +const runtimeEnvironment = new UrlRuntimeEnvironment( window.location ); +const impressionCount = new LocalImpressionCount( page.getTracking().keyword, runtimeEnvironment ); +const tracker = new LegacyTrackerWPORG( mediaWiki, page.getTracking().keyword, eventMappings, runtimeEnvironment ); + +const app = createVueApp( BannerConductor, { + page, + bannerConfig: { + delay: 0, + transitionDuration: 0 + }, + bannerProps: { + settings: createThankYouSettings( new IntegerEn(), page.getCampaignParameters().thankYouCampaign ), + subscribeURL: createTrackedURL( SUBSCRIBE_URL, page.getTracking(), impressionCount, { locale: Locales.EN } ), + useOfFundsURL: createTrackedURL( USE_OF_FUNDS_URL, page.getTracking(), impressionCount, { locale: Locales.EN } ), + membershipWithAmountURL: createTrackedURL( MEMBERSHIP_FORM_URL, page.getTracking(), impressionCount, { + locale: Locales.EN, + interval: '1', + fee: '200', + type: 'sustaining' + } ), + membershipWithoutAmountURL: createTrackedURL( MEMBERSHIP_FORM_URL, page.getTracking(), impressionCount, { locale: Locales.EN, type: 'sustaining' } ) + }, + resizeHandler: new WindowResizeHandler(), + banner: Banner, + impressionCount +} ); + +app.use( TranslationPlugin, translator ); +app.provide( 'tracker', tracker ); +app.provide( 'timer', new WindowTimer() ); + +app.mount( page.getBannerContainer() ); diff --git a/banners/thank_you_2024/banner_ctrl.wpde.ts b/banners/thank_you_2024/banner_ctrl.wpde.ts new file mode 100644 index 000000000..075ca2dfe --- /dev/null +++ b/banners/thank_you_2024/banner_ctrl.wpde.ts @@ -0,0 +1,61 @@ +import { createVueApp } from '@src/createVueApp'; + +import './styles/styles_wpde.scss'; +import { Translator } from '@src/Translator'; +import { UrlRuntimeEnvironment } from '@src/utils/RuntimeEnvironment'; +import { LocalImpressionCount } from '@src/utils/LocalImpressionCount'; +import BannerConductor from '@src/components/BannerConductor/BannerConductor.vue'; +import { WindowResizeHandler } from '@src/utils/ResizeHandler'; +import Banner from './components/BannerCtrl.de.vue'; +import messages from './messages.de'; +import TranslationPlugin from '@src/TranslationPlugin'; +import { createTrackedURL, MEMBERSHIP_FORM_URL, SUBSCRIBE_URL, USE_OF_FUNDS_URL } from './createTrackedURL'; +import PageWPDE from '@src/page/PageWPDE'; +import { TrackerWPDE } from '@src/tracking/TrackerWPDE'; +import eventMap from './event_map.wpde'; +import { createThankYouSettings } from './settings'; +import { IntegerDe } from '@src/utils/DynamicContent/formatters/IntegerDe'; +import { Locales } from '@src/domain/Locales'; +import { WindowTimer } from '@src/utils/Timer'; + +// Tracking placeholders will be replaced by webpack string-replace-loader +// using the campaign configuration ( campaign_info.toml ) for the correct values +const tracking = { + campaign: '!insert-campaign-here!', + keyword: '!insert-keyword-here!' +}; + +const translator = new Translator( messages ); +const page = new PageWPDE( tracking ); +const runtimeEnvironment = new UrlRuntimeEnvironment( window.location ); +const impressionCount = new LocalImpressionCount( page.getTracking().keyword, runtimeEnvironment ); +const tracker = new TrackerWPDE( 'FundraisingTracker', page.getTracking().keyword, eventMap, runtimeEnvironment ); + +const app = createVueApp( BannerConductor, { + page, + bannerConfig: { + delay: 0, + transitionDuration: 0 + }, + bannerProps: { + settings: createThankYouSettings( new IntegerDe(), page.getCampaignParameters().thankYouCampaign ), + subscribeURL: createTrackedURL( SUBSCRIBE_URL, page.getTracking(), impressionCount, { locale: Locales.DE } ), + useOfFundsURL: createTrackedURL( USE_OF_FUNDS_URL, page.getTracking(), impressionCount, { locale: Locales.DE } ), + membershipWithAmountURL: createTrackedURL( MEMBERSHIP_FORM_URL, page.getTracking(), impressionCount, { + locale: Locales.DE, + interval: '1', + fee: '200', + type: 'sustaining' + } ), + membershipWithoutAmountURL: createTrackedURL( MEMBERSHIP_FORM_URL, page.getTracking(), impressionCount, { locale: Locales.DE, type: 'sustaining' } ) + }, + resizeHandler: new WindowResizeHandler(), + banner: Banner, + impressionCount +} ); + +app.use( TranslationPlugin, translator ); +app.provide( 'tracker', tracker ); +app.provide( 'timer', new WindowTimer() ); + +app.mount( page.getBannerContainer() ); diff --git a/banners/thank_you_2024/banner_var.de.ts b/banners/thank_you_2024/banner_var.de.ts new file mode 100644 index 000000000..7f0190ffc --- /dev/null +++ b/banners/thank_you_2024/banner_var.de.ts @@ -0,0 +1,59 @@ +import { createVueApp } from '@src/createVueApp'; + +import './styles/styles_wporg.scss'; + +import PageWPORG from '@src/page/PageWPORG'; +import { SkinFactory } from '@src/page/skin/SkinFactory'; +import { WindowSizeIssueChecker } from '@src/utils/SizeIssueChecker/WindowSizeIssueChecker'; +import { Translator } from '@src/Translator'; +import { WindowMediaWiki } from '@src/page/MediaWiki/WindowMediaWiki'; +import { UrlRuntimeEnvironment } from '@src/utils/RuntimeEnvironment'; +import { LocalImpressionCount } from '@src/utils/LocalImpressionCount'; +import { LegacyTrackerWPORG } from '@src/tracking/LegacyTrackerWPORG'; +import BannerConductor from '@src/components/BannerConductor/BannerConductor.vue'; +import { WindowResizeHandler } from '@src/utils/ResizeHandler'; +import Banner from './components/BannerVar.de.vue'; +import messages from './messages.de'; +import eventMappings from './event_map'; +import TranslationPlugin from '@src/TranslationPlugin'; +import { createTrackedURL, MEMBERSHIP_FORM_URL, SUBSCRIBE_URL, USE_OF_FUNDS_URL } from './createTrackedURL'; +import { createThankYouSettings } from './settings'; +import { IntegerDe } from '@src/utils/DynamicContent/formatters/IntegerDe'; +import { Locales } from '@src/domain/Locales'; +import { WindowTimer } from '@src/utils/Timer'; + +const translator = new Translator( messages ); +const mediaWiki = new WindowMediaWiki(); +const page = new PageWPORG( mediaWiki, ( new SkinFactory( mediaWiki ) ).getSkin(), new WindowSizeIssueChecker( 0 ) ); +const runtimeEnvironment = new UrlRuntimeEnvironment( window.location ); +const impressionCount = new LocalImpressionCount( page.getTracking().keyword, runtimeEnvironment ); +const tracker = new LegacyTrackerWPORG( mediaWiki, page.getTracking().keyword, eventMappings, runtimeEnvironment ); + +const app = createVueApp( BannerConductor, { + page, + bannerConfig: { + delay: 0, + transitionDuration: 0 + }, + bannerProps: { + settings: createThankYouSettings( new IntegerDe(), page.getCampaignParameters().thankYouCampaign ), + subscribeURL: createTrackedURL( SUBSCRIBE_URL, page.getTracking(), impressionCount, { locale: Locales.DE } ), + useOfFundsURL: createTrackedURL( USE_OF_FUNDS_URL, page.getTracking(), impressionCount, { locale: Locales.DE } ), + membershipWithAmountURL: createTrackedURL( MEMBERSHIP_FORM_URL, page.getTracking(), impressionCount, { + locale: Locales.DE, + interval: '1', + fee: '200', + type: 'sustaining' + } ), + membershipWithoutAmountURL: createTrackedURL( MEMBERSHIP_FORM_URL, page.getTracking(), impressionCount, { locale: Locales.DE, type: 'sustaining' } ) + }, + resizeHandler: new WindowResizeHandler(), + banner: Banner, + impressionCount +} ); + +app.use( TranslationPlugin, translator ); +app.provide( 'tracker', tracker ); +app.provide( 'timer', new WindowTimer() ); + +app.mount( page.getBannerContainer() ); diff --git a/banners/thank_you_2024/banner_var.en.ts b/banners/thank_you_2024/banner_var.en.ts new file mode 100644 index 000000000..1c7c7c43b --- /dev/null +++ b/banners/thank_you_2024/banner_var.en.ts @@ -0,0 +1,59 @@ +import { createVueApp } from '@src/createVueApp'; + +import './styles/styles_wporg.scss'; + +import PageWPORG from '@src/page/PageWPORG'; +import { SkinFactory } from '@src/page/skin/SkinFactory'; +import { WindowSizeIssueChecker } from '@src/utils/SizeIssueChecker/WindowSizeIssueChecker'; +import { Translator } from '@src/Translator'; +import { WindowMediaWiki } from '@src/page/MediaWiki/WindowMediaWiki'; +import { UrlRuntimeEnvironment } from '@src/utils/RuntimeEnvironment'; +import { LocalImpressionCount } from '@src/utils/LocalImpressionCount'; +import { LegacyTrackerWPORG } from '@src/tracking/LegacyTrackerWPORG'; +import BannerConductor from '@src/components/BannerConductor/BannerConductor.vue'; +import { WindowResizeHandler } from '@src/utils/ResizeHandler'; +import Banner from './components/BannerVar.en.vue'; +import messages from './messages.en'; +import eventMappings from './event_map'; +import TranslationPlugin from '@src/TranslationPlugin'; +import { createTrackedURL, MEMBERSHIP_FORM_URL, SUBSCRIBE_URL, USE_OF_FUNDS_URL } from './createTrackedURL'; +import { createThankYouSettings } from './settings'; +import { IntegerEn } from '@src/utils/DynamicContent/formatters/IntegerEn'; +import { Locales } from '@src/domain/Locales'; +import { WindowTimer } from '@src/utils/Timer'; + +const translator = new Translator( messages ); +const mediaWiki = new WindowMediaWiki(); +const page = new PageWPORG( mediaWiki, ( new SkinFactory( mediaWiki ) ).getSkin(), new WindowSizeIssueChecker( 0 ) ); +const runtimeEnvironment = new UrlRuntimeEnvironment( window.location ); +const impressionCount = new LocalImpressionCount( page.getTracking().keyword, runtimeEnvironment ); +const tracker = new LegacyTrackerWPORG( mediaWiki, page.getTracking().keyword, eventMappings, runtimeEnvironment ); + +const app = createVueApp( BannerConductor, { + page, + bannerConfig: { + delay: 0, + transitionDuration: 0 + }, + bannerProps: { + settings: createThankYouSettings( new IntegerEn(), page.getCampaignParameters().thankYouCampaign ), + subscribeURL: createTrackedURL( SUBSCRIBE_URL, page.getTracking(), impressionCount, { locale: Locales.EN } ), + useOfFundsURL: createTrackedURL( USE_OF_FUNDS_URL, page.getTracking(), impressionCount, { locale: Locales.EN } ), + membershipWithAmountURL: createTrackedURL( MEMBERSHIP_FORM_URL, page.getTracking(), impressionCount, { + locale: Locales.EN, + interval: '1', + fee: '200', + type: 'sustaining' + } ), + membershipWithoutAmountURL: createTrackedURL( MEMBERSHIP_FORM_URL, page.getTracking(), impressionCount, { locale: Locales.EN, type: 'sustaining' } ) + }, + resizeHandler: new WindowResizeHandler(), + banner: Banner, + impressionCount +} ); + +app.use( TranslationPlugin, translator ); +app.provide( 'tracker', tracker ); +app.provide( 'timer', new WindowTimer() ); + +app.mount( page.getBannerContainer() ); diff --git a/banners/thank_you_2024/banner_var.wpde.ts b/banners/thank_you_2024/banner_var.wpde.ts new file mode 100644 index 000000000..4962da941 --- /dev/null +++ b/banners/thank_you_2024/banner_var.wpde.ts @@ -0,0 +1,61 @@ +import { createVueApp } from '@src/createVueApp'; + +import './styles/styles_wpde.scss'; +import { Translator } from '@src/Translator'; +import { UrlRuntimeEnvironment } from '@src/utils/RuntimeEnvironment'; +import { LocalImpressionCount } from '@src/utils/LocalImpressionCount'; +import BannerConductor from '@src/components/BannerConductor/BannerConductor.vue'; +import { WindowResizeHandler } from '@src/utils/ResizeHandler'; +import Banner from './components/BannerVar.de.vue'; +import messages from './messages.de'; +import TranslationPlugin from '@src/TranslationPlugin'; +import { createTrackedURL, MEMBERSHIP_FORM_URL, SUBSCRIBE_URL, USE_OF_FUNDS_URL } from './createTrackedURL'; +import PageWPDE from '@src/page/PageWPDE'; +import { TrackerWPDE } from '@src/tracking/TrackerWPDE'; +import eventMap from './event_map.wpde'; +import { createThankYouSettings } from './settings'; +import { IntegerDe } from '@src/utils/DynamicContent/formatters/IntegerDe'; +import { Locales } from '@src/domain/Locales'; +import { WindowTimer } from '@src/utils/Timer'; + +// Tracking placeholders will be replaced by webpack string-replace-loader +// using the campaign configuration ( campaign_info.toml ) for the correct values +const tracking = { + campaign: '!insert-campaign-here!', + keyword: '!insert-keyword-here!' +}; + +const translator = new Translator( messages ); +const page = new PageWPDE( tracking ); +const runtimeEnvironment = new UrlRuntimeEnvironment( window.location ); +const impressionCount = new LocalImpressionCount( page.getTracking().keyword, runtimeEnvironment ); +const tracker = new TrackerWPDE( 'FundraisingTracker', page.getTracking().keyword, eventMap, runtimeEnvironment ); + +const app = createVueApp( BannerConductor, { + page, + bannerConfig: { + delay: 0, + transitionDuration: 0 + }, + bannerProps: { + settings: createThankYouSettings( new IntegerDe(), page.getCampaignParameters().thankYouCampaign ), + subscribeURL: createTrackedURL( SUBSCRIBE_URL, page.getTracking(), impressionCount, { locale: Locales.DE } ), + useOfFundsURL: createTrackedURL( USE_OF_FUNDS_URL, page.getTracking(), impressionCount, { locale: Locales.DE } ), + membershipWithAmountURL: createTrackedURL( MEMBERSHIP_FORM_URL, page.getTracking(), impressionCount, { + locale: Locales.DE, + interval: '1', + fee: '200', + type: 'sustaining' + } ), + membershipWithoutAmountURL: createTrackedURL( MEMBERSHIP_FORM_URL, page.getTracking(), impressionCount, { locale: Locales.DE, type: 'sustaining' } ) + }, + resizeHandler: new WindowResizeHandler(), + banner: Banner, + impressionCount +} ); + +app.use( TranslationPlugin, translator ); +app.provide( 'tracker', tracker ); +app.provide( 'timer', new WindowTimer() ); + +app.mount( page.getBannerContainer() ); diff --git a/banners/thank_you_2024/components/BannerCtrl.de.vue b/banners/thank_you_2024/components/BannerCtrl.de.vue new file mode 100644 index 000000000..17c215cb6 --- /dev/null +++ b/banners/thank_you_2024/components/BannerCtrl.de.vue @@ -0,0 +1,110 @@ + + + diff --git a/banners/thank_you_2024/components/BannerCtrl.en.vue b/banners/thank_you_2024/components/BannerCtrl.en.vue new file mode 100644 index 000000000..0e0508d89 --- /dev/null +++ b/banners/thank_you_2024/components/BannerCtrl.en.vue @@ -0,0 +1,110 @@ + + + diff --git a/banners/thank_you_2024/components/BannerVar.de.vue b/banners/thank_you_2024/components/BannerVar.de.vue new file mode 100644 index 000000000..17c215cb6 --- /dev/null +++ b/banners/thank_you_2024/components/BannerVar.de.vue @@ -0,0 +1,110 @@ + + + diff --git a/banners/thank_you_2024/components/BannerVar.en.vue b/banners/thank_you_2024/components/BannerVar.en.vue new file mode 100644 index 000000000..0e0508d89 --- /dev/null +++ b/banners/thank_you_2024/components/BannerVar.en.vue @@ -0,0 +1,110 @@ + + + diff --git a/banners/thank_you_2024/components/CloseButton.vue b/banners/thank_you_2024/components/CloseButton.vue new file mode 100644 index 000000000..b35b761d2 --- /dev/null +++ b/banners/thank_you_2024/components/CloseButton.vue @@ -0,0 +1,23 @@ + + + diff --git a/banners/thank_you_2024/components/FullPageBanner.vue b/banners/thank_you_2024/components/FullPageBanner.vue new file mode 100644 index 000000000..900964d0d --- /dev/null +++ b/banners/thank_you_2024/components/FullPageBanner.vue @@ -0,0 +1,57 @@ + + + diff --git a/banners/thank_you_2024/components/MiniBanner.vue b/banners/thank_you_2024/components/MiniBanner.vue new file mode 100644 index 000000000..e0acc4969 --- /dev/null +++ b/banners/thank_you_2024/components/MiniBanner.vue @@ -0,0 +1,28 @@ + + + diff --git a/banners/thank_you_2024/components/ProgressBar.vue b/banners/thank_you_2024/components/ProgressBar.vue new file mode 100644 index 000000000..47633bedf --- /dev/null +++ b/banners/thank_you_2024/components/ProgressBar.vue @@ -0,0 +1,34 @@ + + + diff --git a/banners/thank_you_2024/components/StatsBox.vue b/banners/thank_you_2024/components/StatsBox.vue new file mode 100644 index 000000000..46442ec8d --- /dev/null +++ b/banners/thank_you_2024/components/StatsBox.vue @@ -0,0 +1,53 @@ + diff --git a/banners/thank_you_2024/content/ExecutiveDirectorsImage.vue b/banners/thank_you_2024/content/ExecutiveDirectorsImage.vue new file mode 100644 index 000000000..39b3530e7 --- /dev/null +++ b/banners/thank_you_2024/content/ExecutiveDirectorsImage.vue @@ -0,0 +1,11 @@ + diff --git a/banners/thank_you_2024/content/ListTick.vue b/banners/thank_you_2024/content/ListTick.vue new file mode 100644 index 000000000..28e771afc --- /dev/null +++ b/banners/thank_you_2024/content/ListTick.vue @@ -0,0 +1,7 @@ + diff --git a/banners/thank_you_2024/content/MembershipBenefits.de.vue b/banners/thank_you_2024/content/MembershipBenefits.de.vue new file mode 100644 index 000000000..d5f1c4791 --- /dev/null +++ b/banners/thank_you_2024/content/MembershipBenefits.de.vue @@ -0,0 +1,11 @@ + + diff --git a/banners/thank_you_2024/content/MembershipBenefits.en.vue b/banners/thank_you_2024/content/MembershipBenefits.en.vue new file mode 100644 index 000000000..9ca92bef0 --- /dev/null +++ b/banners/thank_you_2024/content/MembershipBenefits.en.vue @@ -0,0 +1,11 @@ + + diff --git a/banners/thank_you_2024/content/win/FullPageBannerText.de.vue b/banners/thank_you_2024/content/win/FullPageBannerText.de.vue new file mode 100644 index 000000000..c95d47cfc --- /dev/null +++ b/banners/thank_you_2024/content/win/FullPageBannerText.de.vue @@ -0,0 +1,54 @@ + + diff --git a/banners/thank_you_2024/content/win/FullPageBannerText.en.vue b/banners/thank_you_2024/content/win/FullPageBannerText.en.vue new file mode 100644 index 000000000..3d5221c64 --- /dev/null +++ b/banners/thank_you_2024/content/win/FullPageBannerText.en.vue @@ -0,0 +1,53 @@ + + diff --git a/banners/thank_you_2024/content/win/MiniBannerText.de.vue b/banners/thank_you_2024/content/win/MiniBannerText.de.vue new file mode 100644 index 000000000..2a5f17651 --- /dev/null +++ b/banners/thank_you_2024/content/win/MiniBannerText.de.vue @@ -0,0 +1,18 @@ + + + diff --git a/banners/thank_you_2024/content/win/MiniBannerText.en.vue b/banners/thank_you_2024/content/win/MiniBannerText.en.vue new file mode 100644 index 000000000..21df9e2c3 --- /dev/null +++ b/banners/thank_you_2024/content/win/MiniBannerText.en.vue @@ -0,0 +1,19 @@ + + + diff --git a/banners/thank_you_2024/createTrackedURL.ts b/banners/thank_you_2024/createTrackedURL.ts new file mode 100644 index 000000000..b275de7da --- /dev/null +++ b/banners/thank_you_2024/createTrackedURL.ts @@ -0,0 +1,19 @@ +/* eslint-disable camelcase */ +import { TrackingParameters } from '@src/domain/TrackingParameters'; +import { ImpressionCount } from '@src/utils/ImpressionCount'; + +export const SUBSCRIBE_URL = 'https://www.wikimedia.de/mitglieder/'; +export const USE_OF_FUNDS_URL = 'https://spenden.wikimedia.de/use-of-funds/'; +export const MEMBERSHIP_FORM_URL = 'https://spenden.wikimedia.de/use-of-funds/'; + +export function createTrackedURL( url: string, tracking: TrackingParameters, impressionCount: ImpressionCount, extraUrlParameters: Record = {} ): string { + const urlParameters = new URLSearchParams( { + piwik_kwd: tracking.keyword, + piwik_campaign: tracking.campaign, + impCount: String( impressionCount.overallCountIncremented ), + bImpCount: String( impressionCount.bannerCountIncremented ), + ...extraUrlParameters + } ); + + return `${url}?${urlParameters}`; +} diff --git a/banners/thank_you_2024/event_map.ts b/banners/thank_you_2024/event_map.ts new file mode 100644 index 000000000..645a6cf0d --- /dev/null +++ b/banners/thank_you_2024/event_map.ts @@ -0,0 +1,25 @@ +import { TrackingEventConverterFactory } from '@src/tracking/LegacyTrackerWPORG'; +import { BannerSubmitEvent } from '@src/tracking/events/BannerSubmitEvent'; +import { WMDESizeIssueEvent } from '@src/tracking/WPORG/WMDEBannerSizeIssue'; +import { createViewportInfo } from '@src/tracking/LegacyEventTracking/createViewportInfo'; +import { ThankYouModalShownEvent } from '@src/tracking/events/ThankYouModalShownEvent'; +import { WMDELegacyBannerEvent } from '@src/tracking/WPORG/WMDELegacyBannerEvent'; +import { CloseEvent } from '@src/tracking/events/CloseEvent'; +import { mapCloseEvent } from '@src/tracking/LegacyEventTracking/mapCloseEvent'; +import { NotShownEvent } from '@src/tracking/events/NotShownEvent'; +import { mapNotShownEvent } from '@src/tracking/LegacyEventTracking/mapNotShownEvent'; + +export default new Map( [ + [ NotShownEvent.EVENT_NAME, mapNotShownEvent ], + [ CloseEvent.EVENT_NAME, mapCloseEvent ], + [ + BannerSubmitEvent.EVENT_NAME, + ( e: BannerSubmitEvent ): WMDESizeIssueEvent => { + return new WMDESizeIssueEvent( `submit-${e.userChoice}`, createViewportInfo(), 1 ); + } + ], + [ + ThankYouModalShownEvent.EVENT_NAME, + ( e: ThankYouModalShownEvent ): WMDELegacyBannerEvent => new WMDELegacyBannerEvent( e.eventName, 1 ) + ] +] ); diff --git a/banners/thank_you_2024/event_map.wpde.ts b/banners/thank_you_2024/event_map.wpde.ts new file mode 100644 index 000000000..5d871bc14 --- /dev/null +++ b/banners/thank_you_2024/event_map.wpde.ts @@ -0,0 +1,11 @@ +import { BannerSubmitEvent } from '@src/tracking/events/BannerSubmitEvent'; +import { ThankYouModalShownEvent } from '@src/tracking/events/ThankYouModalShownEvent'; +import { CloseEvent } from '@src/tracking/events/CloseEvent'; +import { NotShownEvent } from '@src/tracking/events/NotShownEvent'; + +export default new Map( [ + [ NotShownEvent.EVENT_NAME, 1 ], + [ CloseEvent.EVENT_NAME, 0.1 ], + [ ThankYouModalShownEvent.EVENT_NAME, 1 ], + [ BannerSubmitEvent.EVENT_NAME, 1 ] +] ); diff --git a/banners/thank_you_2024/messages.de.ts b/banners/thank_you_2024/messages.de.ts new file mode 100644 index 000000000..237f00e65 --- /dev/null +++ b/banners/thank_you_2024/messages.de.ts @@ -0,0 +1,21 @@ +import { TranslationMessages } from '@src/Translator'; + +const messages: TranslationMessages = { + 'progress-bar-inner-text-win': 'Spendenziel erreicht!', + 'progress-bar-inner-text-lose': 'Nicht geschafft', + 'mini-read-more-button': 'So geht es jetzt weiter', + 'close': 'schließen', + 'close-full-page': 'Dankestext schließen', + 'call-to-action-more-info': 'Weitere Informationen auf unserer Webseite', + 'use-of-funds': 'Was Ihre Spende bewirkt', + 'call-to-action-button-amount-per-month': 'Mit {{amount}} € im Monat fördern', + 'call-to-action-button-different-amount': 'Mit anderem Betrag fördern', + 'stats-people-amount': '109.500', + 'stats-people-text': 'Mitglieder', + 'stats-average-amount': '5 €', + 'stats-average-text': 'durchschnittlicher Monatsbeitrag', + 'stats-contribution-amount': '2 €', + 'stats-contribution-text': 'Mindestbeitrag im Monat' +}; + +export default messages; diff --git a/banners/thank_you_2024/messages.en.ts b/banners/thank_you_2024/messages.en.ts new file mode 100644 index 000000000..653ad918b --- /dev/null +++ b/banners/thank_you_2024/messages.en.ts @@ -0,0 +1,21 @@ +import { TranslationMessages } from '@src/Translator'; + +const messages: TranslationMessages = { + 'progress-bar-inner-text-win': 'Target reached!', + 'progress-bar-inner-text-lose': 'We didn\'t make it', + 'mini-read-more-button': 'Read about how we\'ll use it', + 'close': 'schließen', + 'close-full-page': 'Close thank you message', + 'call-to-action-more-info': 'For more information, please visit our website', + 'use-of-funds': 'Where does my donation go?', + 'call-to-action-button-amount-per-month': 'Support with €{{amount}} per month', + 'call-to-action-button-different-amount': 'Support with a custom amount', + 'stats-people-amount': '109.500', + 'stats-people-text': 'members', + 'stats-average-amount': '€5', + 'stats-average-text': 'average monthly membership fee', + 'stats-contribution-amount': '€2', + 'stats-contribution-text': 'monthly minimum contribution' +}; + +export default messages; diff --git a/banners/thank_you_2024/settings.ts b/banners/thank_you_2024/settings.ts new file mode 100644 index 000000000..b0e497ca4 --- /dev/null +++ b/banners/thank_you_2024/settings.ts @@ -0,0 +1,14 @@ +import { Integer } from '@src/utils/DynamicContent/formatters/Integer'; +import { ThankYouCampaignParameters } from '@src/domain/CampaignParameters'; + +export interface ThankYouSettings { + numberOfDonors: string; + progressBarPercentage: number; +} + +export function createThankYouSettings( formatter: Integer, campaignParameters: ThankYouCampaignParameters ): ThankYouSettings { + return { + numberOfDonors: formatter.format( campaignParameters.numberOfDonors ), + progressBarPercentage: campaignParameters.progressBarPercentage + }; +} diff --git a/banners/thank_you_2024/styles/Banner.scss b/banners/thank_you_2024/styles/Banner.scss new file mode 100644 index 000000000..c467f431b --- /dev/null +++ b/banners/thank_you_2024/styles/Banner.scss @@ -0,0 +1,9 @@ +@use './variables/fonts'; + +.wmde-banner { + font-family: fonts.$content; + + &, * { + box-sizing: border-box; + } +} diff --git a/banners/thank_you_2024/styles/CloseButton.scss b/banners/thank_you_2024/styles/CloseButton.scss new file mode 100644 index 000000000..b87363042 --- /dev/null +++ b/banners/thank_you_2024/styles/CloseButton.scss @@ -0,0 +1,24 @@ +.wmde-banner { + &-close { + all: unset; + position: absolute; + top: 10px; + right: 10px; + height: 36px; + line-height: 36px; + min-width: 36px; + text-align: center; + cursor: pointer; + transition: opacity 200ms ease-in-out; + + svg { + position: relative; + top: 4px; + } + + &:hover, + &:focus { + opacity: 0.5; + } + } +} diff --git a/banners/thank_you_2024/styles/ExecutiveDirectors.scss b/banners/thank_you_2024/styles/ExecutiveDirectors.scss new file mode 100644 index 000000000..dc73178ae --- /dev/null +++ b/banners/thank_you_2024/styles/ExecutiveDirectors.scss @@ -0,0 +1,41 @@ +@use './variables/breakpoints'; + +.wmde-banner { + &-eds { + max-width: 264px; + margin: 0 auto 16px; + + @include breakpoints.x-small-up { + float: right; + padding-left: 16px; + } + + @include breakpoints.small-up { + float: none; + padding-left: 0; + } + + img { + margin: 0 0 12px; + } + + p { + font-size: 12px; + margin: 0; + } + + .wmde-banner-eds-copyright { + font-size: 10px; + + a { + color: var( --link-color ); + transition: color 200ms ease-in-out; + + &:hover, + &:focus { + color: var( --link-color-hover ); + } + } + } + } +} diff --git a/banners/thank_you_2024/styles/FullPageBanner.scss b/banners/thank_you_2024/styles/FullPageBanner.scss new file mode 100644 index 000000000..5c5c9417a --- /dev/null +++ b/banners/thank_you_2024/styles/FullPageBanner.scss @@ -0,0 +1,269 @@ +@use './variables/breakpoints'; + +@keyframes fade-in { + 0% { + opacity: 0; + transform: scale( 1.1 ) translateY(-50%); + display: none; + } + + 100% { + opacity: 1; + transform: scale( 1 ) translateY(-50%); + display: block; + } +} + +@keyframes fade-out { + 0% { + opacity: 1; + transform: scale( 1.1 ) translateY(-50%); + display: block; + } + + 100% { + opacity: 0; + transform: scale( 0 ) translateY(-50%); + display: none; + } +} + +.wmde-banner { + &-full { + animation: fade-out 500ms ease-in-out; + width: 100vw; + max-width: 1200px; + height: fit-content; + max-height: 100vh; + height: -webkit-fill-available; + background: var( --full-background ); + color: var( --full-color ); + margin: 0 auto; + border: 0; + padding: 0; + + // This vertically centers the dialog, it needs to be tested more + top: 50%; + transform: translateY(-50%); + + @include breakpoints.small-up { + max-height: calc( 100vh - 80px ); + margin: 40px auto; + } + + &[ open ] { + animation: fade-in 500ms ease-in-out; + } + + &::backdrop { + background-color: rgb( 0 0 0 / 80% ); + } + + .wmde-banner-close { + top: 12px; + right: 20px; + } + + &-content { + display: flex; + flex-wrap: nowrap; + padding: 50px 20px 0; + + @include breakpoints.small-up { + padding: 30px 40px 0; + } + + article { + padding-right: 16px; + } + + aside { + margin: 30px 0 0; + flex: 0 0 264px; + width: 264px; + display: none; + + @include breakpoints.small-up { + display: block; + } + } + } + + h2 { + all: unset; + display: block; + color: var( --full-heading-color ); + font-size: 20px; + line-height: 1.5; + margin-bottom: 24px; + + @include breakpoints.small-up { + font-size: 24px; + margin-bottom: 40px; + } + } + + p { + font-size: 16px; + line-height: 1.5; + margin: 0 0 16px; + } + + .highlight { + background: var( --full-highlight-background ); + } + + footer { + background: var( --footer-background ); + padding: 20px 20px 10px; + + @include breakpoints.small-up { + padding: 30px 40px; + } + } + } + + &-content-columns { + @include breakpoints.medium-up { + columns: 2; + } + } + + &-mobile-only { + @include breakpoints.small-up { + display: none; + } + } + + &-full-cta { + padding: 20px 20px 10px; + text-align: center; + font-size: 16px; + font-weight: bold; + + @include breakpoints.small-up { + font-size: 18px; + padding: 30px 40px; + } + + a { + display: inline-block; + margin: 0 0 16px; + line-height: 54px; + width: 100%; + border-radius: 5px; + transition: background 200ms ease-in-out; + + @include breakpoints.x-small-up { + width: 360px; + } + + @include breakpoints.small-up { + margin: 0 12px 16px; + } + + &:hover, + &:focus { + text-decoration: none; + } + } + + &-with { + background: var( --cta-with-button-background ); + color: var( --cta-with-button-color ); + + &:hover, + &:focus { + color: var( --cta-with-button-color ); + background: var( --cta-with-button-background-hover ); + } + } + + &-without { + background: var( --cta-without-button-background ); + color: var( --cta-without-button-color ); + + &:hover, + &:focus { + color: var( --cta-without-button-color ); + background: var( --cta-without-button-background-hover ); + } + } + } + + &-benefits { + list-style-type: none; + list-style-image: none; + margin: 0 0 16px; + padding: 0; + font-weight: bold; + + @include breakpoints.small-up { + display: flex; + flex-wrap: wrap; + } + + @include breakpoints.large-up { + flex-wrap: nowrap; + } + + li { + position: relative; + padding: 0 10px 0 30px; + margin-bottom: 16px; + overflow-wrap: break-word; + + @include breakpoints.small-up { + width: 50%; + } + + @include breakpoints.large-up { + width: 25%; + } + } + } + + &-subscribe { + text-align: left; + font-size: 14px; + line-height: 1.5; + + @include breakpoints.small-up { + font-size: 16px; + text-align: center; + } + + a { + display: block; + color: var( --link-color ); + text-decoration: underline; + margin-bottom: 10px; + transition: color 200ms ease-in-out; + + @include breakpoints.small-up { + padding: 0 20px; + display: inline; + } + + &:hover, + &:focus { + color: var( --link-color-hover ); + } + } + } + + &-list-tick { + position: absolute; + background: var( --list-tick-background ); + display: inline-block; + height: 22px; + width: 22px; + left: 0; + border-radius: 50%; + + svg { + position: relative; + left: 5px; + } + } +} \ No newline at end of file diff --git a/banners/thank_you_2024/styles/MiniBanner.scss b/banners/thank_you_2024/styles/MiniBanner.scss new file mode 100644 index 000000000..1cd09b22a --- /dev/null +++ b/banners/thank_you_2024/styles/MiniBanner.scss @@ -0,0 +1,122 @@ +@use './variables/fonts'; +@use './variables/breakpoints'; + +$height: 248px !default; + +@keyframes showLetter { + 0% { + transform: scale( 0.5 ); + } + + 100% { + transform: scale( 1 ); + } +} + +.wmde-banner { + &-mini { + background: var( --mini-background ); + box-shadow: var( --mini-box-shadow ); + display: flex; + flex-direction: column; + min-height: $height; + position: relative; + padding: 20px 20px 10px; + + @include breakpoints.small-up { + padding: 30px 40px; + } + + .wmde-banner-close { + top: 10px; + right: 10px; + + &-label { + display: none; + } + } + + &-content { + margin-bottom: 16px; + text-align: center; + + @include breakpoints.small-up { + display: flex; + justify-content: center; + align-items: center; + gap: 40px; + text-align: left; + } + } + + h2 { + all: unset; + display: block; + font-family: fonts.$header; + font-size: 60px; + white-space: nowrap; + margin-bottom: 16px; + + @include breakpoints.small-up { + margin-bottom: 0; + font-size: 90px; + } + + span { + transform: scale( 0.5 ); + display: inline-block; + } + } + + p { + padding: 0; + margin: 0; + font-size: 14px; + + @include breakpoints.small-up { + font-size: 16px; + } + + @include breakpoints.medium-up { + font-size: 18px; + } + + @include breakpoints.large-up { + font-size: 22px; + } + } + + &-actions { + text-align: center; + } + + &-read-more { + all: unset; + background: var( --read-more-background ); + color: var( --read-more-color ); + height: 36px; + padding: 0 20px; + border-radius: 5px; + margin: 0 18px 16px; + cursor: pointer; + font-size: 16px; + transition: background 200ms ease-in-out; + + @include breakpoints.small-up { + margin: 0 18px; + } + &:hover, + &:focus { + background: var( --read-more-background-hover ); + } + } + } + + &--visible { + .wmde-banner-mini h2 > span { + animation: showLetter 2s cubic-bezier( 0, 1.13, .46, 1.97 ); + animation-fill-mode: forwards; + animation-delay: calc( 0.08s * var( --index ) ); + } + } +} diff --git a/banners/thank_you_2024/styles/ProgressBar.scss b/banners/thank_you_2024/styles/ProgressBar.scss new file mode 100644 index 000000000..29b77f3ef --- /dev/null +++ b/banners/thank_you_2024/styles/ProgressBar.scss @@ -0,0 +1,161 @@ +@use './variables/breakpoints'; + +.wmde-banner { + &-progress-bar { + border: 3px solid var( --progress-border ); + height: 34px; + border-radius: 17px; + display: flex; + flex-direction: column; + position: relative; + margin-bottom: 16px; + + @include breakpoints.small-up { + margin-bottom: 34px; + } + + &-fill { + background: var( --progress-fill-background ); + color: var( --progress-color ); + line-height: 28px; + border-radius: 14px; + position: absolute; + left: 0; + height: 100%; + width: 10%; + max-width: 100%; + padding: 0 20px; + font-size: 14px; + font-weight: bold; + transition: width 3000ms ease-in-out; + + &-text { + opacity: 0; + transition: opacity 300ms ease-in-out; + transition-delay: 3000ms; + } + + &-icon { + border: 2px solid var( --progress-fill-icon-border ); + background: var( --progress-fill-icon-background ); + position: absolute; + height: 34px; + width: 34px; + border-radius: 17px; + top: -3px; + right: -3px; + + svg { + position: relative; + left: 7px; + transform: scale( 0 ); + transition: transform 300ms ease-in-out; + transition-delay: 3000ms; + } + + .confetti { + position: absolute; + height: 0; + width: 0; + top: 50%; + left: 50%; + + > span { + position: absolute; + background: var( --progress-fill-icon-content ); + height: 2px; + width: 0; + transition: top 200ms ease-in, width 200ms ease-in; + transition-delay: calc( 3000ms + 0.08s * var( --index ) ); + } + } + + .confetti-1 { + transform: rotate( 34.03deg ); + top: 0; + left: 0; + } + + .confetti-2 { + transform: rotate( -86.03deg ); + top: 0; + left: 0; + } + + .confetti-3 { + transform: rotate( -45deg ); + top: 0; + right: 0; + } + + .confetti-4 { + transform: rotate( -2.01deg ); + top: 0; + right: 0; + } + + .confetti-5 { + transform: rotate( 34.03deg ); + bottom: 0; + right: 0; + } + + .confetti-6 { + transform: rotate( 86.03deg ); + bottom: 0; + left: 0; + } + } + } + } + + &--visible { + .wmde-banner-progress-bar-fill { + width: var( --wmde-banner-progress-bar-width ); + + &-text { + opacity: 1; + } + + &-icon { + svg { + transform: scale( 1 ); + } + + .confetti > span { + width: 8px; + } + + .confetti-1 { + top: -26px; + left: -22px; + } + + .confetti-2 { + top: -32px; + left: 0; + } + + .confetti-3 { + top: -26px; + right: -26px; + } + + .confetti-4 { + top: 0; + right: -32px; + } + + .confetti-5 { + bottom: -22px; + right: -26px; + } + + .confetti-6 { + bottom: -32px; + left: -4px; + } + } + } + } +} diff --git a/banners/thank_you_2024/styles/StatsBox.scss b/banners/thank_you_2024/styles/StatsBox.scss new file mode 100644 index 000000000..e48d038b8 --- /dev/null +++ b/banners/thank_you_2024/styles/StatsBox.scss @@ -0,0 +1,28 @@ +.wmde-banner { + &-stats { + border-top: 2px solid var( --stats-border ); + list-style-type: none; + list-style-image: none; + padding: 0; + margin: 0 0 16px; + font-size: 14px; + + li { + display: flex; + align-items: center; + border-bottom: 2px solid var( --stats-border ); + margin: 0; + height: 100px; + } + + strong { + color: var( --stats-bold-color ); + font-size: 20px; + } + + &-icon { + flex: 0 0 100px; + text-align: center; + } + } +} \ No newline at end of file diff --git a/banners/thank_you_2024/styles/styles_wpde.scss b/banners/thank_you_2024/styles/styles_wpde.scss new file mode 100644 index 000000000..1e1d48b5c --- /dev/null +++ b/banners/thank_you_2024/styles/styles_wpde.scss @@ -0,0 +1,9 @@ +@use './swatches/skin_default'; +@use 'src/components/BannerConductor/banner-transition'; +@use './Banner'; +@use './CloseButton'; +@use './MiniBanner'; +@use './ProgressBar'; +@use './FullPageBanner'; +@use './ExecutiveDirectors'; +@use './StatsBox'; diff --git a/banners/thank_you_2024/styles/styles_wporg.scss b/banners/thank_you_2024/styles/styles_wporg.scss new file mode 100644 index 000000000..aeb94f6ed --- /dev/null +++ b/banners/thank_you_2024/styles/styles_wporg.scss @@ -0,0 +1,9 @@ +@use './swatches/skin_wporg'; +@use 'src/components/BannerConductor/banner-transition'; +@use './Banner'; +@use './CloseButton'; +@use './MiniBanner'; +@use './ProgressBar'; +@use './FullPageBanner'; +@use './ExecutiveDirectors'; +@use './StatsBox'; diff --git a/banners/thank_you_2024/styles/swatches/color_dark.scss b/banners/thank_you_2024/styles/swatches/color_dark.scss new file mode 100644 index 000000000..a4bc83ea6 --- /dev/null +++ b/banners/thank_you_2024/styles/swatches/color_dark.scss @@ -0,0 +1,63 @@ +@use 'sass:color'; + +$black: #000000; +$white: #ffffff; + +$grey200: #d9d9d9; +$grey500: #555555; +$grey800: #242424; + +$sea-blue100: #43e5c5; +$sea-blue300: #0ea789; + +$blue50: #c3d9eb; +$blue200: #8bb8da; +$blue300: #0e75c4; +$blue400: #45779d; +$blue600: #344c5e; + +@mixin swatch() { + --text-color: #{$white}; + --close-icon-stroke: #{$white}; + + --mini-background: #{$grey800}; + --mini-box-shadow: none; + + --progress-border: #{$sea-blue300}; + --progress-color: #{$white}; + --progress-fill-background: #{$sea-blue300}; + --progress-fill-icon-border: #{$grey800}; + --progress-fill-icon-background: #{$sea-blue100}; + --progress-fill-icon-content: #{$white}; + + --read-more-background: #{$blue300}; + --read-more-background-hover: #{color.adjust( $blue300, $lightness: -5% )}; + --read-more-color: #{$white}; + + --full-background: #{$grey800}; + --full-color: #{$white}; + --full-heading-color: #{$blue200}; + --full-highlight-background: #{$blue600}; + + --stats-border: #{$grey500}; + --stats-bold-color: #{$blue200}; + --stats-people-color: #{$blue200}; + --stats-average-column-color: #{$blue200}; + --stats-average-line-color: #{$white}; + --stats-contribution-background-color: #{$blue200}; + --stats-contribution-line-color: #{$grey800}; + + --cta-with-button-background: #{$blue300}; + --cta-with-button-background-hover: #{color.adjust( $blue300, $lightness: -5% )}; + --cta-with-button-color: #{$white}; + + --cta-without-button-background: #{$grey200}; + --cta-without-button-background-hover: #{color.adjust( $grey200, $lightness: -5% )}; + --cta-without-button-color: #{$black}; + + --footer-background: #{$blue600}; + --list-tick-background: #{$sea-blue300}; + --list-tick-stroke: #{$white}; + --link-color: #{$blue50}; + --link-color-hover: #{color.adjust( $blue50, $lightness: -5% )}; +} diff --git a/banners/thank_you_2024/styles/swatches/color_light.scss b/banners/thank_you_2024/styles/swatches/color_light.scss new file mode 100644 index 000000000..a31ddece8 --- /dev/null +++ b/banners/thank_you_2024/styles/swatches/color_light.scss @@ -0,0 +1,62 @@ +@use 'sass:color'; + +$black: #000000; +$white: #ffffff; + +$grey200: #d9d9d9; + +$sea-blue100: #43e5c5; +$sea-blue300: #0ea789; + +$blue100: #ddf1fd; +$blue110: #d7edff; +$blue300: #0e75c4; +$blue400: #45779d; +$blue500: #005782; +$blue510: #2f516a; + +@mixin swatch() { + --text-color: #{$black}; + --close-icon-stroke: #{$black}; + + --mini-background: #{$white}; + --mini-box-shadow: 0 3px 0.6em rgba( 60 60 60 / 40% ); + + --progress-border: #{$sea-blue300}; + --progress-color: #{$white}; + --progress-fill-background: #{$sea-blue300}; + --progress-fill-icon-border: #{$white}; + --progress-fill-icon-background: #{$sea-blue100}; + --progress-fill-icon-content: #{$black}; + + --read-more-background: #{$blue300}; + --read-more-background-hover: #{color.adjust( $blue300, $lightness: -5% )}; + --read-more-color: #{$white}; + + --full-background: #{$white}; + --full-color: #{$black}; + --full-heading-color: #{$blue500}; + --full-highlight-background: #{$blue110}; + + --stats-border: #{$blue110}; + --stats-bold-color: #{$blue500}; + --stats-people-color: #{$blue400}; + --stats-average-column-color: #{$blue110}; + --stats-average-line-color: #{$blue400}; + --stats-contribution-background-color: #{$blue400}; + --stats-contribution-line-color: #{$white}; + + --cta-with-button-background: #{$blue300}; + --cta-with-button-background-hover: #{color.adjust( $blue300, $lightness: -5% )}; + --cta-with-button-color: #{$white}; + + --cta-without-button-background: #{$grey200}; + --cta-without-button-background-hover: #{color.adjust( $grey200, $lightness: -5% )}; + --cta-without-button-color: #{$black}; + + --footer-background: #{$blue100}; + --list-tick-background: #{$sea-blue100}; + --list-tick-stroke: #{$black}; + --link-color: #{$blue510}; + --link-color-hover: #{color.adjust( $blue510, $lightness: 15% )}; +} diff --git a/banners/thank_you_2024/styles/swatches/skin_default.scss b/banners/thank_you_2024/styles/swatches/skin_default.scss new file mode 100644 index 000000000..b9653a8d7 --- /dev/null +++ b/banners/thank_you_2024/styles/swatches/skin_default.scss @@ -0,0 +1,5 @@ +@use 'color_light'; + +.wmde-banner { + @include color_light.swatch; +} diff --git a/banners/thank_you_2024/styles/swatches/skin_wporg.scss b/banners/thank_you_2024/styles/swatches/skin_wporg.scss new file mode 100644 index 000000000..8852ec19b --- /dev/null +++ b/banners/thank_you_2024/styles/swatches/skin_wporg.scss @@ -0,0 +1,21 @@ +@use 'color_dark'; +@use 'color_light'; + +.wmde-banner, +.skin-theme-clientpref-day .wmde-banner { + @include color_light.swatch; +} + +.skin-theme-clientpref-night .wmde-banner { + @include color_dark.swatch; +} + +.skin-theme-clientpref-os .wmde-banner { + @media ( prefers-color-scheme: dark ) { + @include color_dark.swatch; + } + + @media ( prefers-color-scheme: light ) { + @include color_light.swatch; + } +} diff --git a/banners/thank_you_2024/styles/variables/_breakpoints.scss b/banners/thank_you_2024/styles/variables/_breakpoints.scss new file mode 100644 index 000000000..b69d87811 --- /dev/null +++ b/banners/thank_you_2024/styles/variables/_breakpoints.scss @@ -0,0 +1,37 @@ +$breakpoint-xs: 440px; +$breakpoint-s: 750px; +$breakpoint-m: 1000px; +$breakpoint-l: 1200px; + +/* +MIXIN USAGE: +.my-selector { + @include breakpoints.small-up { + // Stuff that happens when bigger than $small + } +} +*/ + +@mixin x-small-up { + @media ( min-width: $breakpoint-xs ) { + @content; + } +} + +@mixin small-up { + @media ( min-width: $breakpoint-s ) { + @content; + } +} + +@mixin medium-up { + @media ( min-width: $breakpoint-m ) { + @content; + } +} + +@mixin large-up { + @media ( min-width: $breakpoint-l ) { + @content; + } +} diff --git a/banners/thank_you_2024/styles/variables/_fonts.scss b/banners/thank_you_2024/styles/variables/_fonts.scss new file mode 100644 index 000000000..0cc70daf4 --- /dev/null +++ b/banners/thank_you_2024/styles/variables/_fonts.scss @@ -0,0 +1,9 @@ +/* These font stacks come from: https://github.com/system-fonts/modern-font-stacks */ +$-antique: 'Georgia Pro', georgia, superclarendon, 'Bookman Old Style', 'URW Bookman', 'URW Bookman L', serif; +$-neo-grotesque: 'Inter', 'Roboto', 'Helvetica Neue', 'Arial Nova', 'Liberation Sans', 'Arial', sans-serif; + +/* This is only used for the thank you text */ +$header: $-antique !default; + +/* This is all other content */ +$content: $-neo-grotesque !default; diff --git a/campaign_info.thank_you.toml b/campaign_info.thank_you.toml index da65bb263..77cf7daf9 100644 --- a/campaign_info.thank_you.toml +++ b/campaign_info.thank_you.toml @@ -5,23 +5,24 @@ # Thank You Campaign [thank_you] name = "Desktop" -campaign = "C23_WMDE_Desktop_DE_ty" +campaign = "C24_WMDE_Desktop_DE_ty" icon = "desktop" -campaign_tracking = "ty01-240101" +campaign_tracking = "ty01-250101" description = "Thank you banner" preview_link = "/wiki/Wikipedia:Hauptseite?devbanner={{banner}}&banner=B22_WMDE_local_prototype" +preview_link_darkmode = "/wiki/Wikipedia:Hauptseite?devbanner={{banner}}&banner=B22_WMDE_local_prototype&vectornightmode=1" preview_url = 'https://de.wikipedia.org/wiki/Wikipedia:Hauptseite?banner={{PLACEHOLDER}}' wrapper_template = "wikipedia_org" [thank_you.banners.ctrl] -filename = "./banners/thank_you/banner_ctrl.de.ts" -pagename = "B23_WMDE_Desktop_DE_ty_ctrl" -tracking = "org-ty-240101-ctrl" +filename = "./banners/thank_you_2024/banner_ctrl.de.ts" +pagename = "B24_WMDE_Desktop_DE_ty_ctrl" +tracking = "org-ty-250101-ctrl" [thank_you.banners.var] -filename = "./banners/thank_you/banner_var.de.ts" -pagename = "B23_WMDE_Desktop_DE_ty_var" -tracking = "org-ty-240101-var" +filename = "./banners/thank_you_2024/banner_var.de.ts" +pagename = "B24_WMDE_Desktop_DE_ty_var" +tracking = "org-ty-250101-var" [thank_you.test_matrix] platform = ["edge", "ie11", "firefox_win10", "chrome_win10", "safari", "firefox_macos", "chrome_macos", "firefox_linux", "chrome_linux"] @@ -30,23 +31,24 @@ resolution = ["800x600", "1024x768", "1280x960", "1600x1200", "1920x1200", "2560 [thank_you_en] name = "English Desktop" -campaign = "C23_WMDE_Desktop_EN_ty" +campaign = "C24_WMDE_Desktop_EN_ty" icon = "desktop" -campaign_tracking = "ty01-240101" +campaign_tracking = "ty01-250101" description = "Thank you banner" preview_link = "/wiki/Main_Page?devbanner={{banner}}&banner=B22_WMDE_local_prototype" +preview_link_darkmode = "/wiki/Main_Page?devbanner={{banner}}&banner=B22_WMDE_local_prototype&vectornightmode=1" preview_url = 'https://en.wikipedia.org/wiki/Main_Page?banner={{PLACEHOLDER}}' wrapper_template = "wikipedia_org" [thank_you_en.banners.ctrl] -filename = "./banners/thank_you/banner_ctrl.en.ts" -pagename = "B23_WMDE_Desktop_EN_ty_ctrl" -tracking = "org-ty-240101-en-ctrl" +filename = "./banners/thank_you_2024/banner_ctrl.en.ts" +pagename = "B24_WMDE_Desktop_EN_ty_ctrl" +tracking = "org-ty-250101-en-ctrl" [thank_you_en.banners.var] -filename = "./banners/thank_you/banner_var.en.ts" -pagename = "B23_WMDE_Desktop_EN_ty_var" -tracking = "org-ty-240101-en-var" +filename = "./banners/thank_you_2024/banner_var.en.ts" +pagename = "B24_WMDE_Desktop_EN_ty_var" +tracking = "org-ty-250101-en-var" [thank_you_en.test_matrix] platform = ["edge", "ie11", "firefox_win10", "chrome_win10", "safari", "firefox_macos", "chrome_macos", "firefox_linux", "chrome_linux"] @@ -55,23 +57,24 @@ resolution = ["800x600", "1024x768", "1280x960", "1600x1200", "1920x1200", "2560 # Thank you campaign mobile wp.org [thank_you_mobile] name = "Mobile" -campaign = "C23_WMDE_Mobile_DE_ty" +campaign = "C24_WMDE_Mobile_DE_ty" icon = "mobile" -campaign_tracking = "ty01-mob-240101" +campaign_tracking = "ty01-mob-250101" description = "Thank you banner" preview_link = "/mobile/wiki/Wikipedia:Hauptseite?devbanner={{banner}}&useskin=minerva&banner=B22_WMDE_local_prototype" +preview_link_darkmode = "/mobile/wiki/Wikipedia:Hauptseite?devbanner={{banner}}&useskin=minerva&banner=B22_WMDE_local_prototype&minervanightmode=1" preview_url = 'https://de.m.wikipedia.org/wiki/Wikipedia:Hauptseite?banner={{PLACEHOLDER}}' wrapper_template = "wikipedia_org" [thank_you_mobile.banners.ctrl] -filename = "./banners/thank_you/banner_ctrl.de.ts" -pagename = "B23_WMDE_Mobile_DE_ty_ctrl" -tracking = "org-mob-ty-240101-ctrl" +filename = "./banners/thank_you_2024/banner_ctrl.de.ts" +pagename = "B24_WMDE_Mobile_DE_ty_ctrl" +tracking = "org-mob-ty-250101-ctrl" [thank_you_mobile.banners.var] -filename = "./banners/thank_you/banner_var.de.ts" -pagename = "B23_WMDE_Mobile_DE_ty_var" -tracking = "org-mob-ty-240101-var" +filename = "./banners/thank_you_2024/banner_var.de.ts" +pagename = "B24_WMDE_Mobile_DE_ty_var" +tracking = "org-mob-ty-250101-var" [thank_you_mobile.test_matrix] device = [ 'samsung_s10', 'iphone_xs_max', 'iphone_5s', 'iphone_se', "iphone_8", "iphone_12_mini", "iphone_7_plus", "iphone_11_pro_max"] @@ -80,23 +83,24 @@ orientation = [ "portrait", "landscape"] # English Thank you campaign mobile wp.org [thank_you_mobile_en] name = "English Mobile" -campaign = "C23_WMDE_Mobile_EN_ty" +campaign = "C24_WMDE_Mobile_EN_ty" icon = "mobile" -campaign_tracking = "ty01-mob-en-240101" +campaign_tracking = "ty01-mob-en-250101" description = "Thank you banner" preview_link = "/en-mobile/wiki/Main_Page?devbanner={{banner}}&useskin=minerva&banner=B22_WMDE_local_prototype" +preview_link_darkmode = "/en-mobile/wiki/Main_Page?devbanner={{banner}}&useskin=minerva&banner=B22_WMDE_local_prototype&minervanightmode=1" preview_url = 'https://en.m.wikipedia.org/wiki/Main_Page?banner={{PLACEHOLDER}}' wrapper_template = "wikipedia_org" [thank_you_mobile_en.banners.ctrl] -filename = "./banners/thank_you/banner_ctrl.en.ts" -pagename = "B23_WMDE_Mobile_EN_ty_ctrl" -tracking = "org-mob-ty-240101-en-ctrl" +filename = "./banners/thank_you_2024/banner_ctrl.en.ts" +pagename = "B24_WMDE_Mobile_EN_ty_ctrl" +tracking = "org-mob-ty-250101-en-ctrl" [thank_you_mobile_en.banners.var] -filename = "./banners/thank_you/banner_var.en.ts" -pagename = "B23_WMDE_Mobile_EN_ty_var" -tracking = "org-mob-ty-240101-en-var" +filename = "./banners/thank_you_2024/banner_var.en.ts" +pagename = "B24_WMDE_Mobile_EN_ty_var" +tracking = "org-mob-ty-250101-en-var" [thank_you_mobile_en.test_matrix] device = [ 'samsung_s10', 'iphone_xs_max', 'iphone_5s', 'iphone_se', "iphone_8", "iphone_12_mini", "iphone_7_plus", "iphone_11_pro_max"] @@ -105,23 +109,24 @@ orientation = [ "portrait", "landscape"] # Thank you campaign ipad wp.org [thank_you_ipad] name = "iPad" -campaign = "C23_WMDE_ipad_DE_ty" +campaign = "C24_WMDE_ipad_DE_ty" icon = "pad" -campaign_tracking = "ty01-ipad-240101" +campaign_tracking = "ty01-ipad-250101" description = "Thank you banner" preview_link = "/wiki/Wikipedia:Hauptseite?devbanner={{banner}}&banner=B22_WMDE_local_prototype" +preview_link_darkmode = "/wiki/Wikipedia:Hauptseite?devbanner={{banner}}&banner=B22_WMDE_local_prototype&vectornightmode=1" preview_url = 'https://de.wikipedia.org/wiki/Wikipedia:Hauptseite?banner={{PLACEHOLDER}}' wrapper_template = "wikipedia_org" [thank_you_ipad.banners.ctrl] -filename = "./banners/thank_you/banner_ctrl.de.ts" -pagename = "B23_WMDE_ipad_DE_ty_ctrl" -tracking = "org-ipad-ty-240101-ctrl" +filename = "./banners/thank_you_2024/banner_ctrl.de.ts" +pagename = "B24_WMDE_ipad_DE_ty_ctrl" +tracking = "org-ipad-ty-250101-ctrl" [thank_you_ipad.banners.var] -filename = "./banners/thank_you/banner_var.de.ts" -pagename = "B23_WMDE_ipad_DE_ty_var" -tracking = "org-ipad-ty-240101-var" +filename = "./banners/thank_you_2024/banner_var.de.ts" +pagename = "B24_WMDE_ipad_DE_ty_var" +tracking = "org-ipad-ty-250101-var" [thank_you_ipad.test_matrix] device = [ 'ipad_mini', 'ipad', 'ipad_pro_9_7_inch', 'ipad_pro_12_inch' ] @@ -130,42 +135,44 @@ orientation = [ "portrait", "landscape"] # Thank you campaign wp.de [thank_you_wpde] campaign = "WPDE Desktop" -name = "C23_WPDE_Desktop_DE_ty" +name = "C24_WPDE_Desktop_DE_ty" icon = "desktop" -campaign_tracking = "ty01-wpde-240101" +campaign_tracking = "ty01-wpde-250101" description = "Thank you banner" preview_link = "/wikipedia.de?devbanner={{banner}}&banner=dev-mode-wpde" +preview_link_darkmode = "/wikipedia.de?devbanner={{banner}}&banner=dev-mode-wpde" preview_url = 'https://www.wikipedia.de/?banner={{PLACEHOLDER}}' wrapper_template = "wikipedia_de" wrap_in_wikitext = false [thank_you_wpde.banners.ctrl] -filename = "./banners/thank_you/banner_ctrl.wpde.ts" -pagename = "B23_WPDE_Desktop_DE_ty_ctrl" -tracking = "de-wpde-ty-240101-ctrl" +filename = "./banners/thank_you_2024/banner_ctrl.wpde.ts" +pagename = "B24_WPDE_Desktop_DE_ty_ctrl" +tracking = "de-wpde-ty-250101-ctrl" [thank_you_wpde.banners.var] -filename = "./banners/thank_you/banner_var.wpde.ts" -pagename = "B23_WPDE_Desktop_DE_ty_var" -tracking = "de-wpde-ty-240101-var" +filename = "./banners/thank_you_2024/banner_var.wpde.ts" +pagename = "B24_WPDE_Desktop_DE_ty_var" +tracking = "de-wpde-ty-250101-var" [thank_you_wpde_mobile] campaign = "WPDE Mobile" -name = "C23_WPDE_Mobile_DE_ty" +name = "C24_WPDE_Mobile_DE_ty" icon = "mobile" -campaign_tracking = "ty01-wpde-mob-240101" +campaign_tracking = "ty01-wpde-mob-250101" description = "Thank you banner" preview_link = "/wikipedia.de?devbanner={{banner}}&banner=dev-mode-wpde" +preview_link_darkmode = "/wikipedia.de?devbanner={{banner}}&banner=dev-mode-wpde" preview_url = 'https://www.wikipedia.de/?banner={{PLACEHOLDER}}' wrapper_template = "wikipedia_de" wrap_in_wikitext = false [thank_you_wpde_mobile.banners.ctrl] -filename = "./banners/thank_you/banner_ctrl.wpde.ts" -pagename = "B23_WPDE_Mobile_DE_ty_ctrl" -tracking = "de-wpde-mob-ty-240101-ctrl" +filename = "./banners/thank_you_2024/banner_ctrl.wpde.ts" +pagename = "B24_WPDE_Mobile_DE_ty_ctrl" +tracking = "de-wpde-mob-ty-250101-ctrl" [thank_you_wpde_mobile.banners.var] -filename = "./banners/thank_you/banner_var.wpde.ts" -pagename = "B23_WPDE_Mobile_DE_ty_var" -tracking = "de-wpde-mob-ty-240101-var" +filename = "./banners/thank_you_2024/banner_var.wpde.ts" +pagename = "B24_WPDE_Mobile_DE_ty_var" +tracking = "de-wpde-mob-ty-250101-var" diff --git a/test/banners/thank_you_2024/BannerCtrl.de.spec.ts b/test/banners/thank_you_2024/BannerCtrl.de.spec.ts new file mode 100644 index 000000000..d630789b7 --- /dev/null +++ b/test/banners/thank_you_2024/BannerCtrl.de.spec.ts @@ -0,0 +1,162 @@ +import { beforeEach, describe, expect, it, Mock, vi } from 'vitest'; +import { mount, VueWrapper } from '@vue/test-utils'; +import { CloseEvent } from '@src/tracking/events/CloseEvent'; +import { CloseChoices } from '@src/domain/CloseChoices'; +import Banner from '@banners/thank_you_2024/components/BannerCtrl.de.vue'; +import MiniBannerTextWin from '@banners/thank_you_2024/content/win/MiniBannerText.de.vue'; +import FullPageBannerTextWin from '@banners/thank_you_2024/content/win/FullPageBannerText.de.vue'; +import { Tracker } from '@src/tracking/Tracker'; +import { ThankYouModalShownEvent } from '@src/tracking/events/ThankYouModalShownEvent'; +import { BannerSubmitEvent } from '@src/tracking/events/BannerSubmitEvent'; +import { BannerStates } from '@src/components/BannerConductor/StateMachine/BannerStates'; +import { TimerStub } from '@test/fixtures/TimerStub'; + +describe( 'BannerCtrl.de.vue', () => { + let tracker: Tracker; + let showCallback: Mock; + let closeCallback: Mock; + + beforeEach( () => { + tracker = { trackEvent: vi.fn() }; + showCallback = vi.fn(); + closeCallback = vi.fn(); + HTMLDialogElement.prototype.showModal = showCallback; + HTMLDialogElement.prototype.close = closeCallback; + } ); + + const getWrapper = ( progressBarPercentage: number = 80 ): VueWrapper => { + return mount( Banner, { + props: { + bannerState: BannerStates.Pending, + settings: { + numberOfDonors: '42', + progressBarPercentage + }, + subscribeURL: 'SUBSCRIBE URL', + useOfFundsURL: 'USE OF FUNDS', + membershipWithAmountURL: 'WITH_AMOUNT', + membershipWithoutAmountURL: 'WITHOUT_AMOUNT' + }, + global: { + mocks: { + $translate: ( key: string ): string => key + }, + provide: { + tracker: tracker, + timer: new TimerStub() + } + } + } ); + }; + + it( 'emits close event', () => { + const wrapper = getWrapper(); + + wrapper.find( '.wmde-banner-close' ).trigger( 'click' ); + + expect( wrapper.emitted( 'bannerClosed' ).length ).toStrictEqual( 1 ); + expect( wrapper.emitted( 'bannerClosed' )[ 0 ][ 0 ] ).toStrictEqual( new CloseEvent( 'MainBanner', CloseChoices.Close ) ); + } ); + + it( 'shows win content', () => { + Object.defineProperty( window, 'innerWidth', { writable: true, configurable: true, value: 751 } ); + const wrapper = getWrapper( 100 ); + + expect( wrapper.findComponent( MiniBannerTextWin ).exists() ).toBeTruthy(); + expect( wrapper.findComponent( FullPageBannerTextWin ).exists() ).toBeTruthy(); + } ); + + it( 'Shows and hides the full page modal', async () => { + const wrapper = getWrapper(); + + await wrapper.find( '.wmde-banner-mini-read-more' ).trigger( 'click' ); + + expect( showCallback ).toHaveBeenCalled(); + + await wrapper.find( '.wmde-banner-full .wmde-banner-close' ).trigger( 'click' ); + + expect( closeCallback ).toHaveBeenCalled(); + } ); + + it( 'emits modal shown events', () => { + const wrapper = getWrapper(); + + wrapper.find( '.wmde-banner-mini-read-more' ).trigger( 'click' ); + + expect( tracker.trackEvent ).toHaveBeenCalledOnce(); + expect( tracker.trackEvent ).toHaveBeenCalledWith( new ThankYouModalShownEvent() ); + expect( wrapper.emitted( 'modalOpened' ).length ).toStrictEqual( 1 ); + } ); + + it( 'emits modal hidden events', () => { + const wrapper = getWrapper(); + + wrapper.find( '.wmde-banner-full .wmde-banner-close' ).trigger( 'click' ); + + expect( wrapper.emitted( 'modalClosed' ).length ).toStrictEqual( 1 ); + } ); + + it( 'sets progress bar fill percentage on slider', () => { + Object.defineProperty( window, 'innerWidth', { writable: true, configurable: true, value: 750 } ); + const wrapper = getWrapper(); + + expect( wrapper.find( '.wmde-banner-progress-bar' ).attributes( 'style' ) ).toStrictEqual( '--wmde-banner-progress-bar-width: 80%;' ); + } ); + + it( 'sets progress bar fill percentage on text', () => { + Object.defineProperty( window, 'innerWidth', { writable: true, configurable: true, value: 751 } ); + const wrapper = getWrapper(); + + expect( wrapper.find( '.wmde-banner-progress-bar' ).attributes( 'style' ) ).toStrictEqual( '--wmde-banner-progress-bar-width: 80%;' ); + } ); + + it( 'redirects when membership buttons are clicked', async () => { + const location = { href: '' }; + Object.defineProperty( window, 'location', { writable: true, configurable: true, value: location } ); + const wrapper = getWrapper(); + + await wrapper.find( '.wmde-banner-full-cta-with' ).trigger( 'click' ); + + expect( location.href ).toStrictEqual( 'WITH_AMOUNT' ); + + await wrapper.find( '.wmde-banner-full-cta-without' ).trigger( 'click' ); + + expect( location.href ).toStrictEqual( 'WITHOUT_AMOUNT' ); + } ); + + it( 'tracks when membership buttons are clicked', async () => { + Object.defineProperty( window, 'location', { writable: true, configurable: true, value: { href: '' } } ); + const wrapper = getWrapper(); + + await wrapper.find( '.wmde-banner-full-cta-with' ).trigger( 'click' ); + await wrapper.find( '.wmde-banner-full-cta-without' ).trigger( 'click' ); + + expect( tracker.trackEvent ).toBeCalledTimes( 2 ); + expect( tracker.trackEvent ).toBeCalledWith( new BannerSubmitEvent( 'ThankYouBanner', 'with-amount-2' ) ); + expect( tracker.trackEvent ).toBeCalledWith( new BannerSubmitEvent( 'ThankYouBanner', 'without-amount' ) ); + } ); + + it( 'tracks and redirects when subscribe link is clicked', async () => { + const location = { href: '' }; + Object.defineProperty( window, 'location', { writable: true, configurable: true, value: location } ); + const wrapper = getWrapper(); + + await wrapper.find( '.wmde-banner-subscribe a:first-child' ).trigger( 'click' ); + + expect( location.href ).toStrictEqual( 'SUBSCRIBE URL' ); + expect( tracker.trackEvent ).toBeCalledTimes( 1 ); + expect( tracker.trackEvent ).toBeCalledWith( new BannerSubmitEvent( 'ThankYouBanner', 'subscribe' ) ); + } ); + + it( 'tracks and redirects when use of funds link is clicked', async () => { + const location = { href: '' }; + Object.defineProperty( window, 'location', { writable: true, configurable: true, value: location } ); + const wrapper = getWrapper(); + + await wrapper.find( '.wmde-banner-subscribe a:last-child' ).trigger( 'click' ); + + expect( location.href ).toStrictEqual( 'USE OF FUNDS' ); + expect( tracker.trackEvent ).toBeCalledTimes( 1 ); + expect( tracker.trackEvent ).toBeCalledWith( new BannerSubmitEvent( 'ThankYouBanner', 'use-of-funds' ) ); + } ); +} ); diff --git a/test/banners/thank_you_2024/BannerCtrl.en.spec.ts b/test/banners/thank_you_2024/BannerCtrl.en.spec.ts new file mode 100644 index 000000000..ca7496ccb --- /dev/null +++ b/test/banners/thank_you_2024/BannerCtrl.en.spec.ts @@ -0,0 +1,162 @@ +import { beforeEach, describe, expect, it, Mock, vi } from 'vitest'; +import { mount, VueWrapper } from '@vue/test-utils'; +import { CloseEvent } from '@src/tracking/events/CloseEvent'; +import { CloseChoices } from '@src/domain/CloseChoices'; +import Banner from '@banners/thank_you_2024/components/BannerCtrl.en.vue'; +import MiniBannerTextWin from '@banners/thank_you_2024/content/win/MiniBannerText.en.vue'; +import FullPageBannerTextWin from '@banners/thank_you_2024/content/win/FullPageBannerText.en.vue'; +import { Tracker } from '@src/tracking/Tracker'; +import { ThankYouModalShownEvent } from '@src/tracking/events/ThankYouModalShownEvent'; +import { BannerSubmitEvent } from '@src/tracking/events/BannerSubmitEvent'; +import { BannerStates } from '@src/components/BannerConductor/StateMachine/BannerStates'; +import { TimerStub } from '@test/fixtures/TimerStub'; + +describe( 'BannerCtrl.en.vue', () => { + let tracker: Tracker; + let showCallback: Mock; + let closeCallback: Mock; + + beforeEach( () => { + tracker = { trackEvent: vi.fn() }; + showCallback = vi.fn(); + closeCallback = vi.fn(); + HTMLDialogElement.prototype.showModal = showCallback; + HTMLDialogElement.prototype.close = closeCallback; + } ); + + const getWrapper = ( progressBarPercentage: number = 80 ): VueWrapper => { + return mount( Banner, { + props: { + bannerState: BannerStates.Pending, + settings: { + numberOfDonors: '42', + progressBarPercentage + }, + subscribeURL: 'SUBSCRIBE URL', + useOfFundsURL: 'USE OF FUNDS', + membershipWithAmountURL: 'WITH_AMOUNT', + membershipWithoutAmountURL: 'WITHOUT_AMOUNT' + }, + global: { + mocks: { + $translate: ( key: string ): string => key + }, + provide: { + tracker: tracker, + timer: new TimerStub() + } + } + } ); + }; + + it( 'emits close event', () => { + const wrapper = getWrapper(); + + wrapper.find( '.wmde-banner-close' ).trigger( 'click' ); + + expect( wrapper.emitted( 'bannerClosed' ).length ).toStrictEqual( 1 ); + expect( wrapper.emitted( 'bannerClosed' )[ 0 ][ 0 ] ).toStrictEqual( new CloseEvent( 'MainBanner', CloseChoices.Close ) ); + } ); + + it( 'shows win content', () => { + Object.defineProperty( window, 'innerWidth', { writable: true, configurable: true, value: 751 } ); + const wrapper = getWrapper( 100 ); + + expect( wrapper.findComponent( MiniBannerTextWin ).exists() ).toBeTruthy(); + expect( wrapper.findComponent( FullPageBannerTextWin ).exists() ).toBeTruthy(); + } ); + + it( 'Shows and hides the full page modal', async () => { + const wrapper = getWrapper(); + + await wrapper.find( '.wmde-banner-mini-read-more' ).trigger( 'click' ); + + expect( showCallback ).toHaveBeenCalled(); + + await wrapper.find( '.wmde-banner-full .wmde-banner-close' ).trigger( 'click' ); + + expect( closeCallback ).toHaveBeenCalled(); + } ); + + it( 'emits modal shown events', () => { + const wrapper = getWrapper(); + + wrapper.find( '.wmde-banner-mini-read-more' ).trigger( 'click' ); + + expect( tracker.trackEvent ).toHaveBeenCalledOnce(); + expect( tracker.trackEvent ).toHaveBeenCalledWith( new ThankYouModalShownEvent() ); + expect( wrapper.emitted( 'modalOpened' ).length ).toStrictEqual( 1 ); + } ); + + it( 'emits modal hidden events', () => { + const wrapper = getWrapper(); + + wrapper.find( '.wmde-banner-full .wmde-banner-close' ).trigger( 'click' ); + + expect( wrapper.emitted( 'modalClosed' ).length ).toStrictEqual( 1 ); + } ); + + it( 'sets progress bar fill percentage on slider', () => { + Object.defineProperty( window, 'innerWidth', { writable: true, configurable: true, value: 750 } ); + const wrapper = getWrapper(); + + expect( wrapper.find( '.wmde-banner-progress-bar' ).attributes( 'style' ) ).toStrictEqual( '--wmde-banner-progress-bar-width: 80%;' ); + } ); + + it( 'sets progress bar fill percentage on text', () => { + Object.defineProperty( window, 'innerWidth', { writable: true, configurable: true, value: 751 } ); + const wrapper = getWrapper(); + + expect( wrapper.find( '.wmde-banner-progress-bar' ).attributes( 'style' ) ).toStrictEqual( '--wmde-banner-progress-bar-width: 80%;' ); + } ); + + it( 'redirects when membership buttons are clicked', async () => { + const location = { href: '' }; + Object.defineProperty( window, 'location', { writable: true, configurable: true, value: location } ); + const wrapper = getWrapper(); + + await wrapper.find( '.wmde-banner-full-cta-with' ).trigger( 'click' ); + + expect( location.href ).toStrictEqual( 'WITH_AMOUNT' ); + + await wrapper.find( '.wmde-banner-full-cta-without' ).trigger( 'click' ); + + expect( location.href ).toStrictEqual( 'WITHOUT_AMOUNT' ); + } ); + + it( 'tracks when membership buttons are clicked', async () => { + Object.defineProperty( window, 'location', { writable: true, configurable: true, value: { href: '' } } ); + const wrapper = getWrapper(); + + await wrapper.find( '.wmde-banner-full-cta-with' ).trigger( 'click' ); + await wrapper.find( '.wmde-banner-full-cta-without' ).trigger( 'click' ); + + expect( tracker.trackEvent ).toBeCalledTimes( 2 ); + expect( tracker.trackEvent ).toBeCalledWith( new BannerSubmitEvent( 'ThankYouBanner', 'with-amount-2' ) ); + expect( tracker.trackEvent ).toBeCalledWith( new BannerSubmitEvent( 'ThankYouBanner', 'without-amount' ) ); + } ); + + it( 'tracks and redirects when subscribe link is clicked', async () => { + const location = { href: '' }; + Object.defineProperty( window, 'location', { writable: true, configurable: true, value: location } ); + const wrapper = getWrapper(); + + await wrapper.find( '.wmde-banner-subscribe a:first-child' ).trigger( 'click' ); + + expect( location.href ).toStrictEqual( 'SUBSCRIBE URL' ); + expect( tracker.trackEvent ).toBeCalledTimes( 1 ); + expect( tracker.trackEvent ).toBeCalledWith( new BannerSubmitEvent( 'ThankYouBanner', 'subscribe' ) ); + } ); + + it( 'tracks and redirects when use of funds link is clicked', async () => { + const location = { href: '' }; + Object.defineProperty( window, 'location', { writable: true, configurable: true, value: location } ); + const wrapper = getWrapper(); + + await wrapper.find( '.wmde-banner-subscribe a:last-child' ).trigger( 'click' ); + + expect( location.href ).toStrictEqual( 'USE OF FUNDS' ); + expect( tracker.trackEvent ).toBeCalledTimes( 1 ); + expect( tracker.trackEvent ).toBeCalledWith( new BannerSubmitEvent( 'ThankYouBanner', 'use-of-funds' ) ); + } ); +} ); diff --git a/test/banners/thank_you_2024/BannerVar.de.spec.ts b/test/banners/thank_you_2024/BannerVar.de.spec.ts new file mode 100644 index 000000000..65ed462c6 --- /dev/null +++ b/test/banners/thank_you_2024/BannerVar.de.spec.ts @@ -0,0 +1,162 @@ +import { beforeEach, describe, expect, it, Mock, vi } from 'vitest'; +import { mount, VueWrapper } from '@vue/test-utils'; +import { CloseEvent } from '@src/tracking/events/CloseEvent'; +import { CloseChoices } from '@src/domain/CloseChoices'; +import Banner from '@banners/thank_you_2024/components/BannerVar.de.vue'; +import MiniBannerTextWin from '@banners/thank_you_2024/content/win/MiniBannerText.de.vue'; +import FullPageBannerTextWin from '@banners/thank_you_2024/content/win/FullPageBannerText.de.vue'; +import { Tracker } from '@src/tracking/Tracker'; +import { ThankYouModalShownEvent } from '@src/tracking/events/ThankYouModalShownEvent'; +import { BannerSubmitEvent } from '@src/tracking/events/BannerSubmitEvent'; +import { BannerStates } from '@src/components/BannerConductor/StateMachine/BannerStates'; +import { TimerStub } from '@test/fixtures/TimerStub'; + +describe( 'BannerVar.de.vue', () => { + let tracker: Tracker; + let showCallback: Mock; + let closeCallback: Mock; + + beforeEach( () => { + tracker = { trackEvent: vi.fn() }; + showCallback = vi.fn(); + closeCallback = vi.fn(); + HTMLDialogElement.prototype.showModal = showCallback; + HTMLDialogElement.prototype.close = closeCallback; + } ); + + const getWrapper = ( progressBarPercentage: number = 80 ): VueWrapper => { + return mount( Banner, { + props: { + bannerState: BannerStates.Pending, + settings: { + numberOfDonors: '42', + progressBarPercentage + }, + subscribeURL: 'SUBSCRIBE URL', + useOfFundsURL: 'USE OF FUNDS', + membershipWithAmountURL: 'WITH_AMOUNT', + membershipWithoutAmountURL: 'WITHOUT_AMOUNT' + }, + global: { + mocks: { + $translate: ( key: string ): string => key + }, + provide: { + tracker: tracker, + timer: new TimerStub() + } + } + } ); + }; + + it( 'emits close event', () => { + const wrapper = getWrapper(); + + wrapper.find( '.wmde-banner-close' ).trigger( 'click' ); + + expect( wrapper.emitted( 'bannerClosed' ).length ).toStrictEqual( 1 ); + expect( wrapper.emitted( 'bannerClosed' )[ 0 ][ 0 ] ).toStrictEqual( new CloseEvent( 'MainBanner', CloseChoices.Close ) ); + } ); + + it( 'shows win content', () => { + Object.defineProperty( window, 'innerWidth', { writable: true, configurable: true, value: 751 } ); + const wrapper = getWrapper( 100 ); + + expect( wrapper.findComponent( MiniBannerTextWin ).exists() ).toBeTruthy(); + expect( wrapper.findComponent( FullPageBannerTextWin ).exists() ).toBeTruthy(); + } ); + + it( 'Shows and hides the full page modal', async () => { + const wrapper = getWrapper(); + + await wrapper.find( '.wmde-banner-mini-read-more' ).trigger( 'click' ); + + expect( showCallback ).toHaveBeenCalled(); + + await wrapper.find( '.wmde-banner-full .wmde-banner-close' ).trigger( 'click' ); + + expect( closeCallback ).toHaveBeenCalled(); + } ); + + it( 'emits modal shown events', () => { + const wrapper = getWrapper(); + + wrapper.find( '.wmde-banner-mini-read-more' ).trigger( 'click' ); + + expect( tracker.trackEvent ).toHaveBeenCalledOnce(); + expect( tracker.trackEvent ).toHaveBeenCalledWith( new ThankYouModalShownEvent() ); + expect( wrapper.emitted( 'modalOpened' ).length ).toStrictEqual( 1 ); + } ); + + it( 'emits modal hidden events', () => { + const wrapper = getWrapper(); + + wrapper.find( '.wmde-banner-full .wmde-banner-close' ).trigger( 'click' ); + + expect( wrapper.emitted( 'modalClosed' ).length ).toStrictEqual( 1 ); + } ); + + it( 'sets progress bar fill percentage on slider', () => { + Object.defineProperty( window, 'innerWidth', { writable: true, configurable: true, value: 750 } ); + const wrapper = getWrapper(); + + expect( wrapper.find( '.wmde-banner-progress-bar' ).attributes( 'style' ) ).toStrictEqual( '--wmde-banner-progress-bar-width: 80%;' ); + } ); + + it( 'sets progress bar fill percentage on text', () => { + Object.defineProperty( window, 'innerWidth', { writable: true, configurable: true, value: 751 } ); + const wrapper = getWrapper(); + + expect( wrapper.find( '.wmde-banner-progress-bar' ).attributes( 'style' ) ).toStrictEqual( '--wmde-banner-progress-bar-width: 80%;' ); + } ); + + it( 'redirects when membership buttons are clicked', async () => { + const location = { href: '' }; + Object.defineProperty( window, 'location', { writable: true, configurable: true, value: location } ); + const wrapper = getWrapper(); + + await wrapper.find( '.wmde-banner-full-cta-with' ).trigger( 'click' ); + + expect( location.href ).toStrictEqual( 'WITH_AMOUNT' ); + + await wrapper.find( '.wmde-banner-full-cta-without' ).trigger( 'click' ); + + expect( location.href ).toStrictEqual( 'WITHOUT_AMOUNT' ); + } ); + + it( 'tracks when membership buttons are clicked', async () => { + Object.defineProperty( window, 'location', { writable: true, configurable: true, value: { href: '' } } ); + const wrapper = getWrapper(); + + await wrapper.find( '.wmde-banner-full-cta-with' ).trigger( 'click' ); + await wrapper.find( '.wmde-banner-full-cta-without' ).trigger( 'click' ); + + expect( tracker.trackEvent ).toBeCalledTimes( 2 ); + expect( tracker.trackEvent ).toBeCalledWith( new BannerSubmitEvent( 'ThankYouBanner', 'with-amount-2' ) ); + expect( tracker.trackEvent ).toBeCalledWith( new BannerSubmitEvent( 'ThankYouBanner', 'without-amount' ) ); + } ); + + it( 'tracks and redirects when subscribe link is clicked', async () => { + const location = { href: '' }; + Object.defineProperty( window, 'location', { writable: true, configurable: true, value: location } ); + const wrapper = getWrapper(); + + await wrapper.find( '.wmde-banner-subscribe a:first-child' ).trigger( 'click' ); + + expect( location.href ).toStrictEqual( 'SUBSCRIBE URL' ); + expect( tracker.trackEvent ).toBeCalledTimes( 1 ); + expect( tracker.trackEvent ).toBeCalledWith( new BannerSubmitEvent( 'ThankYouBanner', 'subscribe' ) ); + } ); + + it( 'tracks and redirects when use of funds link is clicked', async () => { + const location = { href: '' }; + Object.defineProperty( window, 'location', { writable: true, configurable: true, value: location } ); + const wrapper = getWrapper(); + + await wrapper.find( '.wmde-banner-subscribe a:last-child' ).trigger( 'click' ); + + expect( location.href ).toStrictEqual( 'USE OF FUNDS' ); + expect( tracker.trackEvent ).toBeCalledTimes( 1 ); + expect( tracker.trackEvent ).toBeCalledWith( new BannerSubmitEvent( 'ThankYouBanner', 'use-of-funds' ) ); + } ); +} ); diff --git a/test/banners/thank_you_2024/BannerVar.en.spec.ts b/test/banners/thank_you_2024/BannerVar.en.spec.ts new file mode 100644 index 000000000..2aafdbc5e --- /dev/null +++ b/test/banners/thank_you_2024/BannerVar.en.spec.ts @@ -0,0 +1,162 @@ +import { beforeEach, describe, expect, it, Mock, vi } from 'vitest'; +import { mount, VueWrapper } from '@vue/test-utils'; +import { CloseEvent } from '@src/tracking/events/CloseEvent'; +import { CloseChoices } from '@src/domain/CloseChoices'; +import Banner from '@banners/thank_you_2024/components/BannerVar.en.vue'; +import MiniBannerTextWin from '@banners/thank_you_2024/content/win/MiniBannerText.en.vue'; +import FullPageBannerTextWin from '@banners/thank_you_2024/content/win/FullPageBannerText.en.vue'; +import { Tracker } from '@src/tracking/Tracker'; +import { ThankYouModalShownEvent } from '@src/tracking/events/ThankYouModalShownEvent'; +import { BannerSubmitEvent } from '@src/tracking/events/BannerSubmitEvent'; +import { BannerStates } from '@src/components/BannerConductor/StateMachine/BannerStates'; +import { TimerStub } from '@test/fixtures/TimerStub'; + +describe( 'BannerVar.en.vue', () => { + let tracker: Tracker; + let showCallback: Mock; + let closeCallback: Mock; + + beforeEach( () => { + tracker = { trackEvent: vi.fn() }; + showCallback = vi.fn(); + closeCallback = vi.fn(); + HTMLDialogElement.prototype.showModal = showCallback; + HTMLDialogElement.prototype.close = closeCallback; + } ); + + const getWrapper = ( progressBarPercentage: number = 80 ): VueWrapper => { + return mount( Banner, { + props: { + bannerState: BannerStates.Pending, + settings: { + numberOfDonors: '42', + progressBarPercentage + }, + subscribeURL: 'SUBSCRIBE URL', + useOfFundsURL: 'USE OF FUNDS', + membershipWithAmountURL: 'WITH_AMOUNT', + membershipWithoutAmountURL: 'WITHOUT_AMOUNT' + }, + global: { + mocks: { + $translate: ( key: string ): string => key + }, + provide: { + tracker: tracker, + timer: new TimerStub() + } + } + } ); + }; + + it( 'emits close event', () => { + const wrapper = getWrapper(); + + wrapper.find( '.wmde-banner-close' ).trigger( 'click' ); + + expect( wrapper.emitted( 'bannerClosed' ).length ).toStrictEqual( 1 ); + expect( wrapper.emitted( 'bannerClosed' )[ 0 ][ 0 ] ).toStrictEqual( new CloseEvent( 'MainBanner', CloseChoices.Close ) ); + } ); + + it( 'shows win content', () => { + Object.defineProperty( window, 'innerWidth', { writable: true, configurable: true, value: 751 } ); + const wrapper = getWrapper( 100 ); + + expect( wrapper.findComponent( MiniBannerTextWin ).exists() ).toBeTruthy(); + expect( wrapper.findComponent( FullPageBannerTextWin ).exists() ).toBeTruthy(); + } ); + + it( 'Shows and hides the full page modal', async () => { + const wrapper = getWrapper(); + + await wrapper.find( '.wmde-banner-mini-read-more' ).trigger( 'click' ); + + expect( showCallback ).toHaveBeenCalled(); + + await wrapper.find( '.wmde-banner-full .wmde-banner-close' ).trigger( 'click' ); + + expect( closeCallback ).toHaveBeenCalled(); + } ); + + it( 'emits modal shown events', () => { + const wrapper = getWrapper(); + + wrapper.find( '.wmde-banner-mini-read-more' ).trigger( 'click' ); + + expect( tracker.trackEvent ).toHaveBeenCalledOnce(); + expect( tracker.trackEvent ).toHaveBeenCalledWith( new ThankYouModalShownEvent() ); + expect( wrapper.emitted( 'modalOpened' ).length ).toStrictEqual( 1 ); + } ); + + it( 'emits modal hidden events', () => { + const wrapper = getWrapper(); + + wrapper.find( '.wmde-banner-full .wmde-banner-close' ).trigger( 'click' ); + + expect( wrapper.emitted( 'modalClosed' ).length ).toStrictEqual( 1 ); + } ); + + it( 'sets progress bar fill percentage on slider', () => { + Object.defineProperty( window, 'innerWidth', { writable: true, configurable: true, value: 750 } ); + const wrapper = getWrapper(); + + expect( wrapper.find( '.wmde-banner-progress-bar' ).attributes( 'style' ) ).toStrictEqual( '--wmde-banner-progress-bar-width: 80%;' ); + } ); + + it( 'sets progress bar fill percentage on text', () => { + Object.defineProperty( window, 'innerWidth', { writable: true, configurable: true, value: 751 } ); + const wrapper = getWrapper(); + + expect( wrapper.find( '.wmde-banner-progress-bar' ).attributes( 'style' ) ).toStrictEqual( '--wmde-banner-progress-bar-width: 80%;' ); + } ); + + it( 'redirects when membership buttons are clicked', async () => { + const location = { href: '' }; + Object.defineProperty( window, 'location', { writable: true, configurable: true, value: location } ); + const wrapper = getWrapper(); + + await wrapper.find( '.wmde-banner-full-cta-with' ).trigger( 'click' ); + + expect( location.href ).toStrictEqual( 'WITH_AMOUNT' ); + + await wrapper.find( '.wmde-banner-full-cta-without' ).trigger( 'click' ); + + expect( location.href ).toStrictEqual( 'WITHOUT_AMOUNT' ); + } ); + + it( 'tracks when membership buttons are clicked', async () => { + Object.defineProperty( window, 'location', { writable: true, configurable: true, value: { href: '' } } ); + const wrapper = getWrapper(); + + await wrapper.find( '.wmde-banner-full-cta-with' ).trigger( 'click' ); + await wrapper.find( '.wmde-banner-full-cta-without' ).trigger( 'click' ); + + expect( tracker.trackEvent ).toBeCalledTimes( 2 ); + expect( tracker.trackEvent ).toBeCalledWith( new BannerSubmitEvent( 'ThankYouBanner', 'with-amount-2' ) ); + expect( tracker.trackEvent ).toBeCalledWith( new BannerSubmitEvent( 'ThankYouBanner', 'without-amount' ) ); + } ); + + it( 'tracks and redirects when subscribe link is clicked', async () => { + const location = { href: '' }; + Object.defineProperty( window, 'location', { writable: true, configurable: true, value: location } ); + const wrapper = getWrapper(); + + await wrapper.find( '.wmde-banner-subscribe a:first-child' ).trigger( 'click' ); + + expect( location.href ).toStrictEqual( 'SUBSCRIBE URL' ); + expect( tracker.trackEvent ).toBeCalledTimes( 1 ); + expect( tracker.trackEvent ).toBeCalledWith( new BannerSubmitEvent( 'ThankYouBanner', 'subscribe' ) ); + } ); + + it( 'tracks and redirects when use of funds link is clicked', async () => { + const location = { href: '' }; + Object.defineProperty( window, 'location', { writable: true, configurable: true, value: location } ); + const wrapper = getWrapper(); + + await wrapper.find( '.wmde-banner-subscribe a:last-child' ).trigger( 'click' ); + + expect( location.href ).toStrictEqual( 'USE OF FUNDS' ); + expect( tracker.trackEvent ).toBeCalledTimes( 1 ); + expect( tracker.trackEvent ).toBeCalledWith( new BannerSubmitEvent( 'ThankYouBanner', 'use-of-funds' ) ); + } ); +} ); diff --git a/test/banners/thank_you_2024/CloseButton.spec.ts b/test/banners/thank_you_2024/CloseButton.spec.ts new file mode 100644 index 000000000..cf14faa5c --- /dev/null +++ b/test/banners/thank_you_2024/CloseButton.spec.ts @@ -0,0 +1,21 @@ +import { describe, expect, it } from 'vitest'; +import { mount, VueWrapper } from '@vue/test-utils'; +import CloseButton from '@banners/thank_you_2024/components/CloseButton.vue'; + +describe( 'CloseButton.vue', () => { + const getWrapper = (): VueWrapper => { + return mount( CloseButton, { + props: { + label: 'CLOSE' + } + } ); + }; + + it( 'Emits events', async () => { + const wrapper = getWrapper(); + + await wrapper.trigger( 'click' ); + + expect( wrapper.emitted( 'click' ).length ).toStrictEqual( 1 ); + } ); +} ); diff --git a/test/banners/thank_you_2024/FullPageBanner.spec.ts b/test/banners/thank_you_2024/FullPageBanner.spec.ts new file mode 100644 index 000000000..674e0958c --- /dev/null +++ b/test/banners/thank_you_2024/FullPageBanner.spec.ts @@ -0,0 +1,52 @@ +import { beforeEach, describe, expect, it, Mock, vi } from 'vitest'; +import { mount, VueWrapper } from '@vue/test-utils'; +import FullPageBanner from '@banners/thank_you_2024/components/FullPageBanner.vue'; + +describe( 'FullPageBanner.vue', () => { + let showCallback: Mock; + let closeCallback: Mock; + + beforeEach( () => { + showCallback = vi.fn(); + closeCallback = vi.fn(); + HTMLDialogElement.prototype.showModal = showCallback; + HTMLDialogElement.prototype.close = closeCallback; + } ); + + const getWrapper = (): VueWrapper => { + return mount( FullPageBanner, { + props: { + visible: false + }, + global: { + mocks: { + $translate: ( key: string ): string => key + } + } + } ); + }; + + it( 'Shows and hides', async () => { + const wrapper = getWrapper(); + + await wrapper.setProps( { visible: true } ); + + expect( showCallback ).toHaveBeenCalled(); + + await wrapper.setProps( { visible: false } ); + + expect( closeCallback ).toHaveBeenCalled(); + } ); + + it( 'Emits events', async () => { + const wrapper = getWrapper(); + + await wrapper.find( '.wmde-banner-close' ).trigger( 'click' ); + await wrapper.find( '.wmde-banner-full-cta-with' ).trigger( 'click' ); + await wrapper.find( '.wmde-banner-full-cta-without' ).trigger( 'click' ); + + expect( wrapper.emitted( 'close' ).length ).toStrictEqual( 1 ); + expect( wrapper.emitted( 'membershipWithAmount' ).length ).toStrictEqual( 1 ); + expect( wrapper.emitted( 'membershipWithoutAmount' ).length ).toStrictEqual( 1 ); + } ); +} ); diff --git a/test/banners/thank_you_2024/MiniBanner.spec.ts b/test/banners/thank_you_2024/MiniBanner.spec.ts new file mode 100644 index 000000000..46cdf80aa --- /dev/null +++ b/test/banners/thank_you_2024/MiniBanner.spec.ts @@ -0,0 +1,41 @@ +import { describe, expect, it } from 'vitest'; +import { mount, VueWrapper } from '@vue/test-utils'; +import MiniBanner from '@banners/thank_you_2024/components/MiniBanner.vue'; + +describe( 'MiniBanner.vue', () => { + const getWrapper = (): VueWrapper => { + return mount( MiniBanner, { + props: { + progressBarFillPercentage: 42, + showSuccessContent: true + }, + global: { + mocks: { + $translate: ( key: string ): string => key + } + } + } ); + }; + + it( 'Sets the progress bar items', async () => { + const wrapper = getWrapper(); + + expect( wrapper.find( '.wmde-banner-progress-bar' ).attributes( 'style' ) ).toStrictEqual( '--wmde-banner-progress-bar-width: 42%;' ); + + expect( wrapper.find( '.wmde-banner-progress-bar-fill-text' ).text() ).toStrictEqual( 'progress-bar-inner-text-win' ); + + await wrapper.setProps( { showSuccessContent: false } ); + + expect( wrapper.find( '.wmde-banner-progress-bar-fill-text' ).text() ).toStrictEqual( 'progress-bar-inner-text-lose' ); + } ); + + it( 'Emits events', async () => { + const wrapper = getWrapper(); + + await wrapper.find( '.wmde-banner-close' ).trigger( 'click' ); + await wrapper.find( '.wmde-banner-mini-read-more' ).trigger( 'click' ); + + expect( wrapper.emitted( 'close' ).length ).toStrictEqual( 1 ); + expect( wrapper.emitted( 'read-more' ).length ).toStrictEqual( 1 ); + } ); +} ); diff --git a/test/banners/thank_you_2024/ProgressBar.spec.ts b/test/banners/thank_you_2024/ProgressBar.spec.ts new file mode 100644 index 000000000..87bd360f0 --- /dev/null +++ b/test/banners/thank_you_2024/ProgressBar.spec.ts @@ -0,0 +1,35 @@ +import { describe, expect, it } from 'vitest'; +import { mount, VueWrapper } from '@vue/test-utils'; +import ProgressBar from '@banners/thank_you_2024/components/ProgressBar.vue'; + +describe( 'ProgressBar.vue', () => { + const getWrapper = (): VueWrapper => { + return mount( ProgressBar, { + props: { + fillPercentage: 42, + showSuccessContent: true + }, + global: { + mocks: { + $translate: ( key: string ): string => key + } + } + } ); + }; + + it( 'Sets the fill', () => { + const wrapper = getWrapper(); + + expect( wrapper.find( '.wmde-banner-progress-bar' ).attributes( 'style' ) ).toStrictEqual( '--wmde-banner-progress-bar-width: 42%;' ); + } ); + + it( 'Sets win and lose items', async () => { + const wrapper = getWrapper(); + + expect( wrapper.find( '.wmde-banner-progress-bar-fill-text' ).text() ).toStrictEqual( 'progress-bar-inner-text-win' ); + + await wrapper.setProps( { showSuccessContent: false } ); + + expect( wrapper.find( '.wmde-banner-progress-bar-fill-text' ).text() ).toStrictEqual( 'progress-bar-inner-text-lose' ); + } ); +} );