1
0
mirror of https://github.com/kremalicious/portfolio.git synced 2024-06-25 18:56:39 +02:00

more Pure Components

This commit is contained in:
Matthias Kretschmann 2018-11-25 01:52:31 +01:00
parent 2cb9ca9181
commit 7a386c9ade
Signed by: m
GPG Key ID: 606EEEF3C479A91F
9 changed files with 183 additions and 169 deletions

View File

@ -34,7 +34,6 @@ const Typekit = () => (
return ( return (
typekitID && ( typekitID && (
<Helmet> <Helmet>
<link rel="dns-prefetch" href="https://use.typekit.net/" />
<link rel="dns-prefetch" href="https://p.typekit.net/" /> <link rel="dns-prefetch" href="https://p.typekit.net/" />
{TypekitScript(typekitID)} {TypekitScript(typekitID)}

View File

@ -51,7 +51,6 @@
transform-origin: top center; transform-origin: top center;
transform-box: border-box; transform-box: border-box;
// stylelint-disable no-descending-specificity
.logounit__title, .logounit__title,
.logounit__description { .logounit__description {
color: $text-color-light; color: $text-color-light;
@ -60,7 +59,6 @@
color: $text-color-light--dark; color: $text-color-light--dark;
} }
} }
// stylelint-enable no-descending-specificity
.logounit__logo { .logounit__logo {
margin-bottom: $spacer / 3; margin-bottom: $spacer / 3;

View File

@ -27,20 +27,22 @@ const query = graphql`
} }
` `
const NetworkIcon = props => { class NetworkIcon extends PureComponent {
switch (props.title) { render() {
case 'Email': switch (this.props.title) {
return <Email {...props} /> case 'Email':
case 'Blog': return <Email {...this.props} />
return <Blog {...props} /> case 'Blog':
case 'Twitter': return <Blog {...this.props} />
return <Twitter {...props} /> case 'Twitter':
case 'GitHub': return <Twitter {...this.props} />
return <GitHub {...props} /> case 'GitHub':
case 'Dribbble': return <GitHub {...this.props} />
return <Dribbble {...props} /> case 'Dribbble':
default: return <Dribbble {...this.props} />
return null default:
return null
}
} }
} }

View File

@ -1,4 +1,4 @@
import React from 'react' import React, { PureComponent } from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import Button from '../atoms/Button' import Button from '../atoms/Button'
@ -50,31 +50,33 @@ const LinkIcon = ({ title, type, ...props }) => {
} }
} }
const ProjectLinks = ({ links }) => ( export default class ProjectLinks extends PureComponent {
<div className={styles.projectLinks}> static propTypes = {
<h3 className={styles.title}> links: PropTypes.array
Links <span>Learn more on the interwebz.</span> }
</h3>
<ul> render() {
{links.map(link => { return (
const { title, url, type } = link <div className={styles.projectLinks}>
<h3 className={styles.title}>
Links <span>Learn more on the interwebz.</span>
</h3>
return ( <ul>
<li key={title}> {this.props.links.map(link => {
<Button href={url}> const { title, url, type } = link
<LinkIcon title={title} type={type} className={icons.icon} />
{title}
</Button>
</li>
)
})}
</ul>
</div>
)
ProjectLinks.propTypes = { return (
links: PropTypes.array <li key={title}>
<Button href={url}>
<LinkIcon title={title} type={type} className={icons.icon} />
{title}
</Button>
</li>
)
})}
</ul>
</div>
)
}
} }
export default ProjectLinks

View File

@ -1,4 +1,4 @@
import React, { Component } from 'react' import React, { PureComponent } from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { Link, graphql, StaticQuery } from 'gatsby' import { Link, graphql, StaticQuery } from 'gatsby'
import Img from 'gatsby-image' import Img from 'gatsby-image'
@ -24,18 +24,24 @@ const query = graphql`
} }
` `
const ProjectLink = ({ node }) => ( class ProjectLink extends PureComponent {
<Link className={styles.link} to={node.slug}> render() {
<Img const { node } = this.props
className={styles.image}
fluid={node.img.childImageSharp.fluid}
alt={node.title}
/>
<h1 className={styles.title}>{node.title}</h1>
</Link>
)
export default class ProjectNav extends Component { return (
<Link className={styles.link} to={node.slug}>
<Img
className={styles.image}
fluid={node.img.childImageSharp.fluid}
alt={node.title}
/>
<h1 className={styles.title}>{node.title}</h1>
</Link>
)
}
}
export default class ProjectNav extends PureComponent {
state = { state = {
scrolledToCurrent: false scrolledToCurrent: false
} }

View File

@ -1,6 +1,5 @@
import React, { PureComponent } from 'react' import React, { PureComponent } from 'react'
import PropTypes from 'prop-types' import { Link, StaticQuery, graphql } from 'gatsby'
import { StaticQuery, graphql } from 'gatsby'
import Vcard from '../atoms/Vcard' import Vcard from '../atoms/Vcard'
import LogoUnit from '../molecules/LogoUnit' import LogoUnit from '../molecules/LogoUnit'
import Networks from '../molecules/Networks' import Networks from '../molecules/Networks'
@ -23,33 +22,30 @@ const query = graphql`
} }
` `
const FooterMarkup = ({ meta, pkg, year }) => (
<footer className={styles.footer}>
<LogoUnit minimal />
<Networks minimal />
<p className={styles.footer__actions}>
<Vcard />
<a href={meta.gpg}>PGP/GPG key</a>
<a href={pkg.bugs}>Found a bug?</a>
</p>
<p className={styles.footer__copyright}>
<small>
&copy; {year} {meta.title} &mdash; All Rights Reserved
</small>
</p>
</footer>
)
FooterMarkup.propTypes = {
meta: PropTypes.object,
pkg: PropTypes.object,
year: PropTypes.number
}
export default class Footer extends PureComponent { export default class Footer extends PureComponent {
state = { year: new Date().getFullYear() } state = { year: new Date().getFullYear() }
FooterMarkup = ({ meta, pkg, year }) => (
<footer className={styles.footer}>
<Link to={'/'}>
<LogoUnit minimal />
</Link>
<Networks minimal />
<p className={styles.footer__actions}>
<Vcard />
<a href={meta.gpg}>PGP/GPG key</a>
<a href={pkg.bugs}>Found a bug?</a>
</p>
<p className={styles.footer__copyright}>
<small>
&copy; {year} {meta.title} &mdash; All Rights Reserved
</small>
</p>
</footer>
)
render() { render() {
return ( return (
<StaticQuery <StaticQuery
@ -58,7 +54,9 @@ export default class Footer extends PureComponent {
const pkg = data.portfolioJson const pkg = data.portfolioJson
const meta = data.dataYaml const meta = data.dataYaml
return <FooterMarkup year={this.state.year} pkg={pkg} meta={meta} /> return (
<this.FooterMarkup year={this.state.year} pkg={pkg} meta={meta} />
)
}} }}
/> />
) )

View File

@ -18,6 +18,10 @@ const query = graphql`
` `
export default class Header extends PureComponent { export default class Header extends PureComponent {
static propTypes = {
minimal: PropTypes.bool
}
state = { isMinimal: this.props.minimal } state = { isMinimal: this.props.minimal }
checkMinimal = () => { checkMinimal = () => {
@ -61,7 +65,3 @@ export default class Header extends PureComponent {
) )
} }
} }
Header.propTypes = {
minimal: PropTypes.bool
}

View File

@ -1,4 +1,4 @@
import React from 'react' import React, { PureComponent } from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { Link, graphql } from 'gatsby' import { Link, graphql } from 'gatsby'
import SEO from '../components/atoms/SEO' import SEO from '../components/atoms/SEO'
@ -6,7 +6,7 @@ import ProjectImage from '../components/molecules/ProjectImage'
import { ReactComponent as Images } from '../images/images.svg' import { ReactComponent as Images } from '../images/images.svg'
import styles from './index.module.scss' import styles from './index.module.scss'
const getImageCount = (images, slug) => { function getImageCount(images, slug) {
let array = [] let array = []
let slugWithoutSlashes = slug.replace(/\//g, '') let slugWithoutSlashes = slug.replace(/\//g, '')
@ -17,49 +17,50 @@ const getImageCount = (images, slug) => {
return array.length return array.length
} }
const Home = ({ data }) => { export default class Home extends PureComponent {
const projects = data.allProjectsYaml.edges static propTypes = {
const images = data.projectImageFiles.edges data: PropTypes.object,
location: PropTypes.object
}
return ( render() {
<> const { data } = this.props
<SEO /> const projects = data.allProjectsYaml.edges
const images = data.projectImageFiles.edges
<div className={styles.projects}> return (
{projects.map(({ node }) => { <>
const { slug, title, img } = node <SEO />
const imageCount = getImageCount(images, slug)
return ( <div className={styles.projects}>
<article className={styles.project} key={slug}> {projects.map(({ node }) => {
<Link to={slug}> const { slug, title, img } = node
<h1 className={styles.title}>{title}</h1> const imageCount = getImageCount(images, slug)
<ProjectImage fluid={img.childImageSharp.fluid} alt={title} />
{imageCount > 1 && ( return (
<small <article className={styles.project} key={slug}>
className={styles.imageCount} <Link to={slug}>
title={`${imageCount} project images`} <h1 className={styles.title}>{title}</h1>
> <ProjectImage fluid={img.childImageSharp.fluid} alt={title} />
<Images /> {imageCount}
</small> {imageCount > 1 && (
)} <small
</Link> className={styles.imageCount}
</article> title={`${imageCount} project images`}
) >
})} <Images /> {imageCount}
</div> </small>
</> )}
) </Link>
</article>
)
})}
</div>
</>
)
}
} }
Home.propTypes = {
data: PropTypes.object,
location: PropTypes.object
}
export default Home
export const IndexQuery = graphql` export const IndexQuery = graphql`
query { query {
allProjectsYaml { allProjectsYaml {

View File

@ -1,4 +1,4 @@
import React from 'react' import React, { PureComponent } from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { graphql } from 'gatsby' import { graphql } from 'gatsby'
import FullWidth from '../components/atoms/FullWidth' import FullWidth from '../components/atoms/FullWidth'
@ -9,12 +9,23 @@ import ProjectNav from '../components/molecules/ProjectNav'
import SEO from '../components/atoms/SEO' import SEO from '../components/atoms/SEO'
import styles from './Project.module.scss' import styles from './Project.module.scss'
const ProjectMeta = ({ links, techstack }) => ( class ProjectMeta extends PureComponent {
<footer className={styles.meta}> static propTypes = {
{!!links && <ProjectLinks links={links} />} links: PropTypes.array,
{!!techstack && <ProjectTechstack techstack={techstack} />} techstack: PropTypes.array
</footer> }
)
render() {
const { links, techstack } = this.props
return (
<footer className={styles.meta}>
{!!links && <ProjectLinks links={links} />}
{!!techstack && <ProjectTechstack techstack={techstack} />}
</footer>
)
}
}
const ProjectImages = ({ projectImages, title }) => ( const ProjectImages = ({ projectImages, title }) => (
<FullWidth> <FullWidth>
@ -26,50 +37,44 @@ const ProjectImages = ({ projectImages, title }) => (
</FullWidth> </FullWidth>
) )
const Project = ({ data }) => {
const project = data.projectsYaml
const projectImages = data.projectImages.edges
const { title, links, techstack } = project
const description = data.projectsYaml.description
const descriptionWithLineBreaks = description.split('\n').join('\n\n')
return (
<>
<SEO project={project} />
<article>
<header>
<h1 className={styles.title}>{title}</h1>
</header>
<div
className={styles.description}
dangerouslySetInnerHTML={{ __html: descriptionHtml }}
/>
<ProjectImages projectImages={projectImages} title={title} />
<ProjectMeta links={links} techstack={techstack} />
</article>
<ProjectNav slug={project.slug} />
</>
)
}
ProjectMeta.propTypes = {
links: PropTypes.array,
techstack: PropTypes.array
}
ProjectImages.propTypes = { ProjectImages.propTypes = {
projectImages: PropTypes.array, projectImages: PropTypes.array,
title: PropTypes.string title: PropTypes.string
} }
Project.propTypes = { export default class Project extends PureComponent {
data: PropTypes.object.isRequired, static propTypes = {
location: PropTypes.object.isRequired data: PropTypes.object.isRequired,
} location: PropTypes.object.isRequired
}
export default Project render() {
const project = this.props.data.projectsYaml
const projectImages = this.props.data.projectImages.edges
const descriptionHtml = this.props.data.projectsYaml.fields.descriptionHtml
const { title, links, techstack } = project
return (
<>
<SEO project={project} />
<article>
<header>
<h1 className={styles.title}>{title}</h1>
</header>
<div
className={styles.description}
dangerouslySetInnerHTML={{ __html: descriptionHtml }}
/>
<ProjectImages projectImages={projectImages} title={title} />
<ProjectMeta links={links} techstack={techstack} />
</article>
<ProjectNav slug={project.slug} />
</>
)
}
}
export const projectAndProjectsQuery = graphql` export const projectAndProjectsQuery = graphql`
query($slug: String!) { query($slug: String!) {
@ -77,6 +82,9 @@ export const projectAndProjectsQuery = graphql`
title title
slug slug
description description
fields {
descriptionHtml
}
links { links {
title title
url url