Skip to content

Commit

Permalink
Merge pull request CSID-DGU#84 from Minn-Choi/feature/CSID-DGU#6
Browse files Browse the repository at this point in the history
Feature/CSID-DGU#6
  • Loading branch information
Minn-Choi authored Dec 5, 2024
2 parents d94bbea + 3e0488b commit 8710c4a
Show file tree
Hide file tree
Showing 4 changed files with 498 additions and 323 deletions.
5 changes: 5 additions & 0 deletions src/assets/images/92.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
285 changes: 152 additions & 133 deletions src/components/common/feed/FriendGoal.vue
Original file line number Diff line number Diff line change
@@ -1,166 +1,157 @@
<template>
<div v-if="friendNickname && friendGoalContent" class="friend-goal">
<div class="goal-content">
<span class="friendName">{{ friendNickname }}</span>
<span class="friendContent">{{ friendGoalContent }}</span>
<button class="btn" @click="toggleCommentSection">
<img src="../../../assets/images/comment.svg" alt="๋Œ“๊ธ€">
</button>
</div>

<!-- ๋Œ“๊ธ€ ์ž…๋ ฅ ์„น์…˜ -->
<div v-if="showCommentSection">
<div class="comment-input">
<select v-model="selectedEmoji">
<option value="" disabled selected hidden>#๏ธโƒฃ</option>
<option value="๐Ÿ˜Š">๐Ÿ˜Š</option>
<option value="๐Ÿ‘">๐Ÿ‘</option>
<option value="โค๏ธ">โค๏ธ</option>
<option value="๐Ÿ˜Ž">๐Ÿ˜Ž</option>
<option value="๐Ÿ˜">๐Ÿ˜</option>
</select>
<input
class="realinput"
type="text"
v-model="comment"
placeholder="๋Œ“๊ธ€ ์ž…๋ ฅ"
/>
<button @click="submitComment">
<img src="../../../assets/images/add.svg" />
<div v-if="goals.length" class="friend-goals">
<div v-for="goal in goals" :key="goal.goalId" class="friend-goal">
<div class="goal-content">
<span class="friendName">{{ goal.nickname }}</span>
<span class="friendContent">{{ goal.content }}</span>
<button class="btn" @click="toggleCommentSection(goal.goalId)">
<img src="../../../assets/images/comment.svg" alt="๋Œ“๊ธ€">
</button>
</div>

<div class="comment-list">
<div v-for="comment in comments" :key="comment.id" class="comment">
<div class="nick">{{ comment.nickname }}</div>
<div>{{ getEmoji(comment.emoji) }}</div> <!-- ์ด๋ชจ์ง€ ๋ณ€ํ™˜ -->
<div class="comment-content">{{ comment.content }}</div>
<div v-if="showCommentSection === goal.goalId">
<div class="comment-input">
<select v-model="comments[goal.goalId].emoji">
<option value="" disabled selected hidden>#๏ธโƒฃ</option>
<option value="๐Ÿ˜Š">๐Ÿ˜Š</option>
<option value="๐Ÿ‘">๐Ÿ‘</option>
<option value="โค๏ธ">โค๏ธ</option>
<option value="๐Ÿ˜Ž">๐Ÿ˜Ž</option>
<option value="๐Ÿ˜">๐Ÿ˜</option>
</select>
<input
class="realinput"
type="text"
v-model="comments[goal.goalId].content"
placeholder="๋Œ“๊ธ€ ์ž…๋ ฅ"
/>
<div class="'btn2'" @click="submitComment(goal.goalId)">
<img src="../../../assets/images/add.svg" />
</div>
</div>

