All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 2m54s
76 lines
2.6 KiB
TypeScript
76 lines
2.6 KiB
TypeScript
import fs from "fs";
|
|
import path from "path";
|
|
import Link from "next/link";
|
|
import { PageTransition } from "@/components/PageTransition";
|
|
import { Metadata } from "next";
|
|
import BackButton from "@/components/BackButton";
|
|
|
|
export const metadata: Metadata = {
|
|
title: "Blog",
|
|
description: "Read Asher Falcon's blog posts on software engineering, projects, and technology",
|
|
keywords: ["blog", "software engineering", "coding", "projects", "tech"],
|
|
};
|
|
|
|
const postsDirectory = path.join(process.cwd(), "src/app/blog/posts");
|
|
|
|
// Filter out system files and hidden files
|
|
const isValidPostDirectory = (dirname: string) => {
|
|
return !dirname.startsWith(".") && !dirname.includes(".DS_Store") && fs.statSync(path.join(postsDirectory, dirname)).isDirectory();
|
|
};
|
|
|
|
export async function generateStaticParams() {
|
|
const allFiles = fs.readdirSync(postsDirectory);
|
|
const postFolders = allFiles.filter(isValidPostDirectory);
|
|
return postFolders.map((slug) => ({ slug }));
|
|
}
|
|
|
|
type PostData = {
|
|
slug: string;
|
|
title: string;
|
|
description: string;
|
|
};
|
|
|
|
export default async function BlogPage() {
|
|
const allFiles = fs.readdirSync(postsDirectory);
|
|
const postFolders = allFiles.filter(isValidPostDirectory);
|
|
|
|
const posts = await Promise.all(
|
|
postFolders.map(async (slug): Promise<PostData | null> => {
|
|
try {
|
|
const { title, description } = await import(`./posts/${slug}/metadata.ts`);
|
|
return { slug, title, description };
|
|
} catch (error) {
|
|
console.error(`Error loading metadata for ${slug}:`, error);
|
|
return null;
|
|
}
|
|
})
|
|
);
|
|
|
|
// Filter out any posts that failed to load and reverse for newest first
|
|
const validPosts: PostData[] = posts.filter((post): post is PostData => post !== null).reverse();
|
|
|
|
return (
|
|
<PageTransition>
|
|
<div>
|
|
<div style={{paddingTop: "50px"}} className="relative flex justify-center items-center h-[50px]">
|
|
<div className="absolute left-0 flex items-center h-full ml-6">
|
|
<BackButton />
|
|
</div>
|
|
<span className="text-xl">Posts</span>
|
|
</div>
|
|
<div className="pt-[100px] md:w-[70%] xl:w-[50%] w-[85%] mx-auto">
|
|
<ul>
|
|
{validPosts.map(({ slug, title, description }) => (
|
|
<li key={slug} className="pb-4">
|
|
<Link href={`/blog/posts/${slug}`}>
|
|
<span className="text-xl">{title}</span>
|
|
<p className="line-clamp-2 blur-text">{description}</p>
|
|
</Link>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</PageTransition>
|
|
);
|
|
} |