Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#91] 내 문의 조회 기능 구현 #208

Open
wants to merge 6 commits into
base: frontend-dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 52 additions & 31 deletions frontend/src/components/board/BoardDetailNavComponent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@
<nav class="css-1le17tz en4zazl1">
<ul class="css-tse2s2 en4zazl0">
<li :class="[
'css-1tzhzcg',
'efe6b6j1',
'tab',
{ active: activeTab === 'description' },
]" @click.prevent="activeTab = 'description'">
'css-1tzhzcg',
'efe6b6j1',
'tab',
{ active: activeTab === 'description' },
]" @click.prevent="activeTab = 'description'">
<a class="css-1t0ft7s efe6b6j0"><span class="name">상품설명</span></a>
</li>
<li :class="[
'css-1tzhzcg',
'efe6b6j1',
'tab',
{ active: activeTab === 'inquiries' },
]" @click.prevent="loadInquiries">
'css-1tzhzcg',
'efe6b6j1',
'tab',
{ active: activeTab === 'inquiries' },
]" @click.prevent="loadInquiries">
<a class="css-1t0ft7s efe6b6j0"><span class="name">문의</span></a>
</li>
</ul>
Expand Down Expand Up @@ -87,22 +87,22 @@
<span>{{ row.content }}<br /></span>
</div>
</div>
<div class="css-1j49yxi e11ufodi1" v-if="row.answerStatus !== '답변완료'">
<div class="css-1j49yxi e11ufodi1" v-if="row.answerStatus !== '답변완료' && row.email === this.userEmail">
<button type=" button" @click="openEditModal(index)">수정</button>
<button type="button" class="css-1ankuif e11ufodi0" @click="deleteInquiry(index)">삭제</button>
<button type="button" class="css-1ankuif e11ufodi0" @click="deleteInquiry(row.idx, index)">삭제</button>
</div>
</div>
<div class=" css-tnubsz e1ptpt003" v-if="row.answerStatus !== '답변대기'">
<div class="css-1n83etr e1ptpt002">
<div class="css-tnubsz e1ptpt003" v-if="row.answerStatus !== '답변대기'">
<div class="css-1n83etr e1ptpt002" v-for="(answer, answerIndex) in row.answers" :key="answerIndex">
<div class="css-m1wgq7 e1ptpt001">
<span class="css-1non6l6 ey0f1wv0"></span>
</div>
<div class="css-1bv2zte e1ptpt000">
<div>{{ row.answer_content }}</div>
<div>{{ answer.content }}</div>
</div>
<div class="css-17g9jzg e1gk8zam0">
{{ answer.createdAt ? formatDate(answer.createdAt) : '작성 시간 없음' }}
</div>
</div>
<div class="css-17g9jzg e1gk8zam0">
{{ row.answer_modified_at || row.answer_created_at }}
</div>
</div>
</td>
Expand All @@ -125,11 +125,16 @@
import { useQnaStore } from "@/stores/useQnaStore";
import QnaRegisterModalComponent from "../qna/QnaRegisterModalComponent.vue";
import { mapStores } from "pinia";
import { useUserStore } from "@/stores/useUserStore";
import axios from "axios";

