Garrit Franke
3 years ago
8 changed files with 3399 additions and 9923 deletions
@ -1,278 +1,306 @@ |
|||||||
import Head from "next/head"; |
import Head from "next/head"; |
||||||
|
|
||||||
export default function Meta(props) { |
export default function Meta(props) { |
||||||
return ( |
return ( |
||||||
<> |
<> |
||||||
<Head> |
<Head> |
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" /> |
<meta |
||||||
<meta charSet="utf-8" /> |
name="viewport" |
||||||
<title>{props.siteTitle}</title> |
content="width=device-width, initial-scale=1" |
||||||
<meta |
/> |
||||||
name="Description" |
<meta charSet="utf-8" /> |
||||||
content="Random thoughts, tips and rants about software" |
<title>{props.siteTitle}</title> |
||||||
></meta> |
<meta |
||||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" /> |
name="Description" |
||||||
|
content="Random thoughts, tips and rants about software" |
||||||
|
></meta> |
||||||
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" /> |
||||||
|
|
||||||
<script async defer data-domain="blog.garrit.xyz" src="https://analytics.slashdev.space/js/plausible.js"></script> |
<script |
||||||
|
async |
||||||
|
defer |
||||||
|
data-domain="blog.garrit.xyz" |
||||||
|
src="https://analytics.slashdev.space/js/plausible.js" |
||||||
|
></script> |
||||||
|
</Head> |
||||||
|
<style jsx global> |
||||||
|
{` |
||||||
|
@import url("https://fonts.googleapis.com/css?family=Work+Sans&display=swap"); |
||||||
|
* { |
||||||
|
box-sizing: inherit; |
||||||
|
} |
||||||
|
html { |
||||||
|
box-sizing: border-box; |
||||||
|
overflow-y: scroll; |
||||||
|
} |
||||||
|
body { |
||||||
|
margin: 0; |
||||||
|
font-family: "Work Sans", "Helvetica Neue", Helvetica, |
||||||
|
sans-serif; |
||||||
|
overflow-x: hidden; |
||||||
|
color: #000; |
||||||
|
font-size: 16px; |
||||||
|
-webkit-font-smoothing: antialiased; |
||||||
|
-moz-osx-font-smoothing: grayscale; |
||||||
|
} |
||||||
|
a { |
||||||
|
text-decoration: none; |
||||||
|
color: inherit; |
||||||
|
transition: opacity 0.2s ease; |
||||||
|
} |
||||||
|
a:hover { |
||||||
|
transition: opacity 0.2s ease; |
||||||
|
opacity: 0.5; |
||||||
|
text-decoration-color: inherit; |
||||||
|
} |
||||||
|
ul { |
||||||
|
margin: 0; |
||||||
|
padding-bottom: 0; |
||||||
|
padding-left: 0; |
||||||
|
padding-right: 0; |
||||||
|
padding-top: 0; |
||||||
|
list-style-position: outside; |
||||||
|
list-style-image: none; |
||||||
|
} |
||||||
|
ol { |
||||||
|
margin: 0; |
||||||
|
padding-bottom: 0; |
||||||
|
padding-left: 0; |
||||||
|
padding-right: 0; |
||||||
|
padding-top: 0; |
||||||
|
list-style-position: outside; |
||||||
|
list-style-image: none; |
||||||
|
} |
||||||
|
ul, |
||||||
|
ol, |
||||||
|
p { |
||||||
|
margin-bottom: 1.45rem; |
||||||
|
} |
||||||
|
img { |
||||||
|
max-width: 100%; |
||||||
|
} |
||||||
|
img, |
||||||
|
figure, |
||||||
|
table, |
||||||
|
fieldset { |
||||||
|
margin-left: 0; |
||||||
|
margin-right: 0; |
||||||
|
margin-top: 0; |
||||||
|
padding-bottom: 0; |
||||||
|
padding-left: 0; |
||||||
|
padding-right: 0; |
||||||
|
padding-top: 0; |
||||||
|
margin-bottom: 1.45rem; |
||||||
|
} |
||||||
|
pre { |
||||||
|
margin-left: 0; |
||||||
|
margin-right: 0; |
||||||
|
margin-top: 0; |
||||||
|
margin-bottom: 1.45rem; |
||||||
|
font-size: 0.85rem; |
||||||
|
line-height: 1.42; |
||||||
|
background: hsla(0, 0%, 0%, 0.04); |
||||||
|
border-radius: 3px; |
||||||
|
overflow: auto; |
||||||
|
word-wrap: normal; |
||||||
|
padding: 1.45rem; |
||||||
|
} |
||||||
|
table { |
||||||
|
font-size: 1rem; |
||||||
|
line-height: 1.45rem; |
||||||
|
border-collapse: collapse; |
||||||
|
width: 100%; |
||||||
|
} |
||||||
|
blockquote { |
||||||
|
margin-left: 1.45rem; |
||||||
|
margin-right: 1.45rem; |
||||||
|
margin-top: 0; |
||||||
|
padding-bottom: 0; |
||||||
|
padding-left: 0; |
||||||
|
padding-right: 0; |
||||||
|
padding-top: 0; |
||||||
|
margin-bottom: 1.45rem; |
||||||
|
} |
||||||
|
strong { |
||||||
|
font-weight: bold; |
||||||
|
} |
||||||
|
li { |
||||||
|
margin-bottom: calc(1.45rem / 2); |
||||||
|
} |
||||||
|
ol li { |
||||||
|
padding-left: 0; |
||||||
|
} |
||||||
|
ul li { |
||||||
|
padding-left: 0; |
||||||
|
} |
||||||
|
li > ol { |
||||||
|
margin-left: 1.45rem; |
||||||
|
margin-bottom: calc(1.45rem / 2); |
||||||
|
margin-top: calc(1.45rem / 2); |
||||||
|
} |
||||||
|
li > ul { |
||||||
|
margin-left: 1.45rem; |
||||||
|
margin-bottom: calc(1.45rem / 2); |
||||||
|
margin-top: calc(1.45rem / 2); |
||||||
|
} |
||||||
|
blockquote *:last-child { |
||||||
|
margin-bottom: 0; |
||||||
|
} |
||||||
|
li *:last-child { |
||||||
|
margin-bottom: 0; |
||||||
|
} |
||||||
|
p *:last-child { |
||||||
|
margin-bottom: 0; |
||||||
|
} |
||||||
|
li > p { |
||||||
|
margin-bottom: calc(1.45rem / 2); |
||||||
|
} |
||||||
|
code { |
||||||
|
line-height: 1.45rem; |
||||||
|
} |
||||||
|
p code { |
||||||
|
background: hsla(0, 0%, 0%, 0.1); |
||||||
|
padding: 0 0.4rem; |
||||||
|
} |
||||||
|
@media (prefers-reduced-motion) { |
||||||
|
* { |
||||||
|
transition: none !important; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
</Head> |
{ |
||||||
<style jsx global> |
/* //TYPOGRAPHY------------------------------------- */ |
||||||
{` |
} |
||||||
@import url("https://fonts.googleapis.com/css?family=Work+Sans&display=swap"); |
h1, |
||||||
* { |
h2, |
||||||
box-sizing: inherit; |
h3, |
||||||
} |
h4, |
||||||
html { |
h5, |
||||||
box-sizing: border-box; |
h6, |
||||||
overflow-y: scroll; |
p { |
||||||
} |
font-family: "Work Sans", "Helvetica Neue", Helvetica, |
||||||
body { |
sans-serif; |
||||||
margin: 0; |
margin-left: 0; |
||||||
font-family: "Work Sans", "Helvetica Neue", Helvetica, sans-serif; |
margin-right: 0; |
||||||
overflow-x: hidden; |
margin-top: 0; |
||||||
color: #000; |
padding-bottom: 0; |
||||||
font-size: 16px; |
padding-left: 0; |
||||||
-webkit-font-smoothing: antialiased; |
padding-right: 0; |
||||||
-moz-osx-font-smoothing: grayscale; |
padding-top: 0; |
||||||
} |
margin-bottom: 1.45rem; |
||||||
a { |
color: inherit; |
||||||
text-decoration: none; |
text-rendering: optimizeLegibility; |
||||||
color: inherit; |
} |
||||||
transition: opacity 0.2s ease; |
h1, |
||||||
} |
h2 { |
||||||
a:hover { |
font-weight: 500; |
||||||
transition: opacity 0.2s ease; |
} |
||||||
opacity: 0.5; |
h1 { |
||||||
text-decoration-color: inherit; |
font-size: 2rem; |
||||||
} |
letter-spacing: -1px; |
||||||
ul { |
line-height: 1.1875; |
||||||
list-style: none; |
} |
||||||
margin: 0; |
h2 { |
||||||
padding-bottom: 0; |
font-size: 1.7rem; |
||||||
padding-left: 0; |
letter-spacing: -0.75px; |
||||||
padding-right: 0; |
line-height: 1.2; |
||||||
padding-top: 0; |
} |
||||||
list-style-position: outside; |
h3 { |
||||||
list-style-image: none; |
font-size: 1.2rem; |
||||||
} |
letter-spacing: -0.5px; |
||||||
ol { |
line-height: 1.1875; |
||||||
margin: 0; |
color: #a0a0a0; |
||||||
padding-bottom: 0; |
font-weight: normal; |
||||||
padding-left: 0; |
} |
||||||
padding-right: 0; |
p { |
||||||
padding-top: 0; |
font-size: 1.2rem; |
||||||
list-style-position: outside; |
letter-spacing: -0.5px; |
||||||
list-style-image: none; |
line-height: 1.5; |
||||||
} |
color: #464646; |
||||||
ul, |
} |
||||||
ol, |
@media (min-width: 1280px) { |
||||||
p { |
h1 { |
||||||
margin-bottom: 1.45rem; |
font-size: 2rem; |
||||||
} |
letter-spacing: -1px; |
||||||
img { |
line-height: 1.1875; |
||||||
max-width: 100%; |
} |
||||||
} |
h2 { |
||||||
img, |
font-size: 1.5rem; |
||||||
figure, |
letter-spacing: -0.75px; |
||||||
table, |
line-height: 1.1667; |
||||||
fieldset { |
} |
||||||
margin-left: 0; |
h3 { |
||||||
margin-right: 0; |
font-size: 1rem; |
||||||
margin-top: 0; |
letter-spacing: -0.5px; |
||||||
padding-bottom: 0; |
line-height: 1.1875; |
||||||
padding-left: 0; |
color: #a0a0a0; |
||||||
padding-right: 0; |
font-weight: normal; |
||||||
padding-top: 0; |
} |
||||||
margin-bottom: 1.45rem; |
p { |
||||||
} |
line-height: 1.4375; |
||||||
pre { |
} |
||||||
margin-left: 0; |
} |
||||||
margin-right: 0; |
|
||||||
margin-top: 0; |
|
||||||
margin-bottom: 1.45rem; |
|
||||||
font-size: 0.85rem; |
|
||||||
line-height: 1.42; |
|
||||||
background: hsla(0, 0%, 0%, 0.04); |
|
||||||
border-radius: 3px; |
|
||||||
overflow: auto; |
|
||||||
word-wrap: normal; |
|
||||||
padding: 1.45rem; |
|
||||||
} |
|
||||||
table { |
|
||||||
font-size: 1rem; |
|
||||||
line-height: 1.45rem; |
|
||||||
border-collapse: collapse; |
|
||||||
width: 100%; |
|
||||||
} |
|
||||||
blockquote { |
|
||||||
margin-left: 1.45rem; |
|
||||||
margin-right: 1.45rem; |
|
||||||
margin-top: 0; |
|
||||||
padding-bottom: 0; |
|
||||||
padding-left: 0; |
|
||||||
padding-right: 0; |
|
||||||
padding-top: 0; |
|
||||||
margin-bottom: 1.45rem; |
|
||||||
} |
|
||||||
strong { |
|
||||||
font-weight: bold; |
|
||||||
} |
|
||||||
li { |
|
||||||
margin-bottom: calc(1.45rem / 2); |
|
||||||
} |
|
||||||
ol li { |
|
||||||
padding-left: 0; |
|
||||||
} |
|
||||||
ul li { |
|
||||||
padding-left: 0; |
|
||||||
} |
|
||||||
li > ol { |
|
||||||
margin-left: 1.45rem; |
|
||||||
margin-bottom: calc(1.45rem / 2); |
|
||||||
margin-top: calc(1.45rem / 2); |
|
||||||
} |
|
||||||
li > ul { |
|
||||||
margin-left: 1.45rem; |
|
||||||
margin-bottom: calc(1.45rem / 2); |
|
||||||
margin-top: calc(1.45rem / 2); |
|
||||||
} |
|
||||||
blockquote *:last-child { |
|
||||||
margin-bottom: 0; |
|
||||||
} |
|
||||||
li *:last-child { |
|
||||||
margin-bottom: 0; |
|
||||||
} |
|
||||||
p *:last-child { |
|
||||||
margin-bottom: 0; |
|
||||||
} |
|
||||||
li > p { |
|
||||||
margin-bottom: calc(1.45rem / 2); |
|
||||||
} |
|
||||||
code { |
|
||||||
line-height: 1.45rem; |
|
||||||
} |
|
||||||
p code { |
|
||||||
background: hsla(0, 0%, 0%, 0.1); |
|
||||||
padding: 0 0.4rem; |
|
||||||
} |
|
||||||
@media (prefers-reduced-motion) { |
|
||||||
* { |
|
||||||
transition: none !important; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
{ |
// FIXME: I could not get this to work inside the post component,
|
||||||
/* //TYPOGRAPHY------------------------------------- */ |
// but here it apparently works. Maybe an overriding selector?
|
||||||
} |
.page__body a, |
||||||
h1, |
.page__footer a { |
||||||
h2, |
text-decoration: underline; |
||||||
h3, |
} |
||||||
h4, |
|
||||||
h5, |
|
||||||
h6, |
|
||||||
p { |
|
||||||
font-family: "Work Sans", "Helvetica Neue", Helvetica, sans-serif; |
|
||||||
margin-left: 0; |
|
||||||
margin-right: 0; |
|
||||||
margin-top: 0; |
|
||||||
padding-bottom: 0; |
|
||||||
padding-left: 0; |
|
||||||
padding-right: 0; |
|
||||||
padding-top: 0; |
|
||||||
margin-bottom: 1.45rem; |
|
||||||
color: inherit; |
|
||||||
text-rendering: optimizeLegibility; |
|
||||||
} |
|
||||||
h1, |
|
||||||
h2 { |
|
||||||
font-weight: 500; |
|
||||||
} |
|
||||||
h1 { |
|
||||||
font-size: 2rem; |
|
||||||
letter-spacing: -1px; |
|
||||||
line-height: 1.1875; |
|
||||||
} |
|
||||||
h2 { |
|
||||||
font-size: 1.7rem; |
|
||||||
letter-spacing: -0.75px; |
|
||||||
line-height: 1.2; |
|
||||||
} |
|
||||||
h3 { |
|
||||||
font-size: 1.2rem; |
|
||||||
letter-spacing: -0.5px; |
|
||||||
line-height: 1.1875; |
|
||||||
color: #a0a0a0; |
|
||||||
font-weight: normal; |
|
||||||
} |
|
||||||
p { |
|
||||||
font-size: 1.2rem; |
|
||||||
letter-spacing: -0.5px; |
|
||||||
line-height: 1.5; |
|
||||||
color: #464646; |
|
||||||
} |
|
||||||
@media (min-width: 1280px) { |
|
||||||
h1 { |
|
||||||
font-size: 2rem; |
|
||||||
letter-spacing: -1px; |
|
||||||
line-height: 1.1875; |
|
||||||
} |
|
||||||
h2 { |
|
||||||
font-size: 1.5rem; |
|
||||||
letter-spacing: -0.75px; |
|
||||||
line-height: 1.1667; |
|
||||||
} |
|
||||||
h3 { |
|
||||||
font-size: 1rem; |
|
||||||
letter-spacing: -0.5px; |
|
||||||
line-height: 1.1875; |
|
||||||
color: #a0a0a0; |
|
||||||
font-weight: normal; |
|
||||||
} |
|
||||||
p { |
|
||||||
line-height: 1.4375; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// FIXME: I could not get this to work inside the post component,
|
@media (prefers-color-scheme: dark) { |
||||||
// but here it apparently works. Maybe an overriding selector?
|
:root { |
||||||
.blog__body a, |
background-color: #161618; |
||||||
.blog__footer a { |
color: #dbd7db; |
||||||
text-decoration: underline; |
} |
||||||
} |
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) { |
html { |
||||||
:root { |
scrollbar-color: #dbd7db #161618 !important; |
||||||
background-color: #161618; |
} |
||||||
color: #dbd7db; |
|
||||||
} |
|
||||||
|
|
||||||
html { |
h1, |
||||||
scrollbar-color: #dbd7db #161618 !important; |
h2, |
||||||
} |
h3, |
||||||
|
h4, |
||||||
|
p, |
||||||
|
pre, |
||||||
|
a, |
||||||
|
ul, |
||||||
|
li, |
||||||
|
blog__body > * { |
||||||
|
color: #dbd7db; |
||||||
|
} |
||||||
|
|
||||||
h1, |
.button__link { |
||||||
h2, |
background-color: #67676c; |
||||||
h3, |
} |
||||||
h4, |
|
||||||
p, |
|
||||||
pre, |
|
||||||
a, |
|
||||||
ul, |
|
||||||
li, |
|
||||||
blog__body > * { |
|
||||||
color: #dbd7db; |
|
||||||
} |
|
||||||
|
|
||||||
.button__link { |
a { |
||||||
background-color: #67676c; |
color: #dbd7db; |
||||||
} |
} |
||||||
|
|
||||||
a { |
|
||||||
color: #dbd7db; |
article a[href^="http"]::after, |
||||||
} |
article a[href^="https://"]::after { |
||||||
} |
filter: invert(100%); |
||||||
`}
|
} |
||||||
</style> |
} |
||||||
</> |
|
||||||
); |
article a[href^="http"]::after, |
||||||
|
article a[href^="https://"]::after |
||||||
|
{ |
||||||
|
content: ""; |
||||||
|
width: 11px; |
||||||
|
height: 11px; |
||||||
|
margin-left: 4px; |
||||||
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M8.636 3.5a.5.5 0 0 0-.5-.5H1.5A1.5 1.5 0 0 0 0 4.5v10A1.5 1.5 0 0 0 1.5 16h10a1.5 1.5 0 0 0 1.5-1.5V7.864a.5.5 0 0 0-1 0V14.5a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h6.636a.5.5 0 0 0 .5-.5z'/%3E%3Cpath fill-rule='evenodd' d='M16 .5a.5.5 0 0 0-.5-.5h-5a.5.5 0 0 0 0 1h3.793L6.146 9.146a.5.5 0 1 0 .708.708L15 1.707V5.5a.5.5 0 0 0 1 0v-5z'/%3E%3C/svg%3E"); |
||||||
|
background-position: center; |
||||||
|
background-repeat: no-repeat; |
||||||
|
background-size: contain; |
||||||
|
display: inline-block; |
||||||
|
} |
||||||
|
`}
|
||||||
|
</style> |
||||||
|
</> |
||||||
|
); |
||||||
} |
} |
||||||
|
@ -0,0 +1,149 @@ |
|||||||
|
import Layout from "./Layout"; |
||||||
|
|
||||||
|
export default function Page(props) { |
||||||
|
const { title, date } = props; |
||||||
|
return ( |
||||||
|
<Layout siteTitle={title}> |
||||||
|
<article className="blog"> |
||||||
|
<div className="page__info"> |
||||||
|
<h1>{title}</h1> |
||||||
|
{ date && <h3>{ date }</h3> } |
||||||
|
</div> |
||||||
|
<div className="page__body"> |
||||||
|
{ props.children } |
||||||
|
</div> |
||||||
|
<div className="page__footer"> |
||||||
|
</div> |
||||||
|
</article> |
||||||
|
<style jsx> |
||||||
|
{` |
||||||
|
.page h1 { |
||||||
|
margin-bottom: 0.7rem; |
||||||
|
} |
||||||
|
.page__hero { |
||||||
|
min-height: 300px; |
||||||
|
height: 60vh; |
||||||
|
width: 100%; |
||||||
|
margin: 0; |
||||||
|
overflow: hidden; |
||||||
|
} |
||||||
|
.page__hero img { |
||||||
|
margin-bottom: 0; |
||||||
|
object-fit: cover; |
||||||
|
min-height: 100%; |
||||||
|
min-width: 100%; |
||||||
|
object-position: center; |
||||||
|
} |
||||||
|
.page__info { |
||||||
|
padding: 1.5rem 1.25rem; |
||||||
|
width: 100%; |
||||||
|
max-width: 768px; |
||||||
|
margin: 0 auto; |
||||||
|
} |
||||||
|
.page__info h1 { |
||||||
|
margin-bottom: 0.66rem; |
||||||
|
} |
||||||
|
.page__info h3 { |
||||||
|
margin-bottom: 0; |
||||||
|
} |
||||||
|
.page__body { |
||||||
|
width: 100%; |
||||||
|
padding: 0 1.25rem; |
||||||
|
margin: 0 auto; |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
justify-content: center; |
||||||
|
} |
||||||
|
.page__body a { |
||||||
|
text-decoration: underline; |
||||||
|
padding-bottom: 1.5rem; |
||||||
|
} |
||||||
|
.page__body:last-child { |
||||||
|
margin-bottom: 0; |
||||||
|
} |
||||||
|
.page__body h1 h2 h3 h4 h5 h6 p { |
||||||
|
font-weight: normal; |
||||||
|
} |
||||||
|
.page__body ul { |
||||||
|
list-style-type: circle; |
||||||
|
} |
||||||
|
.page__body ul ol { |
||||||
|
margin-left: 1.25rem; |
||||||
|
margin-bottom: 1.25rem; |
||||||
|
padding-left: 1.45rem; |
||||||
|
} |
||||||
|
.page__footer { |
||||||
|
display: flex; |
||||||
|
justify-content: space-between; |
||||||
|
align-items: center; |
||||||
|
padding: 1.5rem 1.25rem; |
||||||
|
width: 100%; |
||||||
|
max-width: 800px; |
||||||
|
margin: 0 auto; |
||||||
|
} |
||||||
|
.page__footer h2 { |
||||||
|
margin-bottom: 0; |
||||||
|
} |
||||||
|
.page__footer a { |
||||||
|
display: flex; |
||||||
|
justify-content: space-between; |
||||||
|
align-items: center; |
||||||
|
} |
||||||
|
.page__footer a svg { |
||||||
|
width: 20px; |
||||||
|
} |
||||||
|
@media (max-width: 768px) { |
||||||
|
.page__footer { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
} |
||||||
|
@media (min-width: 768px) { |
||||||
|
.page { |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
} |
||||||
|
.page__body { |
||||||
|
max-width: 800px; |
||||||
|
padding: 0 2rem; |
||||||
|
} |
||||||
|
.page__body span { |
||||||
|
width: 100%; |
||||||
|
margin: 1.5rem auto; |
||||||
|
} |
||||||
|
.page__body ul ol { |
||||||
|
margin-left: 1.5rem; |
||||||
|
margin-bottom: 1.5rem; |
||||||
|
} |
||||||
|
.page__hero { |
||||||
|
min-height: 600px; |
||||||
|
height: 75vh; |
||||||
|
} |
||||||
|
.page__info { |
||||||
|
text-align: center; |
||||||
|
padding: 2rem 0; |
||||||
|
} |
||||||
|
.page__info h1 { |
||||||
|
max-width: 500px; |
||||||
|
margin: 0 auto 0.66rem auto; |
||||||
|
} |
||||||
|
.page__footer { |
||||||
|
padding: 2.25rem; |
||||||
|
} |
||||||
|
} |
||||||
|
@media (min-width: 1440px) { |
||||||
|
.page__hero { |
||||||
|
height: 70vh; |
||||||
|
} |
||||||
|
.page__info { |
||||||
|
padding: 3rem 0; |
||||||
|
} |
||||||
|
.page__footer { |
||||||
|
padding: 2rem 2rem 3rem 2rem; |
||||||
|
} |
||||||
|
} |
||||||
|
`}
|
||||||
|
</style> |
||||||
|
</Layout> |
||||||
|
); |
||||||
|
} |
||||||
|
|
@ -0,0 +1,15 @@ |
|||||||
|
--- |
||||||
|
title: "A comprehensive list of projects that I want to build but probably never will" |
||||||
|
--- |
||||||
|
|
||||||
|
- A fork of [birdsite.live](https://github.com/NicolasConstant/BirdsiteLive) |
||||||
|
for instagram |
||||||
|
- Battle Royale App for habit tracking |
||||||
|
- Federated sports tracker ([somewhat in the making already](https://github.com/SamR1/FitTrackee/issues/16)) |
||||||
|
- C compiler for [uxn](https://wiki.xxiivv.com/site/uxn.html) (or |
||||||
|
[antimony](https://github.com/antimony-lang/antimony) backend?) |
||||||
|
- Turn this blog into my main website |
||||||
|
- Mirror this blog to [Gemini](https://gemini.circumlunar.space/) |
||||||
|
|
||||||
|
|
||||||
|
- [~~"todo" Page on website (this list)~~](/todo) |
@ -0,0 +1,51 @@ |
|||||||
|
import matter from "gray-matter"; |
||||||
|
import ReactMarkdown from "react-markdown"; |
||||||
|
import glob from "glob"; |
||||||
|
import Page from "../components/Page"; |
||||||
|
|
||||||
|
export default function PageTemplate(props) { |
||||||
|
/* |
||||||
|
** Odd fix to get build to run |
||||||
|
** It seems like on first go the props |
||||||
|
** are undefined — could be a Next bug? |
||||||
|
*/ |
||||||
|
if (!props.frontmatter) return <></>; |
||||||
|
|
||||||
|
return ( |
||||||
|
<Page title={props.frontmatter.title}> |
||||||
|
<ReactMarkdown source={props.markdownBody} /> |
||||||
|
</Page> |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
export async function getStaticProps({ ...ctx }) { |
||||||
|
const { page } = ctx.params; |
||||||
|
const content = await import(`../content/${page}.md`); |
||||||
|
const data = matter(content.default); |
||||||
|
|
||||||
|
return { |
||||||
|
props: { |
||||||
|
siteTitle: "~/garrit", |
||||||
|
frontmatter: data.data, |
||||||
|
markdownBody: data.content, |
||||||
|
}, |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
export async function getStaticPaths() { |
||||||
|
//get all .md files in the posts dir
|
||||||
|
const pages = glob.sync("content/*.md"); |
||||||
|
|
||||||
|
//remove path and extension to leave filename only
|
||||||
|
const pageSlugs = pages.map((file) => |
||||||
|
file.split("/")[1].replace(/ /g, "-").slice(0, -3).trim() |
||||||
|
); |
||||||
|
|
||||||
|
// create paths with `slug` param
|
||||||
|
const paths = pageSlugs.map((slug) => `/${slug}`); |
||||||
|
|
||||||
|
return { |
||||||
|
paths, |
||||||
|
fallback: false, |
||||||
|
}; |
||||||
|
} |
@ -1,208 +1,74 @@ |
|||||||
import matter from "gray-matter"; |
import matter from "gray-matter"; |
||||||
import ReactMarkdown from "react-markdown"; |
import ReactMarkdown from "react-markdown"; |
||||||
import Layout from "../../components/Layout"; |
import Page from "../../components/Page"; |
||||||
import glob from "glob"; |
import glob from "glob"; |
||||||
|
|
||||||
export default function BlogTemplate(props) { |
export default function BlogTemplate(props) { |
||||||
function reformatDate(fullDate) { |
function reformatDate(fullDate) { |
||||||
const date = new Date(fullDate); |
const date = new Date(fullDate); |
||||||
return date.toDateString().slice(4); |
return date.toDateString().slice(4); |
||||||
} |
} |
||||||
|
|
||||||
/* |
/* |
||||||
** Odd fix to get build to run |
** Odd fix to get build to run |
||||||
** It seems like on first go the props |
** It seems like on first go the props |
||||||
** are undefined — could be a Next bug? |
** are undefined — could be a Next bug? |
||||||
*/ |
*/ |
||||||
|
|
||||||
if (!props.frontmatter) return <></>; |
if (!props.frontmatter) return <></>; |
||||||
|
|
||||||
return ( |
return ( |
||||||
<Layout siteTitle={props.frontmatter.title}> |
<Page title={props.frontmatter.title}> |
||||||
<article className="blog"> |
<ReactMarkdown |
||||||
<div className="blog__info"> |
source={props.markdownBody} |
||||||
<h1>{props.frontmatter.title}</h1> |
date={props.frontmatter.date} |
||||||
<h3>{reformatDate(props.frontmatter.date)}</h3> |
/> |
||||||
</div> |
<p> |
||||||
<div className="blog__body"> |
If you enjoyed this post, consider{" "} |
||||||
<ReactMarkdown source={props.markdownBody} /> |
<a href="https://donate.slashdev.space">buying me a coffee</a>! |
||||||
<p> |
Got comments? Send me a{" "} |
||||||
If you enjoyed this post, consider{" "} |
<a href="mailto:garrit@slashdev.space">Mail</a>, or shoot me a |
||||||
<a href="https://donate.slashdev.space">buying me a coffee</a>! Got |
message on{" "} |
||||||
comments? Send me a{" "} |
<a href="https://matrix.to/#/@garrit:matrix.slashdev.space"> |
||||||
<a href="mailto:garrit@slashdev.space"> |
Matrix |
||||||
Mail |
</a> |
||||||
</a> |
. |
||||||
, or shoot me a message on{" "} |
</p> |
||||||
<a href="https://matrix.to/#/@garrit:matrix.slashdev.space"> |
<div className="blog__footer"> |
||||||
Matrix |
<h2>Written By: Garrit Franke</h2> |
||||||
</a> |
</div> |
||||||
. |
</Page> |
||||||
</p> |
); |
||||||
</div> |
|
||||||
<div className="blog__footer"> |
|
||||||
<h2>Written By: Garrit Franke</h2> |
|
||||||
</div> |
|
||||||
</article> |
|
||||||
<style jsx> |
|
||||||
{` |
|
||||||
.blog h1 { |
|
||||||
margin-bottom: 0.7rem; |
|
||||||
} |
|
||||||
.blog__hero { |
|
||||||
min-height: 300px; |
|
||||||
height: 60vh; |
|
||||||
width: 100%; |
|
||||||
margin: 0; |
|
||||||
overflow: hidden; |
|
||||||
} |
|
||||||
.blog__hero img { |
|
||||||
margin-bottom: 0; |
|
||||||
object-fit: cover; |
|
||||||
min-height: 100%; |
|
||||||
min-width: 100%; |
|
||||||
object-position: center; |
|
||||||
} |
|
||||||
.blog__info { |
|
||||||
padding: 1.5rem 1.25rem; |
|
||||||
width: 100%; |
|
||||||
max-width: 768px; |
|
||||||
margin: 0 auto; |
|
||||||
} |
|
||||||
.blog__info h1 { |
|
||||||
margin-bottom: 0.66rem; |
|
||||||
} |
|
||||||
.blog__info h3 { |
|
||||||
margin-bottom: 0; |
|
||||||
} |
|
||||||
.blog__body { |
|
||||||
width: 100%; |
|
||||||
padding: 0 1.25rem; |
|
||||||
margin: 0 auto; |
|
||||||
display: flex; |
|
||||||
flex-direction: column; |
|
||||||
justify-content: center; |
|
||||||
} |
|
||||||
.blog__body a { |
|
||||||
padding-bottom: 1.5rem; |
|
||||||
} |
|
||||||
.blog__body:last-child { |
|
||||||
margin-bottom: 0; |
|
||||||
} |
|
||||||
.blog__body h1 h2 h3 h4 h5 h6 p { |
|
||||||
font-weight: normal; |
|
||||||
} |
|
||||||
.blog__body ul { |
|
||||||
list-style: initial; |
|
||||||
} |
|
||||||
.blog__body ul ol { |
|
||||||
margin-left: 1.25rem; |
|
||||||
margin-bottom: 1.25rem; |
|
||||||
padding-left: 1.45rem; |
|
||||||
} |
|
||||||
.blog__footer { |
|
||||||
display: flex; |
|
||||||
justify-content: space-between; |
|
||||||
align-items: center; |
|
||||||
padding: 1.5rem 1.25rem; |
|
||||||
width: 100%; |
|
||||||
max-width: 800px; |
|
||||||
margin: 0 auto; |
|
||||||
} |
|
||||||
.blog__footer h2 { |
|
||||||
margin-bottom: 0; |
|
||||||
} |
|
||||||
.blog__footer a { |
|
||||||
display: flex; |
|
||||||
justify-content: space-between; |
|
||||||
align-items: center; |
|
||||||
} |
|
||||||
.blog__footer a svg { |
|
||||||
width: 20px; |
|
||||||
} |
|
||||||
@media (max-width: 768px) { |
|
||||||
.blog__footer { |
|
||||||
display: none; |
|
||||||
} |
|
||||||
} |
|
||||||
@media (min-width: 768px) { |
|
||||||
.blog { |
|
||||||
display: flex; |
|
||||||
flex-direction: column; |
|
||||||
} |
|
||||||
.blog__body { |
|
||||||
max-width: 800px; |
|
||||||
padding: 0 2rem; |
|
||||||
} |
|
||||||
.blog__body span { |
|
||||||
width: 100%; |
|
||||||
margin: 1.5rem auto; |
|
||||||
} |
|
||||||
.blog__body ul ol { |
|
||||||
margin-left: 1.5rem; |
|
||||||
margin-bottom: 1.5rem; |
|
||||||
} |
|
||||||
.blog__hero { |
|
||||||
min-height: 600px; |
|
||||||
height: 75vh; |
|
||||||
} |
|
||||||
.blog__info { |
|
||||||
text-align: center; |
|
||||||
padding: 2rem 0; |
|
||||||
} |
|
||||||
.blog__info h1 { |
|
||||||
max-width: 500px; |
|
||||||
margin: 0 auto 0.66rem auto; |
|
||||||
} |
|
||||||
.blog__footer { |
|
||||||
padding: 2.25rem; |
|
||||||
} |
|
||||||
} |
|
||||||
@media (min-width: 1440px) { |
|
||||||
.blog__hero { |
|
||||||
height: 70vh; |
|
||||||
} |
|
||||||
.blog__info { |
|
||||||
padding: 3rem 0; |
|
||||||
} |
|
||||||
.blog__footer { |
|
||||||
padding: 2rem 2rem 3rem 2rem; |
|
||||||
} |
|
||||||
} |
|
||||||
`}
|
|
||||||
</style> |
|
||||||
</Layout> |
|
||||||
); |
|
||||||
} |
} |
||||||
|
|
||||||
export async function getStaticProps({ ...ctx }) { |
export async function getStaticProps({ ...ctx }) { |
||||||
const { post } = ctx.params; |
const { post } = ctx.params; |
||||||
const content = await import(`../../content/posts/${post}.md`); |
const content = await import(`../../content/posts/${post}.md`); |
||||||
const data = matter(content.default); |
const data = matter(content.default); |
||||||
|
|
||||||
return { |
return { |
||||||
props: { |
props: { |
||||||
siteTitle: "~/garrit", |
siteTitle: "~/garrit", |
||||||
frontmatter: data.data, |
frontmatter: data.data, |
||||||
markdownBody: data.content, |
markdownBody: data.content, |
||||||
}, |
}, |
||||||
}; |
}; |
||||||
} |
} |
||||||
|
|
||||||
export async function getStaticPaths() { |
export async function getStaticPaths() { |
||||||
//get all .md files in the posts dir
|
//get all .md files in the posts dir
|
||||||
const blogs = glob.sync("content/posts/**/*.md"); |
const blogs = glob.sync("content/posts/**/*.md"); |
||||||
|
|
||||||
//remove path and extension to leave filename only
|
//remove path and extension to leave filename only
|
||||||
const blogSlugs = blogs.map((file) => |
const blogSlugs = blogs.map((file) => |
||||||
file.split("/")[2].replace(/ /g, "-").slice(0, -3).trim() |
file.split("/")[2].replace(/ /g, "-").slice(0, -3).trim() |
||||||
); |
); |
||||||
|
|
||||||
// create paths with `slug` param
|
// create paths with `slug` param
|
||||||
const paths = blogSlugs.map((slug) => `/posts/${slug}`); |
const paths = blogSlugs.map((slug) => `/posts/${slug}`); |
||||||
|
|
||||||
return { |
return { |
||||||
paths, |
paths, |
||||||
fallback: false, |
fallback: false, |
||||||
}; |
}; |
||||||
} |
} |
||||||
|
Loading…
Reference in new issue