130 lines
3.6 KiB
Vue
130 lines
3.6 KiB
Vue
<template>
|
|
<section class="blog-recent">
|
|
<div class="header">
|
|
<h3>Latest Articles</h3>
|
|
<div class="all-articles" v-if="showAllArticlesButton">
|
|
<router-link :to="{ name: 'blog' }">All articles</router-link>
|
|
</div>
|
|
</div>
|
|
<div class="list">
|
|
<ul class="blog-items">
|
|
<li class="blog-item" v-for="article of articles" :key="article.id" @click="onClick(article)">
|
|
<img
|
|
class="article-image"
|
|
src="//via.placeholder.com/128"
|
|
alt="Article Topic"
|
|
/>
|
|
<div class="article-text">
|
|
<h4 class="article-title">
|
|
{{ article.title }}
|
|
</h4>
|
|
<span class="article-date" :title="absDate(article.date)">{{ relDate(article.date) }}</span>
|
|
<span class="article-published" v-if="!article.published">Unpublished</span>
|
|
</div>
|
|
</li>
|
|
</ul>
|
|
|
|
<pagination
|
|
v-if="paginate && !loading"
|
|
v-model:page="page"
|
|
v-model:itemsPerPage="itemsPerPage"
|
|
:max-pages="lastPage"
|
|
></pagination>
|
|
</div>
|
|
</section>
|
|
</template>
|
|
|
|
<script>
|
|
import Pagination from "./Pagination";
|
|
|
|
export default {
|
|
components: {
|
|
Pagination
|
|
},
|
|
data() {
|
|
return {
|
|
loading: false,
|
|
articles: [],
|
|
error: null,
|
|
page: 0,
|
|
lastPage: 0,
|
|
itemsPerPage: 0,
|
|
};
|
|
},
|
|
props: {
|
|
paginate: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
max: {
|
|
type: Number,
|
|
default: 5,
|
|
},
|
|
summary: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
showAllArticlesButton: {
|
|
type: Boolean,
|
|
default: true
|
|
},
|
|
},
|
|
mounted() {
|
|
this.itemsPerPage = this.max;
|
|
|
|
this.updateList(this.itemsPerPage, this.page);
|
|
},
|
|
methods: {
|
|
relDate(date) {
|
|
return moment(date).fromNow();
|
|
},
|
|
absDate(date) {
|
|
return moment(date).format('MMMM Do YYYY, hh:mm:ss');
|
|
},
|
|
onClick(article) {
|
|
const date = moment(article.date);
|
|
const year = date.year();
|
|
const month = date.month() + 1;
|
|
const day = date.date();
|
|
const id = article.id;
|
|
const slug = article.slug;
|
|
|
|
this.$router.push({ name: 'blog-article', params: { year, month, day, id, slug }});
|
|
},
|
|
updateList(limit, page) {
|
|
this.loading = true;
|
|
axios.get("/api/blog/recent", {
|
|
params: {
|
|
limit: limit,
|
|
page: page,
|
|
}
|
|
}).then((res) => {
|
|
if (res.status > 399) {
|
|
this.error = res.statusText;
|
|
} else {
|
|
this.articles = res.data.data;
|
|
this.lastPage = res.data.last_page;
|
|
}
|
|
|
|
this.loading = false;
|
|
}).catch(ex => {
|
|
this.loading = false;
|
|
this.error = ex.message;
|
|
});
|
|
},
|
|
},
|
|
watch: {
|
|
itemsPerPage(value) {
|
|
if (this.page > 0) {
|
|
this.page = 0;
|
|
} else {
|
|
this.updateList(value, this.page);
|
|
}
|
|
},
|
|
page(value) {
|
|
this.updateList(this.itemsPerPage, value);
|
|
},
|
|
}
|
|
}
|
|
</script>
|