mirror of
https://gitlab.com/PronounsPage/PronounsPage.git
synced 2025-09-24 05:05:20 -04:00
(refactor) extract <BlogEntry> for a single thumbnail of a blog entry
This commit is contained in:
parent
be0a4ae61a
commit
15c20ea07c
@ -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>
|
||||
|
51
components/blog/BlogEntry.vue
Normal file
51
components/blog/BlogEntry.vue
Normal 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>
|
Loading…
x
Reference in New Issue
Block a user