Files
nxta-landing/src/components/blog/ArticleCard.astro

84 lines
2.3 KiB
Plaintext

---
import LucideIcon from "@/components/ui/lucide-icon.astro";
import { buttonVariants } from "@/components/ui/button";
import { cn } from "@/lib/utils";
import type { BlogArticle } from "@/lib/blog-types";
interface Props {
article: BlogArticle;
}
const { article } = Astro.props;
const categoryIds = article.categories.map((category) => category.id).join(",");
---
<article
class="blog-card group flex flex-col overflow-hidden rounded-2xl border border-transparent bg-card transition-colors hover:border-secondary/60"
data-categories={categoryIds}
data-title={article.title}
data-excerpt={article.excerpt}
>
<div class="relative aspect-[16/10] overflow-hidden">
{
article.imageUrl ? (
<img
src={article.imageUrl}
alt=""
class="h-full w-full object-cover transition-transform duration-300 group-hover:scale-105"
loading="lazy"
decoding="async"
/>
) : (
<div class="h-full w-full bg-muted" aria-hidden="true" />
)
}
</div>
<div class="flex flex-1 flex-col gap-3 p-5">
<div class="flex items-start justify-between gap-3">
<div class="flex min-w-0 flex-wrap gap-1.5">
{
article.categories.map((category) => (
<span class="rounded-full bg-background/70 px-3 py-1 text-xs font-medium text-primary backdrop-blur-sm">
{category.name}
</span>
))
}
</div>
<time
class="shrink-0 text-xs text-muted-foreground"
datetime={article.dateIso}
>
{article.date}
</time>
</div>
<h2 class="text-base font-bold leading-relaxed text-foreground">
{article.title}
</h2>
<p
class="line-clamp-3 flex-1 text-sm leading-relaxed text-muted-foreground"
>
{article.excerpt}
</p>
<div class="mt-2 flex items-center justify-between gap-3">
<span class="flex items-center gap-1.5 text-xs text-muted-foreground">
<LucideIcon name="clock" class="size-3.5" />
{article.readTime} دقیقه مطالعه
</span>
<a
href={article.href}
class={cn(
buttonVariants({ size: "sm" }),
"rounded-full px-4 py-1.5 text-xs",
)}
>
مطالعه مقاله
</a>
</div>
</div>
</article>