import Link from 'next/link' import type { ReactNode } from 'react' import type { BlogPost, BlogPagination } from '@startsimpli/api/blog' import { ArticleCard } from './ArticleCard' import { cn } from '../../utils/cn' export interface BlogIndexProps { posts: BlogPost[] pagination: BlogPagination /** Current page (1-based). */ page: number /** Route the index lives at, e.g. `/blog`. Used for card links + pagination. */ basePath?: string /** Resolve a post's image URL (pass the client's `getImageUrl`). */ getImageUrl?: (url?: string | null) => string /** Byline shown on each card (typically the site name). */ byline?: string /** Hero copy. */ eyebrow?: string title: string subtitle?: string /** Rendered in place of the grid when there are no posts. */ emptyState?: ReactNode className?: string } /** * Full blog index composer: hero + responsive card grid + windowed pagination. * Apps supply data + copy; everything is themed with shared tokens. Per-app * code reduces to fetching posts and rendering ``. */ export function BlogIndex({ posts, pagination, page, basePath = '/blog', getImageUrl, byline, eyebrow, title, subtitle, emptyState, className, }: BlogIndexProps) { const pageHref = (p: number) => (p <= 1 ? basePath : `${basePath}?page=${p}`) return (
{eyebrow && ( {eyebrow} )}

{title}

{subtitle &&

{subtitle}

}
{posts.length === 0 ? ( emptyState ?? (
No articles yet — check back soon.
) ) : ( <>
{posts.map((post) => ( ))}
{pagination.pageCount > 1 && (
{page > 1 && ( Previous )}
{Array.from({ length: pagination.pageCount }, (_, i) => i + 1) .filter((p) => p === 1 || p === pagination.pageCount || Math.abs(p - page) <= 1) .map((p, idx, arr) => { const prev = arr[idx - 1] const showEllipsis = prev && p - prev > 1 return ( {showEllipsis && } {p} ) })}
{page < pagination.pageCount && ( Next )}
)}
Showing {posts.length} of {pagination.total} articles
)}
) }