1
0
Fork 0
mirror of https://github.com/Unkn0wnCat/KevinK.dev.js.git synced 2025-05-25 14:56:33 +02:00

Add full blogging functionality

This commit is contained in:
Kevin Kandlbinder 2021-11-06 23:32:57 +00:00 committed by GitHub
parent bb7486635c
commit c8e8351b43
14 changed files with 557 additions and 178 deletions

View file

@ -105,11 +105,11 @@ const Navigation = ({ isHome }) => {
<Trans>social</Trans>
</Link>
<Link
id="navBtnScambox"
to="/scambox"
id="navBtnBlog"
to="/blog"
activeClassName={styles.active}
>
<Trans>scambox</Trans>
<Trans>blog.title</Trans>
</Link>
<div className={styles.hamburger}>
<Hamburger

View file

@ -48,11 +48,11 @@ const OffScreenNav = ({ active, close }) => {
<Trans>social</Trans>
</Link>
<Link
id="osnavBtnScambox"
to="/scambox"
id="osnavBtnBlog"
to="/blog"
activeClassName={styles.active}
>
<Trans>scambox</Trans>
<Trans>blog.title</Trans>
</Link>
</div>
</div>,

View file

@ -1,87 +0,0 @@
/* eslint-disable react/prop-types */
import { graphql } from "gatsby";
import { Link } from "gatsby-plugin-react-i18next";
import React from "react";
import { useTranslation } from "react-i18next";
import Layout from "../layouts/default";
import * as styles from "./scambox.module.scss";
const ScamBox = ({ data }) => {
const { t } = useTranslation();
return (
<Layout title={t("scambox")} description={t("scamboxDescription")}>
<section>
<article>
<h1>{t("scambox")}</h1>
<p>{t("scamboxDescription")}</p>
<div className={styles.list}>
{data.scambox.nodes.map((post) => {
return (
<Link
to={`/scambox/${post.childMdx.frontmatter.url}`}
key={post.childMdx.slug}
className={styles.post}
>
<span className={styles.title}>
{post.childMdx.frontmatter.title}
</span>
<span className={styles.meta}>
{t("scamboxPosted", {
date: post.childMdx.frontmatter
.published,
})}
</span>
<span className={styles.excerpt}>
{post.childMdx.excerpt}{" "}
<span>{t("scamboxReadFull")}</span>
</span>
</Link>
);
})}
</div>
<span className={styles.moreSoon}>{t("moreSoon")}</span>
</article>
</section>
</Layout>
);
};
export const query = graphql`
query ($language: String!) {
scambox: allFile(
filter: { sourceInstanceName: { eq: "scamboxContent" } }
sort: { fields: childMdx___frontmatter___published, order: DESC }
) {
nodes {
childMdx {
frontmatter {
platform
tags
title
url
published(formatString: "DD.MM.YYYY")
}
excerpt
}
}
}
locales: allLocale(filter: { language: { eq: $language } }) {
edges {
node {
ns
data
language
}
}
}
}
`;
export default ScamBox;

View file

@ -1,45 +0,0 @@
@import "../variables";
@import "../mixins";
.list {
display: flex;
flex-direction: column;
margin-top: $layoutPadding;
.post {
text-decoration: none;
display: flex;
flex-direction: column;
color: inherit;
padding: $layoutPadding;
border-bottom: thin dotted grey;
.title {
color: $accentColor;
font-size: 1.5em;
text-decoration: underline dotted currentColor;
}
.meta {
margin-bottom: 10px;
opacity: .5;
}
.excerpt {
margin-left: 10px;
> span {
color: $accentColor;
text-decoration: underline dotted currentColor;
}
}
}
}
.moreSoon {
display: block;
padding: $layoutPadding;
text-align: center;
opacity: .5;
}

View file

@ -0,0 +1,187 @@
/* eslint-disable react/prop-types */
import { graphql, Link as Link2 } from "gatsby";
import { StaticImage } from "gatsby-plugin-image";
import { Link } from "gatsby-plugin-react-i18next";
import React from "react";
import { useTranslation } from "react-i18next";
import Layout from "../layouts/default";
import * as styles from "./blogListing.module.scss";
const BlogListing = ({ data, pageContext }) => {
const { t } = useTranslation();
const title = t(`blog.section.${pageContext.section ?? "blog"}.name`);
const description = t(
`blog.section.${pageContext.section ?? "blog"}.description`
);
const hasSection = typeof pageContext.section !== "undefined";
return (
<Layout title={title} description={description}>
<section>
<article>
{hasSection && (
<Link to={"/blog"} className={styles.sectionBacklink}>
{t("blog.title")} /
</Link>
)}
<h1>{title}</h1>
<p>{description}</p>
{!hasSection && (
<>
<h2>Sections</h2>
<div className={styles.sectionList}>
<Link
className={styles.sectionCard}
to={"/blog/scambox"}
>
<div className={styles.sectionImage}>
<div className={styles.sectionBg}>
<StaticImage src="https://source.unsplash.com/gf8e6XvG_3E/300x150"></StaticImage>
</div>
<span className={styles.sectionName}>
Scambox
</span>
</div>
</Link>
</div>
</>
)}
<h2>Posts</h2>
<div className={styles.list}>
{data.posts.nodes.map((post) => {
return (
<Link2
to={`/${
post.childMdx.frontmatter.language
}/blog/${
post.childMdx.frontmatter.section
? post.childMdx.frontmatter
.section + "/"
: ""
}${
post.childMdx.frontmatter.urlPublished
}/${post.childMdx.frontmatter.url}`}
key={post.childMdx.slug}
className={styles.post}
>
<span className={styles.title}>
{post.childMdx.frontmatter.title}
</span>
<span className={styles.meta}>
{t("blog.meta", {
date: post.childMdx.frontmatter
.published,
author: post.childMdx.frontmatter
.author.name,
})}
{post.childMdx.frontmatter.section &&
!hasSection && (
<>
{" | "}
<Link
to={`/blog/${post.childMdx.frontmatter.section}`}
>
{t(
`blog.section.${post.childMdx.frontmatter.section}.name`
)}
</Link>
</>
)}
{" | "}
{t(
`language.${post.childMdx.frontmatter.language}.name`
)}
</span>
<span className={styles.excerpt}>
{post.childMdx.excerpt}{" "}
<span>{t("blog.readFull")}</span>
</span>
</Link2>
);
})}
</div>
<div className={styles.pageSwitcher}>
{pageContext.pageNumber > 0 ? (
<Link to={pageContext.previousPagePath}>
{t("blog.previous")}
</Link>
) : (
<span></span>
)}
<span>
{t("blog.page", {
page: pageContext.humanPageNumber,
maxPage: pageContext.numberOfPages,
})}
</span>
{pageContext.humanPageNumber <
pageContext.numberOfPages ? (
<Link to={pageContext.nextPagePath}>
{t("blog.next")}
</Link>
) : (
<span></span>
)}
</div>
</article>
</section>
</Layout>
);
};
export const query = graphql`
query ($language: String!, $skip: Int!, $limit: Int!, $section: String) {
posts: allFile(
filter: {
sourceInstanceName: { eq: "blogContent" }
childMdx: { frontmatter: { section: { eq: $section } } }
}
sort: { fields: childMdx___frontmatter___published, order: DESC }
limit: $limit
skip: $skip
) {
nodes {
childMdx {
frontmatter {
platform
tags
title
url
published(formatString: "DD.MM.YYYY")
urlPublished: published(formatString: "YYYY/MM")
section
language
author {
name
}
}
excerpt
}
}
}
locales: allLocale(filter: { language: { eq: $language } }) {
edges {
node {
ns
data
language
}
}
}
}
`;
export default BlogListing;

View file

@ -0,0 +1,109 @@
@import "../variables";
@import "../mixins";
.sectionBacklink {
display: block;
margin-top: 2rem;
margin-bottom: -2rem;
font-size: .8em;
text-decoration: none;
}
.sectionList {
@include flexList;
.sectionCard {
@include cardGeneric;
display: flex;
flex-direction: column;
position: relative;
.sectionImage {
width: 300px;
height: 150px;
background-position: center;
background-size: cover;
display: flex;
padding: 10px;
flex-direction: column-reverse;
text-shadow: 0 0 10px black, 0 0 10px black, 0 0 20px black;
color: white;
position: relative;
.sectionBg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 0;
}
.sectionName {
font-size: 2em;
margin-top: -5px;
z-index: 100;
}
}
}
}
.pageSwitcher {
display: flex;
margin-top: $layoutPadding;
>* {
width: 33%;
}
:nth-child(2) {
text-align: center;
}
:nth-child(3) {
text-align: right;
}
}
.list {
display: flex;
flex-direction: column;
margin-top: $layoutPadding;
.post {
text-decoration: none;
display: flex;
flex-direction: column;
color: inherit;
padding: $layoutPadding;
border-bottom: thin dotted grey;
.title {
color: $accentColor;
font-size: 1.5em;
text-decoration: underline dotted currentColor;
}
.meta {
margin-bottom: 10px;
opacity: .5;
}
.excerpt {
margin-left: 10px;
> span {
color: $accentColor;
text-decoration: underline dotted currentColor;
}
}
}
}
.moreSoon {
display: block;
padding: $layoutPadding;
text-align: center;
opacity: .5;
}

View file

@ -8,14 +8,15 @@ import Utterances from "utterances-react";
import Layout from "../layouts/default";
import * as styles from "./scamboxPost.module.scss";
import * as styles from "./blogPost.module.scss";
import { Link } from "gatsby-plugin-react-i18next";
const ScamBoxPost = ({ data }) => {
const { t, i18n } = useTranslation();
const BlogPost = ({ data }) => {
const { t } = useTranslation();
return (
<Layout
title={`${data.mdx.frontmatter.title} | ${t("scambox")}`}
title={`${data.mdx.frontmatter.title}`}
description={data.mdx.excerpt}
seoAdditional={
<script type="application/ld+json">
@ -28,13 +29,12 @@ const ScamBoxPost = ({ data }) => {
"https://example.com/photos/4x3/photo.jpg",
"https://example.com/photos/16x9/photo.jpg"
],*/
datePublished: data.mdx.publishedIso,
dateModified: data.mdx.publishedIso,
datePublished: data.mdx.frontmatter.publishedIso,
dateModified: data.mdx.frontmatter.publishedIso,
author: [
{
"@type": "Person",
name: "Kevin Kandlbinder",
url: "https://kevink.dev",
name: data.mdx.frontmatter.author.name,
},
],
})}
@ -47,11 +47,15 @@ const ScamBoxPost = ({ data }) => {
},
{
name: "article:published_time",
content: data.mdx.publishedIso,
content: data.mdx.frontmatter.publishedIso,
},
{
name: "article:section",
content: "Scambox",
content: t(
`blog.section.${
data.mdx.frontmatter.section ?? "blog"
}.name`
),
},
{
name: "keywords",
@ -63,17 +67,24 @@ const ScamBoxPost = ({ data }) => {
<article>
<h1>{data.mdx.frontmatter.title}</h1>
<span className={styles.meta}>
{t("scamboxPosted", {
{t("blog.meta", {
date: data.mdx.frontmatter.published,
author: data.mdx.frontmatter.author.name,
})}
</span>
{i18n.language !== "en" && (
<div className={styles.noticeBox}>
<b>{t("scamboxNotice")}</b>
<p>{t("scamboxLanguage")}</p>
</div>
)}
{data.mdx.frontmatter.section && (
<>
{" | "}
<Link
to={`/blog/${data.mdx.frontmatter.section}`}
>
{t(
`blog.section.${data.mdx.frontmatter.section}.name`
)}
</Link>
</>
)}
</span>
<MDXProvider components={{ Chat }}>
<MDXRenderer>{data.mdx.body}</MDXRenderer>
@ -81,7 +92,7 @@ const ScamBoxPost = ({ data }) => {
<Utterances
repo="Unkn0wnCat/KevinK.dev.js"
issueTerm={`Scambox-Comments: ${data.mdx.frontmatter.title}`}
issueTerm={`Blog-Comments: ${data.mdx.frontmatter.title}`}
theme="preferred-color-scheme"
label="comments"
style={{
@ -114,6 +125,10 @@ export const query = graphql`
title
published(formatString: "DD.MM.YYYY")
publishedIso: published(formatString: "")
author {
name
}
section
}
}
locales: allLocale(filter: { language: { eq: $language } }) {
@ -128,4 +143,4 @@ export const query = graphql`
}
`;
export default ScamBoxPost;
export default BlogPost;