127 lines
3.7 KiB
Vue
127 lines
3.7 KiB
Vue
<template>
|
|
<div v-if="isOpen" class="modal-dialog" @click.self="closeModal">
|
|
<div class="modal-content p-5">
|
|
<h5 class="modal-title">To. {{ targetUser.MEMBERNAM }} 🎁</h5>
|
|
<button class="close-btn" @click="closeModal">✖</button>
|
|
|
|
<div class="modal-body">
|
|
<p>선물할 연차 개수를 선택하세요.</p>
|
|
|
|
<div class="justify-content-center d-sm-flex gap-sm-3 align-items-md-center mt-8">
|
|
<button @click="decreaseCount" :disabled="grantCount < 2" class="count-btn">-</button>
|
|
<span class="text-dark fw-bold fs-4">{{ grantCount }}</span>
|
|
<button @click="increaseCount" :disabled="grantCount >= availableQuota" class="count-btn">+</button>
|
|
</div>
|
|
<div class="custom-button-container">
|
|
<button class="custom-button" @click="saveVacationGrant" :disabled="grantCount === 0">
|
|
<i class="bx bx-gift"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, defineProps, defineEmits, watch, onMounted } from "vue";
|
|
import axios from "@api";
|
|
import { useToastStore } from '@s/toastStore';
|
|
|
|
const toastStore = useToastStore();
|
|
const props = defineProps({
|
|
isOpen: Boolean,
|
|
targetUser: Object,
|
|
});
|
|
|
|
const emit = defineEmits(["close", "updateVacation"]);
|
|
const grantCount = ref(0);
|
|
const maxQuota = 2;
|
|
const sentCount = ref(0);
|
|
const availableQuota = ref(2);
|
|
|
|
const fetchSentVacationCount = async () => {
|
|
try {
|
|
const payload = { receiverId: props.targetUser.MEMBERSEQ };
|
|
const response = await axios.get("vacation/sent", { params: payload });
|
|
sentCount.value = response.data.data[0].count || 0;
|
|
availableQuota.value = Math.max(maxQuota - sentCount.value, 0);
|
|
grantCount.value = availableQuota.value; // ✅ 남은 개수로 기본값 설정
|
|
} catch (error) {
|
|
console.error("🚨 연차 전송 기록 조회 실패:", error);
|
|
availableQuota.value = maxQuota;
|
|
grantCount.value = maxQuota; // 기본값 설정
|
|
}
|
|
};
|
|
|
|
const increaseCount = () => {
|
|
if (grantCount.value < availableQuota.value) {
|
|
grantCount.value++;
|
|
}
|
|
};
|
|
|
|
const decreaseCount = () => {
|
|
if (grantCount.value > 0) {
|
|
grantCount.value--;
|
|
}
|
|
};
|
|
|
|
const saveVacationGrant = async () => {
|
|
try {
|
|
const payload = [
|
|
{
|
|
date: new Date().toISOString().split("T")[0],
|
|
type: "700103",
|
|
receiverId: props.targetUser.MEMBERSEQ,
|
|
count: grantCount.value,
|
|
},
|
|
];
|
|
const response = await axios.post("vacation", payload);
|
|
if (response.data && response.data.status === "OK") {
|
|
toastStore.onToast('연차가 선물되었습니다.', 's');
|
|
await fetchSentVacationCount();
|
|
emit("updateVacation");
|
|
closeModal();
|
|
} else {
|
|
toastStore.onToast(' 연차 선물 중 오류가 발생했습니다.', 'e');
|
|
}
|
|
} catch (error) {
|
|
console.error("🚨 연차 추가 실패:", error);
|
|
toastStore.onToast(' 연차 선물 실패!!.', 'e');
|
|
}
|
|
};
|
|
|
|
const closeModal = () => {
|
|
emit("close");
|
|
};
|
|
|
|
watch(
|
|
() => props.isOpen,
|
|
async (newVal) => {
|
|
if (newVal && props.targetUser && props.targetUser.MEMBERSEQ) {
|
|
await fetchSentVacationCount();
|
|
}
|
|
}
|
|
);
|
|
|
|
watch(
|
|
() => props.targetUser,
|
|
async (newUser) => {
|
|
if (newUser && newUser.MEMBERSEQ) {
|
|
await fetchSentVacationCount();
|
|
}
|
|
},
|
|
{ deep: true }
|
|
);
|
|
|
|
onMounted(async () => {
|
|
if (props.isOpen && props.targetUser && props.targetUser.MEMBERSEQ) {
|
|
await fetchSentVacationCount();
|
|
}
|
|
});
|
|
</script>
|
|
|
|
|
|
<style scoped>
|
|
|
|
</style>
|