localhost-front/src/components/board/BoardProfile.vue

251 lines
7.0 KiB
Vue

<template>
<div class="d-flex align-items-center flex-wrap">
<div class="d-flex align-items-center">
<div v-if="!unknown" class="avatar me-2">
<img src="/img/avatars/2.png" alt="Avatar" class="rounded-circle" />
</div>
<div class="me-2">
<h6 class="mb-0">{{ profileName }}</h6>
<div class="profile-detail">
<span>{{ date }}</span>
<template v-if="showDetail">
<span class="ms-2">
<i class="fa-regular fa-eye"></i> {{ views }}
</span>
<span>
<i class="bx bx-comment"></i> {{ commentNum }}
</span>
</template>
</div>
</div>
</div>
<!-- 버튼 영역 -->
<div class="ms-auto text-end">
<!-- 수정, 삭제 버튼 -->
<template v-if="author || showDetail">
<EditButton @click="handleEdit" />
<DeleteButton @click="handleDelete" />
</template>
<!-- 비밀번호 입력창 (익명일 경우) -->
<div v-if="isPassword && unknown" class="mt-3">
<div class="input-group">
<input
type="password"
class="form-control"
v-model="password"
placeholder="비밀번호 입력"
/>
<button class="btn btn-primary" @click="handleSubmit">확인</button>
</div>
<span v-if="passwordAlert" class="invalid-feedback d-block text-start">{{ passwordAlert }}</span>
</div>
<!-- 좋아요, 싫어요 버튼 (댓글에서만 표시) -->
<BoardRecommendBtn
v-if="isLike"
:boardId="boardId"
:comment="props.comment"
@updateReaction="handleUpdateReaction"
/>
</div>
</div>
</template>
<script setup>
import { ref, defineProps, defineEmits } from 'vue';
import { useRouter } from 'vue-router';
import axios from '@api';
import DeleteButton from '../button/DeleteBtn.vue';
import EditButton from '../button/EditBtn.vue';
import BoardRecommendBtn from '../button/BoardRecommendBtn.vue';
// Vue Router 인스턴스
const router = useRouter();
const isPassword = ref(false);
const password = ref('');
const passwordAlert = ref(false);
const lastClickedButton = ref('');
// Props 정의
const props = defineProps({
comment: {
type: Object,
required: true,
},
boardId: {
type: Number,
required: false
},
commentId: {
type: Number,
required: false,
},
profileName: {
type: String,
default: '익명 사용자',
},
unknown: {
type: Boolean,
default: true,
},
showDetail: {
type: Boolean,
default: true,
},
// 게시글의 작성자 여부를 확인 : 현재 로그인한 사용자가 이 게시글의 작성자인지 여부
author: {
type: Boolean,
default: false,
},
date: {
type: String,
required: true,
},
views: {
type: Number,
default: 0,
},
commentNum: {
type: Number,
default: 0,
},
isLike: {
type: Boolean,
default: false,
}
});
const emit = defineEmits(['togglePasswordInput', 'updateReaction']);
// 수정 버튼
const handleEdit = () => {
if (props.unknown) {
togglePassword('edit');
} else {
router.push({ name: 'BoardEdit', params: { id: props.boardId } });
}
};
// 삭제 버튼
const handleDelete = () => {
if (props.unknown) {
togglePassword('delete');
} else {
deletePost();
}
};
// 비밀번호 입력 토글
const togglePassword = (button) => {
if (lastClickedButton.value === button) {
isPassword.value = !isPassword.value;
} else {
isPassword.value = true;
}
lastClickedButton.value = button;
};
// 비밀번호 확인
const handleSubmit = async () => {
if (!password.value) {
passwordAlert.value = '비밀번호를 입력해주세요.';
return;
}
try {
const requestData = {
LOCBRDPWD: password.value,
LOCBRDSEQ: 288
}
const postResponse = await axios.post(`board/${props.boardId}/password`, requestData);
if (postResponse.data.code === 200 && postResponse.data.data === true) {
isPassword.value = false;
if (lastClickedButton.value === 'edit') {
router.push({ name: 'BoardEdit', params: { id: props.boardId } });
} else if (lastClickedButton.value === 'delete') {
await deletePost();
}
lastClickedButton.value = null;
} else {
passwordAlert.value = '비밀번호가 일치하지 않습니다.';
}
} catch (error) {
// 401 오류
if (error.response && error.response.status === 401) {
passwordAlert.value = '비밀번호가 일치하지 않습니다.';
} else if (error.response) {
alert(`오류 발생: ${error.response.data.message || '서버 오류'}`);
} else {
alert('네트워크 오류가 발생했습니다. 다시 시도해주세요.');
}
}
};
const deletePost = async () => {
if (confirm('정말 삭제하시겠습니까?')) {
try {
const response = await axios.delete(`board/${props.boardId}`, {
data: { LOCBRDSEQ: props.boardId }
});
if (response.data.code === 200) {
alert('게시물이 삭제되었습니다.');
router.push({ name: 'BoardList' });
} else {
alert('삭제 실패: ' + response.data.message);
}
} catch (error) {
if (error.response) {
alert(`삭제 실패: ${error.response.data.message || '서버 오류'}`);
} else {
alert('네트워크 오류가 발생했습니다. 다시 시도해주세요.');
}
}
}
};
const handleUpdateReaction = (reactionData) => {
// console.log("🔥 BoardProfile에서 좋아요/싫어요 이벤트 발생");
// console.log("📌 게시글 ID:", props.boardId);
// console.log("📌 댓글 ID (수정 후):", props.comment?.commentId);
// console.log("📌 reactionData:", reactionData);
emit("updateReaction", {
boardId: props.boardId,
commentId: props.comment?.commentId,
...reactionData,
});
};
</script>
<style scoped>
.profile-detail span ~ span {
margin-left: 5px;
}
.ms-auto button + button {
margin-left: 5px;
}
.btn.author {
height: 30px;
}
@media screen and (max-width: 450px) {
.btn-area {
margin-top: 10px;
width: 100%;
}
.btn.author {
height: 30px;
}
}
</style>