+
-
+
+
@@ -15,13 +17,25 @@
:options="calendarOptions"
defaultView="dayGridMonth"
class="flatpickr-calendar-only"
- >
-
+ />
+
-
-
+
+
@@ -36,12 +50,14 @@ import dayGridPlugin from '@fullcalendar/daygrid';
import interactionPlugin from '@fullcalendar/interaction';
import 'flatpickr/dist/flatpickr.min.css';
import '@/assets/css/app-calendar.css';
-import { reactive, ref } from 'vue';
+import { reactive, ref, onMounted } from 'vue';
+import axios from '@api'; // Axios 추가
const fullCalendarRef = ref(null);
const calendarEvents = ref([]);
-const selectedDates = ref([]);
-const halfDayType = ref(null); // 오전/오후 반차 선택
+const selectedDates = ref(new Map());
+const halfDayType = ref(null);
+const employeeId = ref(1);
const calendarOptions = reactive({
plugins: [dayGridPlugin, interactionPlugin],
@@ -56,49 +72,153 @@ const calendarOptions = reactive({
dateClick: handleDateClick,
});
+/**
+ * 날짜 클릭 이벤트
+ */
function handleDateClick(info) {
const date = info.dateStr;
const dayElement = info.dayEl;
- if (!selectedDates.value.includes(date)) {
- selectedDates.value.push(date);
- if (halfDayType.value === 'AM') {
+ if (!selectedDates.value.has(date)) {
+ const type = halfDayType.value ? (halfDayType.value === 'AM' ? 'D' : 'N') : 'F';
+ selectedDates.value.set(date, type);
+
+ if (type === 'D') {
dayElement.style.backgroundImage = 'linear-gradient(to bottom, #ade3ff 50%, transparent 50%)';
- } else if (halfDayType.value === 'PM') {
+ } else if (type === 'N') {
dayElement.style.backgroundImage = 'linear-gradient(to top, #ade3ff 50%, transparent 50%)';
} else {
dayElement.style.backgroundColor = '#ade3ff';
}
} else {
- selectedDates.value = selectedDates.value.filter((d) => d !== date);
+ selectedDates.value.delete(date);
dayElement.style.backgroundColor = '';
dayElement.style.backgroundImage = '';
}
- halfDayType.value = null; // 날짜 클릭 후 반차 선택 초기화
+ halfDayType.value = null;
}
+/**
+ * 오전/오후 반차 선택
+ */
function toggleHalfDay(type) {
halfDayType.value = halfDayType.value === type ? null : type;
}
-function addVacationRequest() {
- if (selectedDates.value.length === 0) {
- alert('Please select at least one date.');
+async function fetchVacationData() {
+ try {
+ const response = await axios.get('vacation/list');
+ if (response.data.status === 'OK') {
+ const vacationList = response.data.data;
+
+ // 사원별로 날짜를 그룹화
+ const employeeVacations = new Map();
+
+ vacationList.forEach(({ employeeId, date, type }) => {
+ if (!employeeVacations.has(employeeId)) {
+ employeeVacations.set(employeeId, []);
+ }
+ employeeVacations.get(employeeId).push({ date, type });
+ });
+
+ // 연속된 날짜 그룹화 및 스타일 적용
+ employeeVacations.forEach((dates, employeeId) => {
+ const sortedDates = dates.map(d => new Date(d.date)).sort((a, b) => a - b);
+ const color = getColorByEmployeeId(employeeId); // 사원별 색상 함수
+
+ let previousDate = null;
+
+ sortedDates.forEach(currentDate => {
+ const dateStr = currentDate.toISOString().split('T')[0];
+ const dayElement = document.querySelector(`[data-date="${dateStr}"]`);
+
+ if (dayElement) {
+ if (
+ previousDate &&
+ currentDate - previousDate === 86400000 // 하루 차이인지 확인
+ ) {
+ // 연속된 날짜 스타일 설정
+ dayElement.style.backgroundColor = color;
+ } else {
+ // 새로운 시작점
+ dayElement.style.backgroundColor = color;
+ dayElement.style.borderLeft = `3px solid ${color}`;
+ }
+ previousDate = currentDate;
+ }
+ });
+ });
+ }
+ } catch (error) {
+ console.error('Error fetching vacation data:', error);
+ }
+}
+
+/**
+ * 사원 ID별 색상 반환 함수
+ */
+function getColorByEmployeeId(employeeId) {
+ const colors = ['#ade3ff', '#ffade3', '#ade3ad', '#ffadad'];
+ return colors[employeeId % colors.length];
+}
+
+// 데이터 불러오기 호출
+fetchVacationData();
+
+/**
+ * 휴가 요청 추가
+ */
+async function addVacationRequests() {
+ if (selectedDates.value.size === 0) {
+ alert('휴가를 선택해주세요.');
return;
}
- const newEvents = selectedDates.value.map((date) => ({
- title: halfDayType.value ? `${halfDayType.value} Half Day Vacation` : 'Vacation',
- start: date,
- allDay: true,
+ const vacationRequests = Array.from(selectedDates.value).map(([date, type]) => ({
+ date,
+ type,
+ employeeId: employeeId.value,
}));
- calendarEvents.value = [...calendarEvents.value, ...newEvents];
- alert(`Vacation added for dates: ${selectedDates.value.join(', ')} as ${halfDayType.value || 'Full Day'}`);
- selectedDates.value = [];
- halfDayType.value = null;
+ try {
+ const response = await axios.post('vacation', vacationRequests);
+
+ if (response.data && response.data.status === 'OK') {
+ alert('휴가가 저장되었습니다.');
+
+ const newEvents = vacationRequests.map(req => ({
+ title: req.type === 'D' ? '오전반차' : req.type === 'N' ? '오후반차' : '종일 휴가',
+ start: req.date,
+ allDay: true,
+ }));
+
+ calendarEvents.value = [...calendarEvents.value, ...newEvents];
+ selectedDates.value.clear();
+ resetCalendarStyles();
+ } else {
+ alert('휴가 저장 중 오류가 발생했습니다.');
+ }
+ } catch (error) {
+ console.error(error);
+ alert('휴가 저장에 실패했습니다.');
+ }
}
+
+/**
+ * 초기화
+ */
+function resetCalendarStyles() {
+ const calendarElements = document.querySelectorAll('.fc-daygrid-day');
+ calendarElements.forEach(element => {
+ element.style.backgroundColor = '';
+ element.style.backgroundImage = '';
+ });
+}
+
+onMounted(() => {
+ fetchVacationData();
+});