summaryrefslogtreecommitdiff
path: root/src/components/blog/ListItem.astro
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/blog/ListItem.astro')
-rw-r--r--src/components/blog/ListItem.astro120
1 files changed, 120 insertions, 0 deletions
diff --git a/src/components/blog/ListItem.astro b/src/components/blog/ListItem.astro
new file mode 100644
index 0000000..6a416d6
--- /dev/null
+++ b/src/components/blog/ListItem.astro
@@ -0,0 +1,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-blue-700 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>