mirror of
https://github.com/ArthurDanjou/website-old.git
synced 2026-02-02 21:27:52 +01:00
Implement nuxt-content
This commit is contained in:
@@ -10,16 +10,16 @@
|
||||
</svg>
|
||||
</div>
|
||||
<div class="ml-2">
|
||||
{{ $t('blog_read_back') }}
|
||||
{{ $t('blog.read.back') }}
|
||||
</div>
|
||||
</nuxt-link>
|
||||
</div>
|
||||
</div>
|
||||
<h1 class="text-3xl md:text-5xl font-bold">
|
||||
{{ $t(title) }}
|
||||
{{ post.title }}
|
||||
</h1>
|
||||
<h3 class="text-xl text-gray-800 dark:text-dark-900 my-4 md:mt-8">
|
||||
{{ $t(description) }}
|
||||
{{ post.description }}
|
||||
</h3>
|
||||
<div class="flex flex-row justify-between w-full md:w-2/3 mb-12">
|
||||
<div>
|
||||
@@ -27,24 +27,28 @@
|
||||
<p>{{ formatDate }}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p class="uppercase text-sm font-bold text-gray-800 dark:text-dark-900">{{ $t('blog_read_time') }}</p>
|
||||
<p>{{ reading_time }} min</p>
|
||||
<p class="uppercase text-sm font-bold text-gray-800 dark:text-dark-900">{{ $t('blog.read.time') }}</p>
|
||||
<p>{{ post.reading_time }} min</p>
|
||||
</div>
|
||||
<div>
|
||||
<p :class="tags.length === 0 ? 'opacity-0': 'opacity-100'" class="uppercase text-sm font-bold text-gray-800 dark:text-dark-900">Tags</p>
|
||||
<p :class="post.tags.length === 0 ? 'opacity-0': 'opacity-100'" class="uppercase text-sm font-bold text-gray-800 dark:text-dark-900">Tags</p>
|
||||
<p>{{ formatTags }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full">
|
||||
<div class="flex justify-center w-full h-auto">
|
||||
<img class="w-full h-auto" :src="'http://localhost:5555/files/'+cover.file_name" alt="Cover Img" />
|
||||
<img class="w-full h-auto" :src="'http://localhost:5555/files/'+post.cover" alt="Cover Img" />
|
||||
</div>
|
||||
</div>
|
||||
<p class="my-6 md:my-12 text-gray-800 dark:text-dark-900">
|
||||
{{ $t(content) }}
|
||||
|
||||
</p>
|
||||
<nuxt-content
|
||||
:document="post"
|
||||
class="prose prose-sm sm:prose lg:prose-lg xl:prose-2xl my-6 md:my-12"
|
||||
/>
|
||||
<p class="mb-3">
|
||||
{{ $t('blog_read_thanks') }}
|
||||
{{ $t('blog.read.thanks') }}
|
||||
</p>
|
||||
<div class="flex items-center">
|
||||
<div
|
||||
@@ -59,7 +63,7 @@
|
||||
</div>
|
||||
<a
|
||||
target="_blank"
|
||||
:href="'https://twitter.com/intent/tweet?url=https%3A%2F%2Farthurdanjou.fr%2Fblog%2F' + id + '&text=' + $t('blog_tweet') + ' ' + $t(title) +'&via=ArthurDanj'"
|
||||
:href="'https://twitter.com/intent/tweet?url=https%3A%2F%2Farthurdanjou.fr%2Fblog%2F' + this.post.slug + '&text=' + $t('blog.tweet') + ' ' + post.title"
|
||||
class="h-16 end-blog cursor-pointer duration-300 text-3xl p-3 border-solid border border-gray-400 dark:border-dark-800 mr-2 hover:border-cyan-500 dark:hover:border-cyan-500"
|
||||
>
|
||||
<img class="inline img icon-hover" src="@/assets/img/socials/twitter.svg" alt="Twitter logo" height="40" width="40" />
|
||||
@@ -89,43 +93,29 @@ export default {
|
||||
name: "blog",
|
||||
head() {
|
||||
return {
|
||||
title: 'Blog - Arthur Danjou'
|
||||
title: 'Blog - Arthur Danjou - ' + this.post.title
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
id: this.$route.params.id,
|
||||
title: '',
|
||||
description: '',
|
||||
content: '',
|
||||
tags: [],
|
||||
likes: 0,
|
||||
date: '',
|
||||
cover: '',
|
||||
reading_time: 0,
|
||||
post: null,
|
||||
|
||||
isCopied: false,
|
||||
liked: false
|
||||
}
|
||||
},
|
||||
async asyncData({ params, $axios }) {
|
||||
const {data: post} = await $axios.get('/posts/' + params.id)
|
||||
const {data: liked} = await $axios.get('/post/' + params.id + '/isLiked')
|
||||
async asyncData({ params, $content, app }) {
|
||||
const post = await $content(`articles/${app.i18n.locale}/`, params.slug).fetch()
|
||||
const liked = false
|
||||
return {
|
||||
title: post.title.code,
|
||||
description: post.description.code,
|
||||
content: post.content.code,
|
||||
tags: post.tags,
|
||||
likes: post.likes,
|
||||
date: post.created_at,
|
||||
reading_time: post.reading_time,
|
||||
cover: post.cover,
|
||||
liked: liked !== 0
|
||||
post,
|
||||
liked: liked
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
copyToClipBoard() {
|
||||
navigator.clipboard.writeText('https://arthurdanjou.fr/blog/' + this.id)
|
||||
navigator.clipboard.writeText('https://arthurdanjou.fr/blog/' + this.post.slug)
|
||||
this.isCopied = true
|
||||
setTimeout(() => {
|
||||
this.isCopied = false
|
||||
@@ -133,13 +123,13 @@ export default {
|
||||
},
|
||||
async handleLike() {
|
||||
if (this.liked) {
|
||||
const {data} = await this.$axios.get('/post/' + this.id + '/unlike')
|
||||
const {data} = await this.$axios.get('/post/' + this.post.slug + '/unlike')
|
||||
if (data.code === 200) {
|
||||
this.liked = false
|
||||
this.likes = data.post.likes
|
||||
}
|
||||
} else {
|
||||
const {data} = await this.$axios.get('/post/' + this.id + '/like')
|
||||
const {data} = await this.$axios.get('/post/' + this.post.slug + '/like')
|
||||
if (data.code === 200) {
|
||||
this.liked = true
|
||||
this.likes = data.post.likes
|
||||
@@ -149,16 +139,13 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
formatDate() {
|
||||
const monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sept", "Oct", "Nov", "Dec"
|
||||
];
|
||||
const date = new Date(this.date)
|
||||
return date.getDate() + " " + monthNames[date.getMonth()] + " " + date.getFullYear()
|
||||
const dateFormat = this.post.date.split('-')
|
||||
return dateFormat[0] + " " + this.$t('month.' + dateFormat[1]) + " " + dateFormat[2]
|
||||
},
|
||||
formatTags() {
|
||||
let tags = ""
|
||||
this.tags.map(tag => {
|
||||
tags += this.$t(tag.label.code) + ", "
|
||||
this.post.tags.map(tag => {
|
||||
tags += this.$t(tag) + ", "
|
||||
})
|
||||
return tags.substring(0, tags.length - 2)
|
||||
},
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<main class="blog flex flex-col items-center px-5 xl:px-64">
|
||||
<PageTitle
|
||||
title="home_link_blog"
|
||||
title="part.blog"
|
||||
color="green"
|
||||
>
|
||||
<svg class="inline-block icon" height="40" width="40" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
@@ -12,52 +12,56 @@
|
||||
<h1
|
||||
v-if="current_tag === ''"
|
||||
class="text-lg mb-2"
|
||||
>{{ $t('blog_tags_search') }}</h1>
|
||||
>{{ $t('blog.tags.search') }}</h1>
|
||||
<div
|
||||
@click="resetPosts"
|
||||
v-if="current_tag !== ''"
|
||||
class="w-full home-arrow flex cursor-pointer font-bold"
|
||||
class="w-full"
|
||||
>
|
||||
<div class="arrow duration-300 mr-2">
|
||||
<svg height="25" width="25" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18" />
|
||||
</svg>
|
||||
<div class="w-full home-arrow flex cursor-pointer font-bold mb-3">
|
||||
<div class="arrow duration-300 mr-2">
|
||||
<svg height="25" width="25" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18" />
|
||||
</svg>
|
||||
</div>
|
||||
{{ $t('blog.tags.back') }}
|
||||
</div>
|
||||
<div class="w-full">
|
||||
{{ $t('blog.tags.current', { tag: $t(current_tag)}) }}
|
||||
</div>
|
||||
{{ $t('blog_tags_search_back') }}
|
||||
</div>
|
||||
<div v-else class="flex flex-row w-full overflow-x-scroll md:overflow-x-hidden md:flex-wrap space-x-3 md:space-x-0">
|
||||
<div v-for="tag in tags">
|
||||
<div
|
||||
class="mb-3 md:mr-4 border-b-2 border-opacity-0 hover:border-opacity-100 border-green-400 border-solid duration-300 cursor-pointer font-black"
|
||||
@click="fetchPostsByTag(tag.label.code)"
|
||||
@click="fetchPostsByTag(tag.slug)"
|
||||
>
|
||||
{{ $t(tag.label.code) }}
|
||||
{{ $t(tag.slug) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h1 v-if="posts.length === 0" class="text-xl font-bold text-center my-8 w-full">{{ $t('blog_no_posts') }}</h1>
|
||||
<div class="w-full md:w-1/2" v-else>
|
||||
<h1 v-if="posts.length === 0" class="text-xl font-bold text-center my-8 w-full">{{ $t('blog.no_posts') }}</h1>
|
||||
<div class="w-full xl:w-1/2" v-else>
|
||||
<div class="flex flex-col justify-around items-center py-8 w-full">
|
||||
<div class="w-full" v-for="post in posts">
|
||||
<nuxt-link :to="'/blog/' + post.id">
|
||||
<nuxt-link :to="'/blog/' + post.slug">
|
||||
<Post
|
||||
:title="post.title.code"
|
||||
:title="post.title"
|
||||
:reading_time="post.reading_time"
|
||||
:description="post.description.code"
|
||||
:description="post.description"
|
||||
:tags="displayTags(post.tags)"
|
||||
:cover="post.cover.file_name"
|
||||
:date="post.created_at"
|
||||
:likes="post.likes"
|
||||
:lightBg="post.light_back_ground"
|
||||
:cover="post.cover"
|
||||
:date="post.date"
|
||||
:lightBg="post.background"
|
||||
/>
|
||||
</nuxt-link>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative flex flex-row justify-between w-full mb-4" v-if="postsCount > 5">
|
||||
<div class="relative flex flex-row justify-between w-full mb-4" v-if="next || prev">
|
||||
<div
|
||||
class="duration-500 flex w-1/2 px-5 py-4 justify-center items-center"
|
||||
:class="page > 1 ? 'opacity-100' : 'opacity-0'"
|
||||
class="duration-300 flex w-1/2 px-5 py-4 justify-center items-center"
|
||||
:class="prev === null ? 'opacity-0': 'opacity-100'"
|
||||
>
|
||||
<div class="flex items-center duration-300 prev-arrow" @click="prevPage">
|
||||
<div class="arrow duration-300">
|
||||
@@ -65,15 +69,15 @@
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 15l-3-3m0 0l3-3m-3 3h8M3 12a9 9 0 1118 0 9 9 0 01-18 0z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="inline ml-4 font-bold">{{ $t('blog_pagination_prev') }}</div>
|
||||
<div class="inline ml-4 font-bold">{{ $t('blog.pagination.prev') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="duration-500 flex w-1/2 px-5 py-4 justify-center items-center"
|
||||
:class="hasNextPage ? 'opacity-100' : 'opacity-0'"
|
||||
class="duration-300 flex w-1/2 px-5 py-4 justify-center items-center"
|
||||
:class="next === null ? 'opacity-0': 'opacity-100'"
|
||||
>
|
||||
<div class="flex items-center duration-300 suiv-arrow" @click="nextPage">
|
||||
<div class="ml-4 font-bold">{{ $t('blog_pagination_next') }}</div>
|
||||
<div class="mr-4 font-bold">{{ $t('blog.pagination.next') }}</div>
|
||||
<div class="inline arrow duration-300">
|
||||
<svg class="inline icon" height="30" width="30" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 9l3 3m0 0l-3 3m3-3H8m13 0a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
@@ -99,50 +103,140 @@ export default {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
posts: [],
|
||||
postsCount: 0,
|
||||
page: 1,
|
||||
page: 0,
|
||||
current_tag: '',
|
||||
tags: [],
|
||||
hasNextPage: false,
|
||||
posts: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
displayTags(tags) {
|
||||
const tags_label = []
|
||||
tags.map(tag => {
|
||||
tags_label.push(tag.label.code)
|
||||
tags_label.push(tag)
|
||||
})
|
||||
return tags_label
|
||||
},
|
||||
async fetchPostsByTag(tag) {
|
||||
this.current_tag = tag
|
||||
const {data} = await this.$axios.get('/post/' + tag + '?page=1')
|
||||
this.posts = data.data
|
||||
this.hasNextPage = data.meta.next_page_url !== null
|
||||
this.page = 0
|
||||
await this.fetchPosts()
|
||||
if (this.posts.length !== 0) {
|
||||
await this.fetchPrevAndNext()
|
||||
} else {
|
||||
this.next = null
|
||||
this.prev = null
|
||||
}
|
||||
},
|
||||
async resetPosts() {
|
||||
this.current_tag = ''
|
||||
const {data} = await this.$axios.get('/posts?page=1')
|
||||
this.posts = data.data
|
||||
this.hasNextPage = data.meta.next_page_url !== null
|
||||
this.posts = await this.$content(`articles/${this.$i18n.locale}`)
|
||||
.sortBy('date', 'asc')
|
||||
.limit(5)
|
||||
.fetch()
|
||||
},
|
||||
nextPage() {
|
||||
async nextPage() {
|
||||
this.page++
|
||||
await this.fetchPosts()
|
||||
await this.fetchPrevAndNext()
|
||||
|
||||
window.scrollTo({
|
||||
top: 100,
|
||||
behavior: "smooth"
|
||||
})
|
||||
},
|
||||
prevPage() {
|
||||
async prevPage() {
|
||||
this.page--
|
||||
await this.fetchPosts()
|
||||
await this.fetchPrevAndNext()
|
||||
window.scrollTo({
|
||||
top: 100,
|
||||
behavior: "smooth"
|
||||
})
|
||||
},
|
||||
async fetchPosts() {
|
||||
let postsTemp = []
|
||||
if (this.current_tag === "") {
|
||||
postsTemp = await this.$content(`articles/${this.$i18n.locale}`)
|
||||
.sortBy('date', 'asc')
|
||||
.limit(5)
|
||||
.skip(this.page * 5)
|
||||
.fetch()
|
||||
} else {
|
||||
postsTemp = await this.$content(`articles/${this.$i18n.locale}`)
|
||||
.sortBy('date', 'asc')
|
||||
.limit(5)
|
||||
.skip(this.page * 5)
|
||||
.where({
|
||||
tags: {
|
||||
$contains: this.current_tag
|
||||
}
|
||||
})
|
||||
.fetch()
|
||||
}
|
||||
|
||||
const posts = []
|
||||
postsTemp.map(post => {
|
||||
posts.push(post)
|
||||
})
|
||||
this.posts = posts
|
||||
},
|
||||
async fetchPrevAndNext() {
|
||||
const [_, next] = await this.$content(`articles/${this.$i18n.locale}`)
|
||||
.surround(this.posts[this.posts.length - 1].slug, {
|
||||
before: 1,
|
||||
after: 1
|
||||
})
|
||||
.fetch()
|
||||
const [prev, __] = await this.$content(`articles/${this.$i18n.locale}`)
|
||||
.skip(this.page)
|
||||
.surround(this.posts[0].slug, {
|
||||
before: 1,
|
||||
after: 1
|
||||
})
|
||||
.fetch()
|
||||
|
||||
this.prev = null
|
||||
this.next = null
|
||||
if (this.posts.length === 5) {
|
||||
this.next = next
|
||||
}
|
||||
if (this.page > 0) {
|
||||
this.prev = prev
|
||||
}
|
||||
}
|
||||
},
|
||||
async asyncData ({ $axios }) {
|
||||
const {data: count} = await $axios.get('/posts/size')
|
||||
const {data} = await $axios.get('/posts?page=1')
|
||||
const {data: tags} = await $axios.get('/tags')
|
||||
async asyncData ({ $content, app }) {
|
||||
const tags = await $content('tags').fetch()
|
||||
const postsTemp = await $content(`articles/${app.i18n.locale}`)
|
||||
.sortBy('date', 'asc')
|
||||
.limit(5)
|
||||
.fetch()
|
||||
|
||||
const posts = []
|
||||
postsTemp.map(post => {
|
||||
posts.push(post)
|
||||
})
|
||||
|
||||
const [_, next] = await $content(`articles/${app.i18n.locale}`)
|
||||
.surround(posts[posts.length - 1].slug, {
|
||||
before: 1,
|
||||
after: 1
|
||||
})
|
||||
.fetch()
|
||||
const [prev, __] = await $content(`articles/${app.i18n.locale}`)
|
||||
.surround(posts[0].slug, {
|
||||
before: 1,
|
||||
after: 1
|
||||
})
|
||||
.fetch()
|
||||
|
||||
return {
|
||||
posts: data.data,
|
||||
postsCount: count,
|
||||
posts,
|
||||
postsCount: posts.length,
|
||||
tags,
|
||||
hasNextPage: data.meta.next_page_url !== null
|
||||
prev,
|
||||
next
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user