import type { Metadata } from "next"; import Link from "next/link"; import { ArrowRight, ArrowUpRight, Rss, Sparkles } from "lucide-react"; import { SidebarShell } from "@/components/layout/sidebar-shell"; import { getCategoryCounts } from "@/lib/icons"; import postsData from "@/data/posts.json"; export const metadata: Metadata = { title: "Blog - Announcements & Updates", description: "Latest news, releases, and updates from theSVG. New icon collections, features, and developer resources.", keywords: [ "theSVG blog", "icon library updates", "SVG icon releases", "developer tools blog", "open source icons", ], openGraph: { title: "Blog | theSVG", description: "Latest updates from theSVG - the open SVG brand library.", siteName: "theSVG", }, alternates: { canonical: "https://thesvg.org/blog" }, }; interface Post { slug: string; title: string; excerpt: string; date: string; author: string; tags: string[]; } const TAG_COLORS: Record = { launch: { bg: "bg-emerald-500/10", text: "text-emerald-500", dot: "bg-emerald-500" }, release: { bg: "bg-blue-500/10", text: "text-blue-500", dot: "bg-blue-500" }, aws: { bg: "bg-[#ff9900]/10", text: "text-[#ff9900]", dot: "bg-[#ff9900]" }, azure: { bg: "bg-[#0078d4]/10", text: "text-[#0078d4]", dot: "bg-[#0078d4]" }, gcp: { bg: "bg-[#4285f4]/10", text: "text-[#4285f4]", dot: "bg-[#4285f4]" }, cloud: { bg: "bg-violet-500/10", text: "text-violet-500", dot: "bg-violet-500" }, milestone: { bg: "bg-amber-500/10", text: "text-amber-500", dot: "bg-amber-500" }, roadmap: { bg: "bg-rose-500/10", text: "text-rose-500", dot: "bg-rose-500" }, "open-source": { bg: "bg-green-500/10", text: "text-green-500", dot: "bg-green-500" }, }; const DEFAULT_TAG = { bg: "bg-muted/50", text: "text-muted-foreground", dot: "bg-muted-foreground" }; function formatDate(dateStr: string): string { const date = new Date(dateStr); const now = new Date(); const diffMs = now.getTime() - date.getTime(); const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24)); if (diffDays === 0) return "Today"; if (diffDays === 1) return "Yesterday"; if (diffDays < 7) return `${diffDays} days ago`; if (diffDays < 30) return `${Math.floor(diffDays / 7)} weeks ago`; return date.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" }); } export default function BlogPage() { const posts = (postsData as Post[]).sort( (a, b) => new Date(b.date).getTime() - new Date(a.date).getTime() ); const [featured, ...rest] = posts; return (
{/* Header */}
Updates

Blog

What we shipped, what we learned, and what is next

RSS
{/* Featured post - large card */} {featured && ( {/* Glow */}
{/* Badge */}
Latest

{featured.title}

{featured.excerpt}

{formatDate(featured.date)}
{featured.tags.map((tag) => { const colors = TAG_COLORS[tag] ?? DEFAULT_TAG; return ( {tag} ); })}
Read
)} {/* Timeline posts */} {rest.length > 0 && (
{/* Vertical timeline line */}
{rest.map((post, index) => ( {/* Timeline node */}
{String(rest.length - index).padStart(2, "0")}
{/* Content */}
{formatDate(post.date)}
{post.tags.slice(0, 3).map((tag) => { const colors = TAG_COLORS[tag] ?? DEFAULT_TAG; return ( {tag} ); })}

{post.title}

{post.excerpt}

Read post
))}
)} {/* Subscribe CTA */}

Stay in the loop

Follow our RSS feed or star us on GitHub for updates

); }