2023-04-09 15:57:25 +02:00
|
|
|
// Dependencies
|
|
|
|
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
2023-07-20 18:27:59 +02:00
|
|
|
import { pages as posts } from 'site/prebuild/blog.mjs'
|
|
|
|
import { meta } from 'site/prebuild/blog-meta.mjs'
|
2023-07-18 21:27:36 -06:00
|
|
|
import { getPostIndexPaths, getPostIndexProps } from 'site/components/mdx/posts/utils.mjs'
|
2023-08-08 10:17:01 +02:00
|
|
|
import { cloudflareImageUrl } from 'shared/utils.mjs'
|
2023-08-18 09:53:25 +02:00
|
|
|
import { nsMerge } from 'shared/utils.mjs'
|
2023-06-17 16:57:17 -05:00
|
|
|
// Hooks
|
|
|
|
import { useTranslation } from 'next-i18next'
|
2023-04-09 15:57:25 +02:00
|
|
|
// Components
|
2023-06-17 16:57:17 -05:00
|
|
|
import Link from 'next/link'
|
2023-08-18 09:53:25 +02:00
|
|
|
import { TimeAgo, ns as timeagoNs } from 'shared/components/timeago/index.mjs'
|
2023-04-09 15:57:25 +02:00
|
|
|
import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs'
|
2023-06-21 15:27:19 -05:00
|
|
|
import { Pagination } from 'shared/components/navigation/pagination.mjs'
|
2023-04-09 15:57:25 +02:00
|
|
|
|
|
|
|
// Translation namespaces used on this page
|
2023-08-18 09:53:25 +02:00
|
|
|
const namespaces = nsMerge('designs', 'sections', pageNs, timeagoNs)
|
2023-04-09 15:57:25 +02:00
|
|
|
|
2023-06-17 16:57:17 -05:00
|
|
|
const textShadow = {
|
|
|
|
style: {
|
|
|
|
textShadow:
|
|
|
|
'1px 1px 1px #000000, -1px -1px 1px #000000, 1px -1px 1px #000000, -1px 1px 1px #000000, 2px 2px 1px #000000',
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
const Preview = ({ post, t }) => (
|
|
|
|
<div className="shadow rounded-lg">
|
2023-07-17 20:10:08 -05:00
|
|
|
<Link href={`/${post.s}`} className="hover:underline">
|
2023-06-17 16:57:17 -05:00
|
|
|
<div
|
|
|
|
className="bg-base-100 w-full h-full overflow-hidden shadow flex flex-column items-center rounded-lg"
|
|
|
|
style={{
|
2023-08-08 10:17:01 +02:00
|
|
|
backgroundImage: `url(${cloudflareImageUrl({
|
|
|
|
id: post.s.replace('/', '-'),
|
|
|
|
variant: 'w500',
|
|
|
|
})})`,
|
2023-06-17 16:57:17 -05:00
|
|
|
backgroundSize: 'cover',
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
<div className="text-right my-2 w-full">
|
|
|
|
<div
|
|
|
|
className={`
|
|
|
|
bg-neutral text-neutral-content bg-opacity-40 text-right
|
|
|
|
px-4 py-1
|
|
|
|
lg:px-8 lg:py-4
|
|
|
|
|
|
|
|
`}
|
|
|
|
>
|
|
|
|
<h5
|
|
|
|
className={`
|
|
|
|
text-neutral-content
|
|
|
|
text-xl font-bold
|
|
|
|
md:text-2xl md:font-normal
|
|
|
|
xl:text-3xl
|
|
|
|
`}
|
|
|
|
{...textShadow}
|
|
|
|
>
|
2023-07-17 20:10:08 -05:00
|
|
|
{post.t}
|
2023-06-17 16:57:17 -05:00
|
|
|
</h5>
|
|
|
|
<p
|
|
|
|
className={`
|
|
|
|
hidden md:block
|
|
|
|
m-0 p-1 -mt-2
|
|
|
|
text-neutral-content
|
|
|
|
leading-normal text-sm font-normal
|
|
|
|
opacity-70
|
|
|
|
`}
|
|
|
|
{...textShadow}
|
|
|
|
>
|
2023-07-17 20:10:08 -05:00
|
|
|
<TimeAgo date={post.d} t={t} /> by <strong>{post.a}</strong>
|
2023-06-17 16:57:17 -05:00
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</Link>
|
|
|
|
</div>
|
|
|
|
)
|
2023-07-19 21:11:59 -06:00
|
|
|
|
2023-04-28 21:23:06 +02:00
|
|
|
/*
|
|
|
|
* Each page MUST be wrapped in the PageWrapper component.
|
|
|
|
* You also MUST spread props.page into this wrapper component
|
|
|
|
* when path and locale come from static props (as here)
|
|
|
|
* or set them manually.
|
|
|
|
*/
|
2023-06-22 16:27:08 -05:00
|
|
|
const BlogIndexPage = ({ posts, page, current, total }) => {
|
2023-06-17 16:57:17 -05:00
|
|
|
const { t } = useTranslation()
|
|
|
|
return (
|
2023-07-03 13:28:41 -05:00
|
|
|
<PageWrapper {...page} t={t('sections:blog')}>
|
2023-06-17 16:57:17 -05:00
|
|
|
<div className="grid grid-cols-1 gap-4 lg:grid-cols-2 xl:grid-cols-3 max-w-7xl lg:pr-4 xl:pr-6">
|
|
|
|
{posts.map((post) => (
|
2023-07-21 09:54:05 +02:00
|
|
|
<Preview post={post} t={t} key={post.s} />
|
2023-06-17 16:57:17 -05:00
|
|
|
))}
|
|
|
|
</div>
|
2023-06-22 16:27:08 -05:00
|
|
|
<Pagination {...{ current, total }} />
|
2023-06-17 16:57:17 -05:00
|
|
|
</PageWrapper>
|
|
|
|
)
|
|
|
|
}
|
2023-04-09 15:57:25 +02:00
|
|
|
|
2023-04-28 21:23:06 +02:00
|
|
|
export default BlogIndexPage
|
2023-04-09 15:57:25 +02:00
|
|
|
|
2023-07-19 21:11:59 -06:00
|
|
|
/*
|
|
|
|
* getStaticProps() is used to fetch data at build-time.
|
|
|
|
*
|
|
|
|
* On this page, it fetches data for the blogs to be linked to on this page
|
|
|
|
*
|
|
|
|
* This, in combination with getStaticPaths() below means this
|
|
|
|
* page will be used to link to all blogs.
|
|
|
|
*
|
|
|
|
* To learn more, see: https://nextjs.org/docs/basic-features/data-fetching
|
|
|
|
*/
|
2023-06-22 16:27:08 -05:00
|
|
|
export async function getStaticProps({ locale, params }) {
|
2023-07-20 18:27:59 +02:00
|
|
|
const props = getPostIndexProps(params.page, posts[locale], meta)
|
2023-07-17 20:10:08 -05:00
|
|
|
|
2023-07-19 21:11:59 -06:00
|
|
|
// if there shouldn't be a page with these params, return 404
|
2023-07-18 21:27:36 -06:00
|
|
|
if (props === false) return { notFound: true }
|
2023-06-22 16:27:08 -05:00
|
|
|
|
2023-04-09 15:57:25 +02:00
|
|
|
return {
|
|
|
|
props: {
|
2023-07-17 20:10:08 -05:00
|
|
|
// designs,
|
2023-07-18 21:27:36 -06:00
|
|
|
...props,
|
2023-04-09 15:57:25 +02:00
|
|
|
...(await serverSideTranslations(locale, namespaces)),
|
|
|
|
page: {
|
2023-04-28 21:23:06 +02:00
|
|
|
locale,
|
2023-07-18 21:27:36 -06:00
|
|
|
path: ['showcase'],
|
2023-04-09 15:57:25 +02:00
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
2023-06-22 16:27:08 -05:00
|
|
|
|
2023-07-19 21:11:59 -06:00
|
|
|
/*
|
|
|
|
* getStaticPaths() is used to specify for which routes (think URLs)
|
|
|
|
* this page should be used to generate the result.
|
|
|
|
*
|
|
|
|
* On this page, it is returning a truncated list of routes (think URLs) for pages that list and link to
|
|
|
|
* the mdx blog (markdown) content.
|
|
|
|
* That list comes from prebuild/blog-paths.mjs, which is built in the prebuild step
|
|
|
|
* and contains paths, titles, imageUrls, and intro for all blog posts.
|
|
|
|
*
|
|
|
|
* the fallback: 'blocking' property means that
|
|
|
|
* any pages that haven't been pre-generated
|
|
|
|
* will generate and cache the first time someone visits them
|
|
|
|
*
|
|
|
|
* To learn more, see: https://nextjs.org/docs/basic-features/data-fetching
|
|
|
|
*/
|
2023-06-22 16:27:08 -05:00
|
|
|
export const getStaticPaths = async () => {
|
|
|
|
return {
|
2023-07-20 18:27:59 +02:00
|
|
|
paths: getPostIndexPaths(posts, 'blog'),
|
2023-07-17 20:10:08 -05:00
|
|
|
fallback: 'blocking',
|
2023-06-22 16:27:08 -05:00
|
|
|
}
|
|
|
|
}
|