mirror of
https://github.com/ArthurDanjou/artsite.git
synced 2026-01-25 19:52:36 +01:00
Implementing Drizzle to add views and like for post
This commit is contained in:
@@ -48,10 +48,10 @@ const ide = items.value!.filter(item => item.category === 'ide')
|
||||
size="xs"
|
||||
/>
|
||||
<li class="w-2/3 mx-auto">
|
||||
<NuxtImg
|
||||
<img
|
||||
alt="My IntelliJ IDE"
|
||||
src="/uses/jetbrains.png"
|
||||
/>
|
||||
>
|
||||
<p class="text-center text-sm mt-2 italic">
|
||||
My IntelliJ Idea Ultimate IDE
|
||||
</p>
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
<script lang="ts" setup>
|
||||
const route = useRoute()
|
||||
const { data: post } = await useAsyncData(`writing:${route.params.slug}`, () => queryContent(`/writings/${route.params.slug}`).findOne())
|
||||
const {
|
||||
data: postDB,
|
||||
refresh
|
||||
} = await useAsyncData(`writing:${route.params.slug}:db`, () => $fetch(`/api/posts/${route.params.slug}`, { method: 'POST' }))
|
||||
|
||||
function top() {
|
||||
window.scrollTo({
|
||||
@@ -18,10 +22,25 @@ const { copy, copied } = useClipboard({
|
||||
useHead({
|
||||
title: `${post.value!.title ?? 'Untitled'} | Arthur Danjou`
|
||||
})
|
||||
|
||||
function getDetails() {
|
||||
const likes = postDB.value?.likes ?? 0
|
||||
const views = postDB.value?.views ?? 0
|
||||
|
||||
const like = likes > 1 ? 'likes' : 'like'
|
||||
const view = views > 1 ? 'views' : 'view'
|
||||
|
||||
return `${likes} ${like} · ${views} ${view}`
|
||||
}
|
||||
|
||||
async function handleLike() {
|
||||
await $fetch(`/api/posts/like/${route.params.slug}`, { method: 'PUT' })
|
||||
await refresh()
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main v-if="post">
|
||||
<main v-if="post && postDB">
|
||||
<div class="flex">
|
||||
<NuxtLink
|
||||
class="flex items-center gap-2 mb-8 group text-sm hover:text-black dark:hover:text-white duration-300"
|
||||
@@ -35,21 +54,32 @@ useHead({
|
||||
Go back
|
||||
</NuxtLink>
|
||||
</div>
|
||||
<div class="mb-2 border-l-2 pl-2 border-gray-300 dark:border-gray-700 rounded-sm">
|
||||
{{ useDateFormat(post.publishedAt, 'DD MMMM YYYY').value }} - {{ post.readingTime }}min.
|
||||
<p class="border-l-2 pl-2 border-gray-300 dark:border-gray-700 rounded-sm">
|
||||
{{ getDetails() }}
|
||||
</p>
|
||||
<div>
|
||||
<div class="flex items-end gap-2">
|
||||
<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').value }} · {{ post.readingTime }}min long
|
||||
</p>
|
||||
</div>
|
||||
<p class="mt-4 text-base">
|
||||
{{ post.description }}
|
||||
</p>
|
||||
</div>
|
||||
<AppTitle
|
||||
:description="post.description"
|
||||
:title="post.title ?? 'Untitled'"
|
||||
/>
|
||||
<div
|
||||
v-if="post.cover"
|
||||
class="w-full rounded-md my-8"
|
||||
>
|
||||
<NuxtImg
|
||||
<img
|
||||
:src="`/writings/${post.cover}`"
|
||||
alt="Writing cover"
|
||||
/>
|
||||
>
|
||||
</div>
|
||||
<UDivider
|
||||
class="mt-8"
|
||||
@@ -72,6 +102,15 @@ useHead({
|
||||
forget to leave a like!</strong>
|
||||
</p>
|
||||
<div class="flex gap-4 items-center">
|
||||
<UButton
|
||||
v-if="postDB.likes"
|
||||
:label="postDB?.likes > 1 ? `${postDB?.likes} likes` : `${postDB?.likes} like`"
|
||||
color="red"
|
||||
icon="i-ph-heart-duotone"
|
||||
size="lg"
|
||||
variant="outline"
|
||||
@click.prevent="handleLike()"
|
||||
/>
|
||||
<UButton
|
||||
color="white"
|
||||
icon="i-ph-arrow-fat-lines-up-duotone"
|
||||
@@ -86,7 +125,7 @@ useHead({
|
||||
icon="i-ph-check-square-duotone"
|
||||
label="Link copied"
|
||||
size="lg"
|
||||
variant="solid"
|
||||
variant="outline"
|
||||
@click.prevent="copy()"
|
||||
/>
|
||||
<UButton
|
||||
|
||||
@@ -8,6 +8,20 @@ useSeoMeta({
|
||||
const { data: writings } = await useAsyncData('all-writings', () =>
|
||||
queryContent('/writings').sort({ published: -1 }).without('body').find()
|
||||
)
|
||||
|
||||
const { data: writingsDB } = await useAsyncData('all-writings-db', () =>
|
||||
$fetch(`/api/posts`)
|
||||
)
|
||||
|
||||
function getDetails(slug: string) {
|
||||
const writing = writingsDB.value!.find((writing: any) => writing.slug === slug)
|
||||
if (!writing) return ''
|
||||
|
||||
const like = writing.likes! > 1 ? 'likes' : 'like'
|
||||
const view = writing.views! > 1 ? 'views' : 'view'
|
||||
|
||||
return `${writing.likes} ${like} · ${writing.views} ${view}`
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -25,15 +39,20 @@ const { data: writings } = await useAsyncData('all-writings', () =>
|
||||
:to="writing._path"
|
||||
class="group"
|
||||
>
|
||||
<article>
|
||||
<article class="space-y-1">
|
||||
<div class="border-l-2 pl-2 border-gray-300 dark:border-gray-700 rounded-sm">
|
||||
{{ useDateFormat(writing.publishedAt, 'DD MMMM YYYY').value }} - {{ writing.readingTime }}min.
|
||||
<p>{{ getDetails(writing.slug) }}</p>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<h1
|
||||
class="font-bold text-lg duration-300 text-neutral-600 group-hover:text-black dark:text-neutral-400 dark:group-hover:text-white"
|
||||
>
|
||||
{{ writing.title }}
|
||||
</h1>
|
||||
<p class="text-sm text-neutral-500 group-hover:text-black dark:group-hover:text-white duration-300">
|
||||
{{ useDateFormat(writing.publishedAt, 'DD MMMM YYYY').value }} · {{ writing.readingTime }}min long
|
||||
</p>
|
||||
</div>
|
||||
<h1
|
||||
class="font-bold my-2 text-lg duration-300 text-gray-600 group-hover:text-black dark:text-gray-400 dark:group-hover:text-white"
|
||||
>
|
||||
{{ writing.title }}
|
||||
</h1>
|
||||
<h3>
|
||||
{{ writing.description }}
|
||||
</h3>
|
||||
|
||||
Reference in New Issue
Block a user