1
0
Fork 0
blog/src/components/molecules/RelatedPosts.tsx

105 lines
2.4 KiB
TypeScript
Raw Normal View History

2021-03-01 00:36:51 +01:00
import React, { ReactElement, useState } from 'react'
2019-10-02 13:35:50 +02:00
import { graphql, useStaticQuery } from 'gatsby'
2023-01-29 22:58:19 +01:00
import { PhotoThumb } from '../templates/Photos'
2019-11-24 14:29:25 +01:00
import PostTeaser from './PostTeaser'
import * as styles from './RelatedPosts.module.css'
2019-10-02 13:35:50 +02:00
const query = graphql`
query RelatedPosts {
2022-11-19 23:00:38 +01:00
allArticles: allMarkdownRemark(
sort: { fields: { date: DESC } }
filter: { fields: { type: { regex: "/(article|link)/" } } }
) {
edges {
node {
...PostTeaser
}
}
}
allPhotos: allMarkdownRemark(
sort: { fields: { date: DESC } }
filter: { fields: { type: { eq: "photo" } } }
) {
2019-10-02 13:35:50 +02:00
edges {
node {
2019-11-24 14:29:25 +01:00
...PostTeaser
2019-10-02 13:35:50 +02:00
}
}
}
}
`
2019-10-16 01:45:30 +02:00
function postsWithDataFilter(
2022-11-19 23:00:38 +01:00
posts:
| Queries.RelatedPostsQuery['allArticles']['edges']
| Queries.RelatedPostsQuery['allPhotos']['edges'],
key: keyof Queries.MarkdownRemarkFrontmatter,
2019-10-16 01:45:30 +02:00
valuesToFind: string[]
) {
2022-11-19 23:00:38 +01:00
let filtered = posts.filter(({ node }) => {
const frontmatterKey = node.frontmatter[key]
2021-03-01 01:06:23 +01:00
2022-11-19 23:00:38 +01:00
if (
frontmatterKey !== null &&
frontmatterKey.some((r: string) => valuesToFind?.includes(r))
) {
return node
}
})
2019-10-02 13:35:50 +02:00
2022-11-19 23:00:38 +01:00
if (!filtered?.length) {
filtered = posts.filter(({ node }) => node)
}
2021-03-01 01:06:23 +01:00
2022-11-19 23:00:38 +01:00
filtered = filtered.sort(() => 0.5 - Math.random()).slice(0, 6)
2019-10-05 14:07:15 +02:00
2022-11-19 23:00:38 +01:00
return filtered
2019-10-05 14:07:15 +02:00
}
export default function RelatedPosts({
tags,
2020-07-19 13:31:27 +02:00
isPhotos
2019-10-05 14:07:15 +02:00
}: {
tags: string[]
2020-07-19 13:31:27 +02:00
isPhotos?: boolean
2020-05-22 14:38:19 +02:00
}): ReactElement {
const data = useStaticQuery<Queries.RelatedPostsQuery>(query)
2019-10-05 14:07:15 +02:00
function getPosts() {
2022-11-19 23:00:38 +01:00
const dataByType = isPhotos ? data.allPhotos.edges : data.allArticles.edges
const posts = postsWithDataFilter(dataByType, 'tags', tags)
return posts
2019-10-05 14:07:15 +02:00
}
2021-03-01 01:06:23 +01:00
const [filteredPosts, setFilteredPosts] = useState(getPosts())
2019-10-02 20:48:59 +02:00
function refreshPosts() {
2021-02-28 22:34:52 +01:00
const newPosts = getPosts()
2021-03-01 01:06:23 +01:00
setFilteredPosts(newPosts)
2019-10-02 20:48:59 +02:00
}
2019-10-02 13:35:50 +02:00
return (
2022-11-19 17:31:07 +01:00
<section className={styles.relatedPosts}>
<h1 className={styles.title}>
2020-07-19 13:31:27 +02:00
Related {isPhotos ? 'Photos' : 'Posts'}{' '}
<button className={styles.button} onClick={() => refreshPosts()}>
2019-11-11 01:00:26 +01:00
Refresh
</button>
</h1>
2019-10-02 13:35:50 +02:00
<ul>
{filteredPosts?.map(({ node }) => (
2021-02-28 22:34:52 +01:00
<li key={node.id}>
{isPhotos ? (
<PhotoThumb photo={node} />
) : (
<PostTeaser post={node} hideDate />
)}
</li>
))}
2019-10-02 13:35:50 +02:00
</ul>
2022-11-19 17:31:07 +01:00
</section>
2019-10-02 13:35:50 +02:00
)
}