1
0
mirror of https://github.com/kremalicious/portfolio.git synced 2024-12-22 17:23:22 +01:00
This commit is contained in:
Matthias Kretschmann 2018-04-08 22:49:58 +02:00
parent a6ba0b1ff6
commit 51524e9bd9
Signed by: m
GPG Key ID: 606EEEF3C479A91F
18 changed files with 217 additions and 182 deletions

View File

@ -9,7 +9,8 @@
}, },
"env": { "env": {
"browser": true, "browser": true,
"node": true "node": true,
"es6": true
}, },
"globals": { "globals": {
"graphql": true "graphql": true

View File

@ -1,4 +1,4 @@
const meta = require('./data/meta.json') const meta = require('./src/data/meta.json')
module.exports = { module.exports = {
siteMetadata: { siteMetadata: {
@ -7,24 +7,21 @@ module.exports = {
plugins: [ plugins: [
'gatsby-plugin-react-next', 'gatsby-plugin-react-next',
'gatsby-plugin-react-helmet', 'gatsby-plugin-react-helmet',
'gatsby-transformer-json',
'gatsby-plugin-sitemap', 'gatsby-plugin-sitemap',
'gatsby-plugin-offline', 'gatsby-plugin-offline',
{
resolve: 'gatsby-plugin-sass',
options: {
includePaths: [`${__dirname}/node_modules`, `${__dirname}/src/styles`],
},
},
{ {
resolve: 'gatsby-source-filesystem', resolve: 'gatsby-source-filesystem',
options: { options: {
name: 'data', name: 'data',
path: `${__dirname}/data/`, path: `${__dirname}/src/data/`,
}, },
}, },
{ 'gatsby-transformer-json',
resolve: 'gatsby-plugin-sass', ],
options: {
includePaths: [
`${__dirname}/node_modules`,
`${__dirname}/src/styles`
],
},
}
]
} }

View File

@ -1,12 +1,10 @@
const path = require('path') const path = require('path')
// Implement the Gatsby API “createPages”. This is called once the
// data layer is bootstrapped to let plugins create pages from data.
exports.createPages = ({ boundActionCreators, graphql }) => { exports.createPages = ({ boundActionCreators, graphql }) => {
const { createPage } = boundActionCreators const { createPage } = boundActionCreators
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const template = path.resolve('src/layouts/Project.js') const template = path.resolve('src/components/organisms/Project.js')
resolve( resolve(
graphql(` graphql(`
@ -34,15 +32,27 @@ exports.createPages = ({ boundActionCreators, graphql }) => {
reject(result.errors) reject(result.errors)
} }
console.log(result)
result.data.allProjectsJson.edges.forEach(({ node }) => { result.data.allProjectsJson.edges.forEach(({ node }) => {
const slug = node.slug const slug = node.slug
const title = node.title
const img = node.img
const img_more = node.img_more
const description = node.description
const links = node.links
const techstack = node.techstack
createPage({ createPage({
path: slug, path: slug,
component: template, component: template,
context: { slug: slug }, context: {
title,
slug,
img,
img_more,
description,
techstack,
links
}
}) })
}) })

View File

@ -20,13 +20,14 @@
"babel-eslint": "^8.2.2", "babel-eslint": "^8.2.2",
"eslint": "^4.19.1", "eslint": "^4.19.1",
"eslint-plugin-graphql": "^1.5.0", "eslint-plugin-graphql": "^1.5.0",
"eslint-plugin-prettier": "^2.6.0",
"eslint-plugin-react": "^7.7.0", "eslint-plugin-react": "^7.7.0",
"prettier": "^1.11.1", "prettier": "^1.11.1",
"stylelint": "^9.2.0", "stylelint": "^9.2.0",
"stylelint-config-standard": "^18.2.0" "stylelint-config-standard": "^18.2.0"
}, },
"scripts": { "scripts": {
"lint:js": "eslint ./src/**/*.js", "lint:js": "eslint ./gatsby-*.js && eslint ./src/**/*.js",
"lint:css": "stylelint ./src/**/*.scss", "lint:css": "stylelint ./src/**/*.scss",
"lint": "npm run lint:js && npm run lint:css", "lint": "npm run lint:js && npm run lint:css",
"build": "gatsby build", "build": "gatsby build",

View File

@ -2,7 +2,7 @@ import React from 'react'
import CSSTransition from 'react-transition-group/CSSTransition' import CSSTransition from 'react-transition-group/CSSTransition'
import './FadeIn.scss' import './FadeIn.scss'
const FadeIn = (props) => ( const FadeIn = props => (
<CSSTransition <CSSTransition
{...props} {...props}
classNames="fadein" classNames="fadein"

View File

@ -1,8 +1,8 @@
import React from 'react' import React from 'react'
import meta from '../../../data/meta.json' import PropTypes from 'prop-types'
import './Footer.scss' import './Footer.scss'
const Footer = () => { const Footer = ({ meta }) => {
const year = new Date().getFullYear() const year = new Date().getFullYear()
return ( return (
@ -12,4 +12,8 @@ const Footer = () => {
) )
} }
Footer.propTypes = {
meta: PropTypes.object,
}
export default Footer export default Footer

View File

@ -0,0 +1,20 @@
import React from 'react'
import PropTypes from 'prop-types'
import Helmet from 'react-helmet'
const Head = ({ meta }) => {
return (
<Helmet
defaultTitle={`${meta.title.toLowerCase()} { ${meta.tagline.toLowerCase()} }`}
titleTemplate={`%s // ${meta.title.toLowerCase()} { ${meta.tagline.toLowerCase()} }`}
>
<link rel="stylesheet" href="https://use.typekit.net/dtg3zui.css" />
</Helmet>
)
}
Head.propTypes = {
meta: PropTypes.object,
}
export default Head

View File

@ -1,31 +1,28 @@
import React, { Component } from 'react' import React from 'react'
import Link from 'react-router-dom/Link' import Link from 'react-router-dom/Link'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import Social from './Social' import Social from './Social'
import './Header.scss' import './Header.scss'
import meta from '../../../data/meta.json'
class Header extends Component { const Header = ({ meta, minimal }) => {
render() { const classes = minimal ? 'header header--minimal' : 'header'
const minimal = this.props.minimal
const classes = (minimal ? 'header header--minimal' : 'header')
return ( return (
<header className={classes}> <header className={classes}>
<Link className="header__name" to="/"> <Link className="header__name" to="/">
<span className="header__logo"></span> <span className="header__logo"></span>
<h1 className="header__title">{meta.title}</h1> <h1 className="header__title">{meta.title}</h1>
<p className="header__description">{meta.tagline}</p> <p className="header__description">{meta.tagline}</p>
</Link> </Link>
<Social /> <Social meta={meta} />
</header> </header>
) )
}
} }
Header.propTypes = { Header.propTypes = {
minimal: PropTypes.bool minimal: PropTypes.bool,
meta: PropTypes.object,
} }
export default Header export default Header

View File

@ -1,10 +1,8 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types'
import { Twitter, GitHub, Facebook } from '../atoms/Icons' import { Twitter, GitHub, Facebook } from '../atoms/Icons'
import meta from '../../../data/meta.json'
import './Social.scss' import './Social.scss'
const social = meta.social
const SocialIcon = ({ title }) => { const SocialIcon = ({ title }) => {
if (title === 'Twitter') { if (title === 'Twitter') {
return <Twitter /> return <Twitter />
@ -15,14 +13,22 @@ const SocialIcon = ({ title }) => {
} }
} }
const Social = () => ( const Social = ({ meta }) => {
<aside className="social"> const social = meta.social
{Object.keys(social).map((key, i) => (
<a className="social__link" href={social[key]} key={i} title={key}> return (
<SocialIcon title={key} /> <aside className="social">
</a> {Object.keys(social).map((key, i) => (
))} <a className="social__link" href={social[key]} key={i} title={key}>
</aside> <SocialIcon title={key} />
) </a>
))}
</aside>
)
}
Social.propTypes = {
meta: PropTypes.object,
}
export default Social export default Social

View File

@ -0,0 +1,87 @@
import React, { Fragment } from 'react'
import PropTypes from 'prop-types'
import Helmet from 'react-helmet'
import ReactMarkdown from 'react-markdown'
import Content from '../atoms/Content'
import FullWidth from '../atoms/FullWidth'
import images from '../../images'
import './Project.scss'
const Project = props => {
const project = props.pathContext
const title = project.title
const img = project.img
const img_more = project.img_more
const description = project.description
const links = project.links
const techstack = project.techstack
return (
<Fragment>
<Helmet>
<title>{title}</title>
</Helmet>
<main className="screen screen--project">
<article className="project">
<Content>
<h1 className="project__title">{title}</h1>
<ReactMarkdown
source={description}
escapeHtml={false}
className="project__description"
/>
<FullWidth>
<img className="project__image" src={images[img]} alt={title} />
</FullWidth>
<FullWidth>
{!!img_more &&
img_more.map(key => (
<img
key={key}
className="project__image"
src={images[key]}
alt={title}
/>
))}
</FullWidth>
<footer className="project__meta">
<div className="project__techstack">
<h3 className="project__meta__title">
Technologies <span>The tech stack I was involved with.</span>
</h3>
<ul>
{!!techstack &&
techstack.map(tech => <li key={tech}>{tech}</li>)}
</ul>
</div>
<div className="project__links">
<h3 className="project__meta__title">
Links <span>See the project live on the interwebz.</span>
</h3>
<ul>
{!!links &&
Object.keys(links).map(key => (
<li key={key}>
<a href={links[key]}>{key}</a>
</li>
))}
</ul>
</div>
</footer>
</Content>
</article>
</main>
</Fragment>
)
}
Project.propTypes = {
pathContext: PropTypes.object,
}
export default Project

View File

@ -6,10 +6,10 @@ import images from '../../images'
import './Projects.scss' import './Projects.scss'
const Projects = ({ data }) => { const Projects = ({ data }) => {
const projects = data.allProjectsJson const projects = data.allProjectsJson.edges
return <div className="projects full-width"> return <div className="projects full-width">
{projects.edges.map(({ node }) => <FadeIn key={node.slug}> {projects.map(({ node }) => <FadeIn key={node.slug}>
<Link key={node.slug} to={`/${node.slug}`} className="projects__project"> <Link key={node.slug} to={`/${node.slug}`} className="projects__project">
<h1 className="projects__project__title">{node.title}</h1> <h1 className="projects__project__title">{node.title}</h1>

View File

@ -7,7 +7,6 @@
} }
.projects__project { .projects__project {
max-height: 100vh;
position: relative; position: relative;
background-color: $brand-grey-light; background-color: $brand-grey-light;
margin-bottom: $spacer * 4; margin-bottom: $spacer * 4;

View File

@ -1,101 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import Helmet from 'react-helmet'
import ReactMarkdown from 'react-markdown'
import Header from '../components/molecules/Header'
import Content from '../components/atoms/Content'
import FullWidth from '../components/atoms/FullWidth'
import images from '../images'
import './Project.scss'
const Project = ({ data }) => {
const project = data.allProjectsJson.edges[0].node
const title = project.title
const img = project.img
const img_more = project.img_more
const description = project.description
const links = project.links
const techstack = project.techstack
return (
<div>
<Helmet>
<title>{title}</title>
</Helmet>
<Header minimal />
<main className="screen screen--project">
<article className="project">
<Content>
<h1 className="project__title">{title}</h1>
<ReactMarkdown source={description} escapeHtml={false} className="project__description" />
<FullWidth>
<img className="project__image" src={images[img]} alt={title} />
</FullWidth>
<FullWidth>
{!!img_more && img_more.map(key => (
<img key={key} className="project__image" src={images[key]} alt={title} />
))}
</FullWidth>
<footer className="project__meta">
<div className="project__techstack">
<h3 className="project__meta__title">Technologies <span>The tech stack I was involved with.</span></h3>
<ul>
{!!techstack && techstack.map(tech => (
<li key={tech}>
{tech}
</li>
))}
</ul>
</div>
<div className="project__links">
<h3 className="project__meta__title">Links <span>See the project live on the interwebz.</span></h3>
<ul>
{!!links && Object.keys(links).map(key => (
<li key={key}>
<a href={links[key]}>{key}</a>
</li>
))}
</ul>
</div>
</footer>
</Content>
</article>
</main>
</div>
)
}
Project.propTypes = {
data: PropTypes.object
}
export default Project
export const query = graphql`
query ProjectQuery($slug: String) {
allProjectsJson(filter: { slug: { eq: $slug } }) {
edges {
node {
title
slug
img
img_more
links {
Link
GitHub
Info
}
description
techstack
}
}
}
}
`

View File

@ -1,30 +1,48 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import Helmet from 'react-helmet' import Head from '../components/molecules/Head'
import FadeIn from '../components/atoms/FadeIn' import FadeIn from '../components/atoms/FadeIn'
import Header from '../components/molecules/Header'
import Footer from '../components/molecules/Footer' import Footer from '../components/molecules/Footer'
import meta from '../../data/meta.json'
import './index.scss' import './index.scss'
const Head = () => ( const TemplateWrapper = props => {
<Helmet const meta = props.data.allDataJson.edges[0].node
defaultTitle={`${meta.title.toLowerCase()} { ${meta.tagline.toLowerCase()} }`}
titleTemplate={`%s // ${meta.title.toLowerCase()} { ${meta.tagline.toLowerCase()} }`}
>
<link rel="stylesheet" href="https://use.typekit.net/dtg3zui.css" />
</Helmet>
)
const TemplateWrapper = ({ children }) => ( return <div className="app">
<div className="app"> <Head meta={meta} />
<Head /> <Header meta={meta} />
<FadeIn>{children()}</FadeIn> <FadeIn>{props.children()}</FadeIn>
<Footer /> <Footer meta={meta} />
</div> </div>
) }
TemplateWrapper.propTypes = { TemplateWrapper.propTypes = {
children: PropTypes.func, children: PropTypes.func,
data: PropTypes.object,
} }
export default TemplateWrapper export default TemplateWrapper
export const query = graphql`
query pageLayoutQueryAndMetaQuery {
allDataJson {
edges {
node {
title
tagline
description
url
social {
Twitter
GitHub
Facebook
}
}
}
}
sitePage {
jsonName
}
}
`

View File

@ -1,15 +1,11 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import Header from '../components/molecules/Header'
import Projects from '../components/organisms/Projects' import Projects from '../components/organisms/Projects'
const Home = ({ data }) => ( const Home = ({ data }) => (
<div> <main className="screen screen--home">
<Header /> <Projects data={data} />
<main className="screen screen--home"> </main>
<Projects data={data} />
</main>
</div>
) )
Home.propTypes = { Home.propTypes = {