반응형 회원가입 페이지를 구현해보았습니다. CSS에 뉴모피즘(Neumorphism) 디자인을 적용해 보았습니다. 회원가입을 완료하는 버튼을 하단 가운데, 또는 하단 오른쪽에 배치하여 사용자 편의를 고려했고, 유효하지 않은 데이터를 입력했을 때는 빨간색 계열의 표기를, 유효한 데이터를 입력했을 때는 초록색 계열의 표기를 함으로써 직관적인 정보 전달을 합니다. 폼이 전달되면 회원들의 데이터는 로컬스토리지에 보관됩니다.
.container {
width: 375px;
height: 750px;
background: var(--bg-color);
border-radius: 30px;
box-shadow: 10px 10px 30px rgb(174, 174, 192, 0.5),
-10px -10px 30px rgba(255, 255, 255);
}
flexbox로 구성한 웹은 화면 크기의 변동에 따른 요소의 속성 조절에 용이합니다.
.container {
width: 375px;
}
.form button {
width: 100%;
}
@media screen and (min-width:950px) {
.container {
width: 650px;
}
.form button {
width: 20%;
align-self: flex-end;
}
}
form
의 각 input
항목에 입력한 데이터의 유효성 검사를 합니다. 이메일체크의 경우 stackoverflow에서 이미 만들어둔 코드를 가져왔습니다. 각 항목에 대한 유효성 검사를 한 후, 조건에 맞지 않으면 에러 메시지를 입력하는 함수를 만들어, 폼을 제출할 때 한꺼번에 메시지가 뜨도록 했습니다.
// Check email is valid
function checkEmail(input) {
const re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
if (re.test(input.value.trim())) {
showSuccess(input)
} else {
showError(input, 'Email is not valid')
}
}
// Check Required Fields
function checkRequired(inputArr) {
inputArr.forEach(function(input) {
if (input.value.trim() === '') {
showError(input, `${getFieldName(input)} is required`)
} else {
showSuccess(input)
}
})
}
// Check input length
function checkLength(input, min, max) {
if (input.value.length < min) {
showError(input, `${getFieldName(input)} must be at least ${min} characters`)
} else if (input.value.length > max){
showError(input, `${getFieldName(input)} must be less than ${max} characters`)
} else {
showSuccess(input)
}
}
// Check passwords match
function checkPasswordsMatch(input1, input2) {
if (input1.value !== input2.value) {
showError(input2, 'Passwords do not match')
}
}
회원가입한 유저의 정보를 로컬스토리지에 저장해 줍니다. saveUserInfos(userInfos)
와 getSavedUserInfos()
함수를 각각 만들어, JSON
형태로 저장했다가 다시 파싱하도록 했습니다. 유저가 입력한 정보는 uuidv4
라이브러리로 가져온 고유 id값과 함께 스토리지에 저장됩니다.
//read existing infos from localstorage
const getSavedUserInfos = () => {
const userInfosJSON = localStorage.getItem('userInfos')
try {
return userInfosJSON ? JSON.parse(userInfosJSON) : []
} catch {
return []
}
}
//save the infos to localstorage
const saveUserInfos = (userInfos) => {
localStorage.setItem('userInfos', JSON.stringify(userInfos))
}
const userId = uuidv4()
let userInfos = getSavedUserInfos()
let userInfo = userInfos.find((userInfo) => userInfo.id === userId)
form.addEventListener('submit', (e) => {
e.preventDefault()
checkRequired([username, email, password, password2])
checkLength(username, 3, 15)
checkLength(password, 6, 25)
checkEmail(email)
checkPasswordsMatch(password, password2)
userInfos.push({
id: userId,
username: username.value,
email: email.value,
password: password.value
})
saveUserInfos(userInfos)
})
뉴모피즘 디자인 예쁘네요!