Skip to content

Commit 05db231

Browse files
committed
Add language to writings
Add keywords to writings Add theme switch Add Layout component to add initial Helmet att Rename all scss modules with an underscore Added Storage module
1 parent f6ff65d commit 05db231

36 files changed

+714
-257
lines changed

.prettierrc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
"semi": false,
44
"singleQuote": true,
55
"proseWrap": "always",
6-
"endOfLine": "lf"
6+
"endOfLine": "lf",
7+
"arrowParens": "always"
78
}

content/writings/Der Morgen, die Nacht/index.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,14 @@ title: Der Morgen, die Nacht
33
description: Ein kleines süßes Gedicht
44
created: 02-23-2015
55
modified: 07-12-2019
6-
language: de
76

87
header:
98
image: image.jpg
109
author: Luis Alfonso Orellana
1110
link: https://unsplash.com/@alphonzs?utm_medium=referral&utm_campaign=photographer-credit&utm_content=creditBadge
1211
source: unsplash
1312

14-
tags: [german]
13+
language: de
1514
keywords: [dreams]
1615
---
1716

content/writings/__demo__/index.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,14 @@ description: Ein kleines süßes Gedicht
44
slug: custom slug
55
created: 09-23-2019
66
modified: 07-12-2019
7-
language: en
87

98
header:
109
image: image.jpg
1110
author: Daniil Vnoutchkov
1211
link: https://unsplash.com/@daniilvnoutchkov?utm_medium=referral&utm_campaign=photographer-credit&utm_content=creditBadge
1312
source: unsplash
1413

15-
tags: [german]
14+
language: en
1615
keywords: [dreams]
1716
---
1817

package-lock.json

