65 lines
2.3 KiB
TypeScript
65 lines
2.3 KiB
TypeScript
import Image from "next/image";
|
|
import Link from "next/link";
|
|
import { GhostPost, postExcerpt, formatDate, readingTime } from "@/lib/ghost";
|
|
|
|
/** Shared cover: real Ghost feature image, or a branded fallback when null. */
|
|
function Cover({ post, sizes }: { post: GhostPost; sizes: string }) {
|
|
if (post.feature_image) {
|
|
return (
|
|
<Image
|
|
src={post.feature_image}
|
|
alt={post.feature_image_alt || post.title}
|
|
fill
|
|
className="img-cover"
|
|
sizes={sizes}
|
|
/>
|
|
);
|
|
}
|
|
return (
|
|
<div className="blog-card__placeholder" aria-hidden>
|
|
<span>{(post.primary_tag?.name || post.title).charAt(0)}</span>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function FeaturedBlogCard({ post }: { post: GhostPost }) {
|
|
return (
|
|
<Link href={`/blog/${post.slug}`} className="blog-feature">
|
|
<div className="blog-feature__media">
|
|
<Cover post={post} sizes="(max-width: 900px) 100vw, 640px" />
|
|
</div>
|
|
<div className="blog-feature__body">
|
|
{post.primary_tag && <span className="blog-tag">{post.primary_tag.name}</span>}
|
|
<h2 className="blog-feature__title">{post.title}</h2>
|
|
<p className="blog-feature__excerpt">{postExcerpt(post, 220)}</p>
|
|
<div className="blog-meta">
|
|
<span>{formatDate(post.published_at)}</span>
|
|
{readingTime(post) && <span className="blog-meta__dot">•</span>}
|
|
{readingTime(post) && <span>{readingTime(post)}</span>}
|
|
</div>
|
|
<span className="link-arrow link-arrow--spaced-lg">Read article</span>
|
|
</div>
|
|
</Link>
|
|
);
|
|
}
|
|
|
|
export function BlogCard({ post }: { post: GhostPost }) {
|
|
return (
|
|
<Link href={`/blog/${post.slug}`} className="blog-card">
|
|
<div className="blog-card__media">
|
|
<Cover post={post} sizes="(max-width: 640px) 100vw, 400px" />
|
|
{post.primary_tag && <span className="blog-tag blog-tag--float">{post.primary_tag.name}</span>}
|
|
</div>
|
|
<div className="blog-card__body">
|
|
<h3 className="blog-card__title">{post.title}</h3>
|
|
<p className="blog-card__excerpt">{postExcerpt(post)}</p>
|
|
<div className="blog-meta">
|
|
<span>{formatDate(post.published_at)}</span>
|
|
{readingTime(post) && <span className="blog-meta__dot">•</span>}
|
|
{readingTime(post) && <span>{readingTime(post)}</span>}
|
|
</div>
|
|
</div>
|
|
</Link>
|
|
);
|
|
}
|