(refactor) extract <BlogEntry> for a single thumbnail of a blog entry

This commit is contained in:
Valentyne Stigloher 2025-01-01 22:50:26 +01:00
parent be0a4ae61a
commit 15c20ea07c
2 changed files with 53 additions and 47 deletions

View File

@ -1,8 +1,6 @@
<script setup lang="ts">
import Columnist from 'avris-columnist';
import type { RouteLocationRaw } from 'vue-router';
import useConfig from '~/composables/useConfig.ts';
import type { Post } from '~/server/blog.ts';
const props = defineProps<{
@ -24,25 +22,6 @@ const { data: postsFull } = useAsyncData(`posts-${JSON.stringify(props.posts)}`,
});
});
const config = useConfig();
const shortcuts: Record<string, string | undefined> = {};
if (config.blog && config.blog.shortcuts) {
for (const shortcut in config.blog.shortcuts) {
if (!config.blog.shortcuts.hasOwnProperty(shortcut)) {
continue;
}
shortcuts[config.blog.shortcuts[shortcut]] = shortcut;
}
}
const generateLink = (slug: string): RouteLocationRaw => {
const keepFullPath = config.blog?.keepFullPath || [];
return shortcuts[slug] !== undefined && !keepFullPath.includes(slug)
? `/${shortcuts[slug]}`
: { name: 'blogEntry', params: { slug } };
};
const entries = useTemplateRef<HTMLDivElement>('entries');
onMounted(async () => {
if (entries.value) {
@ -54,32 +33,8 @@ onMounted(async () => {
<template>
<div ref="entries" class="columnist-wall row">
<div v-for="post in postsFull" class="columnist-column col-12 col-sm-6 col-md-4 mb-3">
<div class="card shadow">
<nuxt-link v-if="post.hero" :to="generateLink(post.slug)">
<img :src="post.hero.src" :class="['w-100', post.hero.class]" :alt="post.hero.alt" loading="lazy">
</nuxt-link>
<nuxt-link :to="generateLink(post.slug)" class="card-body text-center h4 p-3 mb-0 post-title">
<Spelling :text="post.title" />
</nuxt-link>
<div v-if="details" class="card-footer small">
<ul class="list-inline mb-0">
<li class="list-inline-item small">
<Icon v="calendar" />
{{ post.date }}
</li>
<li v-for="author in post.authors" class="list-inline-item">
<nuxt-link v-if="author.startsWith('@')" :to="`/${author}`" class="badge bg-light text-dark border">
<Icon v="collective-logo.svg" class="invertible" />
{{ author }}
</nuxt-link>
<span v-else class="badge bg-light text-dark border">
{{ author }}
</span>
</li>
</ul>
</div>
</div>
<div v-for="post in postsFull" :key="post.slug" class="columnist-column col-12 col-sm-6 col-md-4 mb-3">
<BlogEntry :post :details />
</div>
</div>
</template>

View File

@ -0,0 +1,51 @@
<script setup lang="ts">
import type { RouteLocationRaw } from 'vue-router';
import useConfig from '~/composables/useConfig.ts';
import type { Post } from '~/server/blog.ts';
const props = defineProps<{
post: Post;
details?: boolean;
}>();
const config = useConfig();
const link = computed((): RouteLocationRaw => {
const shortcuts = config.blog?.shortcuts ?? {};
const keepFullPath = config.blog?.keepFullPath ?? [];
const shortcut = Object.entries(shortcuts)
.find(([_, slug]) => slug === props.post.slug);
return shortcut !== undefined && !keepFullPath.includes(props.post.slug)
? `/${shortcut[0]}`
: { name: 'blogEntry', params: { slug: props.post.slug } };
});
</script>
<template>
<div class="card shadow">
<nuxt-link v-if="post.hero" :to="link">
<img :src="post.hero.src" :class="['w-100', post.hero.class]" :alt="post.hero.alt" loading="lazy">
</nuxt-link>
<nuxt-link :to="link" class="card-body text-center h4 p-3 mb-0 post-title">
<Spelling :text="post.title" />
</nuxt-link>
<div v-if="details" class="card-footer small">
<ul class="list-inline mb-0">
<li class="list-inline-item small">
<Icon v="calendar" />
{{ post.date }}
</li>
<li v-for="author in post.authors" class="list-inline-item">
<nuxt-link v-if="author.startsWith('@')" :to="`/${author}`" class="badge bg-light text-dark border">
<Icon v="collective-logo.svg" class="invertible" />
{{ author }}
</nuxt-link>
<span v-else class="badge bg-light text-dark border">
{{ author }}
</span>
</li>
</ul>
</div>
</div>
</template>