export default {
name: "BoardDetailNavComponent",
computed: {
...mapStores(useQnaStore),
...mapStores(useQnaStore, useUserStore),
userEmail() {
return this.userStore.userDetail.email || "email 세팅 안 됨";
},
},
props: {
thumbnails: {
Expand Down Expand Up @@ -164,9 +169,27 @@ export default {
methods: {
loadInquiries() {
this.activeTab = "inquiries"; // 문의 탭 활성화
this.qnaStore.fetchInquiries().then(() => {
this.localTableData = this.qnaStore.inquiries;
});

axios.get('/api/user/detail', { withCredentials: true })
.then((response) => {
if (response.data.code === 1000) {
const userEmail = response.data.result.email;
console.log("로그인된 사용자의 이메일:", userEmail);
this.userStore.userDetail = response.data.result;
} else {
console.log("회원 정보를 가져오는 데 실패했습니다.");
}
})
.catch((error) => {
// 에러가 발생해도 alert 대신 로그만 출력
console.error("회원 정보 조회 중 오류 발생:", error);
})
.finally(() => {
// 회원정보 조회에 성공하든 실패하든 문의 목록은 조회하도록
this.qnaStore.fetchInquiries().then(() => {
this.localTableData = this.qnaStore.inquiries;
});
});
},
formatDate(dateString) {
const date = new Date(dateString);
Expand Down Expand Up @@ -208,8 +231,7 @@ export default {
el.style.maxHeight = "0px";
},
addNewInquiry(newInquiry) {
newInquiry.created_at = new Date().toISOString().split("T")[0];
this.localTableData.push(newInquiry);
newInquiry.email = this.userEmail; // 로그인된 사용자의 이메일을 새 문의에 추가
this.closeModal();
},
updateInquiry(updatedInquiry) {
Expand All @@ -224,9 +246,9 @@ export default {
this.closeModal();
}
},
deleteInquiry(index) {
// 문의를 삭제할 때, 현재 토글된 인덱스를 초기화
this.localTableData.splice(index, 1); // 해당 인덱스의 문의 삭제
deleteInquiry(idx, index) {
this.qnaStore.deleteInquiry(idx, index);

if (this.expandedInquiryIndex === index) {
// 삭제된 인덱스가 현재 토글된 인덱스라면 초기화
this.expandedInquiryIndex = null;
Expand Down Expand Up @@ -429,8 +451,7 @@ table {
display: block;
width: 14px;
height: 14px;
background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIiIGhlaWdodD0iMTQiIHZpZXdCb3g9IjAgMCAxMiAxNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxnIGZpbGw9IiNCNUI1QjUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPHBhdGggZD0iTTExLjA0MyAxMi41NzVhLjI1OS4yNTkgMCAwIDEtLjI1OC4yNTdIMS4yMTRhLjI1OS4yNTkgMCAwIDEtLjI1OC0uMjU3VjUuNDJjMC0uMTQyLjExNy0uMjU4LjI1OC0uMjU4aDkuNTdjLjE0NCAwIC4yNi4xMTYuMjYuMjU4djcuMTU1ek0zLjY4NSAzLjIzN0EyLjI4MyAyLjI4MyAwIDAgMSA1Ljk2Ni45NTdhMi4yODIgMi4yODIgMCAwIDEgMi4yODEgMi4yOHYuOTY4SDMuNjg1di0uOTY4em03LjEuOTY4aC0xLjU4di0uOTY4QTMuMjQxIDMuMjQxIDAgMCAwIDUuOTY1IDAgMy4yNCAzLjI0IDAgMCAwIDIuNzMgMy4yMzd2Ljk2OEgxLjIxNEMuNTQ0IDQuMjA1IDAgNC43NSAwIDUuNDJ2Ny4xNTVjMCAuNjY5LjU0NSAxLjIxNCAxLjIxNCAxLjIxNGg5LjU3Yy42NzEgMCAxLjIxNi0uNTQ1IDEuMjE2LTEuMjE0VjUuNDJjMC0uNjctLjU0NS0xLjIxNS0xLjIxNS0xLjIxNXoiLz4KICAgICAgICA8cGF0aCBkPSJNNSA4LjJjMCAuMzQzLjE4NC42MzIuNDQ4LjgxMnYxLjMzaDEuMTAzdi0xLjMzQS45ODYuOTg2IDAgMCAwIDcgOC4yYTEgMSAwIDAgMC0yIDB6Ii8+CiAgICA8L2c+Cjwvc3ZnPgo=)
no-repeat;
background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIiIGhlaWdodD0iMTQiIHZpZXdCb3g9IjAgMCAxMiAxNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxnIGZpbGw9IiNCNUI1QjUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPHBhdGggZD0iTTExLjA0MyAxMi41NzVhLjI1OS4yNTkgMCAwIDEtLjI1OC4yNTdIMS4yMTRhLjI1OS4yNTkgMCAwIDEtLjI1OC0uMjU3VjUuNDJjMC0uMTQyLjExNy0uMjU4LjI1OC0uMjU4aDkuNTdjLjE0NCAwIC4yNi4xMTYuMjYuMjU4djcuMTU1ek0zLjY4NSAzLjIzN0EyLjI4MyAyLjI4MyAwIDAgMSA1Ljk2Ni45NTdhMi4yODIgMi4yODIgMCAwIDEgMi4yODEgMi4yOHYuOTY4SDMuNjg1di0uOTY4em03LjEuOTY4aC0xLjU4di0uOTY4QTMuMjQxIDMuMjQxIDAgMCAwIDUuOTY1IDAgMy4yNCAzLjI0IDAgMCAwIDIuNzMgMy4yMzd2Ljk2OEgxLjIxNEMuNTQ0IDQuMjA1IDAgNC43NSAwIDUuNDJ2Ny4xNTVjMCAuNjY5LjU0NSAxLjIxNCAxLjIxNCAxLjIxNGg5LjU3Yy42NzEgMCAxLjIxNi0uNTQ1IDEuMjE2LTEuMjE0VjUuNDJjMC0uNjctLjU0NS0xLjIxNS0xLjIxNS0xLjIxNXoiLz4KICAgICAgICA8cGF0aCBkPSJNNSA4LjJjMCAuMzQzLjE4NC42MzIuNDQ4LjgxMnYxLjMzaDEuMTAzdi0xLjMzQS45ODYuOTg2IDAgMCAwIDcgOC4yYTEgMSAwIDAgMC0yIDB6Ii8+CiAgICA8L2c+Cjwvc3ZnPgo=) no-repeat;
margin-left: 6px;
}

Expand Down Expand Up @@ -482,7 +503,7 @@ table {
cursor: default;
}

.css-sxxs1g button + button {
.css-sxxs1g button+button {
margin-left: 12px;
}

Expand Down Expand Up @@ -591,7 +612,7 @@ div {

.css-1n83etr {
display: flex;
padding: 22px 20px 10px;
padding: 22px 20px 25px;
align-items: flex-start;
}

Expand Down
147 changes: 147 additions & 0 deletions frontend/src/components/company/CompanyAnswerListModalComponent.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
<template>
<div class="modal" @click.self="closeModal">
<div class="modal-content">
<span class="close" @click="closeModal">&times;</span>
<div class="answer-list-modal">
<h3>답변 목록</h3>
<ul>
<li v-for="answer in selectedInquiry.answers" :key="answer.idx">
<div class="answer-item">
<p class="answer-content">{{ answer.content }}</p>
<div class="answer-footer">
<span class="answer-date">{{ formatDate(answer.createdAt) }}</span>
<button class="delete-button" @click="deleteAnswer(answer.idx)">삭제</button>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
</template>

<script>
import axios from "axios";

export default {
props: {
selectedInquiry: {
type: Object,
required: true,
},
},
methods: {
closeModal() {
this.$emit("closeModal");
},
async deleteAnswer(answerId) {
try {
await axios.delete(`/api/qna/answer/delete/${answerId}`);
this.$emit("answerDeleted", answerId);
} catch (error) {
console.error("답변 삭제 실패:", error);
}
},
formatDate(dateString) {
const date = new Date(dateString);
return date.toLocaleDateString("ko-KR", {
year: "numeric",
month: "2-digit",
day: "2-digit",
});
},
},
};
</script>

<style scoped>
.modal {
position: fixed;
z-index: 1000;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0, 0, 0, 0.4);
}

.modal-content {
background-color: #fefefe;
margin: 10% auto;
padding: 20px;
border: 1px solid #888;
width: 80%;
max-width: 600px;
border-radius: 10px;
}

.close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}

.close:hover,
.close:focus {
color: black;
cursor: pointer;
}

.answer-list-modal {
max-height: 400px;
/* 스크롤이 가능하도록 최대 높이 설정 */
overflow-y: auto;
padding-right: 10px;
}

.answer-list-modal h3 {
font-size: 20px;
margin-bottom: 20px;
border-bottom: 1px solid #ddd;
/* 헤더 아래 줄 추가 */
padding-bottom: 10px;
}

.answer-list-modal ul {
list-style-type: none;
padding: 0;
}

.answer-list-modal .answer-item {
padding: 15px 0;
border-bottom: 1px solid #ddd;
/* 답변 사이에 줄 추가 */
}

.answer-content {
flex: 1;
margin-bottom: 10px;
}

.answer-footer {
display: flex;
justify-content: space-between;
align-items: center;
}

.answer-date {
font-size: 12px;
color: #888;
}

.delete-button {
background-color: #a588af;
color: white;
border: none;
padding: 6px 10px;
cursor: pointer;
border-radius: 5px;
font-size: 12px;
}

.delete-button:hover {
background-color: #5f0080;
}
</style>
Loading