diff --git a/public/css/custom.css b/public/css/custom.css index 9f01857..5c3e23b 100644 --- a/public/css/custom.css +++ b/public/css/custom.css @@ -3,4 +3,94 @@ .display-block { display: block !important; -} \ No newline at end of file +} + +.notice-row td { + color: #DC3545 !important; +} +.notice-row { + background-color: #f8f9fa; +} +.general-row { + background-color: white; + color: black; +} +.clickable-row { + cursor: pointer; +} +.clickable-row:hover { + background-color: #f1f1f1; +} +.new-badge { + font-size: 0.65rem; + padding: 0.2em 0.4em; + vertical-align: middle; +} + + +/* 휴가*/ + +.half-day-buttons { + display: flex; + justify-content: center; + gap: 10px; + margin-top: 20px; + } + .half-day-buttons .btn.active { + border: 2px solid black; + } + .fc-daygrid-day-frame { + min-height: 80px !important; + max-height: 120px !important; + overflow: hidden !important; + padding-top: 25px !important; + } + .fc-daygrid-day-events { + max-height: 100px !important; + overflow-y: auto !important; + } + .fc-daygrid-event { + position: absolute !important; + height: 20px !important; + width: 100% !important; + left: 0 !important; + margin: 2px 0 !important; + padding: 0 !important; + border-radius: 2px !important; + border: none !important; + } + .fc-daygrid-event-harness { + display: flex; + flex-direction: column; + align-items: flex-start; + justify-content: flex-start; + width: 100%; + gap: 22px; + } + .fc-daygrid-event.half-day-am { + width: 45% !important; + left: 0 !important; + } + .fc-daygrid-event.half-day-pm { + width: 45% !important; + left: auto !important; + right: 0 !important; + } + .fc-daygrid-event.full-day { + width: 100% !important; + left: 0 !important; + } + .fc-day-sun .fc-daygrid-day-number, + .fc-col-header-cell:first-child .fc-col-header-cell-cushion { + color: #ff4500 !important; + } + .fc-day-sat .fc-daygrid-day-number, + .fc-col-header-cell:last-child .fc-col-header-cell-cushion { + color: #6076e0 !important; + } + .fc-daygrid-day-number { + position: absolute !important; + top: 0px !important; + left: 5px !important; + text-align: left !important; + } \ No newline at end of file diff --git a/src/common/axios-interceptor.js b/src/common/axios-interceptor.js index 08bf871..f60b3d8 100644 --- a/src/common/axios-interceptor.js +++ b/src/common/axios-interceptor.js @@ -1,5 +1,5 @@ import axios from "axios"; -import router from "@/router/index"; +import { useToastStore } from '@s/toastStore'; const $api = axios.create({ baseURL: 'http://localhost:10325/api/', @@ -30,13 +30,41 @@ $api.interceptors.request.use( // 응답 인터셉터 추가하기 $api.interceptors.response.use( + function (response) { - // 2xx 범위에 있는 상태 코드는 이 함수를 트리거 합니다. - // 응답 데이터가 있는 작업 수행 + // 2xx 범위의 응답 처리 return response; - }, function (error) { - // 2xx 외의 범위에 있는 상태 코드는 이 함수를 트리거 합니다. - // 응답 오류가 있는 작업 수행 + }, + function (error) { + const toastStore = useToastStore() + // 오류 응답 처리 + if (error.response) { + switch (error.response.status) { + case 401: + toastStore.onToast('아이디 혹은 비밀번호가 틀렸습니다.', 'e'); + break; + case 403: + toastStore.onToast('접근 권한이 없습니다.', 'e'); + break; + case 404: + toastStore.onToast('요청한 페이지를 찾을 수 없습니다.', 'e'); + break; + case 500: + toastStore.onToast('서버 오류가 발생했습니다.', 'e'); + break; + default: + toastStore.onToast('알 수 없는 오류가 발생했습니다.', 'e'); + } + } else if (error.request) { + // 요청이 전송되었으나 응답을 받지 못한 경우 + toastStore.onToast('서버와 통신할 수 없습니다.', 'e'); + } else { + // 요청 설정 중에 오류가 발생한 경우 + toastStore.onToast('요청 중 오류가 발생했습니다.', 'e'); + } + return Promise.reject(error); - }); + } +); + export default $api; diff --git a/src/common/commonApi.js b/src/common/commonApi.js index 66cf53b..f7098e0 100644 --- a/src/common/commonApi.js +++ b/src/common/commonApi.js @@ -12,27 +12,28 @@ const commonApi = () => { const colorList = ref([]); const mbtiList = ref([]); const pwhintList = ref([]); + const yearCategory = ref([]); + const cateList = ref([]); + + const CommonCode = async (path, endpoint, targetList) => { + + const response = await $api.get(`${path}/${endpoint}`); + targetList.value = response.data.data.map(item => ({ + label: item.CMNCODNAM, + value: item.CMNCODVAL, + })); - const CommonCode = async (endpoint, targetList) => { - try { - const response = await $api.get(`/user/${endpoint}`); - targetList.value = response.data.data.map(item => ({ - label: item.CMNCODNAM, - value: item.CMNCODVAL - })); - } catch (error) { - console.error(`Error fetching ${endpoint}:`, error); - targetList.value = []; - } }; onMounted(async () => { - await CommonCode("color", colorList); - await CommonCode("mbti", mbtiList); - await CommonCode("pwhint", pwhintList); + await CommonCode("user", "color", colorList); + await CommonCode("user", "mbti", mbtiList); + await CommonCode("user", "pwhint", pwhintList); + await CommonCode("project", "yearCategory", yearCategory); + await CommonCode("worddict", "getWordCategory", cateList); }); - return { colorList, mbtiList, pwhintList }; + return { colorList, mbtiList, pwhintList, yearCategory, cateList }; }; export default commonApi; diff --git a/src/components/board/BoardProfile.vue b/src/components/board/BoardProfile.vue index 59fe548..7a4e538 100644 --- a/src/components/board/BoardProfile.vue +++ b/src/components/board/BoardProfile.vue @@ -74,9 +74,9 @@ const router = useRouter(); // Props 정의 const props = defineProps({ - boardId: { - type: Number, - required: true + boardId: { + type: Number, + required: true }, profileName: { type: String, @@ -125,7 +125,7 @@ const handleEdit = () => { // router.push({ name: 'BoardEdit', params: { id: boardId } }); if (props.unknown) { - togglePassword('edit'); + togglePassword('edit'); } else { router.push({ name: 'BoardEdit', params: { id: 100 } }); // 로그인한 경우 바로 편집 } @@ -154,14 +154,14 @@ const togglePassword = (button) => { const handlePasswordSubmit = async () => { isPassword.value = false; lastClickedButton.value = null; - + console.log('비밀번호:', password.value); - console.log(props.boardId) + console.log(props.boardId) try { const requestData = { - MEMBERSEQ: 288, - LOCBRDPWD: 1234 + LOCBRDPWD: password.value, + LOCBRDSEQ: 288 } console.log(requestData) diff --git a/src/components/category/CategoryBtn.vue b/src/components/category/CategoryBtn.vue index ee8a618..7c0df23 100644 --- a/src/components/category/CategoryBtn.vue +++ b/src/components/category/CategoryBtn.vue @@ -1,21 +1,20 @@ diff --git a/src/components/list/ProjectCardList.vue b/src/components/list/ProjectCardList.vue new file mode 100644 index 0000000..aed26b8 --- /dev/null +++ b/src/components/list/ProjectCardList.vue @@ -0,0 +1,49 @@ + + + diff --git a/src/components/projectlist/ProjectList.vue b/src/components/projectlist/ProjectList.vue new file mode 100644 index 0000000..bae6f34 --- /dev/null +++ b/src/components/projectlist/ProjectList.vue @@ -0,0 +1,19 @@ + + + diff --git a/src/components/user/FindPassword.vue b/src/components/user/FindPassword.vue index 77a8666..c4e073a 100644 --- a/src/components/user/FindPassword.vue +++ b/src/components/user/FindPassword.vue @@ -8,44 +8,43 @@ :useInputGroup="true" @update:data="handleIdChange" :value="id" + :disabled="resetForm" /> - - - - - - - -
- 취소 - -
+
@@ -159,6 +158,16 @@ return; } + const checkResponse = await $api.post('user/checkPassword', { + id: id.value, + password: password.value + }); + + if (checkResponse.data.data === false) { + toastStore.onToast('기존 비밀번호와 동일한 비밀번호로 변경할 수 없습니다.', 'e'); + return; + } + const response = await $api.patch('user/pwNew', { id: id.value, password: password.value diff --git a/src/components/user/LoginForm.vue b/src/components/user/LoginForm.vue index 3727703..7603875 100644 --- a/src/components/user/LoginForm.vue +++ b/src/components/user/LoginForm.vue @@ -63,20 +63,17 @@ }; const handleSubmit = async () => { - const response = await $api.post('user/login', { + $api.post('user/login', { loginId: id.value, password: password.value, remember: remember.value, - }); - - if (response.status === 200) { - await userStore.userInfo(); - router.push('/'); - } else { - toastStore.onToast('아이디 혹은 비밀번호가 틀렸습니다.', 'e'); - } - + }) + .then(res => { + if (res.status === 200) { + userStore.userInfo(); + router.push('/'); + } + }) }; - diff --git a/src/components/wordDict/DictWrite.vue b/src/components/wordDict/DictWrite.vue index eccf5a3..985c69d 100644 --- a/src/components/wordDict/DictWrite.vue +++ b/src/components/wordDict/DictWrite.vue @@ -1,39 +1,49 @@ @@ -124,3 +134,15 @@ const saveWord = () => { emit('addWord', wordData); }; + + \ No newline at end of file diff --git a/src/layouts/TheMenu.vue b/src/layouts/TheMenu.vue index ea814c5..2116b7b 100644 --- a/src/layouts/TheMenu.vue +++ b/src/layouts/TheMenu.vue @@ -46,19 +46,25 @@ +