Files
real-world-springboot/src/vite-frontend/src/views/TheArticleDetail.vue
2022-12-06 00:43:01 +09:00

283 lines
8.9 KiB
Vue

<template>
<div class="article-page">
<div class="banner">
<div class="container">
<h1>{{ articleDetail.article.title }}</h1>
<div class="article-meta">
<a href=""><img :src="articleDetail.article.author.image"/></a>
<div class="info">
<a href="javascript:void(0)" class="author" @click="viewProfile">{{ articleDetail.article.author.username }}</a>
<span class="date">{{convertDate(articleDetail.article.createdAt)}}</span>
</div>
<button v-if= "isMe" class="btn btn-sm btn-outline-secondary" @click="articleUpdate()">
<i class="ion-edit"></i>
Edit Article
</button>
<button v-if= "isMe" class="btn btn-outline-danger btn-sm" @click="articleDelete()">
<i class="ion-trash-a"></i>
Delete Article
</button>
<button v-if= "!isMe" class="btn btn-sm btn-outline-secondary" @click="followUpdate(articleDetail.article.author.following)">
<div v-if="articleDetail.article.author.following">
<i class="ion-minus-round"></i>
unFollow {{articleDetail.article.author.username}}
</div>
<div v-else>
<i class="ion-plus-round"></i>
Follow {{articleDetail.article.author.username}}
</div>
</button>
&nbsp;&nbsp;
<button v-if="!isMe" class="btn btn-sm btn-outline-primary" @click="favoriteUpdate(articleDetail.article.favorited)">
<div v-if="articleDetail.article.favorited">
<i class="ion-heart"></i>
unFavorite Article (<span class="counter">{{articleDetail.article.favoritesCount}}</span>)
</div>
<div v-else>
<i class="ion-heart"></i>
Favorite Article (<span class="counter">{{articleDetail.article.favoritesCount}}</span>)
</div>
</button>
</div>
</div>
</div>
<div class="container page">
<div class="row article-content">
<div class="col-md-12">
{{articleDetail.article.body}}
</div>
</div>
<hr/>
<div class="article-actions">
<div class="article-meta">
<a href="javascript:void(0)"><img :src="articleDetail.article.author.image"/></a>
<div class="info">
<a href="javascript:void(0)" class="author" @click="viewProfile">{{ articleDetail.article.author.username }}</a>
<span class="date">{{convertDate(articleDetail.article.createdAt)}}</span>
</div>
<button v-if= "isMe" class="btn btn-sm btn-outline-secondary" @click="articleUpdate()">
<i class="ion-edit"></i>
Edit Article
</button>
<button v-if= "isMe" class="btn btn-outline-danger btn-sm" @click="articleDelete()">
<i class="ion-trash-a"></i>
Delete Article
</button>
<button v-if= "!isMe" class="btn btn-sm btn-outline-secondary" @click="followUpdate(articleDetail.article.author.following)">
<div v-if="articleDetail.article.author.following">
<i class="ion-minus-round"></i>
unFollow {{articleDetail.article.author.username}}
</div>
<div v-else>
<i class="ion-plus-round"></i>
Follow {{articleDetail.article.author.username}}
</div>
</button>
&nbsp;&nbsp;
<button v-if="!isMe" class="btn btn-sm btn-outline-primary" @click="favoriteUpdate(articleDetail.article.favorited)">
<div v-if="articleDetail.article.favorited">
<i class="ion-heart"></i>
unFavorite Article (<span class="counter">{{articleDetail.article.favoritesCount}}</span>)
</div>
<div v-else>
<i class="ion-heart"></i>
Favorite Article (<span class="counter">{{articleDetail.article.favoritesCount}}</span>)
</div>
</button>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-md-8 offset-md-2">
<form class="card comment-form">
<div class="card-block">
<textarea class="form-control" placeholder="Write a comment..." rows="3" v-model="comment.body"></textarea>
</div>
<div class="card-footer">
<img :src="articleDetail.article.author.image" class="comment-author-img"/>
<button class="btn btn-sm btn-primary" @click="sendComment()">
Post Comment
</button>
</div>
</form>
<comment-list v-for="(comment,index) in getCommentList.comment"
:key="comment.id"
:comment="comment"
@delete:comment="deleteComment"
:imgs="comment.author.image">
</comment-list>
</div>
</div>
</div>
</div>
</template>
<script lang="ts">
import {onMounted, defineComponent, reactive, ref} from "vue";
import commentList from "@/components/commentList.vue";
import router from "@/router";
import { useStore } from "vuex";
import convertDate from "@/ts/common";
import {
addCommentToArticle, deleteArticle, deleteCommentsFromArticle,
favoriteArticle,
followUser,
getArticle,
getCommentsFromArticle, unFavoriteArticle,
unfollowUser
} from "@/api";
export default defineComponent({
name: "TheArticleDetail.vue",
components:{
'comment-list': commentList,
},
props:{
slug: String,
},
setup(props){
const store = useStore();
const token = store.state.token;
const username = store.state.username;
const isMe = ref(false);
const comment = reactive({
body: ""
})
const getCommentList = reactive({
comment: reactive([{id:0,author:{username:"",image:""}}])
})
const articleDetail = reactive({
article: {
slug: "",
title: "",
description: "",
body: "",
tagList: new Array(),
createdAt: "",
updatedAt: "",
favorited: false,
favoritesCount: 0,
author: {
username: "",
bio: "",
image: "",
following: false
}
}
})
const viewProfile = () => {
router.push({
name: 'Profile',
params: {username: articleDetail.article.author.username}})
}
const articleUpdate = async () => {
await router.push({
name: 'ArticleUpdateEditor',
params: {slug: articleDetail.article.slug}
})
}
const articleDelete = async () => {
await deleteArticle(articleDetail.article.slug);
await router.push({
name: 'Home'
})
}
const followUpdate = async (followState: boolean) => {
if(token == ''){
await router.push({name:"Login"});
return;
}
try {
if(followState){
const { data } = await unfollowUser(articleDetail.article.author.username);
articleDetail.article.author.following = data.profile.following;
}else{
const { data } = await followUser(articleDetail.article.author.username);
articleDetail.article.author.following = data.profile.following;
}
}catch (error: any){
alert(error);
}
}
const favoriteUpdate = async (favoriteState: boolean) => {
if(token == ''){
await router.push({name:"Login"});
return;
}
try {
if (favoriteState) {
const {data} = await unFavoriteArticle(props.slug);
articleDetail.article = data.article;
} else {
const {data} = await favoriteArticle(props.slug);
articleDetail.article = data.article;
}
}catch (error: any){
alert(error);
}
}
const sendComment = async () => {
try{
const { data } = await addCommentToArticle(props.slug, comment);
comment.body = "";
getCommentList.comment.push(data.comment);
}catch (error: any){
alert(error);
}
}
const deleteComment = async (commentId: number) => {
await deleteCommentsFromArticle(articleDetail.article.slug,commentId);
getCommentList.comment.splice(commentId,1);
}
onMounted(async ()=>{
try{
const { data } = await getArticle(props.slug);
articleDetail.article = data.article;
if(articleDetail.article.author.username == username){
isMe.value = true;
}
}catch (error: any){
alert(error);
}
try{
const { data } = await getCommentsFromArticle(props.slug);
getCommentList.comment = data.comments;
}catch (error: any){
alert(error);
}
})
return { isMe, articleDetail, comment, getCommentList, convertDate, deleteComment, viewProfile, articleUpdate, followUpdate, favoriteUpdate, sendComment, articleDelete }
}
})
</script>
<style scoped>
</style>