master
 1---
 2import { siteConfig } from '@/config';
 3import { getCategoryUrl, getTagUrl } from '@utils/content-utils';
 4import { t } from '@utils/i18n';
 5import type { ImageMetadata } from 'astro';
 6import MetaList from './MetaList.astro';
 7import PostCardCover from './PostCardCover.astro';
 8import ReadMoreButton from './ReadMoreButton.astro';
 9
10interface Props {
11  class?: string;
12  title: string;
13  url: string;
14  published: Date;
15  tags: string[];
16  category?: string;
17  cover?: string | ImageMetadata;
18  description: string;
19}
20
21const { title, url, published, tags, category, cover } = Astro.props;
22const className = Astro.props.class;
23
24const hasCover = cover !== '' && cover !== undefined && cover !== null;
25
26interface MetaInfo {
27  text: string;
28  link?: string;
29  time?: Date;
30}
31
32const metas: (
33  | ({ icon: string; title?: string } & (MetaInfo | { group: MetaInfo[] }))
34  | undefined
35)[] = [
36  {
37    icon: 'material-symbols:calendar-clock-outline-rounded',
38    title: t.meta.publishedAt(),
39    text: published.toLocaleDateString(siteConfig.lang.replace('_', '-')),
40    time: published,
41  },
42  category
43    ? {
44        icon: 'material-symbols:category-outline-rounded',
45        title: t.meta.category(),
46        text: category,
47        link: getCategoryUrl(category),
48      }
49    : undefined,
50  tags.length > 0
51    ? {
52        icon: 'material-symbols:tag-rounded',
53        title: t.meta.tags(),
54        group: tags.map((tag) => ({
55          text: tag,
56          link: getTagUrl(tag),
57        })),
58      }
59    : undefined,
60];
61---
62
63<div
64  class:list={[
65    'card border-base-300 bg-base-200 flex w-full flex-col-reverse overflow-hidden border md:flex-row md:justify-between',
66    className,
67  ]}
68>
69  <div class="card-body">
70    <a href={url} class="card-title">{title}</a>
71    <MetaList class="text-base-content/60 mt-2 items-start text-sm" metas={metas} />
72  </div>
73  {
74    hasCover ? (
75      <div class="flex items-center justify-center md:h-48 md:w-3/4 md:max-w-96">
76        <PostCardCover url={url} title={title} cover={cover} />
77      </div>
78    ) : (
79      <ReadMoreButton href={url} title={title} />
80    )
81  }
82</div>