1
0
Fork 0
This commit is contained in:
Matthias Kretschmann 2021-02-28 02:21:28 +01:00
parent 96f43a4fb0
commit 71feac2ea8
Signed by: m
GPG Key ID: 606EEEF3C479A91F
9 changed files with 250 additions and 23 deletions

View File

@ -19,7 +19,7 @@ module.exports = {
rss: '/feed.xml',
jsonfeed: '/feed.json',
typekitID: 'msu4qap',
itemsPerPage: 18,
itemsPerPage: 25,
repoContentPath: 'https://github.com/kremalicious/blog/tree/main/content',
menu: [
{

View File

@ -4,9 +4,8 @@
.title {
padding-left: 0.2rem;
padding-right: 0.2rem;
color: $brand-grey-light;
margin-top: $spacer / 2;
margin-bottom: 0;
margin-bottom: $spacer / 6;
font-size: $font-size-base;
transition: color 0.2s ease-out;
}
@ -19,18 +18,20 @@
}
}
.time {
font-style: italic;
font-size: $font-size-small;
color: $text-color-light;
}
.empty {
@include media-frame;
height: 100%;
min-height: 80px;
display: block;
min-height: 95px;
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAACaADAAQAAAABAAAACQAAAAAvQpmhAAAAHElEQVQYGWNgoBL4T8gcggoIGcBA0ASCCmhsBQBhFwX7u70C8QAAAABJRU5ErkJggg==);
a:hover & {
border-color: $link-color;
}
@media (min-width: $screen-md) {
min-height: 110px;
}
}

View File

