diff --git a/src/app/api/blogs/latest/route.ts b/src/app/api/blogs/latest/route.ts new file mode 100644 index 0000000..520f5c0 --- /dev/null +++ b/src/app/api/blogs/latest/route.ts @@ -0,0 +1,35 @@ +import { NextResponse } from "next/server"; + +import { getBlogPosts } from "@/lib/blogContent"; + +export const dynamic = "force-dynamic"; + +const DEFAULT_LIMIT = 7; +const MAX_LIMIT = 20; + +function parseLimit(rawLimit: string | null): number { + if (!rawLimit) { + return DEFAULT_LIMIT; + } + + const parsedLimit = Number.parseInt(rawLimit, 10); + if (!Number.isFinite(parsedLimit) || parsedLimit <= 0) { + return DEFAULT_LIMIT; + } + + return Math.min(parsedLimit, MAX_LIMIT); +} + +export async function GET(request: Request) { + const { searchParams } = new URL(request.url); + const limit = parseLimit(searchParams.get("limit")); + + const posts = await getBlogPosts(); + const latestPosts = posts.slice(0, limit).map((post) => ({ + slug: post.slug, + title: post.title, + date: post.date, + })); + + return NextResponse.json(latestPosts); +} diff --git a/src/app/page.tsx b/src/app/page.tsx index 8bc92de..ffecd06 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -70,10 +70,12 @@ export default function HomePage() {
-
+
- {t.signedIn.replace('{{username}}', user.username)} + {t.signedIn.replace("{{username}}", user.username)}
) : (
- {t.shortcuts.items.map((item, index: number) => { + {shortcutItems.map((item, index: number) => { const Icon = getIcon(item.title, Sparkles); return (
@@ -350,6 +395,12 @@ export function ShortcutsSection() { ); } +type LatestBlogPost = { + slug: string; + title: string; + date?: string; +}; + function LogoPill({ label }: { label: string }) { return (