wip(org): Added blog index page
This commit is contained in:
parent
a23723c6b6
commit
8b7ea76325
2 changed files with 69 additions and 29 deletions
|
@ -1,43 +1,45 @@
|
|||
import Page from 'shared/components/wrappers/page.js'
|
||||
import useApp from 'site/hooks/useApp.js'
|
||||
import Link from 'next/link'
|
||||
import { posts } from 'site/prebuild/strapi.blog.en.js'
|
||||
import orderBy from 'lodash.orderby'
|
||||
import TimeAgo from 'react-timeago'
|
||||
import Head from 'next/head'
|
||||
import HelpUs from 'site/components/help-us.js'
|
||||
import { strapiHost } from 'shared/config/freesewing.mjs'
|
||||
import { strapiImage } from 'shared/utils.js'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||
|
||||
const strapi = "https://posts.freesewing.org"
|
||||
|
||||
const Preview = ({ app, post }) => (
|
||||
<div className="theme-gradient p-1 hover:p-0 hover:mb-1 hover:pointer transition-all">
|
||||
<div className="shadow rounded-lg">
|
||||
<Link href={`/blog/${post.slug}`}>
|
||||
<a title={post.title} className="hover:underline">
|
||||
<div className="bg-base-100 w-full aspect-video shadow flex flex-column items-end" style={{
|
||||
backgroundImage: `url(${strapi}${post.img})`,
|
||||
<div className="bg-base-100 w-full aspect-video shadow flex flex-column items-end rounded-lg" style={{
|
||||
backgroundImage: `url(${strapi}${post.image.sizes.medium.url})`,
|
||||
backgroundSize: 'cover',
|
||||
}}>
|
||||
<div className="grow"></div>
|
||||
<div className="text-right">
|
||||
<div className="text-right mb-8">
|
||||
<div className={`
|
||||
bg-neutral text-neutral-content
|
||||
bg-opacity-80
|
||||
px-4 text-right
|
||||
bg-opacity-90
|
||||
px-8 text-right
|
||||
py-4
|
||||
`}>
|
||||
<h5 className={`
|
||||
text-neutral-content
|
||||
text-xl font-normal
|
||||
md:text-2xl md:font-light
|
||||
xl:text-3xl
|
||||
`}>
|
||||
{post.title}
|
||||
</h5>
|
||||
<p className={`
|
||||
m-0 p-1 -mt-2
|
||||
text-neutral-content
|
||||
opacity-50
|
||||
leading-normal text-sm font-normal
|
||||
opacity-70
|
||||
`}>
|
||||
<TimeAgo date={post.date} /> by {post.author}
|
||||
<TimeAgo date={post.date} /> by <strong>{post.author}</strong>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -49,30 +51,50 @@ const Preview = ({ app, post }) => (
|
|||
|
||||
const BlogIndexPage = (props) => {
|
||||
const app = useApp()
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<Page app={app} title='FreeSewing Development Blog' slug='blog'>
|
||||
<Head>
|
||||
<meta property="og:title" content="FreeSewing Developers Blog" key="title" />
|
||||
<meta property="og:type" content="article" key='type' />
|
||||
<meta property="og:description" content="Content for developers and contributors alike. Strictly no sewing stuff" key='type' />
|
||||
<meta property="og:article:author" content='Joost De Cock' key='author' />
|
||||
<meta property="og:image" content="https://canary.backend.freesewing.org/og-img/en/dev/blog" key='image' />
|
||||
<meta property="og:image:type" content="image/png" />
|
||||
<meta property="og:image:width" content="1200" />
|
||||
<meta property="og:image:height" content="630" />
|
||||
<meta property="og:url" content="https://freesewing.dev/blog" key='url' />
|
||||
<meta property="og:locale" content="en_US" key='locale' />
|
||||
<meta property="og:site_name" content="freesewing.dev" key='site' />
|
||||
</Head>
|
||||
<Page app={app} title={t('blog')} slug='blog'>
|
||||
<div className="grid grid-cols-1 gap-4 lg:grid-cols-2">
|
||||
{Object.values(orderBy(posts, ['date'], ['desc']))
|
||||
.map(post => <Preview app={app} post={post} key={post.slug}/>)
|
||||
{props.posts.map(post => <Preview app={app} post={post} key={post.slug}/>)
|
||||
}
|
||||
</div>
|
||||
<HelpUs slug='/blog' />
|
||||
</Page>
|
||||
)
|
||||
}
|
||||
|
||||
export default BlogIndexPage
|
||||
|
||||
/*
|
||||
* getStaticProps() is used to fetch data at build-time.
|
||||
*
|
||||
* On this page, it is loading the blog content from strapi.
|
||||
*
|
||||
* This, in combination with getStaticPaths() below means this
|
||||
* page will be used to render/generate all blog content.
|
||||
*
|
||||
* To learn more, see: https://nextjs.org/docs/basic-features/data-fetching
|
||||
*/
|
||||
export async function getStaticProps({ params, locale }) {
|
||||
|
||||
const posts = await fetch(
|
||||
`${strapiHost}/blogposts?_locale=${locale}&_sort=date:DESC&dev_ne=true`
|
||||
)
|
||||
.then(response => response.json())
|
||||
.then(data => data)
|
||||
.catch(err => console.log(err))
|
||||
|
||||
return {
|
||||
props: {
|
||||
posts: posts.map(post => ({
|
||||
slug: post.slug,
|
||||
title: post.title,
|
||||
date: post.date,
|
||||
author: post.author.displayname,
|
||||
image: strapiImage(post.image, ['medium']),
|
||||
})),
|
||||
...(await serverSideTranslations(locale)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -76,3 +76,21 @@ export const optionType = option => {
|
|||
|
||||
export const capitalize = string => string.charAt(0).toUpperCase() + string.slice(1);
|
||||
|
||||
export const strapiImage = (img, sizes=['thumbnail', 'xlarge', 'large', 'medium', 'small', 'xsmall']) => {
|
||||
const image = {
|
||||
caption: img.caption,
|
||||
w: img.width,
|
||||
h: img.height,
|
||||
url: img.url,
|
||||
sizes: {}
|
||||
}
|
||||
for (const size of sizes) {
|
||||
if (img.formats[size]) image.sizes[size] = {
|
||||
w: img.formats[size].width,
|
||||
h: img.formats[size].width,
|
||||
url: img.formats[size].url,
|
||||
}
|
||||
}
|
||||
|
||||
return image
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue