From 34bef477f9c28796cd1cc675bab402b40f4e98e5 Mon Sep 17 00:00:00 2001 From: dyhj625 Date: Fri, 14 Mar 2025 16:14:10 +0900 Subject: [PATCH 1/6] =?UTF-8?q?=E3=84=B1=E3=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/board/BoardList.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/board/BoardList.vue b/src/views/board/BoardList.vue index c42c657..6a68b4c 100644 --- a/src/views/board/BoardList.vue +++ b/src/views/board/BoardList.vue @@ -231,7 +231,7 @@ const fetchGeneralPosts = async (page = 1) => { // 공지사항 데이터 로드 const fetchNoticePosts = async () => { try { - const { data } = await axios.get("board/notices", { + const { data } = await axios.get("board/notices2", { params: { searchKeyword: searchText.value } }); From 985351c8f0adc3fb9e6ef2d6d42bc50e46d0d34d Mon Sep 17 00:00:00 2001 From: nevermoregb Date: Sat, 15 Mar 2025 00:56:52 +0900 Subject: [PATCH 2/6] =?UTF-8?q?=EC=98=A4=EB=A5=98=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20noLayout=20=EC=84=A4=EC=A0=95=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/router/index.js | 57 +++++++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/src/router/index.js b/src/router/index.js index e5a575d..20e3067 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -1,4 +1,4 @@ -import { createRouter, createWebHistory } from 'vue-router' +import { createRouter, createWebHistory } from 'vue-router'; import { useAuthStore } from '@s/useAuthStore'; import { useUserInfoStore } from '@s/useUserInfoStore'; @@ -6,7 +6,7 @@ import { useUserInfoStore } from '@s/useUserInfoStore'; const routes = [ { path: '/', - name: "Home", + name: 'Home', component: () => import('@v/MainView.vue'), // meta: { requiresAuth: true } }, @@ -17,23 +17,23 @@ const routes = [ { path: '', name: 'BoardList', - component: () => import('@v/board/BoardList.vue') + component: () => import('@v/board/BoardList.vue'), }, { path: 'write', - component: () => import('@v/board/BoardWrite.vue') + component: () => import('@v/board/BoardWrite.vue'), }, { path: ':id', name: 'BoardDetail', - component: () => import('@v/board/BoardView.vue') + component: () => import('@v/board/BoardView.vue'), }, { path: 'edit/:id', name: 'BoardEdit', - component: () => import('@v/board/BoardEdit.vue') - } - ] + component: () => import('@v/board/BoardEdit.vue'), + }, + ], }, { path: '/wordDict', @@ -67,14 +67,13 @@ const routes = [ children: [ { path: '', - component: () => import('@v/voteboard/voteBoardList.vue') + component: () => import('@v/voteboard/voteBoardList.vue'), }, { path: 'write', - component: () => import('@v/voteboard/voteboardWrite.vue') + component: () => import('@v/voteboard/voteboardWrite.vue'), }, - - ] + ], }, { path: '/projectlist', @@ -87,25 +86,37 @@ const routes = [ { path: '/authorization', component: () => import('@v/admin/TheAuthorization.vue'), - meta: { requiresAuth: true } + meta: { requiresAuth: true }, }, - { path: "/error/400", name: "Error400", component: () => import('@v/error/Error400.vue') }, - { path: "/error/500", name: "Error500", component: () => import('@v/error/Error500.vue') }, { - path: "/:anything(.*)", - name: "Error404", component: () => import('@v/error/Error404.vue') + path: '/error/400', + name: 'Error400', + component: () => import('@v/error/Error400.vue'), + meta: { layout: 'NoLayout' }, + }, + { + path: '/error/500', + name: 'Error500', + component: () => import('@v/error/Error500.vue'), + meta: { layout: 'NoLayout' }, + }, + { + path: '/:anything(.*)', + name: 'Error404', + component: () => import('@v/error/Error404.vue'), + meta: { layout: 'NoLayout' }, }, ]; const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), routes: routes, -}) +}); router.beforeEach(async (to, from, next) => { const authStore = useAuthStore(); await authStore.checkAuthStatus(); // 로그인 상태 확인 - const allowedUserId = 26; // 특정 ID (변경필요!!) + const allowedUserId = 26; // 특정 ID (변경필요!!) const userStore = useUserInfoStore(); const userId = userStore.user?.id ?? null; @@ -115,8 +126,8 @@ router.beforeEach(async (to, from, next) => { } // Authorization 페이지는 ID가 26이 아니면 접근 차단 - if (to.path === "/authorization" && userId !== allowedUserId) { - return next("/"); + if (to.path === '/authorization' && userId !== allowedUserId) { + return next('/'); } // 비로그인 사용자만 접근 가능한 페이지인데 로그인된 경우 → 홈으로 이동 @@ -142,7 +153,7 @@ axios.interceptors.response.use( } return Promise.reject(error); - } + }, ); -export default router +export default router; From 50d3b0d257827ae3c649d821f32fb1bb3914dbfd Mon Sep 17 00:00:00 2001 From: dyhj625 Date: Wed, 19 Mar 2025 17:51:28 +0900 Subject: [PATCH 3/6] =?UTF-8?q?=ED=9C=B4=EA=B0=80=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/css/custom.css | 24 +++++++- src/components/button/HalfDayButtons.vue | 73 ++++++++++++----------- src/views/vacation/VacationManagement.vue | 55 ++++++++++------- 3 files changed, 96 insertions(+), 56 deletions(-) diff --git a/public/css/custom.css b/public/css/custom.css index e57b64f..1e22a80 100644 --- a/public/css/custom.css +++ b/public/css/custom.css @@ -157,7 +157,7 @@ .fc-toolbar-title { cursor: pointer; } -/* 클릭 가능한 날짜 (오늘 + 미래) */ +/* 클릭 가능한 날짜 */ .fc-daygrid-day.clickable { cursor: pointer; transition: background-color 0.2s ease-in-out; @@ -362,6 +362,28 @@ background-color: #0b5ed7 !important; color: white; } +/* 풀 연차 버튼 스타일 */ +.vac-btn-primary { + color: #fff; + background-color: #28a745; /* 녹색 */ + border-color: #28a745; + box-shadow: 0 0.125rem 0.25rem 0 rgba(40, 167, 69, 0.4); + font-size: 28px; + transition: all 0.2s ease-in-out; +} +/* 풀 연차 버튼 활성화 스타일 */ +.vac-btn-primary.active { + background-color: #218838 !important; + color: #fff; + border: 3px solid #91d091 !important; + box-shadow: 0px 4px 15px rgba(0, 0, 0, 0.3); + transform: scale(1.1); +} +/* 풀 연차 버튼이 눌렸을 때 효과 */ +.vac-btn-primary:active { + transform: scale(0.9); + box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.2); +} /* 버튼 기본 */ .vac-btn-success { transition: all 0.2s ease-in-out; diff --git a/src/components/button/HalfDayButtons.vue b/src/components/button/HalfDayButtons.vue index b706a2a..90d48e8 100644 --- a/src/components/button/HalfDayButtons.vue +++ b/src/components/button/HalfDayButtons.vue @@ -1,67 +1,72 @@ - diff --git a/src/views/vacation/VacationManagement.vue b/src/views/vacation/VacationManagement.vue index 7cde896..ae16a4c 100644 --- a/src/views/vacation/VacationManagement.vue +++ b/src/views/vacation/VacationManagement.vue @@ -106,6 +106,7 @@ const isGrantModalOpen = ref(false); const fullCalendarRef = ref(null); const calendarEvents = ref([]); const selectedDates = ref(new Map()); + const halfDayType = ref(null); const vacationCodeMap = ref({}); const holidayDates = ref(new Set()); @@ -118,7 +119,6 @@ const lastRemainingMonth = ref(String(new Date().getMonth() + 1).padStart(2, "0" // 데이트피커 인풋 ref const calendarDatepicker = ref(null); let fpInstance = null; - /* 변경사항 여부 확인 */ const hasChanges = computed(() => { return ( @@ -173,40 +173,53 @@ function handleDateClick(info) { return; } - const isMyVacation = myVacations.value.some(vac => { - const vacDate = vac.date ? vac.date.substring(0, 10) : ""; - return vacDate === clickedDateStr && !vac.receiverId; - }); + // 기존 값 확인 + const currentValue = selectedDates.value.get(clickedDateStr); - if (isMyVacation) { - if (selectedDates.value.get(clickedDateStr) === "delete") { - selectedDates.value.delete(clickedDateStr); + const isMyVacation = myVacations.value.some(vac => vac.date.substring(0, 10) === clickedDateStr && !vac.receiverId); + + // 이미 활성화된 날짜를 한 번 더 클릭하면 비활성화 + if (currentValue && currentValue !== "delete") { + console.log("🛑 활성화된 날짜 비활성화:", clickedDateStr); + selectedDates.value.delete(clickedDateStr); + updateCalendarEvents(); + return; + } + + // 버튼을 누르지 않았을 때 - 삭제 모드 + if (!halfDayType.value) { + if (isMyVacation) { + if (currentValue === "delete") { + selectedDates.value.delete(clickedDateStr); + } else { + selectedDates.value.set(clickedDateStr, "delete"); + } } else { - selectedDates.value.set(clickedDateStr, "delete"); + selectedDates.value.set(clickedDateStr, "700103"); } updateCalendarEvents(); return; } - if (selectedDates.value.has(clickedDateStr)) { - selectedDates.value.delete(clickedDateStr); - updateCalendarEvents(); - return; + // 버튼을 눌렀을 때 - 기존 휴가 삭제 후 새로운 값 추가 + if (isMyVacation) { + console.log("🗑 기존 휴가 삭제 후 새로운 상태 추가:", clickedDateStr); + selectedDates.value.set(clickedDateStr, "delete"); } - const type = halfDayType.value - ? (halfDayType.value === "AM" ? "700101" : "700102") - : "700103"; + + const type = halfDayType.value === "AM" ? "700101" : + halfDayType.value === "PM" ? "700102" : + "700103"; // 풀연차 selectedDates.value.set(clickedDateStr, type); - if (halfDayType.value) { - halfDayType.value = null; - } - updateCalendarEvents(); - + // 버튼을 한 번 사용 후 자동 해제 (일회성) + halfDayType.value = null; if (halfDayButtonsRef.value) { halfDayButtonsRef.value.resetHalfDay(); } + + updateCalendarEvents(); } function markClickableDates() { From 4c010395812fb021422b008b763cde1948b7982d Mon Sep 17 00:00:00 2001 From: dyhj625 Date: Thu, 20 Mar 2025 09:47:55 +0900 Subject: [PATCH 4/6] Merge branch 'main' into vacation From 28067c7f02313b266f4b31e86a92e9c349a0fb20 Mon Sep 17 00:00:00 2001 From: dyhj625 Date: Thu, 20 Mar 2025 09:58:25 +0900 Subject: [PATCH 5/6] =?UTF-8?q?=ED=9C=B4=EA=B0=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/modal/VacationModal.vue | 8 ++++---- src/router/index.js | 2 +- src/views/admin/TheAuthorization.vue | 23 +++++++++++++---------- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/components/modal/VacationModal.vue b/src/components/modal/VacationModal.vue index b8f3439..1db1647 100644 --- a/src/components/modal/VacationModal.vue +++ b/src/components/modal/VacationModal.vue @@ -1,7 +1,7 @@