diff --git a/banners/english/C24_WMDE_Desktop_EN_01/banner_ctrl.ts b/banners/english/C24_WMDE_Desktop_EN_01/banner_ctrl.ts new file mode 100644 index 000000000..d858b2b45 --- /dev/null +++ b/banners/english/C24_WMDE_Desktop_EN_01/banner_ctrl.ts @@ -0,0 +1,73 @@ +import { createVueApp } from '@src/createVueApp'; + +import './styles/styles.scss'; + +import BannerConductor from '@src/components/BannerConductor/FallbackBannerConductor.vue'; +import Banner from './components/BannerCtrl.vue'; +import FallbackBanner from './components/FallbackBanner.vue'; +import { UrlRuntimeEnvironment } from '@src/utils/RuntimeEnvironment'; +import { WindowResizeHandler } from '@src/utils/ResizeHandler'; +import PageWPORG from '@src/page/PageWPORG'; +import { WindowMediaWiki } from '@src/page/MediaWiki/WindowMediaWiki'; +import { SkinFactory } from '@src/page/skin/SkinFactory'; +import { WindowSizeIssueChecker } from '@src/utils/SizeIssueChecker/WindowSizeIssueChecker'; +import TranslationPlugin from '@src/TranslationPlugin'; +import { Translator } from '@src/Translator'; +import DynamicTextPlugin from '@src/DynamicTextPlugin'; +import { LocalImpressionCount } from '@src/utils/LocalImpressionCount'; +import { LegacyTrackerWPORG } from '@src/tracking/LegacyTrackerWPORG'; +import { Locales } from '@src/domain/Locales'; + +// Locale-specific imports +import messages from './messages'; +import { LocaleFactoryEn } from '@src/utils/LocaleFactory/LocaleFactoryEn'; + +// Channel specific form setup +import { createFormItems } from './form_items'; +import { createFormActions } from '@src/createFormActions'; +import eventMappings from './event_map'; +import { createFallbackDonationURL } from '@src/createFallbackDonationURL'; + +const localeFactory = new LocaleFactoryEn(); +const translator = new Translator( messages ); +const mediaWiki = new WindowMediaWiki(); +const page = new PageWPORG( mediaWiki, ( new SkinFactory( mediaWiki ) ).getSkin(), new WindowSizeIssueChecker( 400 ) ); +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: runtimeEnvironment.getBannerDelay( 7500 ), + transitionDuration: 1000 + }, + bannerProps: { + useOfFundsContent: localeFactory.getUseOfFundsLoader().getContent(), + remainingImpressions: impressionCount.getRemainingImpressions( page.getMaxBannerImpressions( 'english' ) ), + donationLink: createFallbackDonationURL( page.getTracking(), impressionCount, { locale: Locales.EN } ) + }, + resizeHandler: new WindowResizeHandler(), + banner: Banner, + fallbackBanner: FallbackBanner, + minWidthForMainBanner: 800, + impressionCount +} ); + +app.use( TranslationPlugin, translator ); +app.use( DynamicTextPlugin, { + campaignParameters: page.getCampaignParameters(), + date: new Date(), + formatters: localeFactory.getFormatters(), + impressionCount, + translator +} ); + +const currencyFormatter = localeFactory.getCurrencyFormatter(); + +app.provide( 'currencyFormatter', currencyFormatter ); +app.provide( 'formItems', createFormItems( translator, currencyFormatter.euroAmount.bind( currencyFormatter ) ) ); +app.provide( 'formActions', createFormActions( page.getTracking(), impressionCount, { locale: Locales.EN, ap: '0' } ) ); +app.provide( 'tracker', tracker ); + +app.mount( page.getBannerContainer() ); diff --git a/banners/english/C24_WMDE_Desktop_EN_01/banner_var.ts b/banners/english/C24_WMDE_Desktop_EN_01/banner_var.ts new file mode 100644 index 000000000..982f09e7f --- /dev/null +++ b/banners/english/C24_WMDE_Desktop_EN_01/banner_var.ts @@ -0,0 +1,73 @@ +import { createVueApp } from '@src/createVueApp'; + +import './styles/styles.scss'; + +import BannerConductor from '@src/components/BannerConductor/FallbackBannerConductor.vue'; +import Banner from './components/BannerCtrl.vue'; +import FallbackBanner from './components/FallbackBanner.vue'; +import { UrlRuntimeEnvironment } from '@src/utils/RuntimeEnvironment'; +import { WindowResizeHandler } from '@src/utils/ResizeHandler'; +import PageWPORG from '@src/page/PageWPORG'; +import { WindowMediaWiki } from '@src/page/MediaWiki/WindowMediaWiki'; +import { SkinFactory } from '@src/page/skin/SkinFactory'; +import { WindowSizeIssueChecker } from '@src/utils/SizeIssueChecker/WindowSizeIssueChecker'; +import TranslationPlugin from '@src/TranslationPlugin'; +import { Translator } from '@src/Translator'; +import DynamicTextPlugin from '@src/DynamicTextPlugin'; +import { LocalImpressionCount } from '@src/utils/LocalImpressionCount'; +import { LegacyTrackerWPORG } from '@src/tracking/LegacyTrackerWPORG'; +import { Locales } from '@src/domain/Locales'; + +// Locale-specific imports +import messages from './messages'; +import { LocaleFactoryEn } from '@src/utils/LocaleFactory/LocaleFactoryEn'; + +// Channel specific form setup +import { createFormItems } from './form_items'; +import { createFormActions } from '@src/createFormActions'; +import eventMappings from './event_map'; +import { createFallbackDonationURL } from '@src/createFallbackDonationURL'; + +const localeFactory = new LocaleFactoryEn(); +const translator = new Translator( messages ); +const mediaWiki = new WindowMediaWiki(); +const page = new PageWPORG( mediaWiki, ( new SkinFactory( mediaWiki ) ).getSkin(), new WindowSizeIssueChecker( 400 ) ); +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: runtimeEnvironment.getBannerDelay( 7500 ), + transitionDuration: 1000 + }, + bannerProps: { + useOfFundsContent: localeFactory.getUseOfFundsLoader().getContent(), + remainingImpressions: impressionCount.getRemainingImpressions( page.getMaxBannerImpressions( 'english' ) ), + donationLink: createFallbackDonationURL( page.getTracking(), impressionCount, { locale: Locales.EN } ) + }, + resizeHandler: new WindowResizeHandler(), + banner: Banner, + fallbackBanner: FallbackBanner, + minWidthForMainBanner: 800, + impressionCount +} ); + +app.use( TranslationPlugin, translator ); +app.use( DynamicTextPlugin, { + campaignParameters: page.getCampaignParameters(), + date: new Date(), + formatters: localeFactory.getFormatters(), + impressionCount, + translator +} ); + +const currencyFormatter = localeFactory.getCurrencyFormatter(); + +app.provide( 'currencyFormatter', currencyFormatter ); +app.provide( 'formItems', createFormItems( translator, currencyFormatter.euroAmount.bind( currencyFormatter ) ) ); +app.provide( 'formActions', createFormActions( page.getTracking(), impressionCount, { locale: Locales.EN, ap: '1' } ) ); +app.provide( 'tracker', tracker ); + +app.mount( page.getBannerContainer() ); diff --git a/banners/english/C24_WMDE_Desktop_EN_01/components/BannerCtrl.vue b/banners/english/C24_WMDE_Desktop_EN_01/components/BannerCtrl.vue new file mode 100644 index 000000000..f34edacb9 --- /dev/null +++ b/banners/english/C24_WMDE_Desktop_EN_01/components/BannerCtrl.vue @@ -0,0 +1,135 @@ + + + diff --git a/banners/english/C24_WMDE_Desktop_EN_01/components/FallbackBanner.vue b/banners/english/C24_WMDE_Desktop_EN_01/components/FallbackBanner.vue new file mode 100644 index 000000000..2c0d8e922 --- /dev/null +++ b/banners/english/C24_WMDE_Desktop_EN_01/components/FallbackBanner.vue @@ -0,0 +1,101 @@ + + + diff --git a/banners/english/C24_WMDE_Desktop_EN_01/components/MainBanner.vue b/banners/english/C24_WMDE_Desktop_EN_01/components/MainBanner.vue new file mode 100644 index 000000000..9f9ebe572 --- /dev/null +++ b/banners/english/C24_WMDE_Desktop_EN_01/components/MainBanner.vue @@ -0,0 +1,50 @@ + + + diff --git a/banners/english/C24_WMDE_Desktop_EN_01/content/BannerSlides.vue b/banners/english/C24_WMDE_Desktop_EN_01/content/BannerSlides.vue new file mode 100644 index 000000000..75d126e61 --- /dev/null +++ b/banners/english/C24_WMDE_Desktop_EN_01/content/BannerSlides.vue @@ -0,0 +1,58 @@ + + + diff --git a/banners/english/C24_WMDE_Desktop_EN_01/content/BannerText.vue b/banners/english/C24_WMDE_Desktop_EN_01/content/BannerText.vue new file mode 100644 index 000000000..ef8b64f82 --- /dev/null +++ b/banners/english/C24_WMDE_Desktop_EN_01/content/BannerText.vue @@ -0,0 +1,46 @@ + + + diff --git a/banners/english/C24_WMDE_Desktop_EN_01/content/FallbackSlides.vue b/banners/english/C24_WMDE_Desktop_EN_01/content/FallbackSlides.vue new file mode 100644 index 000000000..a50a81082 --- /dev/null +++ b/banners/english/C24_WMDE_Desktop_EN_01/content/FallbackSlides.vue @@ -0,0 +1,27 @@ + + + diff --git a/banners/english/C24_WMDE_Desktop_EN_01/content/FallbackText.vue b/banners/english/C24_WMDE_Desktop_EN_01/content/FallbackText.vue new file mode 100644 index 000000000..60a58e80d --- /dev/null +++ b/banners/english/C24_WMDE_Desktop_EN_01/content/FallbackText.vue @@ -0,0 +1,32 @@ + + + diff --git a/banners/english/C24_WMDE_Desktop_EN_01/event_map.ts b/banners/english/C24_WMDE_Desktop_EN_01/event_map.ts new file mode 100644 index 000000000..612f999a8 --- /dev/null +++ b/banners/english/C24_WMDE_Desktop_EN_01/event_map.ts @@ -0,0 +1,38 @@ +import { TrackingEventConverterFactory } from '@src/tracking/LegacyTrackerWPORG'; +import { WMDELegacyBannerEvent } from '@src/tracking/WPORG/WMDELegacyBannerEvent'; +import { FormStepShownEvent } from '@src/tracking/events/FormStepShownEvent'; +import { mapFormStepShownEvent } from '@src/tracking/LegacyEventTracking/mapFormStepShownEvent'; +import { CustomAmountChangedEvent } from '@src/tracking/events/CustomAmountChangedEvent'; +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'; +import { BannerSubmitEvent } from '@src/tracking/events/BannerSubmitEvent'; +import { WMDESizeIssueEvent } from '@src/tracking/WPORG/WMDEBannerSizeIssue'; +import { createViewportInfo } from '@src/tracking/LegacyEventTracking/createViewportInfo'; +import { FallbackBannerSubmitEvent } from '@src/tracking/events/FallbackBannerSubmitEvent'; +import { ShownEvent } from '@src/tracking/events/ShownEvent'; +import { mapShownEvent } from '@src/tracking/LegacyEventTracking/mapShownEvent'; + +export default new Map( [ + [ ShownEvent.EVENT_NAME, mapShownEvent ], + [ CloseEvent.EVENT_NAME, mapCloseEvent ], + + [ FormStepShownEvent.EVENT_NAME, mapFormStepShownEvent ], + [ CustomAmountChangedEvent.EVENT_NAME, + ( e: CustomAmountChangedEvent ): WMDELegacyBannerEvent => + new WMDELegacyBannerEvent( e.userChoice + '-amount', 1 ) + ], + [ NotShownEvent.EVENT_NAME, mapNotShownEvent ], + [ BannerSubmitEvent.EVENT_NAME, ( e: BannerSubmitEvent ): WMDESizeIssueEvent => { + switch ( e.feature ) { + case 'UpgradeToYearlyForm': + return new WMDESizeIssueEvent( `submit-${e.userChoice}`, createViewportInfo(), 1 ); + case 'CustomAmountForm': + return new WMDESizeIssueEvent( `submit-different-amount`, createViewportInfo(), 1 ); + default: + return new WMDESizeIssueEvent( `submit`, createViewportInfo(), 1 ); + } + } ], + [ FallbackBannerSubmitEvent.EVENT_NAME, ( e: FallbackBannerSubmitEvent ): WMDESizeIssueEvent => new WMDESizeIssueEvent( e.eventName, createViewportInfo(), 1 ) ] +] ); diff --git a/banners/english/C24_WMDE_Desktop_EN_01/form_items.ts b/banners/english/C24_WMDE_Desktop_EN_01/form_items.ts new file mode 100644 index 000000000..95a254ccb --- /dev/null +++ b/banners/english/C24_WMDE_Desktop_EN_01/form_items.ts @@ -0,0 +1,21 @@ +import FormItemsBuilder from '@src/utils/FormItemsBuilder/FormItemsBuilder'; +import { Translator } from '@src/Translator'; +import { DonationFormItems } from '@src/utils/FormItemsBuilder/DonationFormItems'; +import { Intervals } from '@src/utils/FormItemsBuilder/fields/Intervals'; +import { PaymentMethods } from '@src/utils/FormItemsBuilder/fields/PaymentMethods'; +import { NumberFormatter } from '@src/utils/DynamicContent/formatters/NumberFormatter'; + +export function createFormItems( translations: Translator, amountFormatter: NumberFormatter ): DonationFormItems { + return new FormItemsBuilder( translations, amountFormatter ) + .setIntervals( + Intervals.ONCE, + Intervals.MONTHLY, + Intervals.QUARTERLY, + Intervals.YEARLY + ) + .setAmounts( 5, 10, 20, 25, 50, 100 ) + .setPaymentMethods( + PaymentMethods.PAYPAL, + PaymentMethods.CREDIT_CARD + ).getItems(); +} diff --git a/banners/english/C24_WMDE_Desktop_EN_01/messages.ts b/banners/english/C24_WMDE_Desktop_EN_01/messages.ts new file mode 100644 index 000000000..d7277d676 --- /dev/null +++ b/banners/english/C24_WMDE_Desktop_EN_01/messages.ts @@ -0,0 +1,24 @@ +import CustomAmountFormEn from '@src/components/DonationForm/Forms/messages/CustomAmountForm.en'; +import DynamicCampaignTextEn from '@src/utils/DynamicContent/messages/DynamicCampaignText.en'; +import { TranslationMessages } from '@src/Translator'; +import UpgradeToYearlyEn from '@src/components/DonationForm/Forms/messages/UpgradeToYearly.en'; +import SoftCloseEn from '@src/components/SoftClose/messages/SoftClose.en'; +import AddressFormEn from '@src/components/DonationForm/Forms/messages/AddressForm.en'; +import FooterEn from '@src/components/Footer/messages/Footer.en'; +import MainDonationFormEn from '@src/components/DonationForm/Forms/messages/MainDonationForm.en'; +import AlreadyDonatedModalEn from '@src/components/AlreadyDonatedModal/translations/AlreadyDonatedModal.en'; +import FallbackBanner from '@src/components/FallbackBanner/messages/FallbackBanner.en'; + +const messages: TranslationMessages = { + ...CustomAmountFormEn, + ...DynamicCampaignTextEn, + ...UpgradeToYearlyEn, + ...SoftCloseEn, + ...AddressFormEn, + ...FooterEn, + ...MainDonationFormEn, + ...AlreadyDonatedModalEn, + ...FallbackBanner +}; + +export default messages; diff --git a/banners/english/C24_WMDE_Desktop_EN_01/styles/Banner.scss b/banners/english/C24_WMDE_Desktop_EN_01/styles/Banner.scss new file mode 100644 index 000000000..f88657686 --- /dev/null +++ b/banners/english/C24_WMDE_Desktop_EN_01/styles/Banner.scss @@ -0,0 +1,17 @@ +@use 'src/themes/Treedip/variables/fonts'; + +.wmde-banner { + &-wrapper { + font-size: 14px; + font-family: fonts.$ui; + box-shadow: var( --main-box-shadow ); + background-color: var( --main-background ); + color: var( --main-color ); + } + + &--closed { + .wmde-banner-wrapper { + display: none; + } + } +} diff --git a/banners/english/C24_WMDE_Desktop_EN_01/styles/FallbackBanner.scss b/banners/english/C24_WMDE_Desktop_EN_01/styles/FallbackBanner.scss new file mode 100644 index 000000000..997f000f9 --- /dev/null +++ b/banners/english/C24_WMDE_Desktop_EN_01/styles/FallbackBanner.scss @@ -0,0 +1,135 @@ +@use 'src/themes/Treedip/variables/globals'; +@use 'src/themes/Treedip/variables/fonts'; +@use 'sass:color'; + +$breakpoint: 800px; + +.wmde-banner { + &-fallback { + width: 100%; + height: 150px; + display: flex; + flex-direction: column; + background: var( --fallback-background ); + box-shadow: var( --main-box-shadow ); + + @media ( min-width: $breakpoint ) { + height: auto; + min-height: 250px; + padding: 4px; + } + + &-small, + &-large { + display: flex; + flex-direction: column; + flex: 1 1 auto; + } + + &-small { + align-items: center; + border: 4px solid var( --fallback-border ); + border-radius: 4px; + padding: 8px; + + .wmde-banner-progress-bar { + height: 25px; + line-height: 25px; + } + + .wmde-banner-progress-bar-text, + .wmde-banner-progress-bar-fill-wrapper { + height: 25px; + } + + .wmde-banner-progress-bar-fill { + line-height: 20px; + } + + .wmde-banner-fallback-button { + margin: 0 0 8px; + } + + .wmde-banner-selection-input-text, + .wmde-banner-selection-input-input { + font-family: fonts.$content; + font-size: 14px; + font-weight: normal; + } + } + + &-large { + align-items: stretch; + } + + &-usage-link { + color: var( --fallback-uof-link ); + } + + &-message { + flex: 1 1 auto; + display: flex; + flex-direction: column; + background: var( --fallback-message-background ); + border: 4px solid var( --fallback-message-border ); + border-radius: 4px; + padding: 8px 0; + } + + &-bank-item { + display: block; + + &-label { + font-weight: bold; + } + } + + .wmde-banner-close { + height: 16px; + width: 16px; + top: 8px; + right: 8px; + + @media ( min-width: $breakpoint ) { + height: 30px; + width: 30px; + top: 12px; + right: 12px; + } + } + + .wmde-banner-slider-container { + padding: 0 0 8px; + } + + .wmde-banner-slide-content { + font-size: 14px; + p { + margin-bottom: 8px; + } + } + + .wmde-banner-slider-navigation-previous, + .wmde-banner-slider-navigation-next { + align-items: end; + } + + .wmde-banner-slider-pagination-dot { + cursor: default; + } + + .wmde-banner-message { + flex: 1 1 auto; + + p { + margin-bottom: 0; + } + } + } + + &--pending { + .wmde-banner-fallback { + box-shadow: none; + } + } +} diff --git a/banners/english/C24_WMDE_Desktop_EN_01/styles/MainBanner.scss b/banners/english/C24_WMDE_Desktop_EN_01/styles/MainBanner.scss new file mode 100644 index 000000000..518b8c959 --- /dev/null +++ b/banners/english/C24_WMDE_Desktop_EN_01/styles/MainBanner.scss @@ -0,0 +1,44 @@ +$banner-height: 357px !default; +$form-width: 300px !default; + +.wmde-banner { + &-main { + min-height: $banner-height; + display: flex; + flex-direction: column; + padding: 12px 24px 0; + } + + &-content { + display: flex; + flex-direction: row; + flex-grow: 1; + } + + &-message { + padding: 0 15px; + } + + &-column-left { + display: flex; + flex-direction: column; + justify-content: center; + flex: 1 1 auto; + margin-bottom: 0; + overflow-y: hidden; + margin-right: 30px; + padding: 0 0 10px; + background: var( --message-background ); + border: 5px solid var( --message-border ); + border-radius: 9px; + } + + &-column-right { + order: 2; + flex: 0 0 $form-width; + display: flex; + flex-direction: column; + width: $form-width; + padding: 10px 0; + } +} diff --git a/banners/english/C24_WMDE_Desktop_EN_01/styles/styles.scss b/banners/english/C24_WMDE_Desktop_EN_01/styles/styles.scss new file mode 100644 index 000000000..c869f1d0c --- /dev/null +++ b/banners/english/C24_WMDE_Desktop_EN_01/styles/styles.scss @@ -0,0 +1,57 @@ +// This is the file where we import the theme-specific component styles +@use 'src/themes/Treedip/swatches/vector-2022' with ( + $slider: true, + $select-group-bubble: true, + $upgrade-to-yearly: true, + $fallback-banner: true, +); +@use 'src/themes/Treedip/variables/breakpoints'; +@use 'src/components/BannerConductor/banner-transition'; +@use 'Banner'; +@use 'MainBanner' with ( + $banner-height: 355px, + $form-width: 300px +); +@use 'src/themes/UseOfFunds/swatches/vector-2022' as uof-vector-2022; +@use 'src/themes/UseOfFunds/UseOfFunds'; +@use 'src/themes/Treedip/defaults'; +@use 'src/themes/Treedip/ButtonClose/ButtonClose' with ( + $padding: 4px, + $top: 12px, + $right: 8px, + $margin: -4.5px +); +@use 'src/themes/Treedip/ProgressBar/ProgressBarAlternative' with ( + $progress-bar-margin: 0 15px +); +@use 'src/themes/Treedip/DonationForm/DonationForm'; +@use 'src/themes/Treedip/DonationForm/MultiStepDonation'; +@use 'src/themes/Treedip/DonationForm/BubbleForm/SelectGroupBubble'; +@use 'src/themes/Treedip/DonationForm/BubbleForm/SelectGroupRadioBubbles' with ( + $height: 34px +); +@use 'src/themes/Treedip/DonationForm/BubbleForm/SelectCustomAmountRadioBubble' with ( + $height: 34px +); +@use 'src/themes/Treedip/DonationForm/BubbleForm/SelectGroupBubbleImageLabel'; +@use 'src/themes/Treedip/DonationForm/BubbleForm/SelectGroupBubbleImageLabel_dark'; +@use 'src/themes/Treedip/DonationForm/SubComponents/SmsBox'; +@use 'src/themes/Treedip/DonationForm/Forms/MainDonationForm' with ( + $padding: 14px 0 0 +); +@use 'src/themes/Treedip/DonationForm/Forms/UpgradeToYearlyButtonForm'; +@use 'src/themes/Treedip/DonationForm/Forms/CustomAmountForm'; +@use 'src/themes/Treedip/Footer/BannerFooter' with ( + $right-column-width: 300px +); +@use 'src/themes/Treedip/Footer/SelectionInput'; +@use 'src/themes/Treedip/Message/Message' with ( + $font-sizes: ( 1400px: 15px, 1600px: 16px, 1800px: 18px ) +); +@use 'src/themes/Treedip/Slider/KeenSlider'; +@use 'src/themes/Treedip/SoftClose/SoftClose'; +@use 'src/themes/Treedip/AlreadyDonatedModal/AlreadyDonatedModal'; +@use 'FallbackBanner'; +@use 'src/themes/Treedip/FallbackBanner/FallbackButton'; +@use 'src/themes/Treedip/FallbackBanner/LargeFooter'; +@use 'src/themes/Treedip/FallbackBanner/SmallFooter'; diff --git a/campaign_info.toml b/campaign_info.toml index d3b0dc578..4437fdd37 100644 --- a/campaign_info.toml +++ b/campaign_info.toml @@ -132,23 +132,23 @@ tracking = "wpde-mob00-240619-var" [english] name = "English Desktop" icon = "desktop" -campaign = "C24_WMDE_Desktop_EN_00" +campaign = "C24_WMDE_Desktop_EN_01" description = "Based on C23_WMDE_Desktop_EN_05" -campaign_tracking = "en00-ba-190624" +campaign_tracking = "en01-ba-090324" preview_link = "/wiki/Main_Page?devbanner={{banner}}&banner=B22_WMDE_local_prototype" preview_url = 'https://en.wikipedia.org/wiki/Main_Page?banner={{banner}}&devMode' wrapper_template = "wikipedia_org" use_of_funds_source = "MediaWiki:WMDE_Fundraising/UseOfFunds_2024_EN" [english.banners.ctrl] -filename = "./banners/english/C24_WMDE_Desktop_EN_00/banner_ctrl.ts" -pagename = "B24_WMDE_Desktop_EN_00_ctrl" -tracking = "org-en00-190624-ctrl" +filename = "./banners/english/C24_WMDE_Desktop_EN_01/banner_ctrl.ts" +pagename = "B24_WMDE_Desktop_EN_01_ctrl" +tracking = "org-en01-090324-ctrl" [english.banners.var] -filename = "./banners/english/C24_WMDE_Desktop_EN_00/banner_var.ts" -pagename = "B24_WMDE_Desktop_EN_00_var" -tracking = "org-en00-190624-var" +filename = "./banners/english/C24_WMDE_Desktop_EN_01/banner_var.ts" +pagename = "B24_WMDE_Desktop_EN_01_var" +tracking = "org-en01-090324-var" [english.test_matrix] platform = ["edge", "firefox_win10", "chrome_win10", "safari", "firefox_macos", "chrome_macos", "firefox_linux", "chrome_linux"] diff --git a/src/themes/Treedip/DonationForm/BubbleForm/SelectCustomAmountRadioBubble.scss b/src/themes/Treedip/DonationForm/BubbleForm/SelectCustomAmountRadioBubble.scss index 2f1ef94e0..62276dc5d 100644 --- a/src/themes/Treedip/DonationForm/BubbleForm/SelectCustomAmountRadioBubble.scss +++ b/src/themes/Treedip/DonationForm/BubbleForm/SelectCustomAmountRadioBubble.scss @@ -1,4 +1,5 @@ @use '../../../../components/DonationForm/SubComponents/SelectCustomAmount'; +@use 'radio-input'; $height: 23px !default; @@ -12,23 +13,16 @@ $height: 23px !default; to keep the styles in sync */ &-select-custom-amount { + position: relative; width: 50%; + height: $height; padding: 0 4px; cursor: pointer; &-radio { - /* Unclear if we need this or what it does. Probably browser fixes for text in focused elements? */ - &:checked + .wmde-banner-select-custom-amount-input-container { - border: 0 none; - outline: 0 none; - } + z-index: 2; - /* This style must be in sync with the "radio button shape" style of SelectGroup */ - &:checked + .wmde-banner-select-custom-amount-input-container::before { - border: 1px solid var( --select-group-bubble-radio-border-checked ); - box-shadow: 0 0 0 1px var( --select-group-bubble-radio-background-checked ); - background-color: var( --select-group-bubble-radio-background-checked ); - } + @include radio-input.styles( $left: 11px ); } &.value-entered, @@ -48,18 +42,6 @@ $height: 23px !default; background-color: var( --select-group-bubble-background ); border-radius: 8px; border: 1px solid var( --select-group-bubble-border ); - - /* This style must be in sync with the "radio button shape" style of SelectGroup */ - &::before { - height: 10px; - width: 10px; - top: 50%; - left: 0; - margin: -5px 0 0 4px; - background: var( --select-group-bubble-radio-background ); - border-radius: 50%; - border: 2px solid #848282; - } } &-euro-symbol { diff --git a/src/themes/Treedip/DonationForm/BubbleForm/SelectGroupRadioBubbles.scss b/src/themes/Treedip/DonationForm/BubbleForm/SelectGroupRadioBubbles.scss index caa8f3700..fe3b06a7c 100644 --- a/src/themes/Treedip/DonationForm/BubbleForm/SelectGroupRadioBubbles.scss +++ b/src/themes/Treedip/DonationForm/BubbleForm/SelectGroupRadioBubbles.scss @@ -1,4 +1,5 @@ @use '../../variables/breakpoints'; +@use 'radio-input'; $height: 23px !default; @@ -6,6 +7,7 @@ $margin-left: -6px; $border-radius: 8px; $font-size: 1.01em; $padding: 0 0 0 3px; +$check-size: 10px; .wmde-banner { &-select-group { @@ -27,6 +29,7 @@ $padding: 0 0 0 3px; } &.active label { + background: var( --select-group-bubble-background-active ); border: 2px solid var( --select-group-bubble-border-active ); } } @@ -37,34 +40,10 @@ $padding: 0 0 0 3px; font-size: $font-size; margin-left: $margin-left; padding: $padding; - - /* This creates the "radio button" shape */ - &::before { - height: 10px; - width: 10px; - margin: -5px 0 0 8px; - background: var( --select-group-bubble-radio-background ); - border-radius: 50%; - border: 2px solid var( --select-group-bubble-radio-border ); - } } &-input { - display: none; - - /* Unclear if we need this or what it does. Probably browser fixes for text in focused elements? */ - &:checked + .wmde-banner-select-group-label { - border: 0 none; - outline: 0 none; - border-radius: 0; - } - - /* This creates the "selected radio button" shape */ - &:checked + .wmde-banner-select-group-label::before { - border: 1px solid var( --select-group-bubble-radio-border-checked ); - box-shadow: 0 0 0 1px var( --select-group-bubble-radio-background-checked ); - background-color: var( --select-group-bubble-radio-background-checked ); - } + @include radio-input.styles; } } } diff --git a/src/themes/Treedip/DonationForm/BubbleForm/radio-input.scss b/src/themes/Treedip/DonationForm/BubbleForm/radio-input.scss new file mode 100644 index 000000000..f64e1d8d7 --- /dev/null +++ b/src/themes/Treedip/DonationForm/BubbleForm/radio-input.scss @@ -0,0 +1,46 @@ +@use 'sass:math'; + +$size: 10px; + +@mixin styles( $left: 6px ) { + appearance: none; + position: absolute; + top: 50%; + margin-top: -( math.div( $size, 2 ) ); + width: $size; + height: $size; + border-radius: 50%; + display: block; + box-sizing: border-box; + cursor: pointer; + transition: background 150ms ease-out; + margin-right: 10px; + left: $left; + background: var( --select-group-bubble-radio-background ); + border: 2px solid var( --select-group-bubble-radio-border ); + + &::before { + position: absolute; + top: 50%; + margin-top: -( math.div( $size, 2 ) ); + width: $size; + height: $size; + border-radius: 50%; + content: ''; + display: flex; + left: 50%; + margin-left: -( math.div( $size, 2 ) ); + background-color: var( --select-group-bubble-radio-checkmark ); + transform: scale( 0 ); + transition: transform 150ms ease-out; + } + + &:checked { + border-color: var( --select-group-bubble-radio-border-checked ); + background-color: var( --select-group-bubble-radio-background-checked ); + + &::before { + transform: scale( 0.5 ); + } + } +} diff --git a/src/themes/Treedip/FallbackBanner/LargeFooter.scss b/src/themes/Treedip/FallbackBanner/LargeFooter.scss index 535a2fe3e..5c91acc6e 100644 --- a/src/themes/Treedip/FallbackBanner/LargeFooter.scss +++ b/src/themes/Treedip/FallbackBanner/LargeFooter.scss @@ -25,7 +25,7 @@ height: 0; border-style: solid; border-width: 6px 6px 0; - border-color: var( --fallback-footer-border ) transparent transparent transparent; + border-color: var( --fallback-message-border ) transparent transparent transparent; } } diff --git a/src/themes/Treedip/swatches/dark.scss b/src/themes/Treedip/swatches/dark.scss index 80114f597..d086d9652 100644 --- a/src/themes/Treedip/swatches/dark.scss +++ b/src/themes/Treedip/swatches/dark.scss @@ -6,14 +6,17 @@ $grey150: #dddddd; $grey200: #bbbbbb; $grey300: #b7b7b7; $grey500: #808080; -$grey600: #747474; -$grey700: #202122; +$grey600: #777777; +$grey650: #383838; +$grey700: #292929; +$grey800: #1f1f1f; $red100: #ff8888; $red600: #990a00; $blue600: #4465a7; $blue700: #2a4b8d; +$blue800: #20303f; @mixin swatch( $slider: false, @@ -26,10 +29,13 @@ $blue700: #2a4b8d; $soft-close: false, $fallback-banner: false, ) { - --main-background: #{$grey700}; - --main-color: #{$grey100}; + --main-background: #{$grey800}; + --main-color: #{$white}; --main-title-line-background: #{$grey100}; --main-border-bottom: #{$grey600}; + --main-box-shadow: none; + + --message-background: #{$grey700}; --message-border: #{$red600}; --color-error: #{$red100}; @@ -42,19 +48,19 @@ $blue700: #2a4b8d; --input-selection-selected-background: #{$red600}; --input-selection-selected-color: #{$white}; - --animated-highlight-color: #{$grey700}; + --animated-highlight-color: #{$white}; /* stylelint-disable */ --animated-highlight-gradient: linear-gradient( 270deg, rgba( 255, 255, 255, 0 ) 0%, rgba( 255, 255, 255, 0 ) 50%, - rgba( 255, 222, 103 ) 50%, - rgba( 255, 222, 103 ) 100% + rgba( 42, 75, 141 ) 50%, + rgba( 42, 75, 141 ) 100% ); /* stylelint-enable */ @if $slider { - --slider-pagination-background: #{$grey700}; + --slider-pagination-background: #{$grey800}; --slider-pagination-border: #{$white}; --slider-pagination-background-active: #{$red600}; --slider-pagination-border-active: #{$red600}; @@ -85,12 +91,15 @@ $blue700: #2a4b8d; @if $select-group-bubble { --select-group-bubble-color: #{$grey150}; --select-group-bubble-background: #{$grey700}; - --select-group-bubble-border: #{$grey300}; + --select-group-bubble-background-active: #{$blue800}; + --select-group-bubble-border: #{$grey650}; --select-group-bubble-border-active: #{$blue700}; + --select-group-bubble-radio-background: #{$white}; - --select-group-bubble-radio-border: #{$grey500}; + --select-group-bubble-radio-border: #{$grey600}; --select-group-bubble-radio-background-checked: #{$blue700}; --select-group-bubble-radio-border-checked: #{$white}; + --select-group-bubble-radio-checkmark: #{$blue700}; } @if $select-group-button { @@ -120,13 +129,13 @@ $blue700: #2a4b8d; } @if $fallback-banner { - --fallback-background: #{$grey700}; - --fallback-border: #{$grey100}; + --fallback-background: #{$grey800}; + --fallback-border: #{$red600}; --fallback-button-background: #{$blue700}; --fallback-button-color: #{$white}; --fallback-button-background-hover: #{$blue600}; + --fallback-message-background: #{$grey700}; --fallback-message-border: #{$red600}; --fallback-uof-link: #{$grey200}; - --fallback-footer-border: #{$grey500}; } } diff --git a/src/themes/Treedip/swatches/light.scss b/src/themes/Treedip/swatches/light.scss index bcb8f7267..674a3781a 100644 --- a/src/themes/Treedip/swatches/light.scss +++ b/src/themes/Treedip/swatches/light.scss @@ -29,6 +29,9 @@ $blue700: #2a4b8d; --main-color: #{$grey700}; --main-title-line-background: #{$red600}; --main-border-bottom: #{$grey200}; + --main-box-shadow: 0 3px 0.6em rgba( 60 60 60 / 40% ); + + --message-background: #{$white}; --message-border: #{$red600}; --color-error: #{$red600}; @@ -84,12 +87,15 @@ $blue700: #2a4b8d; @if $select-group-bubble { --select-group-bubble-color: #{$black}; --select-group-bubble-background: #{$white}; + --select-group-bubble-background-active: #{$white}; --select-group-bubble-border: #{$grey300}; --select-group-bubble-border-active: #{$blue700}; + --select-group-bubble-radio-background: #{$white}; --select-group-bubble-radio-border: #{$grey500}; - --select-group-bubble-radio-background-checked: #{$blue700}; - --select-group-bubble-radio-border-checked: #{$white}; + --select-group-bubble-radio-background-checked: #{$white}; + --select-group-bubble-radio-border-checked: #{$blue700}; + --select-group-bubble-radio-checkmark: #{$blue700}; } @if $select-group-button { @@ -124,8 +130,8 @@ $blue700: #2a4b8d; --fallback-button-background: #{$blue700}; --fallback-button-color: #{$white}; --fallback-button-background-hover: #{$blue600}; + --fallback-message-background: #{$white}; --fallback-message-border: #{$red600}; --fallback-uof-link: #{$grey500}; - --fallback-footer-border: #{$grey500}; } } diff --git a/test/banners/english/components/BannerCtrl.spec.ts b/test/banners/english/components/BannerCtrl.spec.ts index a2091a971..2e9881b74 100644 --- a/test/banners/english/components/BannerCtrl.spec.ts +++ b/test/banners/english/components/BannerCtrl.spec.ts @@ -1,12 +1,11 @@ import { afterEach, beforeEach, describe, test, vi } from 'vitest'; import { mount, VueWrapper } from '@vue/test-utils'; -import Banner from '@banners/english/C24_WMDE_Desktop_EN_00/components/BannerCtrl.vue'; +import Banner from '@banners/english/C24_WMDE_Desktop_EN_01/components/BannerCtrl.vue'; import { BannerStates } from '@src/components/BannerConductor/StateMachine/BannerStates'; import { newDynamicContent } from '@test/banners/dynamicCampaignContent'; import { useOfFundsContent } from '@test/banners/useOfFundsContent'; import { formItems } from '@test/banners/formItems'; import { CurrencyEn } from '@src/utils/DynamicContent/formatters/CurrencyEn'; -import { softCloseFeatures } from '@test/features/SoftCloseDesktop'; import { useOfFundsFeatures } from '@test/features/UseOfFunds'; import { bannerContentAnimatedTextFeatures, bannerContentDateAndTimeFeatures, @@ -61,7 +60,7 @@ describe( 'BannerCtrl.vue', () => { describe( 'Main Banner', () => { test.each( [ - [ 'expectDoesNotEmitCloseEvent' ] + [ 'expectEmitsCloseEvent' ] ] )( '%s', async ( testName: string ) => { await bannerMainFeatures[ testName ]( getWrapper() ); } ); @@ -109,21 +108,6 @@ describe( 'BannerCtrl.vue', () => { } ); } ); - describe( 'Soft Close', () => { - test.each( [ - [ 'expectShowsSoftClose' ], - [ 'expectEmitsSoftCloseCloseEvent' ], - [ 'expectEmitsSoftCloseMaybeLaterEvent' ], - [ 'expectEmitsSoftCloseTimeOutEvent' ], - [ 'expectEmitsBannerContentChangedOnSoftClose' ], - [ 'expectDoesNotShowSoftCloseOnFinalBannerImpression' ], - [ 'expectShowsCloseIcon' ], - [ 'expectCloseIconEmitsCloseEvent' ] - ] )( '%s', async ( testName: string ) => { - await softCloseFeatures[ testName ]( getWrapper() ); - } ); - } ); - describe( 'Use of Funds', () => { test.each( [ [ 'expectShowsUseOfFunds' ], @@ -132,5 +116,4 @@ describe( 'BannerCtrl.vue', () => { await useOfFundsFeatures[ testName ]( getWrapper() ); } ); } ); - } ); diff --git a/test/banners/english/components/BannerVar.spec.ts b/test/banners/english/components/BannerVar.spec.ts deleted file mode 100644 index 5fb6c7b31..000000000 --- a/test/banners/english/components/BannerVar.spec.ts +++ /dev/null @@ -1,146 +0,0 @@ -import { afterEach, beforeEach, describe, test, vi } from 'vitest'; -import { mount, VueWrapper } from '@vue/test-utils'; -import Banner from '@banners/english/C24_WMDE_Desktop_EN_00/components/BannerVar.vue'; -import { BannerStates } from '@src/components/BannerConductor/StateMachine/BannerStates'; -import { newDynamicContent } from '@test/banners/dynamicCampaignContent'; -import { useOfFundsContent } from '@test/banners/useOfFundsContent'; -import { formItems } from '@test/banners/formItems'; -import { CurrencyEn } from '@src/utils/DynamicContent/formatters/CurrencyEn'; -import { softCloseFeatures } from '@test/features/SoftCloseDesktop'; -import { useOfFundsFeatures } from '@test/features/UseOfFunds'; -import { - bannerContentAnimatedTextFeatures, bannerContentDateAndTimeFeatures, - bannerContentDisplaySwitchFeatures, - bannerContentFeatures -} from '@test/features/BannerContent'; -import { TrackerStub } from '@test/fixtures/TrackerStub'; -import { donationFormFeatures } from '@test/features/forms/MainDonation_UpgradeToYearlyButton'; -import { useFormModel } from '@src/components/composables/useFormModel'; -import { resetFormModel } from '@test/resetFormModel'; -import { bannerMainFeatures } from '@test/features/MainBanner'; -import { DynamicContent } from '@src/utils/DynamicContent/DynamicContent'; -import { formActionSwitchFeatures } from '@test/features/form_action_switch/MainDonation_UpgradeToYearlyButton'; - -const formModel = useFormModel(); -const translator = ( key: string ): string => key; - -describe( 'BannerVar.vue', () => { - - beforeEach( () => { - resetFormModel( formModel ); - vi.useFakeTimers(); - } ); - - afterEach( () => { - vi.restoreAllMocks(); - vi.useRealTimers(); - } ); - - const getWrapper = ( dynamicContent: DynamicContent = null ): VueWrapper => { - return mount( Banner, { - attachTo: document.body, - props: { - bannerState: BannerStates.Pending, - useOfFundsContent, - remainingImpressions: 10 - }, - global: { - mocks: { - $translate: translator - }, - provide: { - translator: { translate: translator }, - dynamicCampaignText: dynamicContent ?? newDynamicContent(), - formActions: { donateWithAddressAction: 'https://example.com/with-address', donateAnonymouslyAction: 'https://example.com/without-address' }, - currencyFormatter: new CurrencyEn(), - formItems, - tracker: new TrackerStub() - } - } - } ); - }; - - describe( 'Main Banner', () => { - test.each( [ - [ 'expectDoesNotEmitCloseEvent' ] - ] )( '%s', async ( testName: string ) => { - await bannerMainFeatures[ testName ]( getWrapper() ); - } ); - } ); - - describe( 'Content', () => { - test.each( [ - [ 'expectSlideShowPlaysWhenBecomesVisible' ], - [ 'expectSlideShowStopsOnFormInteraction' ] - ] )( '%s', async ( testName: string ) => { - await bannerContentFeatures[ testName ]( getWrapper() ); - } ); - - test.each( [ - [ 'expectShowsSlideShowOnSmallSizes' ], - [ 'expectShowsMessageOnLargeSizes' ] - ] )( '%s', async ( testName: string ) => { - await bannerContentDisplaySwitchFeatures[ testName ]( getWrapper, 1300 ); - } ); - - test.each( [ - [ 'expectShowsAnimatedVisitorsVsDonorsSentenceInMessage' ], - [ 'expectShowsAnimatedVisitorsVsDonorsSentenceInSlideShow' ] - ] )( '%s', async ( testName: string ) => { - await bannerContentAnimatedTextFeatures[ testName ]( getWrapper ); - } ); - - test.each( [ - [ 'expectShowsLiveDateAndTimeInMessage' ], - [ 'expectShowsLiveDateAndTimeInSlideshow' ] - ] )( '%s', async ( testName: string ) => { - await bannerContentDateAndTimeFeatures[ testName ]( getWrapper ); - } ); - } ); - - describe( 'Donation Form Happy Paths', () => { - test.each( [ - [ 'expectMainDonationFormSubmitsWhenSofortIsSelected' ], - [ 'expectMainDonationFormSubmitsWhenYearlyIsSelected' ], - [ 'expectMainDonationFormGoesToUpgrade' ], - [ 'expectUpgradeToYearlyFormSubmitsUpgrade' ], - [ 'expectUpgradeToYearlyFormSubmitsDontUpgrade' ] - ] )( '%s', async ( testName: string ) => { - await donationFormFeatures[ testName ]( getWrapper() ); - } ); - - test.each( [ - [ 'expectMainDonationFormSubmitsWithAddressForDirectDebit' ], - [ 'expectMainDonationFormSubmitsWithoutAddressForPayPal' ], - [ 'expectUpgradeToYearlyFormSubmitsWithAddressForDirectDebit' ], - [ 'expectUpgradeToYearlyFormSubmitsWithoutAddressForPayPal' ] - ] )( '%s', async ( testName: string ) => { - await formActionSwitchFeatures[ testName ]( getWrapper() ); - } ); - } ); - - describe( 'Soft Close', () => { - test.each( [ - [ 'expectShowsSoftClose' ], - [ 'expectEmitsSoftCloseCloseEvent' ], - [ 'expectEmitsSoftCloseMaybeLaterEvent' ], - [ 'expectEmitsSoftCloseTimeOutEvent' ], - [ 'expectEmitsBannerContentChangedOnSoftClose' ], - [ 'expectDoesNotShowSoftCloseOnFinalBannerImpression' ], - [ 'expectShowsCloseIcon' ], - [ 'expectCloseIconEmitsCloseEvent' ] - ] )( '%s', async ( testName: string ) => { - await softCloseFeatures[ testName ]( getWrapper() ); - } ); - } ); - - describe( 'Use of Funds', () => { - test.each( [ - [ 'expectShowsUseOfFunds' ], - [ 'expectHidesUseOfFunds' ] - ] )( '%s', async ( testName: string ) => { - await useOfFundsFeatures[ testName ]( getWrapper() ); - } ); - } ); - -} ); diff --git a/test/banners/english/components/FallbackBanner.spec.ts b/test/banners/english/components/FallbackBanner.spec.ts index c03310f21..71b523603 100644 --- a/test/banners/english/components/FallbackBanner.spec.ts +++ b/test/banners/english/components/FallbackBanner.spec.ts @@ -1,6 +1,6 @@ import { afterEach, beforeEach, describe, test, vi } from 'vitest'; import { mount, VueWrapper } from '@vue/test-utils'; -import FallbackBanner from '@banners/english/C24_WMDE_Desktop_EN_00/components/FallbackBanner.vue'; +import FallbackBanner from '@banners/english/C24_WMDE_Desktop_EN_01/components/FallbackBanner.vue'; import { BannerStates } from '@src/components/BannerConductor/StateMachine/BannerStates'; import { useOfFundsContent } from '@test/banners/useOfFundsContent'; import { newDynamicContent } from '@test/banners/dynamicCampaignContent';