1
0
mirror of https://github.com/kremalicious/portfolio.git synced 2024-12-23 01:29:41 +01:00

update to Gatsby v3

This commit is contained in:
Matthias Kretschmann 2021-03-12 23:47:28 +01:00
parent c59ef8e4b6
commit 8da788e4d2
Signed by: m
GPG Key ID: 606EEEF3C479A91F
29 changed files with 2931 additions and 5021 deletions

7669
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -20,25 +20,25 @@
"new": "babel-node ./scripts/new.js" "new": "babel-node ./scripts/new.js"
}, },
"dependencies": { "dependencies": {
"@giphy/js-fetch-api": "^2.2.2", "@giphy/js-fetch-api": "^2.4.0",
"axios": "^0.21.1", "axios": "^0.21.1",
"file-saver": "^2.0.5", "file-saver": "^2.0.5",
"gatsby": "^2.32.4", "gatsby": "^3.0.4",
"gatsby-image": "^2.11.0", "gatsby-image": "^3.0.0",
"gatsby-plugin-manifest": "^2.12.0", "gatsby-plugin-manifest": "^3.0.0",
"gatsby-plugin-matomo": "^0.9.0", "gatsby-plugin-matomo": "^0.9.0",
"gatsby-plugin-offline": "^3.10.1", "gatsby-plugin-offline": "^4.0.0",
"gatsby-plugin-postcss": "^3.6.0", "gatsby-plugin-postcss": "^4.0.0",
"gatsby-plugin-react-helmet": "^3.9.0", "gatsby-plugin-react-helmet": "^4.0.0",
"gatsby-plugin-sharp": "^2.13.4", "gatsby-plugin-sharp": "^3.0.1",
"gatsby-plugin-sitemap": "^2.11.0", "gatsby-plugin-sitemap": "^3.0.0",
"gatsby-plugin-svgr": "^2.1.0", "gatsby-plugin-svgr": "^3.0.0-beta.0",
"gatsby-plugin-use-dark-mode": "^1.2.0", "gatsby-plugin-use-dark-mode": "^1.3.0",
"gatsby-plugin-webpack-size": "^1.0.0", "gatsby-plugin-webpack-size": "^2.0.1",
"gatsby-source-filesystem": "^2.10.0", "gatsby-source-filesystem": "^3.0.0",
"gatsby-transformer-json": "^2.10.0", "gatsby-transformer-json": "^3.0.0",
"gatsby-transformer-sharp": "^2.11.0", "gatsby-transformer-sharp": "^3.0.0",
"gatsby-transformer-yaml": "^2.10.0", "gatsby-transformer-yaml": "^3.0.0",
"intersection-observer": "^0.12.0", "intersection-observer": "^0.12.0",
"react": "^17.0.1", "react": "^17.0.1",
"react-dom": "^17.0.1", "react-dom": "^17.0.1",
@ -55,25 +55,25 @@
"vcf": "^2.1.0" "vcf": "^2.1.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.13.1", "@babel/core": "^7.13.10",
"@babel/eslint-parser": "^7.13.4", "@babel/eslint-parser": "^7.13.10",
"@babel/node": "^7.13.0", "@babel/node": "^7.13.10",
"@babel/preset-env": "^7.12.17", "@babel/preset-env": "^7.13.10",
"@loadable/component": "^5.14.1", "@loadable/component": "^5.14.1",
"@svgr/webpack": "^5.5.0", "@svgr/webpack": "^5.5.0",
"@testing-library/jest-dom": "^5.11.9", "@testing-library/jest-dom": "^5.11.9",
"@testing-library/react": "^11.2.5", "@testing-library/react": "^11.2.5",
"@welldone-software/why-did-you-render": "^6.0.5", "@welldone-software/why-did-you-render": "^6.1.0",
"babel-preset-gatsby": "^0.12.1", "babel-preset-gatsby": "^0.12.2",
"chalk": "^4.1.0", "chalk": "^4.1.0",
"eslint": "^7.20.0", "eslint": "^7.21.0",
"eslint-config-prettier": "^8.0.0", "eslint-config-prettier": "^8.1.0",
"eslint-plugin-graphql": "^4.0.0", "eslint-plugin-graphql": "^4.0.0",
"eslint-plugin-prettier": "^3.3.1", "eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-react": "^7.22.0", "eslint-plugin-react": "^7.22.0",
"eslint-plugin-react-hooks": "^4.2.0", "eslint-plugin-react-hooks": "^4.2.0",
"eslint-plugin-testing-library": "^3.10.1", "eslint-plugin-testing-library": "^3.10.1",
"gatsby-plugin-webpack-bundle-analyser-v2": "^1.1.20", "gatsby-plugin-webpack-bundle-analyser-v2": "^1.1.21",
"identity-obj-proxy": "^3.0.0", "identity-obj-proxy": "^3.0.0",
"jest": "^26.6.3", "jest": "^26.6.3",
"jest-canvas-mock": "^2.3.1", "jest-canvas-mock": "^2.3.1",
@ -83,9 +83,9 @@
"prepend": "^1.0.2", "prepend": "^1.0.2",
"prettier": "^2.2.1", "prettier": "^2.2.1",
"slugify": "^1.4.7", "slugify": "^1.4.7",
"stylelint": "^13.11.0", "stylelint": "^13.12.0",
"stylelint-config-prettier": "^8.0.2", "stylelint-config-prettier": "^8.0.2",
"stylelint-prettier": "^1.1.2" "stylelint-prettier": "^1.2.0"
}, },
"browserslist": [ "browserslist": [
">0.2%", ">0.2%",

View File

@ -7,7 +7,7 @@ import HostnameCheck from './atoms/HostnameCheck'
import ThemeSwitch from './molecules/ThemeSwitch' import ThemeSwitch from './molecules/ThemeSwitch'
import Header from './organisms/Header' import Header from './organisms/Header'
import Footer from './organisms/Footer' import Footer from './organisms/Footer'
import styles from './Layout.module.css' import { screen } from './Layout.module.css'
import { useMeta } from '../hooks/use-meta' import { useMeta } from '../hooks/use-meta'
// https://github.com/welldone-software/why-did-you-render // https://github.com/welldone-software/why-did-you-render
@ -49,7 +49,7 @@ export default function Layout({ children, location }) {
delayChildren={timeout} delayChildren={timeout}
> >
<Header minimal={!isHomepage} hide={isResume} /> <Header minimal={!isHomepage} hide={isResume} />
<main className={styles.screen}>{children}</main> <main className={screen}>{children}</main>
</RoutesContainer> </RoutesContainer>
</PoseGroup> </PoseGroup>

View File

@ -1,9 +1,9 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import styles from './Button.module.css' import { button } from './Button.module.css'
const Button = (props) => ( const Button = (props) => (
<a className={styles.button} {...props}> <a className={button} {...props}>
{props.children} {props.children}
</a> </a>
) )

View File

@ -1,10 +1,8 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import styles from './FullWidth.module.css' import { fullWidth } from './FullWidth.module.css'
const FullWidth = ({ children }) => ( const FullWidth = ({ children }) => <div className={fullWidth}>{children}</div>
<div className={styles.fullWidth}>{children}</div>
)
FullWidth.propTypes = { FullWidth.propTypes = {
children: PropTypes.node children: PropTypes.node

View File

@ -1,7 +1,7 @@
import React, { PureComponent } from 'react' import React, { PureComponent } from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { Helmet } from 'react-helmet' import { Helmet } from 'react-helmet'
import styles from './HostnameCheck.module.css' import { hostnameInfo } from './HostnameCheck.module.css'
export default class HostnameCheck extends PureComponent { export default class HostnameCheck extends PureComponent {
static propTypes = { static propTypes = {
@ -33,7 +33,7 @@ export default class HostnameCheck extends PureComponent {
<Helmet> <Helmet>
<meta name="robots" content="noindex,nofollow" /> <meta name="robots" content="noindex,nofollow" />
</Helmet> </Helmet>
<aside className={styles.hostnameInfo}> <aside className={hostnameInfo}>
<p>{`Hi there 👋. Please note that only the code and documentation of this <p>{`Hi there 👋. Please note that only the code and documentation of this
site are open source. But my logo and the combination of typography, site are open source. But my logo and the combination of typography,
colors, and layout making up my brand identity are not. Don't just colors, and layout making up my brand identity are not. Don't just

View File

@ -25,7 +25,7 @@ import {
Info, Info,
Dribbble Dribbble
} from 'react-feather' } from 'react-feather'
import styles from './Icon.module.css' import { icon } from './Icon.module.css'
const Icon = memo(({ name, ...props }) => { const Icon = memo(({ name, ...props }) => {
const components = { const components = {
@ -62,7 +62,7 @@ const Icon = memo(({ name, ...props }) => {
// const IconComp = Feather[name] // const IconComp = Feather[name]
if (!IconMapped) return null if (!IconMapped) return null
return <IconMapped className={styles.icon} {...props} /> return <IconMapped className={icon} {...props} />
}) })
Icon.displayName = 'Icon' Icon.displayName = 'Icon'

View File

@ -2,7 +2,7 @@ import React, { PureComponent } from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { graphql } from 'gatsby' import { graphql } from 'gatsby'
import Img from 'gatsby-image' import Img from 'gatsby-image'
import styles from './ProjectImage.module.css' import { projectImage as styleProjectImage } from './ProjectImage.module.css'
export default class ProjectImage extends PureComponent { export default class ProjectImage extends PureComponent {
static propTypes = { static propTypes = {
@ -13,7 +13,7 @@ export default class ProjectImage extends PureComponent {
render() { render() {
return ( return (
<Img <Img
className={styles.projectImage} className={styleProjectImage}
backgroundColor="transparent" backgroundColor="transparent"
fluid={this.props.fluid} fluid={this.props.fluid}
alt={this.props.alt} alt={this.props.alt}

View File

@ -3,7 +3,10 @@ import PropTypes from 'prop-types'
import posed from 'react-pose' import posed from 'react-pose'
import { fadeIn } from '../atoms/Transitions' import { fadeIn } from '../atoms/Transitions'
import { useMeta } from '../../hooks/use-meta' import { useMeta } from '../../hooks/use-meta'
import styles from './Availability.module.css' import {
availability as styleAvailability,
available as styleAvailable
} from './Availability.module.css'
const Animation = posed.aside(fadeIn) const Animation = posed.aside(fadeIn)
@ -11,8 +14,8 @@ const Availability = ({ hide }) => {
const { availability } = useMeta() const { availability } = useMeta()
const { status, available, unavailable } = availability const { status, available, unavailable } = availability
const className = status const className = status
? `${styles.availability} ${styles.available}` ? `${styleAvailability} ${styleAvailable}`
: `${styles.availability}` : `${styleAvailability}`
const html = status ? available : unavailable const html = status ? available : unavailable
return ( return (

View File

@ -4,7 +4,13 @@ import { Link } from 'gatsby'
import posed from 'react-pose' import posed from 'react-pose'
import { moveInBottom } from '../atoms/Transitions' import { moveInBottom } from '../atoms/Transitions'
import { ReactComponent as Logo } from '../../images/logo.svg' import { ReactComponent as Logo } from '../../images/logo.svg'
import styles from './LogoUnit.module.css' import {
minimal as styleMinimal,
logounit,
logo,
title,
description
} from './LogoUnit.module.css'
import { useResume } from '../../hooks/use-resume' import { useResume } from '../../hooks/use-resume'
LogoUnit.propTypes = { LogoUnit.propTypes = {
@ -18,12 +24,10 @@ function LogoUnit({ minimal }) {
return ( return (
<Animation> <Animation>
<Link className={minimal ? styles.minimal : styles.logounit} to={'/'}> <Link className={minimal ? styleMinimal : logounit} to={'/'}>
<Logo className={styles.logo} /> <Logo className={logo} />
<h1 className={`p-name ${styles.title}`}> <h1 className={`p-name ${title}`}>{basics.name.toLowerCase()}</h1>
{basics.name.toLowerCase()} <p className={`p-job-title ${description}`}>
</h1>
<p className={`p-job-title ${styles.description}`}>
{basics.label.toLowerCase()} {basics.label.toLowerCase()}
</p> </p>
</Link> </Link>

View File

@ -4,10 +4,15 @@ import posed from 'react-pose'
import { moveInTop } from '../atoms/Transitions' import { moveInTop } from '../atoms/Transitions'
import Icon from '../atoms/Icon' import Icon from '../atoms/Icon'
import { useResume } from '../../hooks/use-resume' import { useResume } from '../../hooks/use-resume'
import styles from './Networks.module.css' import {
link,
title,
small as styleSmall,
networks
} from './Networks.module.css'
const linkClasses = (key) => const linkClasses = (key) =>
key === 'Mail' ? `u-email ${styles.link}` : `u-url ${styles.link}` key === 'Mail' ? `u-email ${link}` : `u-url ${link}`
const NetworkLink = ({ name, url }) => ( const NetworkLink = ({ name, url }) => (
<a <a
@ -16,7 +21,7 @@ const NetworkLink = ({ name, url }) => (
data-testid={`network-${name.toLowerCase()}`} data-testid={`network-${name.toLowerCase()}`}
> >
<Icon name={name} /> <Icon name={name} />
<span className={styles.title}>{name}</span> <span className={title}>{name}</span>
</a> </a>
) )
@ -32,7 +37,7 @@ function Networks({ small, hide }) {
const Animation = posed.aside(moveInTop) const Animation = posed.aside(moveInTop)
return ( return (
<Animation className={small ? styles.small : styles.networks}> <Animation className={small ? styleSmall : networks}>
<NetworkLink name="Mail" url={`mailto:${basics.email}`} /> <NetworkLink name="Mail" url={`mailto:${basics.email}`} />
{basics.profiles.map((profile) => ( {basics.profiles.map((profile) => (

View File

@ -2,7 +2,7 @@ import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import Button from '../atoms/Button' import Button from '../atoms/Button'
import Icon from '../atoms/Icon' import Icon from '../atoms/Icon'
import styles from './ProjectLinks.module.css' import { projectLinks, title } from './ProjectLinks.module.css'
ProjectLinks.propTypes = { ProjectLinks.propTypes = {
links: PropTypes.array links: PropTypes.array
@ -10,8 +10,8 @@ ProjectLinks.propTypes = {
export default function ProjectLinks({ links }) { export default function ProjectLinks({ links }) {
return ( return (
<div className={styles.projectLinks}> <div className={projectLinks}>
<h3 className={styles.title}> <h3 className={title}>
Links <span>Learn more on the interwebz.</span> Links <span>Learn more on the interwebz.</span>
</h3> </h3>

View File

@ -3,7 +3,7 @@ import PropTypes from 'prop-types'
import { Link, graphql, StaticQuery } from 'gatsby' import { Link, graphql, StaticQuery } from 'gatsby'
import shortid from 'shortid' import shortid from 'shortid'
import ProjectImage from '../atoms/ProjectImage' import ProjectImage from '../atoms/ProjectImage'
import styles from './ProjectNav.module.css' import { item, link, title, projectNav } from './ProjectNav.module.css'
const query = graphql` const query = graphql`
query { query {
@ -26,14 +26,10 @@ const query = graphql`
` `
const Project = ({ node, refCurrentItem }) => ( const Project = ({ node, refCurrentItem }) => (
<div className={styles.item} ref={refCurrentItem}> <div className={item} ref={refCurrentItem}>
<Link className={styles.link} to={node.slug}> <Link className={link} to={node.slug}>
<ProjectImage <ProjectImage fluid={node.img.childImageSharp.fluid} alt={node.title} />
className={styles.image} <h1 className={title}>{node.title}</h1>
fluid={node.img.childImageSharp.fluid}
alt={node.title}
/>
<h1 className={styles.title}>{node.title}</h1>
</Link> </Link>
</div> </div>
) )
@ -88,7 +84,7 @@ export default class ProjectNav extends PureComponent {
const projects = data.allProjectsYaml.edges const projects = data.allProjectsYaml.edges
return ( return (
<nav className={styles.projectNav} ref={this.scrollContainer}> <nav className={projectNav} ref={this.scrollContainer}>
{projects.map(({ node }) => { {projects.map(({ node }) => {
const isCurrent = node.slug === currentSlug const isCurrent = node.slug === currentSlug

View File

@ -1,10 +1,10 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import styles from './ProjectTechstack.module.css' import { projectTechstack, title } from './ProjectTechstack.module.css'
const ProjectTechstack = ({ techstack }) => ( const ProjectTechstack = ({ techstack }) => (
<div className={styles.projectTechstack}> <div className={projectTechstack}>
<h3 className={styles.title}> <h3 className={title}>
Tools & Technologies <span>The tech stack I was involved with.</span> Tools & Technologies <span>The tech stack I was involved with.</span>
</h3> </h3>
<ul> <ul>

View File

@ -1,7 +1,7 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import Icon from '../atoms/Icon' import Icon from '../atoms/Icon'
import styles from './Repository.module.css' import { repo as styleRepo, repoTitle, meta } from './Repository.module.css'
export default function Repository({ repo }) { export default function Repository({ repo }) {
const { const {
@ -23,12 +23,12 @@ export default function Repository({ repo }) {
: homepage : homepage
return ( return (
<div className={styles.repo}> <div className={styleRepo}>
<h1 className={styles.repoTitle}> <h1 className={repoTitle}>
<a href={repoLink}>{isExternal ? full_name : name}</a> <a href={repoLink}>{isExternal ? full_name : name}</a>
</h1> </h1>
<p>{description}</p> <p>{description}</p>
<p className={styles.meta}> <p className={meta}>
{name === 'portfolio' || name === 'blog' {name === 'portfolio' || name === 'blog'
? null ? null
: !isExternal && : !isExternal &&

View File

@ -3,12 +3,18 @@ import PropTypes from 'prop-types'
import { Helmet } from 'react-helmet' import { Helmet } from 'react-helmet'
import useDarkMode from 'use-dark-mode' import useDarkMode from 'use-dark-mode'
import Icon from '../atoms/Icon' import Icon from '../atoms/Icon'
import styles from './ThemeSwitch.module.css' import {
checkboxContainer,
checkboxFake,
themeSwitch,
checkbox,
label
} from './ThemeSwitch.module.css'
const ThemeToggle = memo(({ dark }) => ( const ThemeToggle = memo(({ dark }) => (
<span id="toggle" className={styles.checkboxContainer} aria-live="assertive"> <span id="toggle" className={checkboxContainer} aria-live="assertive">
<Icon name="Sun" className={!dark ? null : 'active'} /> <Icon name="Sun" className={!dark ? null : 'active'} />
<span className={styles.checkboxFake} /> <span className={checkboxFake} />
<Icon name="Moon" className={dark ? 'active' : null} /> <Icon name="Moon" className={dark ? 'active' : null} />
</span> </span>
)) ))
@ -69,9 +75,9 @@ function ThemeSwitch() {
return ( return (
<> <>
<HeadItems themeColor={themeColor} bodyClass={bodyClass} /> <HeadItems themeColor={themeColor} bodyClass={bodyClass} />
<aside className={styles.themeSwitch}> <aside className={themeSwitch}>
<label className={styles.checkbox}> <label className={checkbox}>
<span className={styles.label}>Toggle Night Mode</span> <span className={label}>Toggle Night Mode</span>
<ThemeToggleInput dark={value} toggleDark={toggle} /> <ThemeToggleInput dark={value} toggleDark={toggle} />
<ThemeToggle dark={value} /> <ThemeToggle dark={value} />
</label> </label>

View File

@ -3,24 +3,24 @@ import PropTypes from 'prop-types'
import loadable from '@loadable/component' import loadable from '@loadable/component'
import LogoUnit from '../molecules/LogoUnit' import LogoUnit from '../molecules/LogoUnit'
import Networks from '../molecules/Networks' import Networks from '../molecules/Networks'
import styles from './Footer.module.css' import { footer, actions, copyright } from './Footer.module.css'
import { useMeta } from '../../hooks/use-meta' import { useMeta } from '../../hooks/use-meta'
const LazyVcard = loadable(() => import('../atoms/Vcard')) const LazyVcard = loadable(() => import('../atoms/Vcard'))
const FooterMarkup = ({ meta, year }) => ( const FooterMarkup = ({ meta, year }) => (
<footer className={`h-card ${styles.footer}`}> <footer className={`h-card ${footer}`}>
<LogoUnit minimal /> <LogoUnit minimal />
<Networks small /> <Networks small />
<p className={styles.actions}> <p className={actions}>
<LazyVcard /> <LazyVcard />
<a className="u-key" href={meta.gpg}> <a className="u-key" href={meta.gpg}>
PGP/GPG key PGP/GPG key
</a> </a>
<a href={meta.bugs}>Found a bug?</a> <a href={meta.bugs}>Found a bug?</a>
</p> </p>
<p className={styles.copyright}> <p className={copyright}>
<small> <small>
&copy; {year}{' '} &copy; {year}{' '}
<a className="u-url" href={meta.url}> <a className="u-url" href={meta.url}>

View File

@ -4,7 +4,7 @@ import Networks from '../molecules/Networks'
import Availability from '../molecules/Availability' import Availability from '../molecules/Availability'
import LogoUnit from '../molecules/LogoUnit' import LogoUnit from '../molecules/LogoUnit'
import styles from './Header.module.css' import { header, minimal as styleMinimal } from './Header.module.css'
import { useMeta } from '../../hooks/use-meta' import { useMeta } from '../../hooks/use-meta'
Header.propTypes = { Header.propTypes = {
@ -16,7 +16,7 @@ export default function Header({ minimal, hide }) {
const { availability } = useMeta() const { availability } = useMeta()
return ( return (
<header className={minimal ? styles.minimal : styles.header}> <header className={minimal ? styleMinimal : header}>
{!hide && ( {!hide && (
<> <>
<LogoUnit minimal={minimal} /> <LogoUnit minimal={minimal} />

View File

@ -2,7 +2,11 @@ import React, { memo } from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import Repository from '../molecules/Repository' import Repository from '../molecules/Repository'
import styles from './Repositories.module.css' import {
section,
sectionTitle,
repos as styleRepos
} from './Repositories.module.css'
Repositories.propTypes = { Repositories.propTypes = {
repos: PropTypes.array repos: PropTypes.array
@ -12,9 +16,9 @@ function Repositories({ repos }) {
if (!repos) return null if (!repos) return null
return ( return (
<section className={styles.section}> <section className={section}>
<h1 className={styles.sectionTitle}>Open Source Projects</h1> <h1 className={sectionTitle}>Open Source Projects</h1>
<div className={styles.repos}> <div className={styleRepos}>
{repos.map((repo) => ( {repos.map((repo) => (
<Repository key={repo.name} repo={repo} /> <Repository key={repo.name} repo={repo} />
))} ))}

View File

@ -2,7 +2,7 @@ import React from 'react'
import shortid from 'shortid' import shortid from 'shortid'
import { useResume } from '../../../hooks/use-resume' import { useResume } from '../../../hooks/use-resume'
import Icon from '../../atoms/Icon' import Icon from '../../atoms/Icon'
import styles from './Header.module.css' import { title, description, contact, languagesList } from './Header.module.css'
export default function Header() { export default function Header() {
const { basics, languages } = useResume() const { basics, languages } = useResume()
@ -12,12 +12,12 @@ export default function Header() {
<> <>
<header> <header>
<p>Résumé</p> <p>Résumé</p>
<h1 className={styles.title}>{name}</h1> <h1 className={title}>{name}</h1>
<h2 className={styles.label}>{label}</h2> <h2 className={description}>{label}</h2>
</header> </header>
<div> <div>
<ul className={styles.contact}> <ul className={contact}>
<li> <li>
<a href={website}> <a href={website}>
<Icon name="Compass" /> <Icon name="Compass" />
@ -32,7 +32,7 @@ export default function Header() {
<Icon name="MapPin" /> <Icon name="MapPin" />
{location.city}, {location.countryCode} {location.city}, {location.countryCode}
</li> </li>
<li className={styles.languages}> <li className={languagesList}>
<Icon name="Globe" /> <Icon name="Globe" />
{languages.map((item) => ( {languages.map((item) => (
<p key={shortid.generate()}> <p key={shortid.generate()}>

View File

@ -9,7 +9,7 @@
} }
} }
.label { .description {
font-size: var(--font-size-h3); font-size: var(--font-size-h3);
color: var(--text-color); color: var(--text-color);
margin-bottom: 0; margin-bottom: 0;
@ -37,20 +37,20 @@
} }
} }
.languages svg { .languagesList svg {
display: inline-block; display: inline-block;
} }
.languages p { .languagesList p {
margin-left: calc(var(--spacer) / 1.1); margin-left: calc(var(--spacer) / 1.1);
} }
.languages p:first-of-type { .languagesList p:first-of-type {
margin-left: 0; margin-left: 0;
display: inline-block; display: inline-block;
} }
.languages span { .languagesList span {
font-size: var(--font-size-small); font-size: var(--font-size-small);
margin-left: calc(var(--spacer) / 4); margin-left: calc(var(--spacer) / 4);
color: var(--text-color-light); color: var(--text-color-light);

View File

@ -5,7 +5,12 @@ import remark2react from 'remark-react'
import parse from 'remark-parse' import parse from 'remark-parse'
import html from 'remark-html' import html from 'remark-html'
import breaks from 'remark-breaks' import breaks from 'remark-breaks'
import styles from './ResumeItem.module.css' import {
resumeItem,
time,
styleTitle,
styleSubTitle
} from './ResumeItem.module.css'
const markdownOutput = (text) => const markdownOutput = (text) =>
remark() remark()
@ -32,13 +37,13 @@ export default function ResumeItem({ content }) {
const isSameYear = dateStart === dateEnd const isSameYear = dateStart === dateEnd
return ( return (
<div className={styles.resumeItem}> <div className={resumeItem}>
<span className={styles.time}> <span className={time}>
{dateStart} {dateStart}
{dateEnd ? !isSameYear && `${dateEnd}` : 'present'}{' '} {dateEnd ? !isSameYear && `${dateEnd}` : 'present'}{' '}
</span> </span>
<h4 className={styles.title}>{title}</h4> <h4 className={styleTitle}>{title}</h4>
<h5 className={styles.subTitle}>{subTitle}</h5> <h5 className={styleSubTitle}>{subTitle}</h5>
{text && markdownOutput(text)} {text && markdownOutput(text)}
</div> </div>
) )

View File

@ -26,12 +26,12 @@
margin-bottom: 0; margin-bottom: 0;
} }
.title { .styleTitle {
margin-bottom: calc(var(--spacer) / 3); margin-bottom: calc(var(--spacer) / 3);
font-size: var(--font-size-h4); font-size: var(--font-size-h4);
} }
.subTitle { .styleSubTitle {
color: var(--text-color-light); color: var(--text-color-light);
font-size: var(--font-size-h5); font-size: var(--font-size-h5);
} }

View File

@ -3,12 +3,12 @@ import PropTypes from 'prop-types'
import shortid from 'shortid' import shortid from 'shortid'
import Icon from '../../atoms/Icon' import Icon from '../../atoms/Icon'
import ResumeItem, { ResumeItemContentProps } from './ResumeItem' import ResumeItem, { ResumeItemContentProps } from './ResumeItem'
import styles from './ResumeSection.module.css' import { subTitle } from './ResumeSection.module.css'
export default function ResumeSection({ section }) { export default function ResumeSection({ section }) {
return ( return (
<> <>
<h3 className={styles.subTitle}> <h3 className={subTitle}>
<Icon name={section.icon} /> <Icon name={section.icon} />
{section.name} {section.name}
</h3> </h3>

View File

@ -3,7 +3,7 @@ import { Link } from 'gatsby'
import { GiphyFetch } from '@giphy/js-fetch-api' import { GiphyFetch } from '@giphy/js-fetch-api'
import SEO from '../components/atoms/SEO' import SEO from '../components/atoms/SEO'
import Button from '../components/atoms/Button' import Button from '../components/atoms/Button'
import styles from './404.module.css' import { content } from './404.module.css'
// Famous last words: // Famous last words:
// "It's just the 404 page so why not expose the dev API key" // "It's just the 404 page so why not expose the dev API key"
@ -41,7 +41,7 @@ export default function NotFound() {
<> <>
<SEO /> <SEO />
<article className={styles.content}> <article className={content}>
<h1>Shenanigans, page not found.</h1> <h1>Shenanigans, page not found.</h1>
<p> <p>
You might want to check the url, or{' '} You might want to check the url, or{' '}

View File

@ -4,7 +4,12 @@ import { Link, graphql } from 'gatsby'
import shortid from 'shortid' import shortid from 'shortid'
import SEO from '../components/atoms/SEO' import SEO from '../components/atoms/SEO'
import ProjectImage from '../components/atoms/ProjectImage' import ProjectImage from '../components/atoms/ProjectImage'
import styles from './index.module.css' import {
project as styleProject,
projects as styleProjects,
title as styleTitle,
imageCount as styleImageCount
} from './index.module.css'
import Repositories from '../components/organisms/Repositories' import Repositories from '../components/organisms/Repositories'
import Icon from '../components/atoms/Icon' import Icon from '../components/atoms/Icon'
@ -33,14 +38,14 @@ function Project({ node, images }) {
const imageCount = getImageCount(images, slug) const imageCount = getImageCount(images, slug)
return ( return (
<article className={styles.project} key={slug}> <article className={styleProject} key={slug}>
<Link to={slug}> <Link to={slug}>
<h1 className={styles.title}>{title}</h1> <h1 className={styleTitle}>{title}</h1>
<ProjectImage fluid={img.childImageSharp.fluid} alt={title} /> <ProjectImage fluid={img.childImageSharp.fluid} alt={title} />
{imageCount > 1 && ( {imageCount > 1 && (
<small <small
className={styles.imageCount} className={styleImageCount}
title={`${imageCount} project images`} title={`${imageCount} project images`}
> >
<Icon name="Image" /> {imageCount} <Icon name="Image" /> {imageCount}
@ -64,7 +69,7 @@ function Home({ data, pageContext }) {
<> <>
<SEO /> <SEO />
<div className={styles.projects}> <div className={styleProjects}>
{projects.map(({ node }) => ( {projects.map(({ node }) => (
<Project key={shortid.generate()} node={node} images={images} /> <Project key={shortid.generate()} node={node} images={images} />
))} ))}

View File

@ -2,7 +2,7 @@ import React from 'react'
import shortid from 'shortid' import shortid from 'shortid'
import SEO from '../components/atoms/SEO' import SEO from '../components/atoms/SEO'
import { useResume } from '../hooks/use-resume' import { useResume } from '../hooks/use-resume'
import styles from './resume.module.css' import { resume } from './resume.module.css'
import Header from '../components/pages/Resume/Header' import Header from '../components/pages/Resume/Header'
import ResumeSection from '../components/pages/Resume/ResumeSection' import ResumeSection from '../components/pages/Resume/ResumeSection'
@ -18,7 +18,7 @@ export default function Resume() {
<> <>
<SEO /> <SEO />
<div className={styles.resume}> <div className={resume}>
<Header /> <Header />
{items.map((item) => ( {items.map((item) => (

View File

@ -7,7 +7,12 @@ import ProjectTechstack from '../components/molecules/ProjectTechstack'
import ProjectLinks from '../components/molecules/ProjectLinks' import ProjectLinks from '../components/molecules/ProjectLinks'
import ProjectNav from '../components/molecules/ProjectNav' import ProjectNav from '../components/molecules/ProjectNav'
import SEO from '../components/atoms/SEO' import SEO from '../components/atoms/SEO'
import styles from './{ProjectsYaml.slug}.module.css' import {
meta,
imageWrap,
headerTitle,
description
} from './{ProjectsYaml.slug}.module.css'
class ProjectMeta extends PureComponent { class ProjectMeta extends PureComponent {
static propTypes = { static propTypes = {
@ -19,7 +24,7 @@ class ProjectMeta extends PureComponent {
const { links, techstack } = this.props const { links, techstack } = this.props
return ( return (
<footer className={styles.meta}> <footer className={meta}>
{!!links && <ProjectLinks links={links} />} {!!links && <ProjectLinks links={links} />}
{!!techstack && <ProjectTechstack techstack={techstack} />} {!!techstack && <ProjectTechstack techstack={techstack} />}
</footer> </footer>
@ -37,7 +42,7 @@ class ProjectImages extends PureComponent {
return ( return (
<FullWidth> <FullWidth>
{this.props.projectImages.map(({ node }) => ( {this.props.projectImages.map(({ node }) => (
<div className={styles.imageWrap} key={node.id}> <div className={imageWrap} key={node.id}>
<ProjectImage fluid={node.fluid} alt={this.props.title} /> <ProjectImage fluid={node.fluid} alt={this.props.title} />
</div> </div>
))} ))}
@ -65,10 +70,10 @@ export default class Project extends PureComponent {
<article> <article>
<header> <header>
<h1 className={styles.title}>{title}</h1> <h1 className={headerTitle}>{title}</h1>
</header> </header>
<div <div
className={styles.description} className={description}
dangerouslySetInnerHTML={{ __html: descriptionHtml }} dangerouslySetInnerHTML={{ __html: descriptionHtml }}
/> />
<ProjectImages projectImages={projectImages} title={title} /> <ProjectImages projectImages={projectImages} title={title} />

View File

@ -2,7 +2,7 @@
margin-bottom: calc(var(--spacer) * 3); margin-bottom: calc(var(--spacer) * 3);
} }
.title { .headerTitle {
font-size: var(--font-size-h2); font-size: var(--font-size-h2);
} }
@ -11,7 +11,7 @@
margin-bottom: calc(var(--spacer) * 6); margin-bottom: calc(var(--spacer) * 6);
} }
.title { .headerTitle {
font-size: var(--font-size-h1); font-size: var(--font-size-h1);
} }
} }