Skip to content

Commit 3415a84

Browse files
author
Carms Ng
committed
[ADD] Use gatsby node to create member pages & recycle card component
1 parent 7af08f6 commit 3415a84

File tree

4 files changed

+216
-8
lines changed

4 files changed

+216
-8
lines changed

gatsby-config.js

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,7 @@ module.exports = {
77
},
88
plugins: [
99
`gatsby-transformer-json`,
10-
{
11-
resolve: `gatsby-source-filesystem`,
12-
options: {
13-
path: `${__dirname}/src/assets/content`,
14-
},
15-
},
10+
1611
`gatsby-plugin-postcss`,
1712
`gatsby-plugin-styled-components`,
1813
`gatsby-plugin-react-helmet`,
@@ -34,8 +29,15 @@ module.exports = {
3429
{
3530
resolve: `gatsby-source-filesystem`,
3631
options: {
32+
name: `content`,
33+
path: `${__dirname}/src/assets/content`,
34+
},
35+
},
36+
{
37+
resolve: `gatsby-source-filesystem`,
38+
options: {
39+
name: `locale`,
3740
path: `${__dirname}/locales`,
38-
name: `locale`
3941
}
4042
},
4143
`gatsby-transformer-sharp`,
@@ -79,7 +81,17 @@ module.exports = {
7981
keySeparator: false,
8082
nsSeparator: false
8183
},
82-
pages: []
84+
pages: [
85+
{
86+
matchPath: '/:language?/members/:name',
87+
getLanguageFromPath: true,
88+
excludeLanguages: []
89+
},
90+
{
91+
matchPath: '/preview',
92+
languages: ['en']
93+
}
94+
]
8395
}
8496
}
8597
],

gatsby-node.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
const { graphql } = require("gatsby")
2+
const path = require(`path`)
3+
4+
// create member pages
5+
exports.createPages = async ({ graphql, actions }) => {
6+
const { createPage } = actions
7+
8+
const result = await graphql(`
9+
query {
10+
allMembersJson {
11+
nodes {
12+
en {
13+
name
14+
}
15+
fr {
16+
name
17+
}
18+
parent {
19+
id
20+
}
21+
}
22+
}
23+
allFile(
24+
filter: {extension: {eq: "json"}, relativeDirectory: {eq: "content/members"}}
25+
) {
26+
nodes {
27+
name
28+
id
29+
}
30+
}
31+
}
32+
`)
33+
34+
result.data.allMembersJson.nodes.forEach(node => {
35+
const member = node.en.name
36+
const id = node.parent.id
37+
const slug = result.data.allFile.nodes.find(node => node.id === id).name.substring(3, )
38+
39+
Object.keys(node).forEach(key => {
40+
if (key !== "parent") {
41+
const language = key
42+
const template = "MemberPage.js"
43+
44+
createPage({
45+
path: `${language === "en" ? "" : "/fr"}/members/${slug}`,
46+
component: path.resolve(`./src/templates/${template}`),
47+
context: { slug: slug, language: language, member: member }
48+
})
49+
}
50+
})
51+
})
52+
}

