Implement new articles and posts

This commit is contained in:
2024-11-26 20:01:01 +01:00
parent 2e8737322e
commit 4d203e5b5c
11 changed files with 175 additions and 52 deletions

View File

@@ -39,7 +39,10 @@ function getDetails() {
const like = likes > 1 ? t('likes.many') : t('likes.one')
const view = views > 1 ? t('views.many') : t('views.one')
return `${likes} ${like} · ${views} ${view}`
return {
likes: `${likes} ${like}`,
views: `${views} ${view}`,
}
}
const likeCookie = useCookie<boolean>(`post:like:${route.params.slug}`, {
@@ -79,20 +82,27 @@ async function handleLike() {
icon="i-ph-warning-duotone"
variant="outline"
/>
<p class="border-l-2 pl-2 border-gray-300 dark:border-gray-700 rounded-sm">
{{ getDetails() }}
</p>
<div class="border-l-2 pl-2 border-gray-300 dark:border-gray-700 rounded-sm flex gap-1 items-center">
<UIcon name="i-ph-heart-duotone" size="16" />
<p>{{ getDetails().likes }} </p>·
<UIcon name="i-ph-eye-duotone" size="16" />
<p>{{ getDetails().views }}</p>
</div>
<div class="mt-2">
<div class="flex items-end gap-2 flex-wrap">
<div class="flex items-end gap-4 flex-wrap">
<h1
class="font-bold text-3xl text-black dark:text-white"
>
{{ post.title }}
</h1>
<p class="text-sm text-neutral-500">
{{ useDateFormat(post.publishedAt, 'DD MMMM YYYY', { locales: currentLocale!.code ?? 'en' }).value }} ·
{{ post.readingTime }}min long
</p>
<div
class="text-sm text-neutral-500 duration-300 flex items-center gap-1"
>
<UIcon name="ph:calendar-duotone" size="16" />
<p>{{ useDateFormat(post.publishedAt, 'DD MMMM YYYY').value }} </p>·
<UIcon name="ph:timer-duotone" size="16" />
<p>{{ post.readingTime }}min long</p>
</div>
</div>
<p class="mt-4 text-base">
{{ post.description }}

View File

@@ -1,4 +1,6 @@
<script setup lang="ts">
import { type Tag, TAGS } from '~~/types'
const { t, locale } = useI18n({
useScope: 'local',
})
@@ -19,22 +21,18 @@ const { data: writings, refresh } = await useAsyncData('all-portfolio', () => qu
watch(tagFilter, async () => await refresh())
const tags = [{
label: 'All',
icon: 'i-ph-books-duotone',
}, {
label: 'Articles',
icon: 'i-ph-pencil-line-duotone',
tag: 'article',
}, {
label: 'Projects',
icon: 'i-ph-briefcase-duotone',
tag: 'project',
}]
const tags: Array<{ label: string, icon: string } & Tag> = [
{
label: 'All',
icon: 'i-ph-books-duotone',
color: 'black',
},
...TAGS,
]
function updateTag(index: number) {
const tag = tags[index]
tagFilter.value = tag?.label === 'All' ? undefined : tag?.tag
tagFilter.value = tag?.label.toLowerCase() === 'all' ? undefined : tag?.label.toLowerCase()
}
</script>
@@ -52,49 +50,49 @@ function updateTag(index: number) {
icon="i-ph-warning-duotone"
variant="outline"
/>
<UTabs :items="tags" @change="updateTag" />
<UTabs :items="tags" class="hidden md:block" @change="updateTag" />
<UTabs :items="tags" orientation="vertical" class="md:hidden" @change="updateTag" />
<ul class="grid grid-cols-1 md:grid-cols-2 gap-8">
<li
<NuxtLink
v-for="(writing, id) in writings"
:key="id"
class="border p-4 shadow-sm border-neutral-200 rounded-md hover:border-neutral-500 dark:border-neutral-700 dark:hover:border-neutral-500 duration-300"
:to="writing._path"
>
<NuxtLink
:to="writing._path"
<li
class=" h-full border p-4 shadow-sm border-neutral-200 rounded-md hover:border-neutral-500 dark:border-neutral-700 dark:hover:border-neutral-500 duration-300"
>
<article class="space-y-2">
<div class="flex gap-2 flex-col">
<h1
class="font-bold text-lg duration-300 text-black dark:text-white"
>
{{ writing.title }}
</h1>
<div
class="text-sm text-neutral-500 duration-300 flex items-center gap-1"
>
<UIcon name="ph:calendar-duotone" size="16" />
<p>{{ useDateFormat(writing.publishedAt, 'DD MMMM YYYY').value }} </p>·
<UIcon name="ph:timer-duotone" size="16" />
<p>{{ writing.readingTime }}min long</p>
</div>
<h1
class="font-bold text-lg duration-300 text-black dark:text-white"
>
{{ writing.title }}
</h1>
<div
class="text-sm text-neutral-500 duration-300 flex items-center gap-1"
>
<UIcon name="ph:calendar-duotone" size="16" />
<p>{{ useDateFormat(writing.publishedAt, 'DD MMMM YYYY').value }} </p>·
<UIcon name="ph:timer-duotone" size="16" />
<p>{{ writing.readingTime }}min long</p>
</div>
<h3>
{{ writing.description }}
</h3>
</article>
<div class="flex gap-2 mt-2 flex-wrap">
<div class="flex gap-2 mt-4 flex-wrap">
<UBadge
v-for="tag in writing.tags"
:key="tag"
color="gray"
:color="TAGS.find(color => color.label.toLowerCase() === tag)?.color || 'black'"
variant="soft"
size="md"
size="sm"
:ui="{ rounded: 'rounded-full' }"
>
{{ tag }}
{{ TAGS.find(color => color.label.toLowerCase() === tag)?.label }}
</UBadge>
</div>
</NuxtLink>
</li>
</li>
</NuxtLink>
</ul>
</main>
</template>