diff --git a/common/js/common/common.service.js b/common/js/common/common.service.js new file mode 100644 index 00000000..898edcbb --- /dev/null +++ b/common/js/common/common.service.js @@ -0,0 +1,22 @@ +const setError = (element, message, type) => { + const inputControl = element.parentElement; + const errorDisplay = inputControl.querySelector('.error'); + + errorDisplay.innerText = message; + inputControl.classList.add('error'); + inputControl.classList.remove('success'); +}; + +const setSuccess = (element) => { + const inputControl = element.parentElement; + const errorDisplay = inputControl.querySelector('.error'); + + errorDisplay.innerText = ''; + inputControl.classList.remove('error'); + inputControl.classList.add('success'); +}; + +export const common = { + setError, + setSuccess, +}; diff --git a/common/js/common/modal.service.js b/common/js/common/modal.service.js new file mode 100644 index 00000000..f2ecd6c5 --- /dev/null +++ b/common/js/common/modal.service.js @@ -0,0 +1,27 @@ +const modal = document.getElementById('error-message-modal'); +const closeModalButton = document.querySelector('.close-modal-button'); + +export const closeModal = () => { + modal.close(); +}; +const handleCloseModal = (e) => { + if (isModalOutSideClicked(e)) { + closeModal(); + } +}; +// 모달 외부 클릭 했는지 확인 +const isModalOutSideClicked = (e) => { + const dialogDimensions = modal.getBoundingClientRect(); + return ( + e.clientX < dialogDimensions.left || + e.clientX > dialogDimensions.right || + e.clientY < dialogDimensions.top || + e.clientY > dialogDimensions.bottom + ); +}; + +export const showModal = () => { + modal.showModal(); +}; + +// controller -> evenService -> commonService들의 조합 diff --git a/common/js/common/validation.service.js b/common/js/common/validation.service.js new file mode 100644 index 00000000..54be7036 --- /dev/null +++ b/common/js/common/validation.service.js @@ -0,0 +1,57 @@ +import { USER_DATA } from '../../data/users.js'; +import { EMAIL_REGEX } from './regex.js'; +import { showModal } from './modal.js'; + +const checkFormButtonDisabled = () => !formButton; +// 유효성 검사 함수 +const isValidInput = (input) => input.value.trim() !== ''; +const isValidPassword = (password) => password.value.trim().length >= 8; +const isEmailRegistered = (email) => { + return USER_DATA.find((user) => user.email === email.value.trim()); +}; +const validateEmail = () => { + const emailValue = email.value.trim(); + if (emailValue === '') { + setError(email, '이메일을 입력해주세요.', 'email'); + } else if (!isValidEmail(emailValue)) { + setError(email, '잘못된 이메일 형식입니다.', 'email'); + } else { + setSuccess(email); + } +}; +const isValidEmail = (email) => { + return EMAIL_REGEX.test(String(email).toLowerCase()); +}; +const validateNickname = () => { + const nicknameValue = nickname.value.trim(); + if (nicknameValue === '') { + setError(nickname, '닉네임을 입력해주세요.', 'nickname'); + } else { + setSuccess(nickname); + } +}; +const validatePassword = () => { + const passwordValue = password.value.trim(); + if (passwordValue === '') { + setError(password, '비밀번호를 입력해주세요.', 'password'); + } else if (passwordValue.length < 8) { + setError(password, '비밀번호를 8자 이상 입력해주세요', 'password'); + } else { + setSuccess(password); + } +}; +const validatePasswordConfirmation = () => { + const passwordValue = password.value.trim(); + const passwordConfirmValue = passwordConfirm.value.trim(); + if (passwordConfirmValue === '') { + setError(passwordConfirm, '비밀번호를 입력해주세요.', 'password-confirm'); + } else if (passwordConfirmValue !== passwordValue) { + setError( + passwordConfirm, + '비밀번호가 일치하지 않습니다.', + 'password-confirm' + ); + } else { + setSuccess(passwordConfirm); + } +}; diff --git a/common/js/controller/event.controller.js b/common/js/controller/event.controller.js new file mode 100644 index 00000000..8b7d2b1f --- /dev/null +++ b/common/js/controller/event.controller.js @@ -0,0 +1,25 @@ +import { handleFormSubmit, updateSubmitButtonState } from './eventFunctions.js'; + +const modal = document.getElementById('error-message-modal'); +const closeModalButton = document.querySelector('.close-modal-button'); +const form = document.getElementById('form'); +const email = document.getElementById('email'); +const nickname = document.getElementById('nickname'); +const password = document.getElementById('password'); +const passwordConfirm = document.getElementById('password-confirm'); +const formButton = document.getElementById('form-button'); +const passwordFields = document.querySelectorAll('.password-field'); +const visibilityImages = document.querySelectorAll( + '.password-visibility-image' +); + +// eventBuilder +// .get('form-button') +// .event('input') +// .eventService(updateSubmitButtonState); + +form.addEventListener('input', updateSubmitButtonState); +form.addEventListener('submit', handleFormSubmit); +form.addEventListener('focusout', handleFocusOut); +closeModalButton.addEventListener('click', closeModal); +modal.addEventListener('click', handleCloseModal); diff --git a/common/js/form-validation.js b/common/js/form-validation.js index ce51ac11..3865e7ce 100644 --- a/common/js/form-validation.js +++ b/common/js/form-validation.js @@ -11,7 +11,7 @@ const formButton = document.getElementById('form-button'); // -----폼 제출 시 이벤트 처리----- -const handleFormSubmit = (e) => { +export const handleFormSubmit = (e) => { e.preventDefault(); // 유효성 검사 @@ -35,7 +35,7 @@ form.addEventListener('submit', handleFormSubmit); // -----입력 시 제출 버튼 상태 업데이트----- -const updateSubmitButtonState = () => { +export const updateSubmitButtonState = () => { setSubmitButtonState(); }; @@ -65,6 +65,13 @@ const setSubmitButtonState = () => { formButton.disabled = !isValid; }; +const checkFormButtonDisabled = () => !formButton; + +export const validates = { + setSubmitButtonState, + checkFormButtonDisabled, +}; + // 유효성 검사 함수 const isValidInput = (input) => input.value.trim() !== ''; const isValidPassword = (password) => password.value.trim().length >= 8; @@ -72,44 +79,38 @@ const isValidPassword = (password) => password.value.trim().length >= 8; // 회원 가입 페이지 폼 제출 이벤트 처리 const handleSignupProcess = () => { // 이미 가입된 이메일인지 확인 - if (isEmailRegistered(email)) { - showModal(); - } else { - // 회원가입 완료 - USER_DATA.push({ - email: email.value.trim(), - password: password.value.trim(), - }); - alert('회원가입이 완료되었습니다.'); - window.location.href = '/pages/auth/login/login.html'; // 로그인 페이지 이동 - } + if (isEmailRegistered(email)) return showModal(); + // 회원가입 완료 + USER_DATA.push({ + email: email.value.trim(), + password: password.value.trim(), + }); + alert('회원가입이 완료되었습니다.'); + window.location.href = '/pages/auth/login/login.html'; // 로그인 페이지 이동 }; -const isEmailRegistered = (email) => { - return USER_DATA.find((user) => user.email === email.value.trim()); -}; +const isEmailRegistered = (email) => + USER_DATA.find((user) => user.email === email.value.trim()); // 로그인 페이지 폼 제출 이벤트 처리 const handleLoginProcess = () => { // 로그인 처리 - if (isUserExist(email, password)) { - // alert('로그인 되었습니다.'); + if (isUserExist(email, password)) window.location.href = '../../../items.html'; // 아이템 페이지 이동 - } else { - showModal(); - } + else showModal(); }; const isUserExist = (email, password) => { - return USER_DATA.find( + const result = USER_DATA.find( (user) => user.email === email.value.trim() && user.password === password.value.trim() ); + return result; }; // -----포커스 아웃 시 유효성 검사----- -const handleFocusOut = (e) => { +export const handleFocusOut = (e) => { const validateElementId = e.target.id; validateForm(validateElementId); }; @@ -128,6 +129,13 @@ const validateForm = (validateElementId) => { } }; +export const validationHandlersA = { + email: () => validateEmail(), + nickname: () => validateNickname(), + password: () => validatePassword(), + 'password-confirm': () => validatePasswordConfirmation(), +}; + // input 요소에 에러 메시지와 상태를 설정하는 함수 const setError = (element, message, type) => { @@ -168,37 +176,29 @@ const setSuccess = (element) => { // 유효성 검사 함수들 const validateEmail = () => { const emailValue = email.value.trim(); - if (emailValue === '') { - setError(email, '이메일을 입력해주세요.', 'email'); - } else if (!isValidEmail(emailValue)) { - setError(email, '잘못된 이메일 형식입니다.', 'email'); - } else { - setSuccess(email); - } + if (emailValue === '') + return setError(email, '이메일을 입력해주세요.', 'email'); + if (!isValidEmail(emailValue)) + return setError(email, '잘못된 이메일 형식입니다.', 'email'); + setSuccess(email); }; -const isValidEmail = (email) => { - return EMAIL_REGEX.test(String(email).toLowerCase()); -}; +const isValidEmail = (email) => EMAIL_REGEX.test(String(email).toLowerCase()); const validateNickname = () => { const nicknameValue = nickname.value.trim(); - if (nicknameValue === '') { + if (nicknameValue === '') setError(nickname, '닉네임을 입력해주세요.', 'nickname'); - } else { - setSuccess(nickname); - } + else setSuccess(nickname); }; const validatePassword = () => { const passwordValue = password.value.trim(); - if (passwordValue === '') { - setError(password, '비밀번호를 입력해주세요.', 'password'); - } else if (passwordValue.length < 8) { - setError(password, '비밀번호를 8자 이상 입력해주세요', 'password'); - } else { - setSuccess(password); - } + if (passwordValue === '') + return setError(password, '비밀번호를 입력해주세요.', 'password'); + if (passwordValue.length < 8) + return setError(password, '비밀번호를 8자 이상 입력해주세요', 'password'); + setSuccess(password); }; const validatePasswordConfirmation = () => { diff --git a/common/js/service/event.service.js b/common/js/service/event.service.js new file mode 100644 index 00000000..277d55b0 --- /dev/null +++ b/common/js/service/event.service.js @@ -0,0 +1,24 @@ +import { validates, validationHandlersA } from './form-validation.js'; + +export const handleFormSubmit = (e) => { + e.preventDefault(); + validates.setSubmitButtonState(); + if (validates.checkFormButtonDisabled()) return; + const currentPage = window.location.pathname; + if (currentPage.includes('signup.html')) return handleSignupProcess(); + if (currentPage.includes('login.html')) return handleLoginProcess(); + alert('페이지를 찾을 수 없습니다.'); +}; + +export const updateSubmitButtonState = () => validates.setSubmitButtonState(); + +export const handleFocusOut = (e) => { + const validateElementId = e.target.id; + validationHandlersA[validateElementId](); +}; + +export const closeModal = () => modal.close(); + +export const handleCloseModal = (e) => { + if (isModalOutSideClicked(e)) closeModal(); +};