84 lines
2.3 KiB
Plaintext
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>
|