Skip to content

[정해성] sprint4 #163

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: Basic-정해성
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions items.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>items</title>
</head>
<body>
<h1>item pages</h1>
</body>
</html>
40 changes: 40 additions & 0 deletions js/ValidationRules.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
function isValidEmail(email) {
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
return regex.test(email)
}

export const validationRules = {
email: [
{ condition: (v) => !v, message: '이메일을 입력해주세요.' },
{
condition: (v) => !isValidEmail(v),
message: '잘못된 이메일 형식입니다.',
},
],
password: [
{ condition: (v) => !v, message: '비밀번호를 입력해주세요.' },
{
condition: (v) => v.length < 8,
message: '비밀번호를 8자 이상 입력해주세요.',
},
],
nickname: [{ condition: (v) => !v, message: '닉네임을 입력해주세요.' }],
}

export function validateInput(
input,
type,
validateErrorMessage,
showError,
clearError
) {
const value = input.value.trim()
const errorEl = validateErrorMessage(input)
const failed = validationRules[type].find(({ condition }) => condition(value))

if (failed) {
showError(input, errorEl, failed.message)
} else {
clearError(input, errorEl)
}
}
95 changes: 95 additions & 0 deletions js/login.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { validateInput } from './ValidationRules.js'

document.addEventListener('DOMContentLoaded', function () {
const emailInput = document.getElementById('email')
const passwordInput = document.getElementById('password')
const loginButton = document.querySelector('.login_button')

// 이메일 부분

emailInput.addEventListener('blur', () => {
validateInput(
emailInput,
'email',
validateErrorMessage,
showError,
clearError
)
updateButtonState()
})

// 비밀번호 부분

passwordInput.addEventListener('blur', () => {
validateInput(
passwordInput,
'password',
validateErrorMessage,
showError,
clearError
)
updateButtonState()
})

function showError(input, errorElement, message) {
const wrapper = input.closest('.login_password_wrap') || input
wrapper.classList.add('error')
errorElement.textContent = message
errorElement.style.display = 'block'
}

function clearError(input, errorElement) {
const wrapper = input.closest('.login_password_wrap') || input
wrapper.classList.remove('error')
errorElement.textContent = ''
errorElement.style.display = 'none'
}

function validateErrorMessage(input) {
let wrapper = input.closest('.login_password_wrap') || input
let next = wrapper.nextElementSibling
if (!next || !next.classList.contains('error-message')) {
const error = document.createElement('p')
error.className = 'error-message'
error.style.color = 'red'
error.style.fontSize = '14px'
error.style.marginTop = '4px'
wrapper.parentNode.insertBefore(error, wrapper.nextSibling)
return error
}
return next
}

function updateButtonState() {
const emailValue = emailInput.value.trim()
const passwordValue = passwordInput.value.trim()

const hasEmailError = validateErrorMessage(emailInput).textContent !== ''
const hasPasswordError =
validateErrorMessage(passwordInput).textContent !== ''

const isValid =
emailValue && passwordValue && !hasEmailError && !hasPasswordError

loginButton.disabled = !isValid

if (isValid) {
loginButton.classList.add('active')
} else {
loginButton.classList.remove('active')
}
}

emailInput.addEventListener('input', updateButtonState)
passwordInput.addEventListener('input', updateButtonState)

const loginForm = document.querySelector('.login_form_container')

loginForm.addEventListener('submit', function (e) {
e.preventDefault() // 폼 제출 방지
if (!loginButton.disabled) {
window.location.href = '/items.html'
}
})
updateButtonState()
})
142 changes: 142 additions & 0 deletions js/signup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import { validateInput } from './ValidationRules.js'

