From 2d20a5a1b1c8376a112d70ce5a654733079929d9 Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Sun, 19 Jul 2020 13:31:27 +0200 Subject: [PATCH] more refactor --- config.js | 4 +- content/articles/2012-08-07-projectpurple.md | 1 - gatsby-node.js | 36 +++++-- gatsby/createPages.js | 47 ++++++-- src/@types/Post.d.ts | 9 ++ src/components/atoms/Image.tsx | 13 ++- src/components/molecules/Featured.module.scss | 54 +--------- src/components/molecules/Featured.tsx | 21 ++-- .../molecules/Pagination.module.scss | 61 ++++++----- src/components/molecules/Pagination.tsx | 40 ++++--- .../molecules/PostTeaser.module.scss | 26 ++--- src/components/molecules/PostTeaser.tsx | 22 ++-- src/components/molecules/RelatedPosts.tsx | 8 +- src/components/organisms/Footer.tsx | 5 +- src/components/templates/Archive.module.scss | 38 ++----- src/components/templates/Archive.tsx | 100 ++++-------------- src/components/templates/Page.module.scss | 19 +++- src/components/templates/Page.tsx | 2 +- .../templates/Photos.module.scss} | 6 +- .../templates/Photos.test.tsx} | 12 ++- src/components/templates/Photos.tsx | 87 +++++++++++++++ src/components/templates/Post/Content.tsx | 2 +- src/components/templates/Post/Lead.tsx | 8 +- src/components/templates/Post/Meta.tsx | 2 +- src/components/templates/Post/Title.tsx | 21 ++-- src/components/templates/Post/index.tsx | 31 +++--- src/pages/index.module.scss | 42 +++++++- src/pages/index.tsx | 89 ++++++++-------- src/pages/photos.tsx | 73 ------------- 29 files changed, 451 insertions(+), 428 deletions(-) rename src/{pages/photos.module.scss => components/templates/Photos.module.scss} (72%) rename src/{pages/__tests__/photos.test.tsx => components/templates/Photos.test.tsx} (53%) create mode 100644 src/components/templates/Photos.tsx delete mode 100644 src/pages/photos.tsx diff --git a/config.js b/config.js index 16a4a567..d96b1812 100644 --- a/config.js +++ b/config.js @@ -19,11 +19,11 @@ module.exports = { rss: '/feed.xml', jsonfeed: '/feed.json', typekitID: 'msu4qap', - itemsPerPage: 20, + itemsPerPage: 18, repoContentPath: 'https://github.com/kremalicious/blog/tree/main/content', menu: [ { - title: 'Articles & Links', + title: 'Articles', link: '/archive' }, { diff --git a/content/articles/2012-08-07-projectpurple.md b/content/articles/2012-08-07-projectpurple.md index caf0462b..b6a1979b 100644 --- a/content/articles/2012-08-07-projectpurple.md +++ b/content/articles/2012-08-07-projectpurple.md @@ -5,7 +5,6 @@ title: Project Purple image: ../media/Teaser-Project-Purple.png download: ../media/project-purple-kremalicious.zip author: Matthias Kretschmann -featured: true date: 2012-08-07 13:15:44+00:00 diff --git a/gatsby-node.js b/gatsby-node.js index 532324a6..4bea24b3 100644 --- a/gatsby-node.js +++ b/gatsby-node.js @@ -3,7 +3,9 @@ const { createExif } = require('./gatsby/createExif') const { generatePostPages, generateTagPages, - generateRedirectPages + generateRedirectPages, + generateArchivePages, + generatePhotosPages } = require('./gatsby/createPages') const { generateJsonFeed } = require('./gatsby/feeds') @@ -19,12 +21,12 @@ exports.onCreateNode = ({ node, actions, getNode, createNodeId }) => { } } -exports.createPages = async ({ graphql, actions }) => { +exports.createPages = async ({ graphql, actions, reporter }) => { const { createPage, createRedirect } = actions const result = await graphql(` { - posts: allMarkdownRemark(sort: { order: DESC, fields: [fields___date] }) { + all: allMarkdownRemark(sort: { order: DESC, fields: [fields___date] }) { edges { next { fields { @@ -53,6 +55,16 @@ exports.createPages = async ({ graphql, actions }) => { } } + photos: allMarkdownRemark( + filter: { frontmatter: { type: { eq: "photo" } } } + ) { + edges { + node { + id + } + } + } + archive: allMarkdownRemark( filter: { frontmatter: { type: { ne: "photo" } } } ) { @@ -72,14 +84,24 @@ exports.createPages = async ({ graphql, actions }) => { } `) - if (result.errors) throw result.errors + if (result.errors) { + reporter.panicOnBuild(`Error while running GraphQL query.`) + return + } - const posts = result.data.posts.edges + const all = result.data.all.edges + const photosLength = result.data.photos.edges.length const archiveLength = result.data.archive.edges.length const tags = result.data.tags.group - // Generate posts & posts index - generatePostPages(createPage, posts, archiveLength) + // Generate post pages + generatePostPages(createPage, all) + + // Generate archive pages + generateArchivePages(createPage, archiveLength) + + // Generate archive pages + generatePhotosPages(createPage, photosLength) // Generate tag pages generateTagPages(createPage, tags) diff --git a/gatsby/createPages.js b/gatsby/createPages.js index 53e0721d..66aa6d0d 100644 --- a/gatsby/createPages.js +++ b/gatsby/createPages.js @@ -3,6 +3,7 @@ const { itemsPerPage } = require('../config') const postTemplate = path.resolve('src/components/templates/Post/index.tsx') const archiveTemplate = path.resolve('src/components/templates/Archive.tsx') +const photosTemplate = path.resolve('src/components/templates/Photos.tsx') const redirects = [ { f: '/feed', t: '/feed.xml' }, @@ -25,7 +26,7 @@ function getPaginationData(i, numPages, slug) { return { prevPagePath, nextPagePath, path } } -exports.generatePostPages = (createPage, posts, archiveLength) => { +exports.generatePostPages = (createPage, posts) => { // Create Post pages posts.forEach((post) => { createPage({ @@ -44,26 +45,56 @@ exports.generatePostPages = (createPage, posts, archiveLength) => { } }) }) +} +exports.generateArchivePages = (createPage, archiveLength) => { // Create paginated archive pages - const numPages = Math.ceil(archiveLength / itemsPerPage) - const slug = `/archive/` + const numPagesArchive = Math.ceil(archiveLength / itemsPerPage) + const slugArchive = `/archive/` - Array.from({ length: numPages }).forEach((_, i) => { + Array.from({ length: numPagesArchive }).forEach((_, i) => { const { prevPagePath, nextPagePath, path } = getPaginationData( i, - numPages, - slug + numPagesArchive, + slugArchive ) createPage({ path, component: archiveTemplate, context: { - slug, + slug: slugArchive, limit: itemsPerPage, skip: i * itemsPerPage, - numPages, + numPages: numPagesArchive, + currentPageNumber: i + 1, + prevPagePath, + nextPagePath + } + }) + }) +} + +exports.generatePhotosPages = (createPage, photosLength) => { + // Create paginated photos pages + const numPagesPhotos = Math.ceil(photosLength / itemsPerPage) + const slugPhotos = `/photos/` + + Array.from({ length: numPagesPhotos }).forEach((_, i) => { + const { prevPagePath, nextPagePath, path } = getPaginationData( + i, + numPagesPhotos, + slugPhotos + ) + + createPage({ + path, + component: photosTemplate, + context: { + slug: slugPhotos, + limit: itemsPerPage, + skip: i * itemsPerPage, + numPages: numPagesPhotos, currentPageNumber: i + 1, prevPagePath, nextPagePath diff --git a/src/@types/Post.d.ts b/src/@types/Post.d.ts index b6a302ab..517ba0e0 100644 --- a/src/@types/Post.d.ts +++ b/src/@types/Post.d.ts @@ -32,3 +32,12 @@ export interface Post { fileAbsolutePath?: string tableOfContents?: string } + +export interface PageContext { + tag?: string + slug: string + currentPageNumber: number + numPages: number + prevPagePath?: string + nextPagePath?: string +} diff --git a/src/components/atoms/Image.tsx b/src/components/atoms/Image.tsx index 9c1f7fa4..4ee509b2 100644 --- a/src/components/atoms/Image.tsx +++ b/src/components/atoms/Image.tsx @@ -33,7 +33,18 @@ export const imageSizeThumb = graphql` original { src } - fluid(maxWidth: 400, maxHeight: 170, quality: 85, cropFocus: CENTER) { + fluid(maxWidth: 420, maxHeight: 140, quality: 85, cropFocus: CENTER) { + ...GatsbyImageSharpFluid_withWebp_noBase64 + } + } +` + +export const photoSizeThumb = graphql` + fragment PhotoFluidThumb on ImageSharp { + original { + src + } + fluid(maxWidth: 300, maxHeight: 300, quality: 85, cropFocus: CENTER) { ...GatsbyImageSharpFluid_withWebp_noBase64 } } diff --git a/src/components/molecules/Featured.module.scss b/src/components/molecules/Featured.module.scss index cb2700f3..b58aac7c 100644 --- a/src/components/molecules/Featured.module.scss +++ b/src/components/molecules/Featured.module.scss @@ -2,59 +2,11 @@ @import 'mixins'; .featured { - @include divider; - display: grid; - gap: $spacer / 2; - grid-template-columns: 1fr 1fr; - padding-bottom: $spacer * $line-height; - margin-bottom: -($spacer / 2); + gap: $spacer; + grid-template-columns: repeat(2, 1fr); @media (min-width: $screen-md) { - @include breakoutviewport; - - gap: $spacer; - padding-bottom: $spacer * 3; - } -} - -.featuredTitle { - transition: 0.1s ease-out; - font-size: $font-size-base; - margin: 0; - position: absolute; - top: 25%; - min-width: 45%; - text-align: right; - padding: $spacer / 3; - background: rgba($link-color, 0.85); - color: #fff !important; - text-shadow: 0 1px 0 #000; - left: 0; - opacity: 0; - transform: translate3d(0, -20px, 0); -} - -.featuredItem { - position: relative; - - a { - display: block; - - &:hover, - &:focus { - .featuredTitle { - opacity: 1; - transform: translate3d(0, 0, 0); - } - } - } - - figure { - margin: 0; - } - - :global(.gatsby-image-wrapper) { - margin-bottom: 0; + grid-template-columns: repeat(3, 1fr); } } diff --git a/src/components/molecules/Featured.tsx b/src/components/molecules/Featured.tsx index e9542cad..fa33e5f7 100644 --- a/src/components/molecules/Featured.tsx +++ b/src/components/molecules/Featured.tsx @@ -1,8 +1,8 @@ import React, { ReactElement } from 'react' -import { Link, graphql, useStaticQuery } from 'gatsby' -import { Image } from '../atoms/Image' +import { graphql, useStaticQuery } from 'gatsby' import styles from './Featured.module.scss' import { Post } from '../../@types/Post' +import PostTeaser from './PostTeaser' const query = graphql` query { @@ -21,21 +21,12 @@ const query = graphql` export default function Featured(): ReactElement { const data = useStaticQuery(query) + return (
- {data.allMarkdownRemark.edges.map(({ node }: { node: Post }) => { - const { title, image } = node.frontmatter - const { slug } = node.fields - - return ( -
- - {title} -

{title}

- -
- ) - })} + {data.allMarkdownRemark.edges.map(({ node }: { node: Post }) => ( + + ))}
) } diff --git a/src/components/molecules/Pagination.module.scss b/src/components/molecules/Pagination.module.scss index de982858..4df41ec5 100644 --- a/src/components/molecules/Pagination.module.scss +++ b/src/components/molecules/Pagination.module.scss @@ -1,36 +1,47 @@ @import 'variables'; +@import 'mixins'; .pagination { - display: flex; - margin-top: $spacer * 2; + @include breakoutviewport; + + margin-top: $spacer * 3; margin-bottom: $spacer; - justify-content: space-between; - - > div { - &:first-child { - margin-right: $spacer; - } - - &:last-child { - margin-left: $spacer; - text-align: right; - } - } + display: flex; + justify-content: center; } .number { text-align: center; - width: 2rem; - height: 2rem; - line-height: 1.7; - display: inline-block; - border-radius: 50%; - border: 1px solid transparent; + padding: $spacer / 6 $spacer / 2; + border: 1px solid $brand-grey-dimmed; + font-variant-numeric: lining-nums; + margin-left: -1px; + display: flex; + align-items: center; + justify-content: center; + min-width: 2.5rem; + box-shadow: 0 1px 0 rgba(255, 255, 255, 0.8); + color: $brand-grey; + + :global(.dark) & { + color: $brand-grey-dimmed; + border-color: darken($body-background-color--dark, 5%); + box-shadow: 0 1px 0 rgba(255, 255, 255, 0.2); + } &:hover, &:focus { - background: rgba(255, 255, 255, 0.3); - border-color: darken($brand-grey-dimmed, 5%); + background: rgba(255, 255, 255, 0.1); + } + + &:first-child { + border-top-left-radius: $border-radius; + border-bottom-left-radius: $border-radius; + } + + &:last-child { + border-top-right-radius: $border-radius; + border-bottom-right-radius: $border-radius; } } @@ -38,10 +49,10 @@ composes: number; cursor: default; pointer-events: none; - border: 1px solid darken($brand-grey-dimmed, 5%); - color: $brand-grey-light; + color: $brand-grey-dimmed; + background: rgba(255, 255, 255, 0.1); :global(.dark) & { - border-color: darken($brand-grey-light, 15%); + color: $brand-grey-light; } } diff --git a/src/components/molecules/Pagination.tsx b/src/components/molecules/Pagination.tsx index d5b97657..d6d0eba3 100644 --- a/src/components/molecules/Pagination.tsx +++ b/src/components/molecules/Pagination.tsx @@ -2,6 +2,8 @@ import React, { ReactElement } from 'react' import { Link } from 'gatsby' import styles from './Pagination.module.scss' import shortid from 'shortid' +import { PageContext } from '../../@types/Post' +import Icon from '../atoms/Icon' const PageNumber = ({ i, @@ -34,8 +36,12 @@ function PrevNext({ const title = prevPagePath ? 'Newer Posts' : 'Older Posts' return ( - - {prevPagePath ? '←' : '→'} + + {prevPagePath ? ( + + ) : ( + + )} ) } @@ -43,13 +49,7 @@ function PrevNext({ export default function Pagination({ pageContext }: { - pageContext: { - slug: string - currentPageNumber: number - numPages: number - prevPagePath?: string - nextPagePath?: string - } + pageContext: PageContext }): ReactElement { const { slug, @@ -63,18 +63,16 @@ export default function Pagination({ return (
-
{!isFirst && }
-
- {Array.from({ length: numPages }, (_, i) => ( - - ))} -
-
{!isLast && }
+ {!isFirst && } + {Array.from({ length: numPages }, (_, i) => ( + + ))} + {!isLast && }
) } diff --git a/src/components/molecules/PostTeaser.module.scss b/src/components/molecules/PostTeaser.module.scss index e39503ba..9a6aafa4 100644 --- a/src/components/molecules/PostTeaser.module.scss +++ b/src/components/molecules/PostTeaser.module.scss @@ -1,25 +1,21 @@ @import 'variables'; @import 'mixins'; -.post { - figure { - margin: 0; - } -} - -.postTitle { - display: inline-block; - margin-top: $spacer / 4; - margin-bottom: 0; - font-size: $font-size-small; - line-height: $line-height-small; - color: $brand-grey-light; +.title { padding-left: 0.2rem; padding-right: 0.2rem; + color: $brand-grey-light; + margin-top: $spacer / 2; + margin-bottom: 0; + font-size: $font-size-base; transition: color 0.2s ease-out; +} - @media (min-width: $screen-md) { - font-size: $font-size-base; +.post { + display: block; + + figure { + margin: 0; } } diff --git a/src/components/molecules/PostTeaser.tsx b/src/components/molecules/PostTeaser.tsx index 477c4d60..393b08a7 100644 --- a/src/components/molecules/PostTeaser.tsx +++ b/src/components/molecules/PostTeaser.tsx @@ -1,20 +1,24 @@ import React, { ReactElement } from 'react' import { Link, graphql } from 'gatsby' import { Image } from '../atoms/Image' -import styles from './PostTeaser.module.scss' import { Post } from '../../@types/Post' +import PostTitle from '../templates/Post/Title' +import styles from './PostTeaser.module.scss' export const postTeaserQuery = graphql` fragment PostTeaser on MarkdownRemark { id fileAbsolutePath frontmatter { + type title + linkurl image { childImageSharp { ...ImageFluidThumb } } + tags } fields { slug @@ -29,7 +33,7 @@ export default function PostTeaser({ post: Partial toggleSearch?: () => void }): ReactElement { - const { image, title } = post.frontmatter + const { image, title, type } = post.frontmatter const { slug } = post.fields return ( @@ -38,12 +42,16 @@ export default function PostTeaser({ to={slug} onClick={toggleSearch && toggleSearch} > - {image ? ( - {title} - ) : ( -
+ {image && ( + {title} )} -

{title}

+ + ) } diff --git a/src/components/molecules/RelatedPosts.tsx b/src/components/molecules/RelatedPosts.tsx index ff0ff546..83c4e53d 100644 --- a/src/components/molecules/RelatedPosts.tsx +++ b/src/components/molecules/RelatedPosts.tsx @@ -47,16 +47,16 @@ function photosWithDataFilter(posts: []) { export default function RelatedPosts({ tags, - photos + isPhotos }: { tags: string[] - photos?: boolean + isPhotos?: boolean }): ReactElement { const data = useStaticQuery(query) const posts = data.allMarkdownRemark.edges function getPosts() { - return photos + return isPhotos ? photosWithDataFilter(posts) : tags && postsWithDataFilter(posts, 'tags', tags) } @@ -71,7 +71,7 @@ export default function RelatedPosts({ return (