summaryrefslogtreecommitdiff
path: root/src/components/blog/ListItem.astro
blob: f078c25141687d1cb97c4333313c5f9fc7f2899c (plain)
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
---
import type { ImageMetadata } from 'astro';
import { Icon } from 'astro-icon/components';
import Image from '~/components/common/Image.astro';
import PostTags from '~/components/blog/Tags.astro';

import { APP_BLOG } from 'astrowind:config';
import type { Post } from '~/types';

import { getPermalink } from '~/utils/permalinks';
import { findImage } from '~/utils/images';
import { getFormattedDate } from '~/utils/utils';

export interface Props {
  post: Post;
}

const { post } = Astro.props;
const image = (await findImage(post.image)) as ImageMetadata | undefined;

const link = APP_BLOG?.post?.isEnabled ? getPermalink(post.permalink, 'post') : '';
---

<article
  class={`max-w-md mx-auto md:max-w-none grid gap-6 md:gap-8 intersect-once intersect-quarter motion-safe:md:opacity-0 motion-safe:md:intersect:animate-fade ${image ? 'md:grid-cols-2' : ''}`}
>
  {
    image &&
      (link ? (
        <a class="relative block group" href={link ?? 'javascript:void(0)'}>
          <div class="relative h-0 pb-[56.25%] md:pb-[75%] md:h-72 lg:pb-[56.25%] overflow-hidden bg-gray-400 dark:bg-slate-700 rounded shadow-lg">
            {image && (
              <Image
                src={image}
                class="absolute inset-0 object-cover w-full h-full mb-6 rounded shadow-lg bg-gray-400 dark:bg-slate-700"
                widths={[400, 900]}
                width={900}
                sizes="(max-width: 900px) 400px, 900px"
                alt={post.title}
                aspectRatio="16:9"
                loading="lazy"
                decoding="async"
              />
            )}
          </div>
        </a>
      ) : (
        <div class="relative h-0 pb-[56.25%] md:pb-[75%] md:h-72 lg:pb-[56.25%] overflow-hidden bg-gray-400 dark:bg-slate-700 rounded shadow-lg">
          {image && (
            <Image
              src={image}
              class="absolute inset-0 object-cover w-full h-full mb-6 rounded shadow-lg bg-gray-400 dark:bg-slate-700"
              widths={[400, 900]}
              width={900}
              sizes="(max-width: 900px) 400px, 900px"
              alt={post.title}
              aspectRatio="16:9"
              loading="lazy"
              decoding="async"
            />
          )}
        </div>
      ))
  }
  <div class="mt-2">
    <header>
      <div class="mb-1">
        <span class="text-sm">
          <Icon name="tabler:clock" class="w-3.5 h-3.5 inline-block -mt-0.5 dark:text-gray-400" />
          <time datetime={String(post.publishDate)} class="inline-block">{getFormattedDate(post.publishDate)}</time>
          {
            post.author && (
              <>
                {' '}
                · <Icon name="tabler:user" class="w-3.5 h-3.5 inline-block -mt-0.5 dark:text-gray-400" />
                <span>{post.author.replaceAll('-', ' ')}</span>
              </>
            )
          }
          {
            post.category && (
              <>
                {' '}
                ·{' '}
                <a class="hover:underline" href={getPermalink(post.category.slug, 'category')}>
                  {post.category.title}
                </a>
              </>
            )
          }
        </span>
      </div>
      <h2 class="text-xl sm:text-2xl font-bold leading-tight mb-2 font-heading dark:text-slate-300">
        {
          link ? (
            <a
              class="inline-block hover:text-primary dark:hover:text-secondary transition ease-in duration-200"
              href={link}
            >
              {post.title}
            </a>
          ) : (
            post.title
          )
        }
      </h2>
    </header>

    {post.excerpt && <p class="flex-grow text-muted dark:text-slate-400 text-lg">{post.excerpt}</p>}
    {
      post.tags && Array.isArray(post.tags) ? (
        <footer class="mt-5">
          <PostTags tags={post.tags} />
        </footer>
      ) : (
        <Fragment />
      )
    }
  </div>
</article>