This commit is contained in:
khj0414 2025-02-27 09:48:33 +09:00
commit 98aa44f497
8 changed files with 225 additions and 99 deletions

View File

@ -1,7 +1,7 @@
<template> <template>
<div> <div>
<BoardProfile <BoardProfile
:unknown="unknown" :unknown="comment.author === '익명'"
:isCommentAuthor="isCommentAuthor" :isCommentAuthor="isCommentAuthor"
:boardId="comment.boardId" :boardId="comment.boardId"
:profileName="comment.author" :profileName="comment.author"
@ -11,7 +11,7 @@
:isLike="!isLike" :isLike="!isLike"
:isCommentPassword="comment.isCommentPassword" :isCommentPassword="comment.isCommentPassword"
:isCommentProfile="true" :isCommentProfile="true"
@editClick="$emit('editClick', comment)" @editClick="aaaa"
@deleteClick="$emit('deleteClick', comment)" @deleteClick="$emit('deleteClick', comment)"
@updateReaction="handleUpdateReaction" @updateReaction="handleUpdateReaction"
/> />
@ -29,8 +29,8 @@
</div> </div>
<span v-if="passwordCommentAlert" class="invalid-feedback d-block text-start">{{ passwordCommentAlert }}</span> <span v-if="passwordCommentAlert" class="invalid-feedback d-block text-start">{{ passwordCommentAlert }}</span>
</div> </div>
<p>authorId:{{ comment.authorId }}</p> <!-- <p>authorId:{{ comment.authorId }}</p>
<p>코멘트 비교: {{comment.isCommentAuthor}}</p> <p>코멘트 비교: {{comment.isCommentAuthor}}</p> -->
<div class="mt-6"> <div class="mt-6">
@ -47,7 +47,7 @@
</div> </div>
<PlusButton v-if="isPlusButton" @click="toggleComment" class="mt-6"/> <PlusButton v-if="isPlusButton" @click="toggleComment" class="mt-6"/>
<BoardCommentArea v-if="isComment" @submitComment="submitComment"/> <BoardCommentArea v-if="isComment" :unknown="unknown" @submitComment="submitComment"/>
<!-- 대댓글 --> <!-- 대댓글 -->
<ul v-if="comment.children && comment.children.length" class="list-unstyled"> <ul v-if="comment.children && comment.children.length" class="list-unstyled">
@ -56,11 +56,20 @@
:key="child.commentId" :key="child.commentId"
class="mt-8 pt-6 ps-10 border-top" class="mt-8 pt-6 ps-10 border-top"
> >
<!-- <p>대댓글 데이터(JSON): {{ JSON.stringify(child, null, 2) }}</p> -->
<!-- <p>comment child: {{ comment.children }}</p> -->
<!-- :unknown="child.author === '익명'" -->
<BoardComment <BoardComment
:comment="child" :comment="child"
:unknown="unknown" :unknown="child.author === '익명'"
:isPlusButton="false" :isPlusButton="false"
:isLike="true" :isLike="true"
:isCommentProfile="true"
:isCommentAuthor="child.isCommentAuthor"
@editClick="$emit('editClick', $event)"
@deleteClick="$emit('deleteClick', child)"
@submitEdit="(comment, editedContent) => $emit('submitEdit', comment, editedContent)"
@cancelEdit="$emit('cancelEdit', child)"
@submitComment="submitComment" @submitComment="submitComment"
@updateReaction="handleUpdateReaction" @updateReaction="handleUpdateReaction"
/> />
@ -155,4 +164,8 @@ const submitEdit = () => {
emit('submitEdit', props.comment, localEditedContent.value); emit('submitEdit', props.comment, localEditedContent.value);
}; };
const aaaa = () => {
emit('editClick', props.comment);
}
</script> </script>

View File