src/components/MemberCard.js

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import * as React from "react";
2+
import styled from 'styled-components';
3+
import { FiLinkedin, FiGithub } from 'react-icons/fi';
4+
import { MdWeb } from 'react-icons/md'
5+
import { GatsbyImage } from "gatsby-plugin-image";
6+
7+
export default function MemberCard({ member }) {
8+
const { name, title, image, linkedin, github, website, highlights } = member
9+
10+
return (
11+
<MemberCardStyles>
12+
<div className="flex flex-1 md:flex-row-reverse overflow-hidden bg-peach md:bg-white">
13+
<GatsbyImage
14+
image={image?.childImageSharp?.gatsbyImageData}
15+
className="w-1/3-vw h-1/3-vw md:w-1/3 md:h-auto"
16+
imgStyle={{ objectPosition: `top center` }}
17+
alt={name}
18+
/>
19+
<div className="p-2 md:p-8 w-2/3">
20+
<div className="flex flex-col md:flex-row justify-between h-full md:h-auto">
21+
<div>
22+
<h1 className="text-sm sm:text-2xl sm:mb-2">{name}</h1>
23+
<p className="text-sm sm:text-xl">{title}</p>
24+
</div>
25+
<div className="text-sm sm:text-2xl md:text-3xl flex">
26+
{
27+
linkedin &&
28+
<a href={linkedin} aria-label="social media icon Linkedin" target="_blank" rel="noreferrer"><FiLinkedin className="mr-3"/></a>
29+
}
30+
{
31+
github &&
32+
<a href={github} aria-label="social media icon Github" target="_blank" rel="noreferrer"><FiGithub className="md:ml-3"/></a>
33+
}
34+
{
35+
website &&
36+
<a href={website} aria-label="social media icon Website" target="_blank" rel="noreferrer"><MdWeb className="md:ml-3"/></a>
37+
}
38+
</div>
39+
</div>
40+
{/* Highlights for large screens, show all */}
41+
<ul className="py-4 hidden md:block">
42+
{highlights.map(hl => <li key={hl}>{hl}</li>)}
43+
</ul>
44+
</div>
45+
</div>
46+
{/* highlights for small screen, show first few */}
47+
<ul className="text-sm py-4 block md:hidden">
48+
{highlights.map((hl, i) => <li key={hl + i}>{hl}</li>)}
49+
</ul>
50+
</MemberCardStyles>
51+
);
52+
}
53+
54+
const MemberCardStyles = styled.div`
55+
margin: 120px auto;
56+
border-radius: 10px;
57+
box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
58+
background: rgba(255, 255, 255, 0.5);
59+
width: 100%;
60+
max-width: 960px;
61+
overflow: hidden;
62+
ul {
63+
list-style-type: "→";
64+
padding-left: 2rem;
65+
li {
66+
padding-left: 0.5rem;
67+
}
68+
}
69+
p, svg {
70+
color: var(--darkgrey);
71+
}
72+
a svg:hover {
73+
color: var(--black);
74+
}
75+
`;

src/templates/MemberPage.js

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { graphql } from 'gatsby';
2+
import React from 'react'
3+
import MemberCard from '../components/MemberCard';
4+
import Layout from '../components/layout'
5+
import Seo from '../components/seo';
6+
import styled from 'styled-components';
7+
8+
export default function MemberPageTemplate({ data, pageContext }) {
9+
const locale = pageContext.language
10+
const member = data.membersJson[locale]
11+
console.log({ data, pageContext })
12+
return (
13+
<Layout>
14+
<Seo title={member.name} />
15+
<MemberPageStyles>
16+
<MemberCard member={member} />
17+
</MemberPageStyles>
18+
</Layout>
19+
)
20+
}
21+
22+
const MemberPageStyles = styled.div`
23+
min-height: calc(100vh - 56px);
24+
display: grid;
25+
place-content: center;
26+
padding: 20px;
27+
`
28+
29+
export const data = graphql`
30+
query($member: String!) {
31+
membersJson(en: { name: { eq: $member } }) {
32+
en {
33+
name
34+
title
35+
linkedin
36+
website
37+
github
38+
image {
39+
childImageSharp {
40+
gatsbyImageData(
41+
width: 360,
42+
height: 500,
43+
placeholder: BLURRED,
44+
layout: CONSTRAINED
45+
)
46+
}
47+
}
48+
highlights
49+
}
50+
fr {
51+
name
52+
title
53+
linkedin
54+
website
55+
github
56+
image {
57+
childImageSharp {
58+
gatsbyImageData(
59+
width: 500,
60+
placeholder: BLURRED,
61+
layout: CONSTRAINED
62+
)
63+
}
64+
}
65+
highlights
66+
}
67+
}
68+
}
69+
`;

0 commit comments

Comments
 (0)