document.addEventListener('DOMContentLoaded', function () {
const emailInput = document.getElementById('email')
const nicknameInput = document.getElementById('nickname')
const passwordInput = document.getElementById('password')
const passwordCheckInput = document.getElementById('passwordCheck')
const signupButton = document.querySelector('.login_button')
const signupForm = document.querySelector('.signup_form_frame')

// 이메일 부분
emailInput.addEventListener('blur', () => {
validateInput(
emailInput,
'email',
validateErrorMessage,
showError,
clearError
)
updateButtonState()
})

// 닉네임 부분
nicknameInput.addEventListener('blur', () =>
validateInput(
nicknameInput,
'nickname',
validateErrorMessage,
showError,
clearError
)
)

// 비밀번호 부분
passwordInput.addEventListener('blur', () =>
validateInput(
passwordInput,
'password',
validateErrorMessage,
showError,
clearError
)
)

// 비밀번호 확인 부분
passwordCheckInput.addEventListener('blur', () => {
const pwValue = passwordInput.value.trim()
const checkValue = passwordCheckInput.value.trim()
const errorMsg = validateErrorMessage(passwordCheckInput)

if (pwValue !== checkValue) {
showError(passwordCheckInput, errorMsg, '비밀번호가 일치하지 않습니다.')
} else {
clearError(passwordCheckInput, errorMsg)
}

updateButtonState()
})

emailInput.addEventListener('input', updateButtonState)
nicknameInput.addEventListener('input', updateButtonState)
passwordInput.addEventListener('input', updateButtonState)
passwordCheckInput.addEventListener('input', updateButtonState)

function updateButtonState() {
const emailValue = emailInput.value.trim()
const nicknameValue = nicknameInput.value.trim()
const passwordValue = passwordInput.value.trim()
const passwordCheckValue = passwordCheckInput.value.trim()

const hasEmailError = validateErrorMessage(emailInput).textContent !== ''
const hasNicknameError =
validateErrorMessage(nicknameInput).textContent !== ''
const hasPasswordError =
validateErrorMessage(passwordInput).textContent !== ''
const hasPasswordCheckError =
validateErrorMessage(passwordCheckInput).textContent !== ''

const isValid =
emailValue &&
nicknameValue &&
passwordValue &&
passwordCheckValue &&
!hasEmailError &&
!hasNicknameError &&
!hasPasswordError &&
!hasPasswordCheckError

signupButton.disabled = !isValid

if (isValid) {
signupButton.classList.add('active')
} else {
signupButton.classList.remove('active')
}
}

// 회원가입시 로그인페이지로
signupForm.addEventListener('submit', function (e) {
e.preventDefault()
if (!signupButton.disabled) {
window.location.href = '/login/index.html'
}
})

function isValidEmail(email) {
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
return regex.test(email)
}

function showError(input, errorElement, message) {
const wrapper = input.closest('.login_password_wrap') || input
wrapper.classList.add('error')
errorElement.textContent = message
errorElement.style.display = 'block'
}

function clearError(input, errorElement) {
const wrapper = input.closest('.login_password_wrap') || input
wrapper.classList.remove('error')
errorElement.textContent = ''
errorElement.style.display = 'none'
}

function validateErrorMessage(input) {
let wrapper = input.closest('.login_password_wrap') || input
let next = wrapper.nextElementSibling
if (!next || !next.classList.contains('error-message')) {
const error = document.createElement('p')
error.className = 'error-message'
error.style.color = 'red'
error.style.fontSize = '14px'
error.style.marginTop = '4px'
wrapper.parentNode.insertBefore(error, wrapper.nextSibling)
return error
}
return next
}

// 페이지 로드 초기화
updateButtonState()
})
1 change: 1 addition & 0 deletions login/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,6 @@
</div>
</div>
</div>
<script type="module" src="../js/login.js"></script>
</body>
</html>
25 changes: 25 additions & 0 deletions login/login.css
Original file line number Diff line number Diff line change
Expand Up @@ -262,3 +262,28 @@ html {
max-width: 640px;
}
}

.error {
border: 1px solid red;
}

.error-message {
color: red;
font-size: 14px;
margin-top: 4px;
}

.login_input.error {
border: 1px solid red !important;
}

.login_password_wrap.error {
border: 1px solid red;
}

.login_button:disabled {
background-color: #d1d5db;
color: white;
cursor: not-allowed;
opacity: 1;
}
1 change: 1 addition & 0 deletions login/signup.html
Original file line number Diff line number Diff line change
Expand Up @@ -96,5 +96,6 @@
</div>
</div>
</div>
<script type="module" src="../js/signup.js"></script>
</body>
</html>