vacation 수정, 게시판 글쓰기 수정

This commit is contained in:
dyhj625 2025-02-27 13:05:10 +09:00
parent bb1715c71b
commit 80e59e4355
5 changed files with 68 additions and 21 deletions

View File

@ -67,6 +67,25 @@ opacity: 0.6; /* 흐려 보이게 */
cursor: not-allowed !important; cursor: not-allowed !important;
opacity: 0.6; /* 흐려 보이게 */ opacity: 0.6; /* 흐려 보이게 */
} }
/* 기본 이벤트 스타일 */
.fc-daygrid-event {
border: none !important;
border-radius: 4px;
}
/* 오전 반차 (왼쪽 절반) */
.selected-event.half-day-am {
width: 50% !important;
left: 0 !important;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
}
/* 오후 반차 (오른쪽 절반) */
.selected-event.half-day-pm {
width: 50% !important;
margin-left: auto !important;
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
}
/* 본인 모달 */ /* 본인 모달 */

View File

@ -1,6 +1,6 @@
<template> <template>
<div class="menu gap-4 justify-content-center mt-5"> <div class="menu gap-4 justify-content-center mt-5">
<!-- 오전 반차 버튼 -->
<button <button
class="btn btn-warning" class="btn btn-warning"
:class="{ active: halfDayType === 'AM' }" :class="{ active: halfDayType === 'AM' }"
@ -8,6 +8,8 @@
> >
<i class="bi bi-sun"></i> <i class="bi bi-sun"></i>
</button> </button>
<!-- 오후 반차 버튼 -->
<button <button
class="btn btn-info" class="btn btn-info"
:class="{ active: halfDayType === 'PM' }" :class="{ active: halfDayType === 'PM' }"
@ -15,32 +17,48 @@
> >
<i class="bi bi-moon"></i> <i class="bi bi-moon"></i>
</button> </button>
<!-- 저장 버튼 -->
<div class="save-button-container"> <div class="save-button-container">
<button class="btn btn-success" @click="addVacationRequests" :disabled="isDisabled"> <button class="btn btn-success" @click="addVacationRequests" :disabled="isDisabled">
</button> </button>
</div> </div>
</div> </div>
</template> </template>
<script setup> <script setup>
import { defineEmits, ref } from "vue"; import { defineEmits, ref, defineProps } from "vue";
defineProps({ const props = defineProps({
isDisabled: Boolean isDisabled: Boolean
}); });
const emit = defineEmits(["toggleHalfDay", "addVacationRequests"]); const emit = defineEmits(["toggleHalfDay", "addVacationRequests", "resetHalfDay"]);
const halfDayType = ref(null); const halfDayType = ref(null);
const toggleHalfDay = (type) => { const toggleHalfDay = (type) => {
halfDayType.value = halfDayType.value === type ? null : type; halfDayType.value = type;
emit("toggleHalfDay", halfDayType.value); emit("toggleHalfDay", halfDayType.value);
// 1
setTimeout(() => {
halfDayType.value = null;
}, 1000);
};
//
const resetHalfDay = () => {
halfDayType.value = null;
emit("resetHalfDay");
}; };
const addVacationRequests = () => { const addVacationRequests = () => {
emit("addVacationRequests"); emit("addVacationRequests");
}; };
defineExpose({ resetHalfDay });
</script> </script>
<style scoped> <style scoped>
@ -112,4 +130,4 @@ const addVacationRequests = () => {
transform: scale(0.95); transform: scale(0.95);
box-shadow: 0px 2px 5px rgba(25, 135, 84, 0.2); box-shadow: 0px 2px 5px rgba(25, 135, 84, 0.2);
} }
</style> </style>

View File

@ -25,7 +25,9 @@
<script setup> <script setup>
import { ref, defineProps, defineEmits, watch, onMounted } from "vue"; import { ref, defineProps, defineEmits, watch, onMounted } from "vue";
import axios from "@api"; import axios from "@api";
import { useToastStore } from '@s/toastStore';
const toastStore = useToastStore();
const props = defineProps({ const props = defineProps({
isOpen: Boolean, isOpen: Boolean,
targetUser: Object, targetUser: Object,
@ -73,21 +75,18 @@
count: grantCount.value, count: grantCount.value,
}, },
]; ];
console.log(props.targetUser)
console.log(payload)
const response = await axios.post("vacation", payload); const response = await axios.post("vacation", payload);
console.log(response)
if (response.data && response.data.status === "OK") { if (response.data && response.data.status === "OK") {
alert("✅ 연차가 부여되었습니다."); toastStore.onToast('연차가 선물되었습니다.', 's');
await fetchSentVacationCount(); await fetchSentVacationCount();
emit("updateVacation"); emit("updateVacation");
closeModal(); closeModal();
} else { } else {
alert("🚨 연차 추가 중 오류가 발생했습니다."); toastStore.onToast(' 연차 선물 중 오류가 발생했습니다.', 'e');
} }
} catch (error) { } catch (error) {
console.error("🚨 연차 추가 실패:", error); console.error("🚨 연차 추가 실패:", error);
alert("연차 추가에 실패했습니다."); toastStore.onToast(' 연차 선물 실패!!.', 'e');
} }
}; };
@ -99,7 +98,6 @@
() => props.isOpen, () => props.isOpen,
async (newVal) => { async (newVal) => {
if (newVal && props.targetUser && props.targetUser.MEMBERSEQ) { if (newVal && props.targetUser && props.targetUser.MEMBERSEQ) {
console.log("🟢 모달이 열렸습니다. 데이터를 로드합니다.");
await fetchSentVacationCount(); await fetchSentVacationCount();
} }
} }