<div class="comment-list">
<div v-for="comment in goal.comments" :key="comment.commentId" class="comment">
<div class="nick">{{ comment.nickname }}</div>
<div class='emo'>{{ getEmoji(comment.emoji) }}</div>
<div class="comment-content">{{ comment.content }}</div>
</div>
</div>
</div>
</div>
</div>
<div v-else>
<p>ํ‘œ์‹œํ•  ๋ชฉํ‘œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.</p>
</div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
<script>
import { ref, reactive, onMounted } from 'vue';
// ๋ฐ์ดํ„ฐ ์ •์˜
const friendNickname = ref('')
const friendGoalContent = ref('')
const comments = ref([])
const showCommentSection = ref(false)
const selectedEmoji = ref('')
const comment = ref('')
const goalId = ref(null) // goalId๋Š” API์—์„œ ๋ฐ›์•„์˜ด
export default {
setup() {
const goals = ref([]);
const showCommentSection = ref(null);
const comments = reactive({});
// ์ด๋ชจ์ง€ ๋งต
const emojiMap = {
'๐Ÿ˜Š': 0,
'๐Ÿ‘': 1,
'โค๏ธ': 2,
'๐Ÿ˜Ž': 3,
'๐Ÿ˜': 4
}
const emojiMap = {
'๐Ÿ˜Š': 0,
'๐Ÿ‘': 1,
'โค๏ธ': 2,
'๐Ÿ˜Ž': 3,
'๐Ÿ˜': 4,
};
// emojiMap์„ ๋ฐ˜๋Œ€๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ์ˆซ์ž ๊ฐ’์„ ์ด๋ชจ์ง€๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜
const getEmoji = (emojiIndex) => {
const reversedMap = Object.keys(emojiMap).reduce((acc, key) => {
acc[emojiMap[key]] = key
return acc
}, {})
return reversedMap[emojiIndex] || '' // ์—†์œผ๋ฉด ๋นˆ ๋ฌธ์ž์—ด ๋ฐ˜ํ™˜
}
const fetchGoals = async () => {
try {
const response = await fetch(`${process.env.VUE_APP_BE_API_URL}/api/feeds`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
credentials: 'include',
});
// ๋ชฉํ‘œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ํ•จ์ˆ˜
const fetchGoals = async () => {
try {
const response = await fetch(`${process.env.VUE_APP_BE_API_URL}/api/feeds`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
credentials: 'include',
})
if (response.ok) {
const data = await response.json();
goals.value = data.filter((goal) => !goal.mine);
if (response.ok) {
const data = await response.json()
console.log('API ์‘๋‹ต ๋ฐ์ดํ„ฐ:', data)
if (data.length > 0) {
const firstGoal = data[0]
friendNickname.value = firstGoal.nickname
friendGoalContent.value = firstGoal.content
comments.value = firstGoal.comments
goalId.value = firstGoal.goalId
goals.value.forEach((goal) => {
comments[goal.goalId] = { content: '', emoji: '' };
});
} else {
console.error('๋ชฉํ‘œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.', response.status);
alert('๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋ฐ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.');
}
} catch (error) {
console.error('API ์š”์ฒญ ์˜ค๋ฅ˜:', error);
alert('์„œ๋ฒ„ ์š”์ฒญ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.');
}
} else {
console.error('๋ชฉํ‘œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.', response.status)
alert('๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋ฐ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.')
}
} catch (error) {
console.error('API ์š”์ฒญ ์˜ค๋ฅ˜:', error)
alert('์„œ๋ฒ„ ์š”์ฒญ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.')
}
}
};
// ๋Œ“๊ธ€์„ ์ž‘์„ฑํ•˜๋Š” ํ•จ์ˆ˜
const submitComment = async () => {
if (!comment.value.trim()) {
alert('๋Œ“๊ธ€์„ ์ž…๋ ฅํ•˜์„ธ์š”.')
return
}
const toggleCommentSection = (goalId) => {
showCommentSection.value = showCommentSection.value === goalId ? null : goalId;
};
try {
const emojiNumber = emojiMap[selectedEmoji.value] ?? -1
const getEmoji = (emoji) => {
return Object.keys(emojiMap).find((key) => emojiMap[key] === emoji) || '#๏ธโƒฃ';
};
const payload = {
emoji: emojiNumber,
content: comment.value,
}
const submitComment = async (goalId) => {
const { content, emoji } = comments[goalId];
const emojiValue = emojiMap[emoji] ?? -1;
console.log("์š”์ฒญํ•  Payload:", payload)
const response = await fetch(
`${process.env.VUE_APP_BE_API_URL}/api/goals/${goalId.value}/comments`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
credentials: 'include',
body: JSON.stringify(payload),
if (!content.trim()) {
alert('๋Œ“๊ธ€์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.');
return;
}
)
if (response.ok) {
const data = await response.json()
console.log("API ์‘๋‹ต ๋ฐ์ดํ„ฐ:", data)
window.location.reload()
alert('๋Œ“๊ธ€์ด ์„ฑ๊ณต์ ์œผ๋กœ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค!')
selectedEmoji.value = ''
comment.value = ''
} else {
alert('๋Œ“๊ธ€ ์ถ”๊ฐ€ ์ค‘ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์‹œ ์‹œ๋„ํ•ด์ฃผ์„ธ์š”.')
}
} catch (error) {
console.error('๋Œ“๊ธ€ ์ „์†ก ์ค‘ ์˜ค๋ฅ˜:', error)
alert('๋Œ“๊ธ€ ์ถ”๊ฐ€ ์ค‘ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์‹œ ์‹œ๋„ํ•ด์ฃผ์„ธ์š”.')
}
}
try {
const payload = { content, emoji: emojiValue };
const response = await fetch(`${process.env.VUE_APP_BE_API_URL}/api/goals/${goalId}/comments`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
credentials: 'include',
body: JSON.stringify(payload),
});
const toggleCommentSection = () => {
showCommentSection.value = !showCommentSection.value
}
if (response.ok) {
alert('๋Œ“๊ธ€์ด ์„ฑ๊ณต์ ์œผ๋กœ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.');
comments[goalId].content = '';
comments[goalId].emoji = '';
fetchGoals();
} else {
console.error('๋Œ“๊ธ€ ์ถ”๊ฐ€ ์‹คํŒจ:', response.status);
alert('๋Œ“๊ธ€ ์ถ”๊ฐ€์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.');
}
} catch (error) {
console.error('๋Œ“๊ธ€ ์ œ์ถœ ์˜ค๋ฅ˜:', error);
alert('์„œ๋ฒ„ ์š”์ฒญ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.');
}
};
onMounted(() => {
fetchGoals()
})
onMounted(fetchGoals);
return {
goals,
showCommentSection,
comments,
toggleCommentSection,
getEmoji,
submitComment,
};
},
};
</script>
<style scoped>
.friend-goal {
display: flex;
flex-direction: column;
gap: 8px;
margin-bottom: 3px;
width: 100%;
border-radius: 10px;
background: #fff;
Expand All @@ -186,8 +177,33 @@ onMounted(() => {
padding: 8px 0;
word-wrap: break-word;
}
.btn,
.btn2{
display: flex;
outline: none;
border: none;
background: none;
cursor: pointer;
}
.btn:focus,
.btn:active,
.btn2:focus,
.btn2:active {
outline: none;
border: none;
cursor: pointer;
}
.emo{
display: flex;
justify-content: center;
align-items: center;
}
.friendContent {
display: flex;
align-items: center;
margin-left: 10px;
margin-right: 5px;
padding: 5px 0;
Expand All @@ -201,15 +217,16 @@ onMounted(() => {
.comment-list {
display: flex;
justify-content: center;
flex-direction: column;
gap: 5px;
margin-bottom: 5px;
}
.comment {
display: flex;
gap: 10px;
margin-left: 5px;
align-items: center;
}
.nick {
Expand All @@ -220,6 +237,7 @@ onMounted(() => {
font-weight: 300;
line-height: normal;
display: flex;
min-width: 40px;
align-items: center;
}
Expand All @@ -232,6 +250,7 @@ onMounted(() => {
line-height: normal;
display: flex;
align-items: center;
justify-content: center;
}
.comment-input {
Expand Down
Loading

0 comments on commit 8710c4a

Please sign in to comment.