Lines changed: 148 additions & 153 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "marvin-digital",
3-
"version": "3.1.0",
3+
"version": "3.2.0",
44
"private": true,
55
"description": "Portfolio of Marvin Heilemann (@muuvmuuv)",
66
"repository": {
@@ -40,32 +40,32 @@
4040
"dependencies": {
4141
"@ibm/plex": "^4.0.2",
4242
"dayjs": "^1.8.19",
43-
"gatsby": "^2.18.18",
44-
"gatsby-image": "^2.2.37",
43+
"gatsby": "^2.18.21",
44+
"gatsby-image": "^2.2.38",
4545
"gatsby-plugin-breadcrumb": "^6.3.0",
46-
"gatsby-plugin-canonical-urls": "^2.1.18",
47-
"gatsby-plugin-catch-links": "^2.1.21",
46+
"gatsby-plugin-canonical-urls": "^2.1.19",
47+
"gatsby-plugin-catch-links": "^2.1.24",
4848
"gatsby-plugin-humans-txt": "^1.1.4",
49-
"gatsby-plugin-layout": "^1.1.18",
50-
"gatsby-plugin-manifest": "^2.2.34",
49+
"gatsby-plugin-layout": "^1.1.21",
50+
"gatsby-plugin-manifest": "^2.2.37",
5151
"gatsby-plugin-module-resolver": "^1.0.3",
52-
"gatsby-plugin-postcss": "^2.1.18",
53-
"gatsby-plugin-preact": "^3.1.24",
52+
"gatsby-plugin-postcss": "^2.1.19",
53+
"gatsby-plugin-preact": "^3.1.25",
5454
"gatsby-plugin-purgecss": "^4.0.1",
55-
"gatsby-plugin-react-helmet": "^3.1.18",
55+
"gatsby-plugin-react-helmet": "^3.1.21",
5656
"gatsby-plugin-remove-generator": "^1.0.4",
5757
"gatsby-plugin-robots-txt": "^1.5.0",
58-
"gatsby-plugin-sass": "^2.1.26",
59-
"gatsby-plugin-sharp": "^2.3.10",
60-
"gatsby-plugin-sitemap": "^2.2.24",
58+
"gatsby-plugin-sass": "^2.1.27",
59+
"gatsby-plugin-sharp": "^2.3.13",
60+
"gatsby-plugin-sitemap": "^2.2.25",
6161
"gatsby-plugin-webpack-bundle-analyzer": "^1.0.5",
6262
"gatsby-remark-emoji": "0.0.3",
63-
"gatsby-remark-images": "^3.1.39",
64-
"gatsby-remark-prismjs": "^3.3.29",
65-
"gatsby-source-filesystem": "^2.1.43",
66-
"gatsby-transformer-json": "^2.2.22",
67-
"gatsby-transformer-remark": "^2.6.45",
68-
"gatsby-transformer-sharp": "^2.3.9",
63+
"gatsby-remark-images": "^3.1.42",
64+
"gatsby-remark-prismjs": "^3.3.30",
65+
"gatsby-source-filesystem": "^2.1.46",
66+
"gatsby-transformer-json": "^2.2.25",
67+
"gatsby-transformer-remark": "^2.6.48",
68+
"gatsby-transformer-sharp": "^2.3.12",
6969
"kleur": "^3.0.3",
7070
"node-sass": "^4.13.0",
7171
"postcss-easing-gradients": "^3.0.1",
@@ -83,7 +83,7 @@
8383
"del-cli": "^3.0.0",
8484
"eslint": "^6.8.0",
8585
"eslint-config-react-app": "^5.1.0",
86-
"gatsby-plugin-remove-trailing-slashes": "^2.1.17",
86+
"gatsby-plugin-remove-trailing-slashes": "^2.1.20",
8787
"lighthouse": "^5.6.0",
8888
"npm-run-all": "^4.1.5",
8989
"prettier": "^1.19.1",

src/components/HeroWritings.jsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,18 @@ import Backdrop from './Backdrop'
44
import Time from './Time'
55
import Language from './Language'
66
import Separator from './Separator'
7+
import Keywords from './Keywords'
78

8-
const HeroWritings = ({ img, title, lang, time }) => (
9+
const HeroWritings = ({ img, title, keywords, lang, time }) => (
910
<div id="hero">
1011
<Backdrop img={img.image.childImageSharp.fluid}></Backdrop>
1112

1213
<div className="container">
1314
<div className="post-title">
1415
<h1>{title}</h1>
1516
<h2>
17+
<Keywords list={keywords} />
18+
<Separator />
1619
<Time date={time} format="LL" />
1720
<Separator />
1821
<Language lang={lang} />

src/components/Keywords.jsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import React from 'react'
2+
3+
const Keywords = ({ list }) => (
4+
<span className="keywords">
5+
{list.map((item, i) => (
6+
<span key={i}>
7+
{item}
8+
{list.length > i + 1 ? ', ' : ''}
9+
</span>
10+
))}
11+
</span>
12+
)
13+
14+
export default Keywords

src/components/ThemeSwitch.jsx

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import React, { useContext } from 'react'
2+
3+
import { Theme } from '../store'
4+
import { modes } from '../store/theme'
5+
6+
/**
7+
* @link https://codepen.io/muuvmuuv/pen/jOEzYLa?editors=0110
8+
*/
9+
const ThemeSwitch = () => {
10+
const themeState = useContext(Theme.State)
11+
12+
const current = modes.findIndex((m) => m === themeState.mode)
13+
const index = current + 1 >= modes.length ? 0 : current + 1
14+
const nextMode = modes[index]
15+
16+
function toggleTheme(event) {
17+
const element = event.target
18+
element.classList.add('animating')
19+
themeState.toggle()
20+
}
21+
22+
function onAnimationEnd(event) {
23+
const element = event.target
24+
element.classList.remove('animating')
25+
}
26+
27+
return (
28+
<button
29+
id="theme-switch"
30+
onKeyPress={toggleTheme}
31+
onClick={toggleTheme}
32+
mode={themeState.mode}
33+
theme={themeState.theme}
34+
onAnimationEnd={onAnimationEnd}
35+
aria-label={`Switch to ${nextMode} appearance`}
36+
title={`Switch to ${nextMode} appearance`}
37+
></button>
38+
)
39+
}
40+
41+
export default ThemeSwitch

src/layouts/Layout.jsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import React, { useContext } from 'react'
2+
import { Helmet } from 'react-helmet-async'
3+
4+
import { Theme } from '../store'
5+
6+
const Layout = ({ children }) => {
7+
const themeState = useContext(Theme.State)
8+
9+
return (
10+
<>
11+
<Helmet
12+
htmlAttributes={{
13+
theme: themeState.theme,
14+
}}
15+
/>
16+
17+
{children}
18+
</>
19+
)
20+
}
21+
22+
export default Layout

src/layouts/header.jsx

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,13 @@
11
import React from 'react'
22

33
import Logo from '../components/Logo'
4-
import Navigation from '../components/Navigation'
54
import Breadcrumb from '../components/Breadcrumb'
5+
import Navigation from '../components/Navigation'
6+
import ThemeSwitch from '../components/ThemeSwitch'
67

78
class Header extends React.PureComponent {
8-
constructor(props) {
9-
super(props)
10-
11-
this.state = {
12-
sticky: false,
13-
}
14-
15-
this.handleScroll = this.handleScroll.bind(this)
9+
state = {
10+
sticky: false,
1611
}
1712

1813
componentDidMount() {
@@ -24,7 +19,7 @@ class Header extends React.PureComponent {
2419
}
2520

2621
// TODO: test this with SSR
27-
handleScroll(event) {
22+
handleScroll = (event) => {
2823
this.setState({
2924
sticky: window.pageYOffset > 0,
3025
})
@@ -36,6 +31,7 @@ class Header extends React.PureComponent {
3631
<Logo />
3732
<Breadcrumb />
3833
<Navigation />
34+
<ThemeSwitch />
3935
</header>
4036
)
4137
}

src/layouts/index.jsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@ import { HelmetProvider } from 'react-helmet-async'
33

44
import { Store } from '../store'
55
import Header from './Header'
6+
import Layout from './Layout'
67

78
const App = ({ children }) => (
89
<Store>
910
<HelmetProvider>
10-
<Header></Header>
11-
<main>{children}</main>
11+
<Layout>
12+
<Header></Header>
13+
<main>{children}</main>
14+
</Layout>
1215
</HelmetProvider>
1316
</Store>
1417
)

src/pages/writings.jsx

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { isDev } from '../environment'
66
import Link from '../components/Link'
77
import SEO from '../components/SEO'
88
import { History } from '../store'
9+
import Time from '../components/Time'
910

1011
const Page = ({
1112
pageContext: { breadcrumb },
@@ -40,11 +41,16 @@ const Page = ({
4041

4142
<div className="container container--medium">
4243
<div className="list">
43-
{edges.map(({ node }, index) => (
44-
<Link key={index} to={node.fields.slug}>
45-
<h2>{node.frontmatter.title}</h2>
46-
<p>{node.excerpt}</p>
47-
</Link>
44+
{edges.map(({ node: { frontmatter, fields, excerpt } }, index) => (
45+
<div className="item" key={index}>
46+
<Link to={fields.slug}>
47+
<header>
48+
<h2>{frontmatter.title}</h2>
49+
<Time date={frontmatter.created} />
50+
</header>
51+
<p>{excerpt}</p>
52+
</Link>
53+
</div>
4854
))}
4955
</div>
5056
</div>
@@ -65,6 +71,8 @@ export const pageQuery = graphql`
6571
node {
6672
frontmatter {
6773
title
74+
keywords
75+
created
6876
}
6977
fields {
7078
slug

src/storage.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
function setItem(key, data) {
2+
return new Promise((resolve, reject) => {
3+
if (!key || !data) {
4+
reject('No key or data provided!')
5+
}
6+
localStorage.setItem(key, JSON.stringify(data))
7+
resolve()
8+
})
9+
}
10+
11+
function getItem(key) {
12+
return new Promise((resolve, reject) => {
13+
if (!key) {
14+
reject('No key provided!')
15+
}
16+
let content = localStorage.getItem(key)
17+
content = JSON.parse(content)
18+
resolve(content)
19+
})
20+
}
21+
22+
function removeItem(key) {
23+
return new Promise((resolve, reject) => {
24+
if (!key) {
25+
reject('No key provided!')
26+
}
27+
localStorage.removeItem(key)
28+
resolve()
29+
})
30+
}
31+
32+
function clearAll() {
33+
return new Promise(resolve => {
34+
localStorage.clear()
35+
resolve()
36+
})
37+
}
38+
39+
const Storage = { setItem, getItem, removeItem, clearAll }
40+
export default Storage

src/store/index.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,16 @@
77

88
import React from 'react'
99

10-
import { Scheme } from './scheme'
10+
import { Theme } from './theme'
1111
import { History } from './history'
1212
import { Nav } from './nav'
1313

14-
const providers = [<Scheme.Provider />, <History.Provider />, <Nav.Provider />]
14+
const providers = [<Theme.Provider />, <History.Provider />, <Nav.Provider />]
1515

1616
const Store = ({ children: initial }) =>
1717
providers.reduce(
1818
(children, parent) => React.cloneElement(parent, { children }),
1919
initial
2020
)
2121

22-
export { Store, Scheme, History, Nav }
22+
export { Store, Theme, History, Nav }

0 commit comments

Comments
 (0)