@ -17,6 +17,7 @@
rows="3" rows="3"
v-model="comment" v-model="comment"
></textarea> ></textarea>
<span v-if="commentAlert" class="invalid-feedback d-block text-start ms-2">{{ commentAlert }}</span>
</div> </div>
</div> </div>
@ -42,6 +43,7 @@
id="basic-default-password" id="basic-default-password"
class="form-control flex-grow-1" class="form-control flex-grow-1"
v-model="password" v-model="password"
placeholder="비밀번호 입력"
/> />
<span v-if="passwordAlert" class="invalid-feedback d-block text-start ms-2">{{ passwordAlert }}</span> <span v-if="passwordAlert" class="invalid-feedback d-block text-start ms-2">{{ passwordAlert }}</span>
</div> </div>
@ -74,28 +76,35 @@ const props = defineProps({
passwordAlert: { passwordAlert: {
type: String, type: String,
default: false default: false
},
commentAlert: {
type: String,
default: false
} }
}); });
const comment = ref(''); const comment = ref('');
const password = ref(''); const password = ref('');
const isCheck = ref(false); const isCheck = ref(props.unknown);
const emit = defineEmits(['submitComment']);
const emit = defineEmits(['submitComment']);
const LOCBRDTYP = isCheck.value ? '300102' : null;
function handleCommentSubmit() { function handleCommentSubmit() {
if (props.unknown && isCheck.value && !password.value) {
alert('익명 댓글을 작성하려면 비밀번호를 입력해야 합니다.');
return;
}
const LOCBRDTYP = isCheck.value ? '300102' : null;
emit('submitComment', { emit('submitComment', {
comment: comment.value, comment: comment.value,
password: isCheck.value ? password.value : '', password: isCheck.value ? password.value : '',
LOCBRDTYP, isCheck: isCheck.value,
LOCBRDTYP, // '300102'
isCheck: isCheck.value isCheck: isCheck.value
}); });
}
watch(() => props.passwordAlert, () => {
if (!props.passwordAlert) {
comment.value = ''; comment.value = '';
password.value = ''; password.value = '';
isCheck.value = false; // }
} });
</script> </script>

View File

@ -2,9 +2,32 @@
<div class="container-xxl flex-grow-1 container-p-y"> <div class="container-xxl flex-grow-1 container-p-y">
<div class="card app-calendar-wrapper"> <div class="card app-calendar-wrapper">
<div class="row g-0"> <div class="row g-0">
<div class="col app-calendar-sidebar border-end text-center" id="app-calendar-sidebar"> <div class="col-3 border-end text-center">
<div class="card-body pb-0"> <div class="card-body pb-0">
<img v-if="user" :src="`http://localhost:10325/upload/img/profile/${user.profile}`" alt="Profile Image" class="w-px-50 h-auto rounded-circle"/> <img v-if="user" :src="`${baseUrl}upload/img/profile/${user.profile}`" alt="Profile Image" class="w-px-50 h-auto rounded-circle" @error="$event.target.src = '/img/icons/icon.png'"/>
<p class="mt-2">
{{ user.name }}
</p>
<div class="row g-0">
<div class="col-6 pe-1">
<p>출근시간</p>
<button class="btn btn-outline-primary border-3 w-100 py-0">
<i class='bx bx-run fs-2'></i>
</button>
</div>
<div class="col-6 ps-1">
<p>퇴근시간</p>
<button class="btn btn-outline-secondary border-3 w-100 py-0">
<i class='bx bxs-door-open fs-2'></i>
</button>
</div>
<div v-for="post in project" :key="post.PROJCTSEQ" class="border border-2 mt-3" :style="`border-color: ${post.projctcolor} !important; color: ${post.projctcolor} !important;`">
{{ post.PROJCTNAM }}
</div>
</div>
</div> </div>
</div> </div>
@ -62,15 +85,16 @@ import { isEmpty } from '@/common/utils';
import FormInput from '../input/FormInput.vue'; import FormInput from '../input/FormInput.vue';
import 'flatpickr/dist/flatpickr.min.css'; import 'flatpickr/dist/flatpickr.min.css';
import '@/assets/css/app-calendar.css'; import '@/assets/css/app-calendar.css';
import { useThemeStore } from '@s/darkmode';
import { fetchHolidays } from '@c/calendar/holiday'; import { fetchHolidays } from '@c/calendar/holiday';
import { useUserInfoStore } from '@/stores/useUserInfoStore'; import { useUserInfoStore } from '@/stores/useUserInfoStore';
import { useProjectStore } from '@/stores/useProjectStore';
const user = ref(null); const baseUrl = $api.defaults.baseURL.replace(/api\/$/, '');
const user = ref({});
const project = ref({});
const userStore = useUserInfoStore(); const userStore = useUserInfoStore();
const projectStore = useProjectStore();
const themeStore = useThemeStore();
const dayjs = inject('dayjs'); const dayjs = inject('dayjs');
const fullCalendarRef = ref(null); const fullCalendarRef = ref(null);
const calendarEvents = ref([]); const calendarEvents = ref([]);
@ -85,118 +109,139 @@ const selectedDate = ref(null);
// //
const handleDateSelect = (selectedDates) => { const handleDateSelect = (selectedDates) => {
if (selectedDates.length > 0) { if (selectedDates.length > 0) {
// YYYY-MM-DD
const selectedDate = dayjs(selectedDates[0]).format('YYYY-MM-DD'); const selectedDate = dayjs(selectedDates[0]).format('YYYY-MM-DD');
eventDate.value = selectedDate; eventDate.value = selectedDate;
showModal(); showModal(); //
} }
}; };
// //
const fetchData = async () => { const fetchData = async () => {
// FullCalendar API
const calendarApi = fullCalendarRef.value?.getApi(); const calendarApi = fullCalendarRef.value?.getApi();
if (!calendarApi) return; if (!calendarApi) return;
// ,
const date = calendarApi.currentData.viewTitle; const date = calendarApi.currentData.viewTitle;
const dateArr = date.split(' '); const dateArr = date.split(' ');
let currentYear = dateArr[0].trim(); let currentYear = dateArr[0].trim();
let currentMonth = dateArr[1].trim(); let currentMonth = dateArr[1].trim();
const regex = /\D/g; const regex = /\D/g;
//
currentYear = parseInt(currentYear.replace(regex, ''), 10); currentYear = parseInt(currentYear.replace(regex, ''), 10);
currentMonth = parseInt(currentMonth.replace(regex, ''), 10); currentMonth = parseInt(currentMonth.replace(regex, ''), 10);
try { try {
//
const holidayEvents = await fetchHolidays(currentYear, String(currentMonth).padStart(2, '0')); const holidayEvents = await fetchHolidays(currentYear, String(currentMonth).padStart(2, '0'));
//
const existingEvents = calendarEvents.value.filter(event => !event.classNames?.includes('holiday-event')); const existingEvents = calendarEvents.value.filter(event => !event.classNames?.includes('holiday-event'));
//
calendarEvents.value = [...existingEvents, ...holidayEvents]; calendarEvents.value = [...existingEvents, ...holidayEvents];
} catch (error) { } catch (error) {
console.error('공휴일 정보 로딩 실패:', error); console.error('공휴일 정보 로딩 실패:', error);
} }
}; };
// // (, , )
const moveCalendar = async (value = 0) => { const moveCalendar = async (value = 0) => {
const calendarApi = fullCalendarRef.value?.getApi(); const calendarApi = fullCalendarRef.value?.getApi();
if (value === 1) { if (value === 1) {
calendarApi.prev(); calendarApi.prev(); //
} else if (value === 2) { } else if (value === 2) {
calendarApi.next(); calendarApi.next(); //
} else if (value === 3) { } else if (value === 3) {
calendarApi.today(); calendarApi.today(); //
} }
//
await fetchData(); await fetchData();
}; };
//
const showModal = () => { const showModal = () => {
isModalVisible.value = true; isModalVisible.value = true;
}; };
//
const closeModal = () => { const closeModal = () => {
isModalVisible.value = false; isModalVisible.value = false;
//
eventTitle.value = ''; eventTitle.value = '';
eventDate.value = ''; eventDate.value = '';
}; };
//
const addEvent = () => { const addEvent = () => {
//
if (!checkEvent()) { if (!checkEvent()) {
//
calendarEvents.value.push({ calendarEvents.value.push({
title: eventTitle.value, title: eventTitle.value,
start: eventDate.value, start: eventDate.value,
backgroundColor: '#4CAF50' // backgroundColor: '#4CAF50' //
}); });
closeModal(); closeModal(); //
} }
}; };
//
const checkEvent = () => { const checkEvent = () => {
//
eventAlert.value = isEmpty(eventTitle.value); eventAlert.value = isEmpty(eventTitle.value);
eventDateAlert.value = isEmpty(eventDate.value); eventDateAlert.value = isEmpty(eventDate.value);
// true ( )
return eventAlert.value || eventDateAlert.value; return eventAlert.value || eventDateAlert.value;
}; };
//
const calendarOptions = reactive({ const calendarOptions = reactive({
plugins: [dayGridPlugin, interactionPlugin], plugins: [dayGridPlugin, interactionPlugin], //
initialView: 'dayGridMonth', initialView: 'dayGridMonth', // ()
headerToolbar: { headerToolbar: { //
left: 'today', left: 'today', // :
center: 'title', center: 'title', // : ()
right: 'prev,next', right: 'prev,next', // : /
}, },
locale: 'kr', locale: 'kr', //
events: calendarEvents, events: calendarEvents, //
eventOrder: 'sortIdx', eventOrder: 'sortIdx', //
selectable: true, selectable: true, //
dateClick: handleDateSelect, dateClick: handleDateSelect, //
droppable: false, droppable: false, //
eventDisplay: 'block', eventDisplay: 'block', //
//
customButtons: { customButtons: {
prev: { prev: {
text: 'PREV', text: 'PREV', //
click: () => moveCalendar(1), click: () => moveCalendar(1), //
}, },
today: { today: {
text: 'TODAY', text: 'TODAY', //
click: () => moveCalendar(3), click: () => moveCalendar(3), //
}, },
next: { next: {
text: 'NEXT', text: 'NEXT', //
click: () => moveCalendar(2), click: () => moveCalendar(2), //
}, },
}, },
}); });
// // ( )
watch(() => fullCalendarRef.value?.getApi().currentData.viewTitle, async () => { watch(() => fullCalendarRef.value?.getApi().currentData.viewTitle, async () => {
await fetchData(); await fetchData();
}); });
console.log(project)
onMounted(async () => { onMounted(async () => {
await fetchData(); await fetchData();
await userStore.userInfo(); await userStore.userInfo();
user.value = userStore.user; user.value = userStore.user;
await projectStore.getProjectList();
project.value = projectStore.projectList;
}); });
</script> </script>

View File

@ -7,11 +7,11 @@
<!-- 프로젝트 목록 --> <!-- 프로젝트 목록 -->
<div class="mt-4"> <div class="mt-4">
<div v-if="projectList.length === 0" class="text-center"> <div v-if="projectStore.projectList.length === 0" class="text-center">
<p class="text-muted mt-4">등록된 프로젝트가 없습니다.</p> <p class="text-muted mt-4">등록된 프로젝트가 없습니다.</p>
</div> </div>
<div v-for="post in projectList" :key="post.PROJCTSEQ" @click="openEditModal(post)" class="cursor-pointer"> <div v-for="post in projectStore.projectList" :key="post.PROJCTSEQ" @click="openEditModal(post)" class="cursor-pointer">
<ProjectCard <ProjectCard
:title="post.PROJCTNAM" :title="post.PROJCTNAM"
:description="post.PROJCTDES" :description="post.PROJCTDES"
@ -161,6 +161,7 @@ import ArrInput from '@c/input/ArrInput.vue';
import commonApi from '@/common/commonApi'; import commonApi from '@/common/commonApi';
import { useToastStore } from '@s/toastStore'; import { useToastStore } from '@s/toastStore';
import { useUserInfoStore } from '@/stores/useUserInfoStore'; import { useUserInfoStore } from '@/stores/useUserInfoStore';
import { useProjectStore } from '@/stores/useProjectStore';
import $api from '@api'; import $api from '@api';
import SaveButton from '@c/button/SaveBtn.vue'; import SaveButton from '@c/button/SaveBtn.vue';
import BackButton from '@c/button/BackBtn.vue' import BackButton from '@c/button/BackBtn.vue'
@ -169,10 +170,10 @@ const dayjs = inject('dayjs');
const today = dayjs().format('YYYY-MM-DD'); const today = dayjs().format('YYYY-MM-DD');
const toastStore = useToastStore(); const toastStore = useToastStore();
const userStore = useUserInfoStore(); const userStore = useUserInfoStore();
const projectStore = useProjectStore();
// //
const user = ref(null); const user = ref(null);
const projectList = ref([]);
const selectedCategory = ref(null); const selectedCategory = ref(null);
const searchText = ref(''); const searchText = ref('');
@ -212,17 +213,6 @@ const { yearCategory, colorList } = commonApi({
loadYearCategory: true, loadYearCategory: true,
}); });
//
const getProjectList = async () => {
const res = await $api.get('project/select', {
params: {
searchKeyword : searchText.value,
category : selectedYear.value,
},
});
projectList.value = res.data.data.projectList;
};
// //
const search = async (searchKeyword) => { const search = async (searchKeyword) => {
searchText.value = searchKeyword.trim(); searchText.value = searchKeyword.trim();
@ -237,6 +227,10 @@ const selectedYear = computed(() => {
return yearCategory.value.find(item => item.value === selectedCategory.value)?.label || null; return yearCategory.value.find(item => item.value === selectedCategory.value)?.label || null;
}); });
//
const getProjectList = async () => {
await projectStore.getProjectList(searchText.value, selectedYear.value);
};
// //
watch(selectedCategory, async () => { watch(selectedCategory, async () => {
@ -250,6 +244,20 @@ const openCreateModal = () => {
const closeCreateModal = () => { const closeCreateModal = () => {
isCreateModalOpen.value = false; isCreateModalOpen.value = false;
resetCreateForm();
};
const resetCreateForm = () => {
name.value = '';
color.value = '';
address.value = '';
detailAddress.value = '';
postcode.value = '';
startDay.value = today;
endDay.value = '';
description.value = '';
nameAlert.value = false;
addressAlert.value = false;
}; };
// :: // ::
@ -283,7 +291,7 @@ const handleCreate = async () => {
if (res.status === 200) { if (res.status === 200) {
toastStore.onToast('프로젝트가 등록되었습니다.', 's'); toastStore.onToast('프로젝트가 등록되었습니다.', 's');
closeCreateModal(); closeCreateModal();
location.reload(); getProjectList();
} }
}); });
}; };
@ -307,7 +315,7 @@ const allColors = computed(() => {
// //
const hasChanges = computed(() => { const hasChanges = computed(() => {
const original = projectList.value.find(p => p.PROJCTSEQ === selectedProject.value.PROJCTSEQ); const original = projectStore.projectList.find(p => p.PROJCTSEQ === selectedProject.value.PROJCTSEQ);
if (!original) return false; if (!original) return false;
return ( return (

View File

@ -32,7 +32,7 @@
<script setup> <script setup>
import $api from '@api'; import $api from '@api';
import router from '@/router'; import router from '@/router';
import { ref } from 'vue'; import { nextTick, ref } from 'vue';
import UserFormInput from '@c/input/UserFormInput.vue'; import UserFormInput from '@c/input/UserFormInput.vue';
import { useUserInfoStore } from '@/stores/useUserInfoStore'; import { useUserInfoStore } from '@/stores/useUserInfoStore';
@ -70,10 +70,11 @@
password: password.value, password: password.value,
remember: remember.value, remember: remember.value,
}, { headers: { isLogin: true } }) }, { headers: { isLogin: true } })
.then(res => { .then(async res => {
if (res.status === 200) { if (res.status === 200) {
userStore.userInfo(); userStore.userInfo();
router.push('/'); await nextTick();
router.push('/')
} }
}).catch(error => { }).catch(error => {
if (error.response) { if (error.response) {

View File

@ -0,0 +1,30 @@
/*
작성자 : 박지윤
작성일 : 2025-02-25
수정자 :
수정일 :
설명 : 프로젝트 목록
*/
import { defineStore } from 'pinia';
import { ref } from 'vue';
import $api from '@api';
export const useProjectStore = defineStore('project', () => {
const projectList = ref([]);
const getProjectList = async (searchText, selectedYear) => {
try {
const res = await $api.get('project/select', {
params: {
searchKeyword: searchText,
category: selectedYear,
},
});
projectList.value = res.data.data.projectList;
} catch (error) {
console.error('프로젝트 목록 조회 실패:', error);
}
};
return { projectList, getProjectList };
});

View File

@ -140,7 +140,6 @@ import { ref, onMounted, computed } from 'vue';
import { useRoute, useRouter } from 'vue-router'; import { useRoute, useRouter } from 'vue-router';
import { useUserInfoStore } from '@/stores/useUserInfoStore'; import { useUserInfoStore } from '@/stores/useUserInfoStore';
import axios from '@api'; import axios from '@api';
import { formattedDate } from '@/common/formattedDate.js';
// //
const profileName = ref(''); const profileName = ref('');
@ -376,63 +375,77 @@ const fetchComments = async (page = 1) => {
}; };
// //
const handleCommentSubmit = async (data) => { const handleCommentSubmit = async (data, isCheck) => {
if (!data) {
console.error("handleCommentSubmit: data가 undefined입니다.");
return;
}
const { comment, password } = data; const { comment, password } = data;
const LOCBRDTYP = data.LOCBRDTYP || null; // undefined const LOCBRDTYP = data.LOCBRDTYP || null;
if (!comment || comment.trim() === "") {
commentAlert.value = '댓글을 입력해주세요.';
return;
} else {
commentAlert.value = '';
}
if (unknown.value && isCheck && (!password || password.trim() === "")) {
passwordAlert.value = "비밀번호를 입력해야 합니다.";
return;
}
try { try {
const response = await axios.post(`board/${currentBoardId.value}/comment`, { const response = await axios.post(`board/${currentBoardId.value}/comment`, {
LOCBRDSEQ: currentBoardId.value, LOCBRDSEQ: currentBoardId.value,
LOCCMTRPY: comment, LOCCMTRPY: comment,
LOCCMTPWD: password, LOCCMTPWD: isCheck ? password : '',
LOCCMTPNT: 1, LOCCMTPNT: 1,
LOCBRDTYP // LOCBRDTYP
}); });
if (response.status === 200) { if (response.status === 200) {
console.log('댓글 작성 성공:', response.data.message); console.log('댓글 작성 성공:', response.data.message);
passwordAlert.value = '';
commentAlert.value = '';
await fetchComments(); await fetchComments();
} else { } else {
console.log('댓글 작성 실패:', response.data.message); console.error('댓글 작성 실패:', response.data.message);
} }
} catch (error) { } catch (error) {
console.log('댓글 작성 중 오류 발생:', error); console.error('댓글 작성 중 오류 발생:', error);
} }
}; };
// ( `BoardCommentList` ) // ( `BoardCommentList` )
const handleCommentReply = async (reply) => { const handleCommentReply = async (reply) => {
try { try {
// ( LOCBRDTYP 300102 ) const response = await axios.post(`board/${currentBoardId.value}/comment`, {
const requestBody = {
LOCBRDSEQ: currentBoardId.value, LOCBRDSEQ: currentBoardId.value,
LOCCMTRPY: reply.comment, LOCCMTRPY: reply.comment,
LOCCMTPWD: reply.password || null, LOCCMTPWD: reply.password || null,
LOCCMTPNT: reply.parentId, LOCCMTPNT: reply.parentId,
LOCBRDTYP: reply.isCheck ? "300102" : null LOCBRDTYP: reply.isCheck ? "300102" : null
}; });
console.log(requestBody)
const response = await axios.post(`board/${currentBoardId.value}/comment`, requestBody);
if (response.status === 200) { if (response.status === 200) {
if (response.data.code === 200) { if (response.data.code === 200) { //
console.log('대댓글 작성 성공:', response.data); console.log('대댓글 작성 성공:', response.data);
await fetchComments(); await fetchComments(); //
} else { } else {
console.log('대댓글 작성 실패 - 서버 응답:', response.data); console.log('대댓글 작성 실패 - 서버 응답:', response.data);
alert('대댓글 작성에 실패했습니다.'); alert('대댓글 작성에 실패했습니다.');
} }
} }
} catch (error) { } catch (error) {
console.error('🚨 대댓글 작성 중 오류 발생:', error); console.error('대댓글 작성 중 오류 발생:', error);
if (error.response) { if (error.response) {
console.error('📌 서버 응답 에러:', error.response.data); console.error('서버 응답 에러:', error.response.data);
} }
alert('대댓글 작성 중 오류가 발생했습니다.'); alert('대댓글 작성 중 오류가 발생했습니다.');
} }
}; }
// //
const editClick = (unknown) => { const editClick = (unknown) => {
@ -484,6 +497,7 @@ const editComment = (comment) => {
// //
if (unknown.value) { if (unknown.value) {
console.log('익명 코멘트인가?')
toggleCommentPassword(comment, "edit"); toggleCommentPassword(comment, "edit");
} }
} }
@ -736,6 +750,14 @@ const handleCommentDeleted = (deletedCommentId) => {
console.error("❌ 삭제할 댓글을 찾을 수 없음:", deletedCommentId); console.error("❌ 삭제할 댓글을 찾을 수 없음:", deletedCommentId);
}; };
//
const formattedDate = (dateString) => {
if (!dateString) return "날짜 없음";
const dateObj = new Date(dateString);
return `${dateObj.getFullYear()}-${String(dateObj.getMonth() + 1).padStart(2, '0')}-${String(dateObj.getDate()).padStart(2, '0')} ${String(dateObj.getHours()).padStart(2, '0')}:${String(dateObj.getMinutes()).padStart(2, '0')}`;
};
const formattedBoardDate = computed(() => formattedDate(date.value)); const formattedBoardDate = computed(() => formattedDate(date.value));
// //

View File

@ -1,9 +1,7 @@
<template> <template>
<Calendar /> <CommuteCalendar />
</template> </template>
<script setup> <script setup>
import Calendar from '@c/commuters/Calendar.vue'; import CommuteCalendar from '@c/commuters/CommuteCalendar.vue';
</script> </script>