From 3501959eaf6480c0a68c88d900ee6d42cf2e6e69 Mon Sep 17 00:00:00 2001 From: njazuli <78890281+njazuli-deriv@users.noreply.github.com> Date: Thu, 26 Aug 2021 21:57:18 +0800 Subject: [PATCH] added sidebanner email subscription --- .../blog-article-email-subscription.svg | 1 + .../_agreement-label.js | 64 +++ .../side-subscription-banner/index.js | 377 ++++++++++++++++++ src/pages/academy/blog/posts/_style.js | 12 + src/pages/academy/blog/posts/preview/index.js | 302 +++++++------- src/pages/blog/components/_subscribe.js | 4 + src/templates/article.js | 310 +++++++------- src/themes/variables.js | 1 + 8 files changed, 802 insertions(+), 269 deletions(-) create mode 100644 src/images/svg/blog/articles/blog-article-email-subscription.svg create mode 100644 src/pages/academy/blog/components/side-subscription-banner/_agreement-label.js create mode 100644 src/pages/academy/blog/components/side-subscription-banner/index.js diff --git a/src/images/svg/blog/articles/blog-article-email-subscription.svg b/src/images/svg/blog/articles/blog-article-email-subscription.svg new file mode 100644 index 00000000000..9244210b924 --- /dev/null +++ b/src/images/svg/blog/articles/blog-article-email-subscription.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/pages/academy/blog/components/side-subscription-banner/_agreement-label.js b/src/pages/academy/blog/components/side-subscription-banner/_agreement-label.js new file mode 100644 index 00000000000..7d09cc1d50a --- /dev/null +++ b/src/pages/academy/blog/components/side-subscription-banner/_agreement-label.js @@ -0,0 +1,64 @@ +import React from 'react' +import PropTypes from 'prop-types' +import styled from 'styled-components' +import { Checkbox, LocalizedLinkText } from 'components/elements' +import { Localize } from 'components/localization' +import device from 'themes/device.js' + +const CheckboxSpan = styled.span` + font-size: var(--text-size-xs); + color: ${(props) => (props.color ? props.color : 'black')}; + + a { + font-weight: 700; + } + @media ${device.tabletL} { + font-size: 1.75rem; + } +` +const AgreementLabel = ({ handleChangeCheckbox, isChecked, color }) => { + const handleChange = (event) => { + handleChangeCheckbox(event) + } + + return ( + + ) +} + +AgreementLabel.propTypes = { + color: PropTypes.string, + handleChangeCheckbox: PropTypes.func, + isChecked: PropTypes.bool, +} + +export default AgreementLabel diff --git a/src/pages/academy/blog/components/side-subscription-banner/index.js b/src/pages/academy/blog/components/side-subscription-banner/index.js new file mode 100644 index 00000000000..c904121a2be --- /dev/null +++ b/src/pages/academy/blog/components/side-subscription-banner/index.js @@ -0,0 +1,377 @@ +import React, { useEffect } from 'react' +import styled from 'styled-components' +import { TextWrapper } from '../../../../blog/components/_common' +import AgreementLabel from './_agreement-label' +import validation from 'common/validation' +import { localize, Localize } from 'components/localization' +import { Button } from 'components/form' +import { Header, Text } from 'components/elements' +import { Flex } from 'components/containers' +import device from 'themes/device.js' +import { DerivStore } from 'store' +import EmailSubscriptionSVG from 'images/svg/blog/articles/blog-article-email-subscription.svg' +import CrossIcon from 'images/svg/cross.svg' + +const SubscribeBannerWrapper = styled(Flex)` + max-width: 282px; + padding: 32px 16px; + background: var(--color-grey-42); + border-radius: 8px; + margin-top: 40px; + @media ${device.tabletL} { + max-width: 328px; + padding: 32px 18.5px; + } + @media ${device.mobileS} { + max-width: 100%; + } +` +const ImageWrapper = styled.img` + width: 167.49px; +` +const StyledHeader = styled(Header)` + margin-bottom: 16px; + @media ${device.tabletL} { + margin-bottom: 8px; + } +` +const StyledSmallHeader = styled(Header)` + margin-bottom: 24px; +` +const EmailForm = styled.form` + width: 100%; + display: flex; + flex-direction: column; + + .link-text { + color: var(--color-grey-19); + font-weight: bold; + } +` +const InputWrapper = styled.div` + width: 100%; + display: flex; + flex-direction: column; + position: relative; +` +const Input = styled.input` + width: 100%; + height: 46.5px; + border-radius: 4px; + padding: 16px 18px 14px; + margin-bottom: 8px; + font-size: 12px; + line-height: 18px; + color: var(--color-grey-5); + border: 1px solid var(--color-grey-6); + background-color: var(--color-white); + + &:hover, + &:focus-within { + border-color: var(--color-grey-5); + } + &:focus { + outline: none; + } +` +const EmailButton = styled(Button)` + padding: 9px 28px; + border-radius: 4px; + margin-bottom: 8px; + height: 46px; + @media ${device.tabletL} { + padding: 10px 16px; + white-space: nowrap; + min-width: unset; + margin-left: 0; + width: auto; + } +` +const ErrorMessages = styled(Text)` + font-size: 11px; + min-height: 16px; + margin-top: -4px; + margin-bottom: 4px; +` +const StyledError = styled.img` + position: absolute; + right: 8px; + top: 16px; + height: 1.6rem; + width: 1.6rem; + cursor: pointer; +` + +const ArticleEmailBanner = () => { + const [is_checked, setChecked] = React.useState(false) + const [email, setEmail] = React.useState('') + const [name, setName] = React.useState('') + const [is_submitting, setIsSubmitting] = React.useState(false) + const [submit_status, setSubmitStatus] = React.useState('') + const [email_error_msg, setEmailErrorMsg] = React.useState('') + const [name_error_msg, setNameErrorMsg] = React.useState('') + const [submit_error_msg, setSubmitErrorMsg] = React.useState('') + + const { is_eu_country } = React.useContext(DerivStore) + + useEffect(() => { + addScriptForCIO() + const options = { + headers: new Headers({ 'content-type': 'application/json' }), + mode: 'no-cors', + } + const url = 'https://assets.customer.io/assets/track.js' + fetch(url, options) + .then(() => { + setSubmitStatus(true) + }) + .catch(() => { + setSubmitStatus(false) + }) + }, []) + + const addScriptForCIO = () => { + const addScript = (settings) => { + const script = document.createElement('script') + const { async, text, src, id } = settings + + if (async) script.async = settings['async'] + if (text) script.text = settings['text'] + if (src) script.src = settings['src'] + if (id) script.id = settings['id'] + document.body.appendChild(script) + } + const site_id = process.env.GATSBY_ENV_CIO_SITE_ID + + let cio_url = 'https://assets.customer.io/assets/track.js' + if (is_eu_country) { + cio_url = 'https://assets.customer.io/assets/track-eu.js' + } + + addScript({ + text: ` + var _cio = _cio || []; + var a,b,c;a=function(f){return function(){_cio.push([f]. + concat(Array.prototype.slice.call(arguments,0)))}};b=["load","identify", + "sidentify","track","page"];for(c=0;c { + setChecked(event.currentTarget.checked) + } + + const handleInputNameChange = (e) => { + const { value } = e.target + + setName(value) + handleValidation(value, 'name') + } + + const handleInputChange = (e) => { + const { value } = e.target + + setEmail(value) + handleValidation(value, 'email') + } + + const handleValidation = (param, type) => { + const message = typeof param === 'object' ? param.target.value : param + + if (type == 'email') { + setEmailErrorMsg(validateEmail(message.replace(/\s/g, ''))) + } + + if (type == 'name') { + setNameErrorMsg(validateName(message.replace(/\s/g, ''))) + } + } + + const validateEmail = (email) => { + const error_message = validation.email(email) || submit_error_msg + + if (submit_error_msg) { + setSubmitErrorMsg('') + setSubmitStatus('') + } + + return error_message + } + + const validateName = (name) => { + const error_message = validation.name(name) || submit_error_msg + + if (submit_error_msg) { + setSubmitErrorMsg('') + setSubmitStatus('') + } + + return error_message + } + + const clearEmail = () => { + setEmail('') + setEmailErrorMsg('') + } + + const clearName = () => { + setName('') + setNameErrorMsg('') + } + + const customerioData = () => { + window._cio.identify({ + id: email, + email, + created_at: Math.round(Date.now() / 1000), + name, + }) + } + + const handleEmailSignup = (e) => { + e.preventDefault() + setIsSubmitting(true) + const formattedEmail = email.replace(/\s/g, '') + handleValidation(email, 'email') + handleValidation(name, 'name') + const has_error_email = validateEmail(formattedEmail) + const has_error_name = validateName(formattedEmail) + + if (has_error_email || has_error_name || email_error_msg || name_error_msg) { + return setIsSubmitting(false) + } + + customerioData(formattedEmail) + submit_status && setSubmitStatus('success') + clearName() + clearEmail() + } + + return ( + + + + + + {localize('Subscribe to our blog via email')} + + + {localize( + 'Be among the first to get new content delivered to your inbox once a month by subscribing to our blog updates. ', + )} + + + + + + + {name_error_msg && ( + <> + + {name_error_msg} + + + { + clearName(name) + }} + /> + + )} + + + + {email_error_msg && ( + <> + + {email_error_msg} + + + { + clearEmail(email) + }} + /> + + )} + + {localize('Subscribe')} + + {submit_status === true && ( + + )} + + + + {submit_status === 'success' && ( + + + + )} + {submit_status === false && ( + + + + )} + + + ) +} + +export default ArticleEmailBanner diff --git a/src/pages/academy/blog/posts/_style.js b/src/pages/academy/blog/posts/_style.js index 5af906a8d3c..f8fdc474dea 100644 --- a/src/pages/academy/blog/posts/_style.js +++ b/src/pages/academy/blog/posts/_style.js @@ -327,3 +327,15 @@ export const LeftSocialComponents = styled.div` export const RightSocialComponents = styled.div` width: auto; ` +export const DesktopWrapper = styled(Flex)` + @media ${device.tabletS} { + display: none; + } +` +export const MobileWrapper = styled.div` + display: none; + + @media ${device.tabletS} { + display: flex; + } +` diff --git a/src/pages/academy/blog/posts/preview/index.js b/src/pages/academy/blog/posts/preview/index.js index 9ea40571d71..287df2cd3c6 100644 --- a/src/pages/academy/blog/posts/preview/index.js +++ b/src/pages/academy/blog/posts/preview/index.js @@ -19,8 +19,11 @@ import { SocialComponentsWrapper, LeftSocialComponents, RightSocialComponents, + DesktopWrapper, + MobileWrapper, } from '../_style' import Banner from '../../../../blog/components/_banner' +import ArticleEmailBanner from '../../components/side-subscription-banner' import SocialSharing from '../../../../blog/_social-sharing' import { localize, WithIntl } from 'components/localization' import Layout from 'components/layout/layout' @@ -121,6 +124,7 @@ const BlogPreview = (props) => { return items.id == params }) setPostData(item_data) + window.scrollTo(0, 0) } }, [isMounted]) @@ -153,153 +157,181 @@ const BlogPreview = (props) => { title={'Blog Post Preview | Deriv Academy'} no_index /> + <> + {isMounted && ( + + + + + + {post_data?.published_date && + localize(convertDate(post_data?.published_date))} + +
+ {post_data?.blog_title} +
+ + {post_data?.read_time_in_minutes && + localize(post_data?.read_time_in_minutes + ' min read')} + + + + + {post_data?.tags.map((tag) => { + return ( + <> + {tag?.tags_id?.id && ( + + {tag?.tags_id?.tag_name} + + )} + + ) + })} + + + - - - - - - {post_data?.published_date && - localize(convertDate(post_data?.published_date))} - -
- {post_data?.blog_title} -
- - {post_data?.read_time_in_minutes && - localize(post_data?.read_time_in_minutes + ' min read')} - - - - - {post_data?.tags.map((tag) => { - return ( + + {post_data?.author && ( + <> - {tag?.tags_id?.id && ( - - {tag?.tags_id?.tag_name} - + {post_data?.author?.image && ( + + + )} - ) - })} - - - - - {post_data?.author && ( - - <> - {post_data?.author?.image && ( - - - - )} - - - - - {localize('Written by')} - - {localize(post_data?.author?.name)} - - - )} - -
- - - - - -
-
- - - - - {post_data?.author && ( - - <> - {post_data?.author?.image && ( - - - + + + {localize('Written by')} + + + {localize(post_data?.author?.name)} + + + )} - + +
+ + + + + +
+
- - - {localize('Written by')} - - {localize(post_data?.author?.name)} - - - )} - - - - - {post_data?.tags.map((tag) => { - return ( + + + + {post_data?.author && ( + <> - {tag?.tags_id?.id && ( - - {tag?.tags_id?.tag_name} - + {post_data?.author?.image && ( + + + )} - ) - })} - - {side_banner_data_details && ( - - )} - - - - - - <\/p>/g, '/>'), - }} - /> - - {footer_banner_details && } - - - - - - - {side_banner_data_details && ( - - - - + + + {localize('Written by')} + + + {localize(post_data?.author?.name)} + + + + )} - )} - - - -
+ + + + {post_data?.tags.map((tag) => { + return ( + <> + {tag?.tags_id?.id && ( + + {tag?.tags_id?.tag_name} + + )} + + ) + })} + + {side_banner_data_details && ( + + )} + + + + + + + + + <\/p>/g, '/>'), + }} + /> + + {footer_banner_details && ( + + )} + + + + + + + + {side_banner_data_details && ( + + + + + + )} + + + + + + + + )} + ) } diff --git a/src/pages/blog/components/_subscribe.js b/src/pages/blog/components/_subscribe.js index 477cd6860f0..06ad27b6dd6 100644 --- a/src/pages/blog/components/_subscribe.js +++ b/src/pages/blog/components/_subscribe.js @@ -107,6 +107,10 @@ const InputWrapper = styled.div` margin-left: 0 !important; width: 100% !important; } + input#email { + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + } } @media ${device.tablet} { margin-right: 0; diff --git a/src/templates/article.js b/src/templates/article.js index 4a2d7796cc8..4e3054efbda 100644 --- a/src/templates/article.js +++ b/src/templates/article.js @@ -1,4 +1,4 @@ -import React from 'react' +import React, { useEffect, useState } from 'react' import PropTypes from 'prop-types' import { graphql } from 'gatsby' import { @@ -19,8 +19,11 @@ import { SocialComponentsWrapper, LeftSocialComponents, RightSocialComponents, + DesktopWrapper, + MobileWrapper, } from '../pages/academy/blog/posts/_style' import Banner from '../pages/blog/components/_banner' +import ArticleEmailBanner from '../pages/academy/blog/components/side-subscription-banner' import SocialSharing from '../pages/blog/_social-sharing' import { localize, WithIntl } from 'components/localization' import Layout from 'components/layout/layout' @@ -29,6 +32,12 @@ import { Header, QueryImage } from 'components/elements' import { convertDate } from 'common/utility' const ArticlesTemplate = (props) => { + const [isMounted, setMounted] = useState(false) + useEffect(() => { + setMounted(true) + isMounted && window.scrollTo(0, 0) + }, [isMounted]) + const pathname = props.pageContext.pathname const post_data = props.data.directus.blog[0] const footer_banner_data = post_data?.footer_banners @@ -59,146 +68,179 @@ const ArticlesTemplate = (props) => { return ( + <> + {isMounted && ( + + + + + + {post_data?.published_date && + convertDate(post_data?.published_date)} + +
+ {post_data?.blog_title} +
+ + {post_data?.read_time_in_minutes && + localize(post_data?.read_time_in_minutes + ' min read')} + + + + + {post_data?.tags.map((tag) => { + return ( + + {tag.tags_id.tag_name} + + ) + })} + + + - - - - - - {post_data?.published_date && - convertDate(post_data?.published_date)} - -
- {post_data?.blog_title} -
- - {post_data?.read_time_in_minutes && - localize(post_data?.read_time_in_minutes + ' min read')} - - - - - {post_data?.tags.map((tag) => { - return ( - - {tag.tags_id.tag_name} - - ) - })} - - - + + {post_data?.author && ( + + <> + {post_data?.author?.image && ( + + + + )} + - - {post_data?.author && ( - - <> - {post_data?.author?.image && ( - - - - )} - + + + {localize('Written by')} + + + {localize(post_data?.author?.name)} + + + + )} + +
+ + + + + +
+
- - - {localize('Written by')} - - {localize(post_data?.author?.name)} - - - )} - -
- - - - - -
-
+ + + + {post_data?.author && ( + + <> + {post_data?.author?.image && ( + + + + )} + - - - - {post_data?.author && ( - - <> - {post_data?.author?.image && ( - - - + + + {localize('Written by')} + + + {localize(post_data?.author?.name)} + + + + )} + + + + + {post_data?.tags.map((tag) => { + return ( + + {tag.tags_id.tag_name} + + ) + })} + + {side_banner_data_details && ( + )} - - - - - {localize('Written by')} - - {localize(post_data?.author?.name)} - - - )} - - - - - {post_data?.tags.map((tag) => { - return ( - {tag.tags_id.tag_name} - ) - })} - - {side_banner_data_details && ( - - )} - - - - - - <\/p>/g, '/>'), - }} - /> + + + + + + + + + <\/p>/g, '/>'), + }} + /> - {footer_banner_details && } - - - - - - + {footer_banner_details && ( + + )} + + + + + + - {side_banner_data_details && ( - - - - - - )} - - - -
+ {side_banner_data_details && ( + + + + + + )} + + + + + + + + )} +
) } diff --git a/src/themes/variables.js b/src/themes/variables.js index 6a7af7d92b8..bf9c7f2c82c 100644 --- a/src/themes/variables.js +++ b/src/themes/variables.js @@ -60,6 +60,7 @@ const Variables = css` --color-grey-39: #f7fafb; --color-grey-40: #b3b3b3; --color-grey-41: #f8fafb; + --color-grey-42: #f5f8f9; --color-green: #85acb0; --color-blue: #4c76be; --color-blue-2: #365899;