src/components/BlogCard.astro (view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
--- import { Badge } from '@/components/ui/badge' import { Separator } from '@/components/ui/separator' import { formatDate, parseAuthors, readingTime } from '@/lib/utils' import { Image } from 'astro:assets' import type { CollectionEntry } from 'astro:content' import Link from './Link.astro' type Props = { entry: CollectionEntry<'blog'> } const { entry } = Astro.props as { entry: CollectionEntry<'blog'> } const formattedDate = formatDate(entry.data.date) const readTime = readingTime(entry.body) const authors = await parseAuthors(entry.data.authors ?? []) --- <div class="not-prose rounded-xl border p-4 transition-colors duration-300 ease-in-out hover:bg-secondary/50" > <Link href={`/${entry.collection}/${entry.slug}`} class="flex flex-col gap-4 sm:flex-row" > { entry.data.image && ( <div class="max-w-[200px] sm:flex-shrink-0"> <Image src={entry.data.image} alt={entry.data.title} width={1200} height={630} class="object-cover" /> </div> ) } <div class="flex-grow"> <h3 class="mb-1 text-lg font-semibold"> {entry.data.title} </h3> <p class="mb-2 text-sm text-muted-foreground"> {entry.data.description} </p> <div class="mb-2 flex flex-wrap items-center gap-x-2 text-xs text-muted-foreground" > <span>{formattedDate}</span> <Separator orientation="vertical" className="h-4" /> <span>{readTime}</span> </div> { entry.data.tags && ( <div class="flex flex-wrap gap-2"> {entry.data.tags.map((tag) => ( <Badge variant="secondary">{tag}</Badge> ))} </div> ) } </div> </Link> </div> |