From 8040b2c8fca2115e3cf10c564406d020cfb69c16 Mon Sep 17 00:00:00 2001 From: viphan007 Date: Tue, 16 Jan 2024 14:04:38 +0700 Subject: [PATCH] Create author profile page --- .github/workflows/integrate.yml | 1 + gatsby-node.js | 86 ++++- src/components/AuthorProfileContent.js | 348 ++++++++++++++++++ .../Contentful/ContentfulNewsAuthor.js | 54 +++ .../Contentful/ContentfulNewsCategory.js | 2 + src/components/Contentful/ContentfulSeo.js | 1 - src/components/Contentful/index.js | 2 + src/components/NewsAuthor.js | 30 ++ src/components/NewsList.js | 18 +- src/components/SocialIcon.js | 2 + src/components/hubspotForm.js | 5 +- src/components/layout.scss | 8 - src/fragments/ContentfulContent.js | 41 ++- src/fragments/previewFragment.js | 23 ++ src/fragments/previewQuery.js | 10 + src/images/icons/twitter-x.svg | 3 + src/lib/utils/fetchContentfulData.js | 4 + src/templates/AuthorProfileLayout.js | 122 ++++++ src/templates/NewsLayout.js | 18 +- 19 files changed, 718 insertions(+), 60 deletions(-) create mode 100644 src/components/AuthorProfileContent.js create mode 100644 src/components/Contentful/ContentfulNewsAuthor.js create mode 100644 src/components/NewsAuthor.js create mode 100644 src/images/icons/twitter-x.svg create mode 100644 src/templates/AuthorProfileLayout.js diff --git a/.github/workflows/integrate.yml b/.github/workflows/integrate.yml index cb1ffdc3c51..91b264be1b3 100644 --- a/.github/workflows/integrate.yml +++ b/.github/workflows/integrate.yml @@ -45,6 +45,7 @@ jobs: uses: actions/setup-node@f1f314fca9dfce2769ece7d933488f076716723e with: node-version: "${{ steps.nvm.outputs.NVMRC }}" + cache: "yarn" - name: Build 🔧 run: | diff --git a/gatsby-node.js b/gatsby-node.js index 4bdf4398a8a..513af8d09ec 100644 --- a/gatsby-node.js +++ b/gatsby-node.js @@ -23,7 +23,7 @@ exports.createPages = async ({ graphql, actions }) => { redirects.data?.allRedirects.nodes.forEach(r => createRedirect({ fromPath: r.fromPath, - toPath: r.toPath + toPath: r.toPath, }) ) @@ -31,7 +31,9 @@ exports.createPages = async ({ graphql, actions }) => { const newsCategories = [] const result = await graphql(` { - allCategories: allContentfulNewsCategory(filter: {name: {regex: "/^(?!.*(?:Latest|example)).*$/"}}) { + allCategories: allContentfulNewsCategory( + filter: { name: { regex: "/^(?!.*(?:Latest|example)).*$/" } } + ) { nodes { contentful_id name @@ -100,13 +102,13 @@ exports.createPages = async ({ graphql, actions }) => { filename } } - ...on ContentfulPortfolioIntro { + ... on ContentfulPortfolioIntro { contentful_id } - ...on ContentfulPortfolioInstructions { + ... on ContentfulPortfolioInstructions { contentful_id } - ...on ContentfulPortfolioMap { + ... on ContentfulPortfolioMap { contentful_id } } @@ -152,10 +154,12 @@ exports.createPages = async ({ graphql, actions }) => { })) if (assetUrls) { - ; (async () => { + ;(async () => { await Promise.all( - assetUrls.map(url => download(url, `public/assets/${path.parse(url).base}`)) - ).catch((_) => { + assetUrls.map(url => + download(url, `public/assets/${path.parse(url).base}`) + ) + ).catch(_ => { return Promise.reject('Fetch MetaMask assets failed!') }) })() @@ -198,18 +202,22 @@ exports.createPages = async ({ graphql, actions }) => { }) } - let legalPages = ['/terms-of-use/', '/privacy-policy/', '/privacy-policy/cookies/'] + let legalPages = [ + '/terms-of-use/', + '/privacy-policy/', + '/privacy-policy/cookies/', + ] if (legalPages.includes(slug)) { - const resolvedData = legalData?.find(s => s?.frontmatter?.slug === slug) + const resolvedData = legalData?.find( + s => s?.frontmatter?.slug === slug + ) if (!resolvedData) { // Skip creating page - return; + return } createPage({ path: slug, - component: path.resolve( - `./src/templates/MarkdownPageLayout.js` - ), + component: path.resolve(`./src/templates/MarkdownPageLayout.js`), context: { headerId, footerId, @@ -224,22 +232,24 @@ exports.createPages = async ({ graphql, actions }) => { return } - if (slug === "/portfolio/") { + if (slug === '/portfolio/') { createPage({ path: slug, - component: path.resolve(`./src/templates/ContentfulPortfolioLayout.js`), + component: path.resolve( + `./src/templates/ContentfulPortfolioLayout.js` + ), context: { headerId, footerId, seoId, pathBuild: slug, modules: moduleIds, - } + }, }) return } - const extraData = slug === "/developer/" ? devChangelogData : null + const extraData = slug === '/developer/' ? devChangelogData : null createPage({ path: slug, // slug validation in Contentful CMS component: path.resolve(`./src/templates/ContentfulLayout.js`), @@ -307,8 +317,46 @@ exports.createPages = async ({ graphql, actions }) => { .catch(error => { console.log(' Error generating News Page: ', error) }) + // Author profile page + const contentfulAuthorProfile = graphql(` + { + authors: allContentfulNewsAuthor( + filter: { createProfilePage: { eq: true } } + ) { + nodes { + contentful_id + name + profileUrl + } + } + } + `) + .then(result => { + if (result.data && result.data.authors) { + const authors = result.data.authors.nodes + return authors.map(author => { + const { contentful_id, profileUrl } = author + const slug = '/author/' + profileUrl + '/' + createPage({ + path: slug, + component: path.resolve('./src/templates/AuthorProfileLayout.js'), + context: { + author_id: contentful_id, + pathBuild: slug, + }, + }) + }) + } + }) + .catch(error => { + console.log(' Error generating author profile page: ', error) + }) - const autoGeneratedPages = [contentfulLayouts, contentfulNews] + const autoGeneratedPages = [ + contentfulLayouts, + contentfulNews, + contentfulAuthorProfile, + ] return Promise.all(autoGeneratedPages) } diff --git a/src/components/AuthorProfileContent.js b/src/components/AuthorProfileContent.js new file mode 100644 index 00000000000..2f008b6e828 --- /dev/null +++ b/src/components/AuthorProfileContent.js @@ -0,0 +1,348 @@ +import React from 'react' +import styled from 'styled-components' +import isEmpty from 'lodash/isEmpty' +import NewsList from './NewsList' +import { Link } from 'gatsby' +import ArrowIcon from './ArrowIcon' +import { Section } from './StyledGeneral' +import ContentWrapper from './ContentWrapper' +import ParseMD from './ParseMD' +import SocialIcon from './SocialIcon' +import Image from './Image' + +function AuthorProfileContent({ + name, + position, + twitter, + linkedin, + relatedNews, + expertise, + description, + education, + image, + heroBgUrl, + heroBgDarkUrl, + bgImageUrl, + bgImageDarkUrl, + previewMode, +}) { + const twRegex = /(?:https?:\/\/)?(?:www\.)?twitter\.com\/(?:#!\/)?@?([^\/]+)/ + const liRegex = /(?:https?:\/\/)?(?:www\.)?linkedin\.com\/in\/([^\/]+)/ + const twMatch = twitter.match(twRegex) + const liMatch = linkedin.match(liRegex) + const twitterName = twMatch && twMatch[1] + const linkedinName = liMatch && liMatch[1] + return ( + + +
+ + + +
+

{name}

+ {position &&
{position}
} +
+
+
+
+
+ +
+ + +
+ {twitterName && ( + + )} + {linkedinName && ( + + )} +
+
+ {expertise && ( +
+ Expertise +

{expertise}

+
+ )} + {education && ( +
+ Education + {education} +
+ )} +
+ {description && ( + <> +

Experience

+ {description} + + )} +
+
+
+
+
+ {!previewMode && ( + +
+ +
+
+ + + All posts + +
+

Articles by {name}

+
+
+
+ {!isEmpty(relatedNews) ? ( + + ) : ( +
No articles found
+ )} +
+ +
+
+ )} +
+ ) +} + +export default AuthorProfileContent + +const AuthorWrapper = styled.div`` + +const BgImageWrapper = styled.div` + background-size: contain; + background-repeat: no-repeat; + background-position: bottom; + + ${({ bgUrl }) => + bgUrl + ? ` background-image: url(${bgUrl}); + ` + : ''} + + ${({ darkBgUrl }) => + darkBgUrl + ? ` + body.dark-mode && { + background-image: url(${darkBgUrl}); + } + ` + : ''} + + ${({ cover }) => + cover + ? ` + background-size: cover; + ` + : ''} + .profile-image { + width: 182px; + border-radius: 50%; + } +` + +const RelatedNewsWrapper = styled.div` + .related-news-header { + display: flex; + flex-direction: column-reverse; + align-items: center; + justify-content: space-between; + h2 { + font-size: 24px; + margin-bottom: 24px; + text-align: center; + line-height: 1.2; + } + .cta-wrapper { + align-self: flex-start; + display: flex; + align-items: center; + margin-bottom: 16px; + a { + display: inline-flex; + align-items: center; + color: ${({ theme }) => theme.text.default}; + transition: color 0.15s ease; + svg > path { + transition: stroke 0.15s ease; + stroke: ${({ theme }) => theme.text.default}; + } + &:hover { + color: ${({ theme }) => theme.lightBlue}; + svg > path { + stroke: ${({ theme }) => theme.lightBlue}; + } + } + } + } + .left, + .right { + flex: 1; + } + @media (min-width: ${({ theme }) => theme.device.tablet}) { + flex-direction: row; + align-items: center; + margin-bottom: 64px; + .cta-wrapper { + align-self: flex-end; + margin-bottom: 0; + } + h2 { + margin-bottom: 0; + font-size: 40px; + } + } + } + .news-list-wrapper { + display: flex; + flex-wrap: wrap; + justify-content: center; + gap: 24px; + & > * { + width: 100%; + max-width: 315px; + } + .no-blog-found { + text-align: center; + } + @media (min-width: ${({ theme }) => theme.device.mobile}) { + & > * { + flex: 1; + } + } + } +` + +const HeroWrapper = styled.div` + display: flex; + max-width: 788px; + column-gap: 48px; + row-gap: 16px; + align-items: center; + justify-content: center; + flex-direction: column; + text-align: center; + margin: 0 auto; + + h1 { + font-size: 36px; + line-height: 1.2; + margin-bottom: 16px; + } + @media (min-width: ${({ theme }) => theme.device.mobile}) { + flex-direction: row; + justify-content: flex-start; + text-align: left; + } + @media (min-width: ${({ theme }) => theme.device.tablet}) { + h1 { + font-size: 48px; + } + } +` + +const BodyContentWrapper = styled.div` + display: flex; + max-width: 788px; + margin: 0 auto; + gap: 2rem; + flex-direction: column-reverse; + + .social { + display: flex; + flex-direction: column; + gap: 10px; + .social-item { + display: flex; + column-gap: 8px; + font-size: 14px; + align-items: center; + padding: 12px; + border: 1px solid #d6d9dc; + border-radius: 8px; + a { + color: #bbc0c5; + + :hover { + color: ${({ theme }) => theme.lightBlue}; + text-decoration: underline; + text-underline-offset: 4px; + } + } + + span { + padding: 0; + } + } + } + .profile-content { + .content-item { + strong { + font-size: 18px; + font-weight: 500; + margin-bottom: 12px; + } + a:hover { + text-decoration: underline; + } + &:not(:last-child) { + margin-bottom: 30px; + } + } + h3 { + font-size: 24px; + margin-bottom: 24px; + } + p { + color: ${({ theme }) => theme.darkGray}; + .dark-mode & { + color: ${({ theme }) => theme.white}; + } + &:last-child { + margin-bottom: 0; + } + } + } + hr { + margin: 30px 0; + } + @media (min-width: ${({ theme }) => theme.device.mobile}) { + flex-direction: row; + } + @media (min-width: ${({ theme }) => theme.device.tablet}) { + .social { + .social-item { + min-width: 168px; + } + } + hr { + margin: 50px 0; + } + } +` diff --git a/src/components/Contentful/ContentfulNewsAuthor.js b/src/components/Contentful/ContentfulNewsAuthor.js new file mode 100644 index 00000000000..59ebded21bf --- /dev/null +++ b/src/components/Contentful/ContentfulNewsAuthor.js @@ -0,0 +1,54 @@ +import React from 'react' +import withProcessPreviewData from '../../lib/utils/withProcessPreviewData' +import Layout from '../layout' +import AuthorProfileContent from '../AuthorProfileContent' + +// For preview only +const ContentfulLayout = props => { + const { + description, + education, + expertise, + image, + linkedin, + name, + position, + twitter, + } = props + + const heroBgUrl = + 'https://images.ctfassets.net/9sy2a0egs6zh/2DkHpHReuWGy3rlFwsseg9/3ef9fca08861ff252af636e02e0e38d1/News_Hero.png?q=80&fm=webp' + const heroBgDarkUrl = + 'https://images.ctfassets.net/9sy2a0egs6zh/6UanQYPkBrOZaZ2wQKrjkn/c012919df0961ce6d3cf5c5bcee08ce9/Auto_Layout_Vertical-dark.png?q=80&fm=webp' + const bgImageUrl = + 'https://images.ctfassets.net/9sy2a0egs6zh/3hGSTCAVrdhSMmLJHSHOWT/2d0c9f9d98cbe8afac92b501b2b935b4/news-detail-bg-2.svg' + const bgImageDarkUrl = + 'https://images.ctfassets.net/9sy2a0egs6zh/7jkrYvvMuFweNJ4KL2yhRP/44c8086d95b64cb6cab71f0393b814dd/news-detail-dark-bg.png?q=80&fm=webp' + + return ( + + + + ) +} + +const parsePreviewData = data => { + data = data.moduleConfig + return data +} + +export default withProcessPreviewData(parsePreviewData)(ContentfulLayout) diff --git a/src/components/Contentful/ContentfulNewsCategory.js b/src/components/Contentful/ContentfulNewsCategory.js index 9c66e288365..0ca38206649 100644 --- a/src/components/Contentful/ContentfulNewsCategory.js +++ b/src/components/Contentful/ContentfulNewsCategory.js @@ -22,6 +22,8 @@ function ContentfulNewsCategory(props) { publishDate(formatString: "MMMM D, YYYY") authors { name + createProfilePage + profileUrl } categories { name diff --git a/src/components/Contentful/ContentfulSeo.js b/src/components/Contentful/ContentfulSeo.js index 366c1a62656..a31133d2777 100644 --- a/src/components/Contentful/ContentfulSeo.js +++ b/src/components/Contentful/ContentfulSeo.js @@ -36,7 +36,6 @@ const ContentfulSeo = props => { } ContentfulSeo.propTypes = { - seoPage: PropTypes.object, pageTitle: PropTypes.string, pageDescription: PropTypes.string, metaTags: PropTypes.arrayOf(PropTypes.object), diff --git a/src/components/Contentful/index.js b/src/components/Contentful/index.js index 3a4f71f8cfe..849252c2564 100644 --- a/src/components/Contentful/index.js +++ b/src/components/Contentful/index.js @@ -20,6 +20,7 @@ import ContentfulNewsCategory from './ContentfulNewsCategory' import ContentfulTimeline from './ContentfulTimeline' import ContentfulNewsLayout from './ContentfulNewsLayout' import ContentfulLayout from './ContentfulLayout' +import ContentfulNewsAuthor from './ContentfulNewsAuthor' export { ContentfulLayoutHeader, @@ -44,4 +45,5 @@ export { ContentfulTimeline, ContentfulNewsLayout, ContentfulLayout, + ContentfulNewsAuthor, } diff --git a/src/components/NewsAuthor.js b/src/components/NewsAuthor.js new file mode 100644 index 00000000000..d5403f868b1 --- /dev/null +++ b/src/components/NewsAuthor.js @@ -0,0 +1,30 @@ +import React from 'react' +import Link from '../components/Link' +import isEmpty from 'lodash/isEmpty' + +function NewsAuthor({ listAuthors }) { + const generateAuthor = authors => + authors.reduce((acc, cur, index) => { + if (acc.length) { + acc.push({', '}) + } + if (cur.createProfilePage) { + acc.push( + + {cur.name} + + ) + } else { + acc.push({cur.name}) + } + return acc + }, []) + + return ( + + {!isEmpty(listAuthors) ? generateAuthor(listAuthors) : 'MetaMask'} + + ) +} + +export default NewsAuthor diff --git a/src/components/NewsList.js b/src/components/NewsList.js index 8a40b53bf96..56657a25d59 100644 --- a/src/components/NewsList.js +++ b/src/components/NewsList.js @@ -3,13 +3,8 @@ import React from 'react' import Card from './Card' import { getNewsUrl } from '../lib/utils/news' import styled from 'styled-components' +import NewsAuthor from './NewsAuthor' -/** - * @name - - * @summary - - * @description - - * @prop - - */ function NewsList(props) { const { data } = props @@ -18,13 +13,6 @@ function NewsList(props) { {data.map((news, index) => { const { title, subtitle, image, publishDate, authors } = news const newsUrl = getNewsUrl(news) - const hasAuthors = authors && authors.length > 0 - const authorsName = - hasAuthors && - authors.reduce((acc, cur) => { - acc.push(cur.name) - return acc - }, []) return ( by  - - {hasAuthors ? authorsName.join(', ') : 'MetaMask'} - + {publishDate} diff --git a/src/components/SocialIcon.js b/src/components/SocialIcon.js index 8b42f95dfe9..3a180918125 100644 --- a/src/components/SocialIcon.js +++ b/src/components/SocialIcon.js @@ -2,6 +2,7 @@ import React from 'react' import PropTypes from 'prop-types' import styled from 'styled-components' import Twitter from '../images/icons/twitter.svg' +import TwitterX from '../images/icons/twitter-x.svg' import Facebook from '../images/icons/facebook.svg' import Linkedin from '../images/icons/linkedin.svg' import Copy from '../images/icons/icon-copy.svg' @@ -12,6 +13,7 @@ const SocialIcon = props => { {'copy' === name && } {'twitter' === name && } + {'twitter-x' === name && } {'facebook' === name && } {'linkedin' === name && } {text ? {text} : null} diff --git a/src/components/hubspotForm.js b/src/components/hubspotForm.js index df10eea11bb..856db4e7b7f 100644 --- a/src/components/hubspotForm.js +++ b/src/components/hubspotForm.js @@ -134,16 +134,13 @@ const Wrapper = styled.div` const Content = styled.div` .newsletterOnNewsDetail & { - background: ${({ theme }) => theme.background.white}; + background: #fff; box-shadow: rgba(0, 0, 0, 0.1) 0px 7px 29px 0px; border-radius: 24px; padding: 32px; position: absolute; z-index: 1; width: calc(100% - 40px); - .dark-mode & { - box-shadow: 0 10px 30px 0 rgba(255, 255, 255, 0.2); - } } .accessFireBlockForm & { padding: 40px; diff --git a/src/components/layout.scss b/src/components/layout.scss index cd97d3779e2..a4bc6495412 100644 --- a/src/components/layout.scss +++ b/src/components/layout.scss @@ -1790,10 +1790,6 @@ body.dark-mode { span { color: #24272a; font-weight: normal; - - .dark-mode & { - color: #fff; - } } } } @@ -1830,10 +1826,6 @@ body.dark-mode { margin-bottom: 32px; color: #24272a; font-weight: normal; - - .dark-mode & { - color: #fff; - } } } diff --git a/src/fragments/ContentfulContent.js b/src/fragments/ContentfulContent.js index c80246b001f..2b6d7d530e2 100644 --- a/src/fragments/ContentfulContent.js +++ b/src/fragments/ContentfulContent.js @@ -844,6 +844,41 @@ export const ContentfulModuleContainerFields = graphql` } ` +export const ContentfulNewsAuthorFields = graphql` + fragment ContentfulNewsAuthorFields on ContentfulNewsAuthor { + contentful_id + internal { + type + } + name + position + image { + title + description + file { + url + } + gatsbyImageData(width: 200, quality: 80) + } + expertise + education { + childMarkdownRemark { + html + } + } + description { + childMarkdownRemark { + html + } + } + twitter + linkedin + seo { + ...ContentfulSeoFields + } + } +` + export const ContentfulNewsFields = graphql` fragment ContentfulNewsFields on ContentfulNews { contentful_id @@ -864,9 +899,13 @@ export const ContentfulNewsFields = graphql` publishDate(formatString: "MMMM D, YYYY") authors { name + createProfilePage + profileUrl } content { - content + childMarkdownRemark { + html + } } categories { ... on ContentfulNewsCategory { diff --git a/src/fragments/previewFragment.js b/src/fragments/previewFragment.js index 0a2754c8ec5..e760e1b879c 100644 --- a/src/fragments/previewFragment.js +++ b/src/fragments/previewFragment.js @@ -170,6 +170,27 @@ export const ContentfulPortfolioMapFields = gql` } ` +export const ContentfulNewsAuthorFields = gql` + fragment ContentfulNewsAuthorFields on NewsAuthor { + __typename + sys { + id + } + name + position + image(preview: true) { + title + description + url + } + expertise + education + description + twitter + linkedin + } +` + export const ContentfulNewsLayoutFields = gql` fragment ContentfulNewsLayoutFields on NewsLayout { __typename @@ -186,6 +207,8 @@ export const ContentfulNewsLayoutFields = gql` authorsCollection(preview: true) { items { name + createProfilePage + profileUrl } } publishDate diff --git a/src/fragments/previewQuery.js b/src/fragments/previewQuery.js index 74f0848e921..cb96db288c5 100644 --- a/src/fragments/previewQuery.js +++ b/src/fragments/previewQuery.js @@ -16,6 +16,7 @@ import { ContentfulLogoFields, ContentfulModuleContainerFields, ContentfulNewsCategoryFields, + ContentfulNewsAuthorFields, ContentfulNewsLayoutFields, ContentfulPopupAnnouncementFields, ContentfulRichTextFields, @@ -168,6 +169,15 @@ export const ContentfulNewsLayoutQuery = gql` } ` +export const ContentfulNewsAuthorQuery = gql` + ${ContentfulNewsAuthorFields} + query($id: String!) { + previewContent: newsAuthor(id: $id) { + ...ContentfulNewsAuthorFields + } + } +` + export const ContentfulNewsCategoryQuery = gql` ${ContentfulNewsCategoryFields} query($id: String!) { diff --git a/src/images/icons/twitter-x.svg b/src/images/icons/twitter-x.svg new file mode 100644 index 00000000000..4b5b7cfa42a --- /dev/null +++ b/src/images/icons/twitter-x.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/lib/utils/fetchContentfulData.js b/src/lib/utils/fetchContentfulData.js index c3dab035c46..7d3ed59c072 100644 --- a/src/lib/utils/fetchContentfulData.js +++ b/src/lib/utils/fetchContentfulData.js @@ -25,6 +25,7 @@ import { ContentfulLogoQuery, ContentfulModuleContainerQuery, ContentfulNewsCategoryQuery, + ContentfulNewsAuthorQuery, ContentfulNewsLayoutQuery, ContentfulPopupAnnouncementQuery, ContentfulRichTextQuery, @@ -106,6 +107,9 @@ const mapTypeToQuery = type => { case 'ContentfulModuleContainer': query = ContentfulModuleContainerQuery break + case 'ContentfulNewsAuthor': + query = ContentfulNewsAuthorQuery + break case 'ContentfulNewsLayout': query = ContentfulNewsLayoutQuery break diff --git a/src/templates/AuthorProfileLayout.js b/src/templates/AuthorProfileLayout.js new file mode 100644 index 00000000000..01803013b12 --- /dev/null +++ b/src/templates/AuthorProfileLayout.js @@ -0,0 +1,122 @@ +import { graphql } from 'gatsby' +import PropTypes from 'prop-types' +import React from 'react' +import getWebpImage from '../lib/utils/getWebpImage' +import { contentfulModuleToComponent } from '../lib/utils/moduleToComponent' +import Layout from './PageLayout' +import orderBy from 'lodash/orderBy' +import takeRight from 'lodash/takeRight' +import AuthorProfileContent from '../components/AuthorProfileContent' + +function AuthorProfileLayout(props) { + const { + data: { + header, + footer, + author: { + name, + position, + image, + expertise, + education, + description, + twitter, + linkedin, + seo, + news, + }, + heroBg, + heroBgDark, + bgImage, + bgImageDark, + }, + pageContext: { pathBuild }, + } = props + + const heroBgUrl = getWebpImage(heroBg?.file?.url) + const heroBgDarkUrl = getWebpImage(heroBgDark?.file?.url) + const bgImageUrl = getWebpImage(bgImage?.file?.url) + const bgImageDarkUrl = getWebpImage(bgImageDark?.file?.url) + const { childMarkdownRemark: { html: descriptionHtml } = {} } = + description || {} + const { childMarkdownRemark: { html: educationHtml } = {} } = education || {} + let relatedNews = orderBy(news, el => new Date(el.publishDate), 'asc') + relatedNews = takeRight(relatedNews, 3) + + return ( + + {seo && contentfulModuleToComponent({ ...seo, pagePath: pathBuild })} + {header && contentfulModuleToComponent(header)} + + {footer && contentfulModuleToComponent(footer)} + + ) +} + +AuthorProfileLayout.propTypes = { + data: PropTypes.shape({}).isRequired, + pageContext: PropTypes.shape({ + pathBuild: PropTypes.string, + }).isRequired, +} + +export const AuthorProfileLayoutQuery = graphql` + query($author_id: String!) { + header: contentfulLayoutHeader( + contentful_id: { eq: "6I0knvqLf0DS5PB72DqUlM" } + ) { + ...ContentfulLayoutHeaderFields + } + author: contentfulNewsAuthor(contentful_id: { eq: $author_id }) { + ...ContentfulNewsAuthorFields + news { + ...ContentfulNewsFields + } + } + heroBg: contentfulAsset(contentful_id: { eq: "2DkHpHReuWGy3rlFwsseg9" }) { + file { + url + } + } + heroBgDark: contentfulAsset( + contentful_id: { eq: "6UanQYPkBrOZaZ2wQKrjkn" } + ) { + file { + url + } + } + bgImage: contentfulAsset(contentful_id: { eq: "3hGSTCAVrdhSMmLJHSHOWT" }) { + file { + url + } + } + bgImageDark: contentfulAsset( + contentful_id: { eq: "7jkrYvvMuFweNJ4KL2yhRP" } + ) { + file { + url + } + } + footer: contentfulLayoutFooter( + contentful_id: { eq: "75bFgEllkMxpVsY8wWlroX" } + ) { + ...ContentfulLayoutFooterFields + } + } +` + +export default AuthorProfileLayout diff --git a/src/templates/NewsLayout.js b/src/templates/NewsLayout.js index 35db1d8ce1a..7d8ed2c169f 100644 --- a/src/templates/NewsLayout.js +++ b/src/templates/NewsLayout.js @@ -9,6 +9,7 @@ import { Section } from '../components/StyledGeneral' import ContentWrapper from '../components/ContentWrapper' import Image from '../components/Image' import SocialButtonList from '../components/SocialButtonList' +import NewsAuthor from '../components/NewsAuthor' function NewsLayout(props) { const { @@ -53,14 +54,6 @@ function NewsLayout(props) { displayTitle: false, } - const hasAuthors = authors && authors.length > 0 - const authorsName = - hasAuthors && - authors.reduce((acc, cur) => { - acc.push(cur.name) - return acc - }, []) - return ( {contentfulModuleToComponent(seoModuleConfig)} @@ -77,9 +70,7 @@ function NewsLayout(props) { {subtitle} by  - - {hasAuthors ? authorsName.join(', ') : 'MetaMask'} - + {publishDate} @@ -106,6 +97,11 @@ function NewsLayout(props) { const NewsContainer = styled(Section)` position: relative; + + .gatsby-image-wrapper img { + width: 100%; + height: 100%; + } ` const SocialShare = styled.div` margin: 32px 0;