View File

@ -91,7 +91,9 @@ import router from '@/router';
import axios from '@api'; import axios 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'
import { useToastStore } from '@s/toastStore';
const toastStore = useToastStore();
const categoryList = ref([]); const categoryList = ref([]);
const title = ref(''); const title = ref('');
const password = ref(''); const password = ref('');
@ -113,6 +115,11 @@ const fetchCategories = async () => {
try { try {
const response = await axios.get('board/categories'); const response = await axios.get('board/categories');
categoryList.value = response.data.data; categoryList.value = response.data.data;
// "" (CMNCODNAM '' )
const freeCategory = categoryList.value.find(category => category.CMNCODNAM === '자유');
if (freeCategory) {
categoryValue.value = freeCategory.CMNCODVAL; //
}
} catch (error) { } catch (error) {
console.error('카테고리 불러오기 오류:', error); console.error('카테고리 불러오기 오류:', error);
} }
@ -167,11 +174,11 @@ const write = async () => {
} }
} }
alert('게시물이 작성되었습니다.'); toastStore.onToast('게시물이 작성되었습니다.', 's');
goList(); goList();
} catch (error) { } catch (error) {
console.error(error); console.error(error);
alert('게시물 작성 중 오류가 발생했습니다.'); toastStore.onToast('게시물 작성 중 오류가 발생했습니다.', 'e');
} }
}; };
</script> </script>

View File

@ -79,7 +79,9 @@
import { useUserStore } from "@s/userList"; import { useUserStore } from "@s/userList";
import { useUserInfoStore } from "@s/useUserInfoStore"; import { useUserInfoStore } from "@s/useUserInfoStore";
import { fetchHolidays } from "@c/calendar/holiday.js"; import { fetchHolidays } from "@c/calendar/holiday.js";
import { useToastStore } from '@s/toastStore';
const toastStore = useToastStore();
const userStore = useUserInfoStore(); const userStore = useUserInfoStore();
const userListStore = useUserStore(); const userListStore = useUserStore();
const userList = ref([]); const userList = ref([]);
@ -102,6 +104,7 @@
const vacationCodeMap = ref({}); const vacationCodeMap = ref({});
const holidayDates = ref(new Set()); const holidayDates = ref(new Set());
const fetchedEvents = ref([]); const fetchedEvents = ref([]);
const halfDayButtonsRef = ref(null);
// ref // ref
const calendarDatepicker = ref(null); const calendarDatepicker = ref(null);
@ -163,6 +166,10 @@ function handleDateClick(info) {
selectedDates.value.set(clickedDateStr, type); selectedDates.value.set(clickedDateStr, type);
halfDayType.value = null; halfDayType.value = null;
updateCalendarEvents(); updateCalendarEvents();
//
if (halfDayButtonsRef.value) {
halfDayButtonsRef.value.resetHalfDay();
}
} }
const calendarOptions = reactive({ const calendarOptions = reactive({
@ -342,7 +349,6 @@ function handleDateClick(info) {
const selectedEvents = Array.from(selectedDates.value) const selectedEvents = Array.from(selectedDates.value)
.filter(([date, type]) => type !== "delete") .filter(([date, type]) => type !== "delete")
.map(([date, type]) => ({ .map(([date, type]) => ({
title: getVacationType(type),
start: date, start: date,
backgroundColor: "rgb(113 212 243 / 76%)", backgroundColor: "rgb(113 212 243 / 76%)",
textColor: "#fff", textColor: "#fff",
@ -435,7 +441,7 @@ function handleDateClick(info) {
delete: vacationsToDelete delete: vacationsToDelete
}); });
if (response.data && response.data.status === "OK") { if (response.data && response.data.status === "OK") {
alert("✅ 휴가 변경 사항이 저장되었습니다."); toastStore.onToast('휴가 변경 사항이 저장되었습니다.', 's');
await fetchRemainingVacation(); await fetchRemainingVacation();
if (isModalOpen.value) { if (isModalOpen.value) {
await fetchVacationHistory(lastRemainingYear.value); await fetchVacationHistory(lastRemainingYear.value);
@ -445,11 +451,11 @@ function handleDateClick(info) {
selectedDates.value.clear(); selectedDates.value.clear();
updateCalendarEvents(); updateCalendarEvents();
} else { } else {
alert("❌ 휴가 저장 중 오류가 발생했습니다."); toastStore.onToast('휴가 저장 중 오류가 발생했습니다.', 'e');
} }
} catch (error) { } catch (error) {
console.error("🚨 휴가 변경 저장 실패:", error); console.error("🚨 휴가 변경 저장 실패:", error);
alert("❌ 휴가 저장 요청에 실패했습니다."); toastStore.onToast('휴가 저장 요청에 실패했습니다.', 'e');
} }
} }
@ -531,5 +537,4 @@ watch([holidayDates, lastRemainingYear, lastRemainingMonth], () => {
<style> <style>
</style> </style>