Garrit Franke
3 years ago
8 changed files with 3399 additions and 9923 deletions
@ -1,278 +1,306 @@
|
||||
import Head from "next/head"; |
||||
|
||||
export default function Meta(props) { |
||||
return ( |
||||
<> |
||||
<Head> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1" /> |
||||
<meta charSet="utf-8" /> |
||||
<title>{props.siteTitle}</title> |
||||
<meta |
||||
name="Description" |
||||
content="Random thoughts, tips and rants about software" |
||||
></meta> |
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" /> |
||||
return ( |
||||
<> |
||||
<Head> |
||||
<meta |
||||
name="viewport" |
||||
content="width=device-width, initial-scale=1" |
||||
/> |
||||
<meta charSet="utf-8" /> |
||||
<title>{props.siteTitle}</title> |
||||
<meta |
||||
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> |
||||
{` |
||||
@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 { |
||||
list-style: none; |
||||
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; |
||||
} |
||||
} |
||||
{ |
||||
/* //TYPOGRAPHY------------------------------------- */ |
||||
} |
||||
h1, |
||||
h2, |
||||
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; |
||||
} |
||||
} |
||||
|
||||
{ |
||||
/* //TYPOGRAPHY------------------------------------- */ |
||||
} |
||||
h1, |
||||
h2, |
||||
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,
|
||||
// but here it apparently works. Maybe an overriding selector?
|
||||
.page__body a, |
||||
.page__footer a { |
||||
text-decoration: underline; |
||||
} |
||||
|
||||
// FIXME: I could not get this to work inside the post component,
|
||||
// but here it apparently works. Maybe an overriding selector?
|
||||
.blog__body a, |
||||
.blog__footer a { |
||||
text-decoration: underline; |
||||
} |
||||
@media (prefers-color-scheme: dark) { |
||||
:root { |
||||
background-color: #161618; |
||||
color: #dbd7db; |
||||
} |
||||
|
||||
@media (prefers-color-scheme: dark) { |
||||
:root { |
||||
background-color: #161618; |
||||
color: #dbd7db; |
||||
} |
||||
html { |
||||
scrollbar-color: #dbd7db #161618 !important; |
||||
} |
||||
|
||||
html { |
||||
scrollbar-color: #dbd7db #161618 !important; |
||||
} |
||||
h1, |
||||
h2, |
||||
h3, |
||||
h4, |
||||
p, |
||||
pre, |
||||
a, |
||||
ul, |
||||
li, |
||||
blog__body > * { |
||||
color: #dbd7db; |
||||
} |
||||
|
||||
h1, |
||||
h2, |
||||
h3, |
||||
h4, |
||||
p, |
||||
pre, |
||||
a, |
||||
ul, |
||||
li, |
||||
blog__body > * { |
||||
color: #dbd7db; |
||||
} |
||||
.button__link { |
||||
background-color: #67676c; |
||||
} |
||||
|
||||
.button__link { |
||||
background-color: #67676c; |
||||
} |
||||
a { |
||||
color: #dbd7db; |
||||
} |
||||
|
||||
a { |
||||
color: #dbd7db; |
||||
} |
||||
} |
||||
`}
|
||||
</style> |
||||
</> |
||||
); |
||||
|
||||
article a[href^="http"]::after, |
||||
article a[href^="https://"]::after { |
||||
filter: invert(100%); |
||||
} |
||||
} |
||||
|
||||
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 ReactMarkdown from "react-markdown"; |
||||
import Layout from "../../components/Layout"; |
||||
import Page from "../../components/Page"; |
||||
import glob from "glob"; |
||||
|
||||
export default function BlogTemplate(props) { |
||||
function reformatDate(fullDate) { |
||||
const date = new Date(fullDate); |
||||
return date.toDateString().slice(4); |
||||
} |
||||
function reformatDate(fullDate) { |
||||
const date = new Date(fullDate); |
||||
return date.toDateString().slice(4); |
||||
} |
||||
|
||||
/* |
||||
** Odd fix to get build to run |
||||
** It seems like on first go the props |
||||
** are undefined — could be a Next bug? |
||||
*/ |
||||
/* |
||||
** 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 <></>; |
||||
if (!props.frontmatter) return <></>; |
||||
|
||||
return ( |
||||
<Layout siteTitle={props.frontmatter.title}> |
||||
<article className="blog"> |
||||
<div className="blog__info"> |
||||
<h1>{props.frontmatter.title}</h1> |
||||
<h3>{reformatDate(props.frontmatter.date)}</h3> |
||||
</div> |
||||
<div className="blog__body"> |
||||
<ReactMarkdown source={props.markdownBody} /> |
||||
<p> |
||||
If you enjoyed this post, consider{" "} |
||||
<a href="https://donate.slashdev.space">buying me a coffee</a>! Got |
||||
comments? Send me a{" "} |
||||
<a href="mailto:garrit@slashdev.space"> |
||||
Mail |
||||
</a> |
||||
, or shoot me a message on{" "} |
||||
<a href="https://matrix.to/#/@garrit:matrix.slashdev.space"> |
||||
Matrix |
||||
</a> |
||||
. |
||||
</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> |
||||
); |
||||
return ( |
||||
<Page title={props.frontmatter.title}> |
||||
<ReactMarkdown |
||||
source={props.markdownBody} |
||||
date={props.frontmatter.date} |
||||
/> |
||||
<p> |
||||
If you enjoyed this post, consider{" "} |
||||
<a href="https://donate.slashdev.space">buying me a coffee</a>! |
||||
Got comments? Send me a{" "} |
||||
<a href="mailto:garrit@slashdev.space">Mail</a>, or shoot me a |
||||
message on{" "} |
||||
<a href="https://matrix.to/#/@garrit:matrix.slashdev.space"> |
||||
Matrix |
||||
</a> |
||||
. |
||||
</p> |
||||
<div className="blog__footer"> |
||||
<h2>Written By: Garrit Franke</h2> |
||||
</div> |
||||
</Page> |
||||
); |
||||
} |
||||
|
||||
export async function getStaticProps({ ...ctx }) { |
||||
const { post } = ctx.params; |
||||
const content = await import(`../../content/posts/${post}.md`); |
||||
const data = matter(content.default); |
||||
const { post } = ctx.params; |
||||
const content = await import(`../../content/posts/${post}.md`); |
||||
const data = matter(content.default); |
||||
|
||||
return { |
||||
props: { |
||||
siteTitle: "~/garrit", |
||||
frontmatter: data.data, |
||||
markdownBody: data.content, |
||||
}, |
||||
}; |
||||
return { |
||||
props: { |
||||
siteTitle: "~/garrit", |
||||
frontmatter: data.data, |
||||
markdownBody: data.content, |
||||
}, |
||||
}; |
||||
} |
||||
|
||||
export async function getStaticPaths() { |
||||
//get all .md files in the posts dir
|
||||
const blogs = glob.sync("content/posts/**/*.md"); |
||||
//get all .md files in the posts dir
|
||||
const blogs = glob.sync("content/posts/**/*.md"); |
||||
|
||||
//remove path and extension to leave filename only
|
||||
const blogSlugs = blogs.map((file) => |
||||
file.split("/")[2].replace(/ /g, "-").slice(0, -3).trim() |
||||
); |
||||
//remove path and extension to leave filename only
|
||||
const blogSlugs = blogs.map((file) => |
||||
file.split("/")[2].replace(/ /g, "-").slice(0, -3).trim() |
||||
); |
||||
|
||||
// create paths with `slug` param
|
||||
const paths = blogSlugs.map((slug) => `/posts/${slug}`); |
||||
// create paths with `slug` param
|
||||
const paths = blogSlugs.map((slug) => `/posts/${slug}`); |
||||
|
||||
return { |
||||
paths, |
||||
fallback: false, |
||||
}; |
||||
return { |
||||
paths, |
||||
fallback: false, |
||||
}; |
||||
} |
||||
|
Loading…
Reference in new issue