@ -4,6 +4,7 @@ import { Image } from '../atoms/Image'
import { Post } from '../../@types/Post'
import PostTitle from '../templates/Post/Title'
import styles from './PostTeaser.module.scss'
import Time from '../atoms/Time'
export const postTeaserQuery = graphql`
fragment PostTeaser on MarkdownRemark {
@ -13,6 +14,7 @@ export const postTeaserQuery = graphql`
type
title
linkurl
updated
image {
childImageSharp {
...ImageFluidThumb
@ -22,6 +24,7 @@ export const postTeaserQuery = graphql`
}
fields {
slug
date
}
}
`
@ -33,8 +36,8 @@ export default function PostTeaser({
post: Partial<Post>
toggleSearch?: () => void
}): ReactElement {
const { image, title, type } = post.frontmatter
const { slug } = post.fields
const { image, title, type, updated } = post.frontmatter
const { slug, date } = post.fields
return (
<Link
@ -42,16 +45,23 @@ export default function PostTeaser({
to={slug}
onClick={toggleSearch && toggleSearch}
>
{image && (
{image ? (
<Image
title={type === 'photo' ? title : null}
fluid={image.childImageSharp.fluid}
alt={title}
original={image.childImageSharp.original}
/>
) : (
<span className={styles.empty} />
)}
<PostTitle slug={slug} title={title} className={styles.title} />
{date && (
<div className={styles.time}>
<Time date={date} />
</div>
)}
</Link>
)
}

View File

@ -11,3 +11,7 @@
grid-template-columns: repeat(2, 1fr);
}
}
.posts h1 {
font-size: $font-size-h3;
}

View File

@ -0,0 +1,39 @@
@import 'variables';
@import 'mixins';
.hentry {
@include divider;
margin-top: 0;
margin-bottom: 0;
padding-top: $spacer * 2;
padding-bottom: $spacer * 2;
:global(.gatsby-image-wrapper) {
max-height: 100vh;
}
@media (min-width: $screen-md) {
padding-top: $spacer * 4;
padding-bottom: $spacer * 4;
}
}
.archivetitle {
@include divider;
font-size: $font-size-h3;
margin-top: 0;
margin-bottom: 0;
padding-bottom: $spacer * $line-height;
span {
color: $brand-grey-light;
padding-right: $spacer / 12;
font-size: $font-size-base;
}
}
.paginationTitle {
composes: archivetitle;
}

View File

@ -0,0 +1,28 @@
import React from 'react'
import { render } from '@testing-library/react'
import { createHistory, createMemorySource } from '@reach/router'
import Posts from './Posts'
import data from '../../../jest/__fixtures__/posts.json'
describe('Post', () => {
const history = createHistory(createMemorySource('/photos'))
const pageContext = {
tag: 'hello',
slug: '/hello',
currentPageNumber: 2,
numPages: 20
}
it('renders without crashing', () => {
const { container } = render(
<Posts
data={data}
pageContext={pageContext}
location={history.location}
/>
)
expect(container.firstChild).toBeInTheDocument()
})
})

View File

@ -0,0 +1,123 @@
import React, { ReactElement } from 'react'
import { Link, graphql } from 'gatsby'
import { Post } from '../../@types/Post'
import Pagination from '../molecules/Pagination'
import Featured from '../molecules/Featured'
import PostTitle from './Post/Title'
import PostLead from './Post/Lead'
import PostContent from './Post/Content'
import PostMore from './Post/More'
import PostLinkActions from './Post/LinkActions'
import SEO from '../atoms/SEO'
import styles from './Posts.module.scss'
import { Image } from '../atoms/Image'
export default function Posts({
data,
location,
pageContext
}: {
data: any
location: Location
pageContext: {
tag: string
slug: string
currentPageNumber: number
numPages: number
}
}): ReactElement {
const edges = data.allMarkdownRemark.edges
const { tag, currentPageNumber, numPages } = pageContext
const PostsList = edges.map(({ node }: { node: Post }) => {
const { type, linkurl, title, image } = node.frontmatter
const { slug } = node.fields
return (
<article className={styles.hentry} key={node.id}>
{type !== 'photo' && (
<PostTitle type={type} slug={slug} linkurl={linkurl} title={title} />
)}
{image && (
<Link to={slug} title={title}>
<Image
title={type === 'photo' ? title : null}
fluid={image.childImageSharp.fluid}
alt={title}
original={image.childImageSharp.original}
/>
</Link>
)}
{type === 'post' && (
<>
<PostLead post={node} index />
<PostMore to={slug}>Continue Reading</PostMore>
</>
)}
{type === 'link' && (
<>
<PostContent post={node} />
<PostLinkActions slug={slug} linkurl={linkurl} />
</>
)}
</article>
)
})
return (
<>
<SEO />
{location.pathname === '/' && <Featured />}
{tag && (
<h1 className={styles.archivetitle}>
<span>#</span>
{tag}
</h1>
)}
{numPages > 1 && currentPageNumber > 1 && (
<h2
className={styles.paginationTitle}
>{`Page ${currentPageNumber} / ${numPages}`}</h2>
)}
{PostsList}
{numPages > 1 && <Pagination pageContext={pageContext} />}
</>
)
}
export const postsQuery = graphql`
query($tag: String, $skip: Int, $limit: Int) {
allMarkdownRemark(
filter: { frontmatter: { tags: { eq: $tag } } }
sort: { order: DESC, fields: [fields___date] }
skip: $skip
limit: $limit
) {
edges {
node {
id
html
excerpt(pruneLength: 250)
frontmatter {
title
type
linkurl
image {
childImageSharp {
...ImageFluid
}
}
tags
}
fields {
slug
date(formatString: "MMMM DD, YYYY")
}
}
}
}
}
`

View File

@ -24,11 +24,25 @@
}
}
.articles:first-of-type h1 {
font-size: $font-size-h3;
}
.articlesLast {
margin-top: $spacer * 1.5;
@media (min-width: $screen-sm) {
gap: $spacer * 1.5;
grid-template-columns: repeat(3, 1fr);
}
}
.photos {
grid-template-columns: repeat(2, 1fr);
@media (min-width: $screen-sm) {
grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
gap: $spacer * 1.5;
grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
}
}

View File

@ -1,26 +1,34 @@
import React, { ReactElement } from 'react'
import { graphql, PageProps } from 'gatsby'
import React, { ReactElement } from 'react'
import { Post } from '../@types/Post'
import styles from './index.module.scss'
import Featured from '../components/molecules/Featured'
import { PhotoThumb } from '../components/templates/Photos'
import SEO from '../components/atoms/SEO'
import PostTeaser from '../components/molecules/PostTeaser'
import { PhotoThumb } from '../components/templates/Photos'
import PostMore from '../components/templates/Post/More'
import styles from './index.module.scss'
export default function Home(props: PageProps): ReactElement {
return (
<>
<SEO />
<section className={styles.section}>
<h2 className={styles.title}>
Latest Articles <PostMore to="/archive">All Articles</PostMore>
</h2>
<div className={styles.articles}>
{(props.data as any).latestArticles.edges.map(
({ node }: { node: Post }) => (
{(props.data as any).latestArticles.edges
.slice(0, 2)
.map(({ node }: { node: Post }) => (
<PostTeaser key={node.id} post={node} />
)
)}
))}
</div>
<div className={`${styles.articles} ${styles.articlesLast}`}>
{(props.data as any).latestArticles.edges
.slice(2, 8)
.map(({ node }: { node: Post }) => (
<PostTeaser key={node.id} post={node} />
))}
</div>
</section>
@ -46,7 +54,7 @@ export const homeQuery = graphql`
latestArticles: allMarkdownRemark(
filter: { frontmatter: { type: { ne: "photo" } } }
sort: { order: DESC, fields: [fields___date] }
limit: 6
limit: 8
) {
edges {
node {
@ -58,7 +66,7 @@ export const homeQuery = graphql`
latestPhotos: allMarkdownRemark(
filter: { frontmatter: { type: { eq: "photo" } } }
sort: { order: DESC, fields: [fields___date] }
limit: 15
limit: 12
) {
edges {
node {