75 lines
1.8 KiB
TypeScript
75 lines
1.8 KiB
TypeScript
import type { Metadata } from 'next';
|
|
import type { BlogPost } from './types';
|
|
import { blogPosts } from './blog-posts';
|
|
|
|
export const getAllPosts = (): BlogPost[] => blogPosts;
|
|
|
|
export const getPostBySlug = (slug: string): BlogPost | undefined =>
|
|
blogPosts.find((p) => p.slug === slug);
|
|
|
|
export const getPostsBySlugs = (slugs: string[]): BlogPost[] =>
|
|
slugs
|
|
.map((slug) => getPostBySlug(slug))
|
|
.filter((post): post is BlogPost => post !== undefined);
|
|
|
|
export const generatePostMetadata = (post: BlogPost): Metadata => ({
|
|
title: `${post.title} | Banatie Blog`,
|
|
description: post.description,
|
|
robots: 'index, follow',
|
|
|
|
alternates: {
|
|
canonical: `/blog/${post.slug}/`,
|
|
languages: {
|
|
en: `/blog/${post.slug}/`,
|
|
'x-default': `/blog/${post.slug}/`,
|
|
},
|
|
},
|
|
|
|
openGraph: {
|
|
type: 'article',
|
|
url: `/blog/${post.slug}/`,
|
|
title: post.title,
|
|
description: post.description,
|
|
siteName: 'Banatie',
|
|
locale: 'en_US',
|
|
images: [
|
|
{
|
|
url: post.heroImage,
|
|
width: 1200,
|
|
height: 630,
|
|
alt: post.title,
|
|
},
|
|
],
|
|
publishedTime: post.date,
|
|
authors: [post.author.name],
|
|
},
|
|
|
|
twitter: {
|
|
card: 'summary_large_image',
|
|
site: '@BanatieApp',
|
|
creator: '@BanatieApp',
|
|
title: post.title,
|
|
description: post.description,
|
|
images: [post.heroImage],
|
|
},
|
|
});
|
|
|
|
export const formatDate = (dateString: string): string => {
|
|
const date = new Date(dateString);
|
|
return date.toLocaleDateString('en-US', {
|
|
year: 'numeric',
|
|
month: 'long',
|
|
day: 'numeric',
|
|
});
|
|
};
|
|
|
|
export const getCategories = (): Record<string, number> => {
|
|
return blogPosts.reduce(
|
|
(acc, post) => {
|
|
acc[post.category] = (acc[post.category] || 0) + 1;
|
|
return acc;
|
|
},
|
|
{} as Record<string, number>
|
|
);
|
|
};
|