diff --git a/src/assets/image/newsletter-feature/newsletter.webp b/src/assets/image/newsletter-feature/newsletter.webp new file mode 100644 index 000000000..8448c4aa5 Binary files /dev/null and b/src/assets/image/newsletter-feature/newsletter.webp differ diff --git a/src/components/__tests__/NewsletterFeature.cy.js b/src/components/__tests__/NewsletterFeature.cy.js index a4598c07c..3fee4801e 100644 --- a/src/components/__tests__/NewsletterFeature.cy.js +++ b/src/components/__tests__/NewsletterFeature.cy.js @@ -2,20 +2,43 @@ import { colors } from 'quasar'; import NewsletterFeature from '../homepage/NewsletterFeature.vue'; import { i18n } from '../../boot/i18n'; +// colors const { getPaletteColor } = colors; -const black = getPaletteColor('black'); +const grey10 = getPaletteColor('grey-10'); +const primary = getPaletteColor('primary'); + +// selectors +const selectorSectionHeadingTitle = 'section-heading-title'; +const selectorSectionHeadingPerex = 'section-heading-perex'; +const selectorNewsletterFeatureImage = 'newsletter-feature-image'; +const selectorNewsletterFeatureItem = 'newsletter-feature-item'; +const selectorNewsletterFeatureSeparator = 'newsletter-feature-separator'; +const selectorNewsletterColImage = 'newsletter-col-image'; +const selectorNewsletterColContent = 'newsletter-col-content'; + +// variables +const fontSizeTitle = '24px'; +const fontWeightBold = '700'; +const fontSizePerex = '14px'; +const fontWeightRegular = '400'; +const marginMd = '16px'; +const props = { + title: 'Custom title', + description: 'Custom description', +}; describe('', () => { it('has translation for all strings', () => { cy.testLanguageStringsInContext( [ - 'title', - 'description', 'aboutChallenges', 'aboutEvents', 'aboutMobility', + 'description', 'following', 'follow', + 'hint', + 'title', ], 'index.newsletterFeature', i18n, @@ -30,43 +53,15 @@ describe('', () => { cy.viewport('macbook-16'); }); - it('renders title', () => { - cy.window().then(() => { - cy.dataCy('section-heading-title') - .should('have.css', 'font-size', '20px') - .and('have.css', 'font-weight', '500') - .and('have.color', black) - .and('contain', i18n.global.t('index.newsletterFeature.title')) - .then(($title) => { - expect($title.text()).to.contain( - i18n.global.t('index.newsletterFeature.title'), - ); - }); - }); - }); - - it('renders description', () => { - cy.window().then(() => { - cy.dataCy('section-heading-perex') - .should('have.css', 'font-size', '14px') - .and('have.css', 'font-weight', '400') - .and('have.color', black) - .and('contain', i18n.global.t('index.newsletterFeature.description')) - .then(($title) => { - expect($title.text()).to.contain( - i18n.global.t('index.newsletterFeature.description'), - ); - }); - }); - }); + coreTests(); it('renders image', () => { cy.window().then(() => { - cy.dataCy('newsletter-feature-image') + cy.dataCy(selectorNewsletterFeatureImage) .should('be.visible') .find('img') .should('be.visible'); - cy.dataCy('newsletter-feature-image').matchImageSnapshot({ + cy.dataCy(selectorNewsletterFeatureImage).matchImageSnapshot({ failureThreshold: 0.5, failureThresholdType: 'percent', }); @@ -75,7 +70,7 @@ describe('', () => { it('renders correct number of items', () => { cy.window().then(() => { - cy.dataCy('newsletter-feature-item') + cy.dataCy(selectorNewsletterFeatureItem) .should('have.length', 3) .each(($item) => { cy.wrap($item).should('be.visible'); @@ -85,73 +80,103 @@ describe('', () => { it('renders divider between items', () => { cy.window().then(() => { - cy.dataCy('newsletter-feature-separator') + cy.dataCy(selectorNewsletterFeatureSeparator) .should('be.visible') .and('have.length', 2) - .and('have.css', 'margin-top', '16px') - .and('have.css', 'margin-bottom', '16px'); + .and('have.css', 'margin-top', marginMd) + .and('have.css', 'margin-bottom', marginMd); }); }); it('renders grid', () => { cy.window().then(() => { - cy.testElementPercentageWidth(cy.dataCy('newsletter-col-image'), 16.6); cy.testElementPercentageWidth( - cy.dataCy('newsletter-col-content'), - 83.3, + cy.dataCy(selectorNewsletterColImage), + 25, + ); + cy.testElementPercentageWidth( + cy.dataCy(selectorNewsletterColContent), + 75, ); }); }); }); - context('mobile', () => { + context('desktop override props', () => { beforeEach(() => { cy.mount(NewsletterFeature, { - props: {}, + props, }); - cy.viewport('iphone-6'); + cy.viewport('macbook-16'); }); it('renders title', () => { - cy.window().then(() => { - cy.dataCy('section-heading-title') - .should('have.css', 'font-size', '20px') - .and('have.css', 'font-weight', '500') - .and('have.color', black) - .and('contain', i18n.global.t('index.newsletterFeature.title')) - .then(($title) => { - expect($title.text()).to.contain( - i18n.global.t('index.newsletterFeature.title'), - ); - }); - }); + cy.dataCy(selectorSectionHeadingTitle).should('contain', props.title); }); it('renders description', () => { - cy.window().then(() => { - cy.dataCy('section-heading-perex') - .should('have.css', 'font-size', '14px') - .and('have.css', 'font-weight', '400') - .and('have.color', black) - .and('contain', i18n.global.t('index.newsletterFeature.description')) - .then(($title) => { - expect($title.text()).to.contain( - i18n.global.t('index.newsletterFeature.description'), - ); - }); + cy.dataCy(selectorSectionHeadingPerex).should( + 'contain', + props.description, + ); + }); + }); + + context('mobile', () => { + beforeEach(() => { + cy.mount(NewsletterFeature, { + props: {}, }); + cy.viewport('iphone-6'); }); + coreTests(); + it('does not render image', () => { cy.window().then(() => { - cy.dataCy('newsletter-feature-image').should('not.be.visible'); + cy.dataCy(selectorNewsletterFeatureImage).should('not.be.visible'); }); }); it('renders grid', () => { cy.window().then(() => { - cy.testElementPercentageWidth(cy.dataCy('newsletter-col-content'), 100); + cy.testElementPercentageWidth( + cy.dataCy(selectorNewsletterColContent), + 100, + ); }); }); }); }); + +function coreTests() { + it('renders title', () => { + cy.window().then(() => { + cy.dataCy(selectorSectionHeadingTitle) + .should('have.css', 'font-size', fontSizeTitle) + .and('have.css', 'font-weight', fontWeightBold) + .and('have.color', primary) + .and('contain', i18n.global.t('index.newsletterFeature.title')) + .then(($title) => { + expect($title.text()).to.contain( + i18n.global.t('index.newsletterFeature.title'), + ); + }); + }); + }); + + it('renders description', () => { + cy.window().then(() => { + cy.dataCy(selectorSectionHeadingPerex) + .should('have.css', 'font-size', fontSizePerex) + .and('have.css', 'font-weight', fontWeightRegular) + .and('have.color', grey10) + .and('contain', i18n.global.t('index.newsletterFeature.description')) + .then(($title) => { + expect($title.text()).to.contain( + i18n.global.t('index.newsletterFeature.description'), + ); + }); + }); + }); +} diff --git a/src/components/homepage/NewsletterFeature.vue b/src/components/homepage/NewsletterFeature.vue index a729416be..dfae20213 100644 --- a/src/components/homepage/NewsletterFeature.vue +++ b/src/components/homepage/NewsletterFeature.vue @@ -2,43 +2,81 @@ /** * NewsletterFeature Component * - * The `NewsletterFeature` component displays a newsletter section, - * with various newsletter option items. - * * @description - * This component provides a visually appealing section to promote newsletters. - * It uses predefined mock data to display a list of newsletter items using the - * `NewsletterItem` child component. + * Display a newsletter section with a title, description, and a list of + * newsletter items. You can subscribe to the different topics. + * You can use the title prop to override the default title. + * You can use the description prop to override the default description. + * + * @props + * - `title`: (string) Custom title for the newsletter section. + * - `description`: (string) Custom description for the newsletter section. * * @components * - `NewsletterItem`: Component to render individual newsletter details. - * - `SectionHeading`: Component to render a heading. * * @example - * + * * * @see [Figma Design](https://www.figma.com/file/L8dVREySVXxh3X12TcFDdR/Do-pr%C3%A1ce-na-kole?type=design&node-id=4858%3A105656&mode=dev) */ // libraries -import { defineComponent } from 'vue'; +import { Screen } from 'quasar'; +import { computed, defineComponent, reactive } from 'vue'; + +// components +import NewsletterItem from './NewsletterItem.vue'; + +// composables +import { i18n } from '../../boot/i18n'; // mocks import { newsletterItems } from '../../mocks/homepage'; -// components -import NewsletterItem from './NewsletterItem.vue'; -import SectionHeading from '../global/SectionHeading.vue'; +// stores +import { useLoginStore } from '../../stores/login'; export default defineComponent({ name: 'NewsletterFeature', + props: { + title: { + type: String, + required: false, + }, + description: { + type: String, + required: false, + }, + }, components: { NewsletterItem, - SectionHeading, }, - setup() { + setup(props) { + const loginStore = useLoginStore(); + const user = reactive(loginStore.getUser); + + const newsletterTitle = computed(() => { + return props.title + ? props.title + : i18n.global.t('index.newsletterFeature.title'); + }); + + const newsletterDescription = computed(() => { + return props.description + ? props.description + : i18n.global.t('index.newsletterFeature.description', { + email: user?.email ? ` ${user.email}` : '', + }); + }); + + const headingMaxWidth = Screen.sizes.sm; + return { + headingMaxWidth, + newsletterDescription, newsletterItems, + newsletterTitle, }; }, }); @@ -50,30 +88,44 @@ export default defineComponent({ class="row q-col-gutter-lg items-center justify-between" > -
+
-
+
- - {{ $t('index.newsletterFeature.title') }} - - -
+

+ {{ newsletterTitle }} +

+
+
+ {{ $t('index.newsletterFeature.hint') }} +
+
@@ -86,10 +138,3 @@ export default defineComponent({
- - diff --git a/src/i18n/cs.toml b/src/i18n/cs.toml index 8d7f20afc..c7103619d 100755 --- a/src/i18n/cs.toml +++ b/src/i18n/cs.toml @@ -374,13 +374,14 @@ title = "Vaše výsledky" button = "Všechny výsledky" [index.newsletterFeature] -title = "Odebírejte od nás novinky, ať vám nic neuteče" -description = "Newsletter vám budeme posílat na e-mail jana.anonymni[at]dopracenakole.cz." aboutChallenges = "O budoucích výzvách" aboutEvents = "O doprovodných akcích (cyklojízdách, snídaních...), Akcích na triko a slevách" aboutMobility = "O udržitelné mobilitě" +description = "Newsletter vám budeme posílat na e-mail{email}." following = "Již sledujete" follow = "Začít sledovat" +hint = "O čem chcete být informováni e-mailem?" +title = "Odebírejte od nás novinky, ať vám nic neuteče" [index.newsletterSwitch] title = "Zůstaňte informováni o všem kolem Do práce na kole" diff --git a/src/i18n/en.toml b/src/i18n/en.toml index 288c74eb9..c2db7ed6e 100755 --- a/src/i18n/en.toml +++ b/src/i18n/en.toml @@ -371,13 +371,14 @@ title = "Your results" button = "All results" [index.newsletterFeature] -title = "Subscribe to our newsletter so you don't miss anything" -description = "The newsletter will be sent to your email jana.anonymni[at]dopracenakole.cz." aboutChallenges = "About future challenges" aboutEvents = "About accompanying events (bike rides, breakfasts...), T-shirt events and discounts" aboutMobility = "About sustainable mobility" +description = "The newsletter will be sent to your email{email}." following = "Following" follow = "Follow" +hint = "What do you want to be informed about by email?" +title = "Subscribe to our newsletter so you don't miss anything" [index.newsletterSwitch] title = "Stay informed about everything around Ride to Work by Bike" diff --git a/src/i18n/sk.toml b/src/i18n/sk.toml index 7369a35ab..e03f84c90 100755 --- a/src/i18n/sk.toml +++ b/src/i18n/sk.toml @@ -371,13 +371,14 @@ title = "Vaše výsledky" button = "Všetky výsledky" [index.newsletterFeature] -title = "Prihláste sa na odber nášho newslettera, aby vám nič neuniklo" -description = "Newsletter vám bude zaslaný na e-mailovú adresu jana.anonymni[at]dopracenakole.cz." aboutChallenges = "O budúcich výzvach" aboutEvents = "O sprievodných podujatiach (cyklojazdy, raňajky...), akciách na tričká a zľavách" aboutMobility = "O udržateľnej mobilite" +description = "Newsletter vám bude zaslaný na e-mailovú adresu{email}." following = "Už sledujete" follow = "Začať sledovať" +hint = "O čom chcete byť informovaní e-mailom?" +title = "Prihláste sa na odber nášho newslettera, aby vám nič neuniklo" [index.newsletterSwitch] title = "Zostaňte informovaní o všetkom, čo sa týka dochádzania do práce na bicykli"