130 lines
3.2 KiB
TypeScript
130 lines
3.2 KiB
TypeScript
import { Link, graphql, PageProps } from 'gatsby'
|
||
import * as React from 'react'
|
||
import kebabCase from 'lodash/kebabCase'
|
||
import styled from 'styled-components'
|
||
|
||
import Layout from '../components/layout'
|
||
import Seo from '../components/seo'
|
||
|
||
import { Section } from '../components/shared'
|
||
import {
|
||
SectionHeading,
|
||
SectionDesc,
|
||
SolidButton
|
||
} from '../components/shared/styledComponents'
|
||
|
||
import Post from './postpreview'
|
||
import { SideBar } from './sidebar'
|
||
|
||
import type { PostNode, PageContext } from '../types'
|
||
|
||
interface BlogListData {
|
||
remark: {
|
||
posts: Array<{ post: PostNode }>
|
||
}
|
||
}
|
||
|
||
const BlogListTemplate: React.FC<PageProps<BlogListData, PageContext>> = ({
|
||
data,
|
||
location,
|
||
pageContext
|
||
}) => {
|
||
const posts = data.remark.posts
|
||
|
||
const iniPath: string =
|
||
pageContext.page === 'index'
|
||
? `/blog/`
|
||
: pageContext.page === 'year'
|
||
? `/${pageContext.year}/`
|
||
: pageContext.page === 'category'
|
||
? `/category/${kebabCase(pageContext.tag ?? '')}/`
|
||
: `/blog/`
|
||
|
||
const pageInfo = `Page ${pageContext.currentPage} of ${pageContext.numPages}`
|
||
const paginationJSX = Array.from(
|
||
{ length: pageContext.numPages ?? 0 },
|
||
(_, i) => i + 1
|
||
).map((pageIndex) => {
|
||
const link = pageIndex === 1 ? iniPath : `${iniPath}page/${pageIndex}`
|
||
return (
|
||
<Link
|
||
key={pageIndex}
|
||
to={link}
|
||
className={`btn btn-outline-dark btn-sm ${
|
||
pageIndex === pageContext.currentPage ? 'disabled' : ''
|
||
}`}
|
||
style={{
|
||
borderRadius: '50%',
|
||
padding: '.375rem .75rem',
|
||
margin: '0.25rem'
|
||
}}
|
||
>
|
||
{pageIndex}
|
||
</Link>
|
||
)
|
||
})
|
||
return (
|
||
<Layout
|
||
location={location}
|
||
heading="Data Controller’s Knowledge Base"
|
||
desc="A section dedicated to news, updates and educational pieces."
|
||
>
|
||
<Section color="black" bgColor="white" bottomArrow={false}>
|
||
<div className="row">
|
||
<div className="col-md-7">
|
||
<div className="row">
|
||
{posts.map(({ post }, i) => (
|
||
<Post key={i} post={post} />
|
||
))}
|
||
</div>
|
||
<span className="float-start">{paginationJSX}</span>
|
||
<span className="float-end">{pageInfo}</span>
|
||
</div>
|
||
<div className="col-md-5">
|
||
<SideBar pageContext={pageContext} location={location} />
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
</Layout>
|
||
)
|
||
}
|
||
|
||
export default BlogListTemplate
|
||
|
||
export const pageQuery = graphql`
|
||
query BlogListQuery(
|
||
$filter: MarkdownRemarkFilterInput!
|
||
$skip: Int!
|
||
$limit: Int!
|
||
) {
|
||
remark: allMarkdownRemark(
|
||
filter: $filter
|
||
limit: $limit
|
||
skip: $skip
|
||
sort: { frontmatter: { date: DESC } }
|
||
) {
|
||
posts: edges {
|
||
post: node {
|
||
html
|
||
fields {
|
||
slug
|
||
}
|
||
frontmatter {
|
||
title
|
||
date(formatString: "MMMM DD, YYYY")
|
||
author
|
||
authorLink
|
||
previewImg {
|
||
childImageSharp {
|
||
gatsbyImageData(layout: CONSTRAINED)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
`
|
||
|
||
export const Head = () => <Seo title="Blog" />
|