diff --git a/public/css/custom.css b/public/css/custom.css index ca12d03..f85e0b1 100644 --- a/public/css/custom.css +++ b/public/css/custom.css @@ -16,6 +16,7 @@ height: 8px !important; border-radius: 2px !important; font-size: 0px !important; + margin-left: -0.5% !important; } /* 오후 반차 그래프 (오른쪽 절반) */ .fc-daygrid-event.half-day-pm { @@ -24,6 +25,7 @@ margin-left: auto !important; border-radius: 2px !important; font-size: 0px !important; + margin-right: -0.5% !important; } /* 연차 그래프 (풀) */ .fc-daygrid-event.full-day { @@ -69,7 +71,7 @@ background-color: rgba(0, 0, 0, 0.05); /* 연한 배경 효과 */ .fc-day-sat-sun { cursor: not-allowed !important; } -/* 과거 날짜 (오늘 이전) */ +/* 과거 날짜 (오늘 -7일일) */ .fc-daygrid-day.past { cursor: not-allowed !important; } diff --git a/src/common/common.js b/src/common/common.js index 5bf3125..24dcf2d 100644 --- a/src/common/common.js +++ b/src/common/common.js @@ -124,12 +124,21 @@ const common = { * @param { String } profileImg * @returns */ - getProfileImage(profileImg) { - let profileImgUrl = '/img/icons/icon.png'; // 기본 프로필 이미지 경로 + getProfileImage(profileImg, isAnonymous = false) { + const defaultProfileImg = '/img/icons/icon.png'; // 기본 프로필 이미지 경로 + const anonymousImg = '/img/avatars/default-Profile.jpg'; // 익명 이미지 + let profileImgUrl = isAnonymous ? anonymousImg : defaultProfileImg; const UserProfile = `${import.meta.env.VITE_SERVER}upload/img/profile/${profileImg}`; return !profileImg || profileImg === '' ? profileImgUrl : UserProfile; }, + + setDefaultImage(event, deafultImg = '/img/icons/icon.png') { + return (event.target.src = deafultImg); + }, + showImage(event) { + return (event.target.style.visibility = 'visible'); + }, }; export default { diff --git a/src/components/board/BoardProfile.vue b/src/components/board/BoardProfile.vue index c9c5306..0bdee71 100644 --- a/src/components/board/BoardProfile.vue +++ b/src/components/board/BoardProfile.vue @@ -2,7 +2,13 @@
- Avatar + user
@@ -120,6 +126,14 @@ // 프로필 이미지 경로 설정 const getProfileImage = profileImg => { - return $common.getProfileImage(profileImg); + return $common.getProfileImage(profileImg, true); + }; + + const setDefaultImage = e => { + return $common.setDefaultImage(e); + }; + + const showImage = e => { + return $common.showImage(e); }; diff --git a/src/components/user/RegisterForm.vue b/src/components/user/RegisterForm.vue index d92a2f5..655a329 100644 --- a/src/components/user/RegisterForm.vue +++ b/src/components/user/RegisterForm.vue @@ -5,7 +5,7 @@ for="profilePic" class="rounded-circle m-auto ui-bg-cover position-relative cursor-pointer" id="profileLabel" - style="width: 100px; height: 100px; background-image: url(public/img/avatars/default-Profile.jpg); background-repeat: no-repeat;" + style="width: 100px; height: 100px; background-image: url(img/avatars/default-Profile.jpg); background-repeat: no-repeat" > @@ -53,14 +53,14 @@ {{ passwordcheckError }} import { ref, watch } from 'vue'; import $api from '@api'; - import commonApi from '@/common/commonApi' + import commonApi from '@/common/commonApi'; import UserFormInput from '@c/input/UserFormInput.vue'; import FormSelect from '@c/input/FormSelect.vue'; import ArrInput from '@c/input/ArrInput.vue'; @@ -187,13 +187,13 @@ const birth = ref(''); const address = ref(''); const detailAddress = ref(''); - const postcode = ref(''); // 우편번호 + const postcode = ref(''); // 우편번호 const phone = ref(''); const phoneError = ref(''); const color = ref(''); // 선택된 color const colorError = ref(''); - const mbti = ref(''); // 선택된 MBTI - const pwhint = ref(''); // 선택된 pwhint + const mbti = ref(''); // 선택된 MBTI + const pwhint = ref(''); // 선택된 pwhint const profilAlert = ref(false); const idAlert = ref(false); @@ -211,7 +211,6 @@ const toastStore = useToastStore(); - // 프로필 체크 const profileValid = (size, type) => { const maxSize = 5 * 1024 * 1024; @@ -240,7 +239,7 @@ // 사이즈, 파일 타입 안 맞으면 기본 이미지 if (!profileValid(file.size, file.type)) { e.target.value = ''; - profileLabel.style.backgroundImage = 'url("public/img/avatars/default-Profile.jpg")'; + profileLabel.style.backgroundImage = 'url("img/avatars/default-Profile.jpg")'; return false; } @@ -277,16 +276,17 @@ // 컬러, mbti, 비밀번호 힌트 목록 불러오기 const { colorList, mbtiList, pwhintList } = commonApi({ - loadColor: true, colorType: 'YON', + loadColor: true, + colorType: 'YON', loadMbti: true, loadPwhint: true, }); // 주소 업데이트 핸들러 - const handleAddressUpdate = (addressData) => { + const handleAddressUpdate = addressData => { address.value = addressData.address; detailAddress.value = addressData.detailAddress; - postcode.value = addressData.postcode; // 우편번호 + postcode.value = addressData.postcode; // 우편번호 }; // 비밀번호 확인 체크 @@ -313,7 +313,7 @@ } }; - const handleColorUpdate = async (newColor) => { + const handleColorUpdate = async newColor => { color.value = newColor; colorError.value = ''; colorErrorAlert.value = false; @@ -357,9 +357,21 @@ profilAlert.value = false; } - if (profilAlert.value || idAlert.value || idErrorAlert.value || passwordAlert.value || passwordcheckAlert.value || - passwordcheckErrorAlert.value || pwhintResAlert.value || nameAlert.value || birthAlert.value || - addressAlert.value || phoneAlert.value || phoneErrorAlert.value || colorErrorAlert.value) { + if ( + profilAlert.value || + idAlert.value || + idErrorAlert.value || + passwordAlert.value || + passwordcheckAlert.value || + passwordcheckErrorAlert.value || + pwhintResAlert.value || + nameAlert.value || + birthAlert.value || + addressAlert.value || + phoneAlert.value || + phoneErrorAlert.value || + colorErrorAlert.value + ) { return; } @@ -378,7 +390,7 @@ formData.append('memberMbt', mbti.value); formData.append('memberPrf', profile.value); - const response = await $api.post('/user/join', formData, { isFormData : true }); + const response = await $api.post('/user/join', formData, { isFormData: true }); if (response.status === 200) { toastStore.onToast('등록신청이 완료되었습니다. 관리자 승인 후 이용가능합니다.', 's'); @@ -386,4 +398,3 @@ } }; - diff --git a/src/views/board/BoardList.vue b/src/views/board/BoardList.vue index da16bc4..c42c657 100644 --- a/src/views/board/BoardList.vue +++ b/src/views/board/BoardList.vue @@ -291,5 +291,7 @@ onMounted(() => { color: #ff5733; border-radius: 4px; padding: 2px 6px; + position: relative; + top: -1px; } diff --git a/src/views/vacation/VacationManagement.vue b/src/views/vacation/VacationManagement.vue index 0a76af2..488b6f4 100644 --- a/src/views/vacation/VacationManagement.vue +++ b/src/views/vacation/VacationManagement.vue @@ -152,23 +152,30 @@ function handleMonthChange(viewInfo) { loadCalendarData(year, month); } // 캘린더 클릭 +// 캘린더 클릭 function handleDateClick(info) { const clickedDateStr = info.dateStr; const clickedDate = info.date; const todayStr = new Date().toISOString().split("T")[0]; + const todayObj = new Date(todayStr); + const oneWeekAgoObj = new Date(todayObj); + oneWeekAgoObj.setDate(todayObj.getDate() - 8); // 오늘 기준 7일 전 날짜 + // 주말(토, 일) 또는 공휴일 또는 오늘 -7일 날짜 → 클릭 불가능 if ( - clickedDate.getDay() === 0 || - clickedDate.getDay() === 6 || - holidayDates.value.has(clickedDateStr) || - clickedDateStr < todayStr + clickedDate.getDay() === 0 || // 일요일 + clickedDate.getDay() === 6 || // 토요일 + holidayDates.value.has(clickedDateStr) || // 공휴일 + clickedDateStr <= oneWeekAgoObj.toISOString().split("T")[0] // 오늘 -7일 날짜 포함 과거 날짜 클릭 방지 ) { return; } + const isMyVacation = myVacations.value.some(vac => { const vacDate = vac.date ? vac.date.substring(0, 10) : ""; return vacDate === clickedDateStr && !vac.receiverId; }); + if (isMyVacation) { if (selectedDates.value.get(clickedDateStr) === "delete") { selectedDates.value.delete(clickedDateStr); @@ -178,45 +185,55 @@ function handleDateClick(info) { updateCalendarEvents(); return; } + if (selectedDates.value.has(clickedDateStr)) { selectedDates.value.delete(clickedDateStr); updateCalendarEvents(); return; } + const type = halfDayType.value ? (halfDayType.value === "AM" ? "700101" : "700102") : "700103"; + selectedDates.value.set(clickedDateStr, type); halfDayType.value = null; updateCalendarEvents(); + if (halfDayButtonsRef.value) { halfDayButtonsRef.value.resetHalfDay(); } } -// 오늘 이후의 날짜만 클릭 가능하도록 설정 + function markClickableDates() { nextTick(() => { - const todayStr = new Date().toISOString().split("T")[0]; // 오늘 날짜 YYYY-MM-DD + const todayStr = new Date().toISOString().split("T")[0]; // 오늘 날짜 (YYYY-MM-DD) const todayObj = new Date(todayStr); + const oneWeekAgoObj = new Date(todayObj); + oneWeekAgoObj.setDate(todayObj.getDate() - 8); // 오늘 기준 7일 전 날짜 document.querySelectorAll(".fc-daygrid-day").forEach((cell) => { const dateStr = cell.getAttribute("data-date"); if (!dateStr) return; // 날짜가 없으면 스킵 + const dateObj = new Date(dateStr); - // 주말 (토요일, 일요일) - if (dateObj.getDay() === 0 || dateObj.getDay() === 6 || holidayDates.value.has(dateStr)) { + + // 주말(토요일, 일요일) 또는 공휴일 또는 오늘 -7일 날짜 → 클릭 불가능 + if ( + dateObj.getDay() === 0 || // 일요일 + dateObj.getDay() === 6 || // 토요일 + holidayDates.value.has(dateStr) || // 공휴일 + dateObj.getTime() === oneWeekAgoObj.getTime() // 오늘 -7일 날짜 + ) { cell.classList.remove("clickable"); cell.classList.add("fc-day-sat-sun"); + cell.removeEventListener("click", handleDateClick); // 클릭 이벤트 제거 } - // 과거 날짜 (오늘 이전) - else if (dateObj < todayObj) { - cell.classList.remove("clickable"); - cell.classList.add("past"); // 과거 날짜 비활성화 - } - // 오늘 & 미래 날짜 (클릭 가능) + // 오늘 -6일부터 미래 날짜까지 클릭 가능 else { cell.classList.add("clickable"); cell.classList.remove("past", "fc-day-sat-sun"); + cell.addEventListener("click", handleDateClick); // 클릭 이벤트 추가 } }); });