Product pages emit crawler-readable meta, public URLs use id plus Farsi slugs, and the homepage catalog matches the dashboard slot keys. Co-authored-by: Cursor <cursoragent@cursor.com>
39 lines
1.4 KiB
TypeScript
39 lines
1.4 KiB
TypeScript
import Link from "next/link";
|
|
import { getLatestPosts } from "@/lib/mappers";
|
|
import { Carousel } from "./Carousel";
|
|
import { Media } from "./Media";
|
|
|
|
export async function BlogCarousel() {
|
|
const posts = await getLatestPosts();
|
|
if (!posts.length) return null;
|
|
|
|
return (
|
|
<section className="container-site mt-14">
|
|
<div className="flex items-end justify-between mb-6">
|
|
<h2 className="section-title">آخرین مقالات</h2>
|
|
<Link href="/blog" className="text-sm text-brand">
|
|
همه مقالات
|
|
</Link>
|
|
</div>
|
|
<Carousel ariaLabel="مقالات">
|
|
{posts.map((post) => (
|
|
<Link
|
|
key={post.id || post.slug}
|
|
href={post.href || `/blog/${post.slug}`}
|
|
className="snap-start shrink-0 w-[240px] sm:w-[280px] rounded-2xl bg-white border border-black/5 overflow-hidden hover:border-brand/40"
|
|
>
|
|
<Media src={post.image} alt={post.title} className="aspect-[16/10]" sizes="280px" />
|
|
<div className="p-4">
|
|
<time className="text-xs text-zinc-400">{post.date}</time>
|
|
<h3 className="mt-2 text-sm leading-7 line-clamp-2">{post.title}</h3>
|
|
{post.abstract ? (
|
|
<p className="mt-1 text-xs leading-6 text-zinc-500 line-clamp-2">{post.abstract}</p>
|
|
) : null}
|
|
</div>
|
|
</Link>
|
|
))}
|
|
</Carousel>
|
|
</section>
|
|
);
|
|
}
|