-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #94 from codesquad-memeber-2020/feature/fe/validate
[#21] Feat: 유효성 검증 중간 PR
- Loading branch information
Showing
22 changed files
with
381 additions
and
1,055 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
import "./scss/home.scss"; |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
export const PATTERN = { | ||
userId: /^[a-z0-9-_]{5,20}$/, | ||
password: { | ||
all: /^(?=.*[A-Za-z])(?=.*d)(?=.*[!@#$%^&*_+~])[A-Za-zd!@#$%^&*_+~]{8,16}$/, | ||
upperCase: /(.*[A-Z])/, | ||
number: /(.*[0-9])/, | ||
sign: /(.*[!@#$%^&*_+~])/, | ||
}, | ||
email: /^(([^<>()\[\]\\.,;:\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,}))$/, | ||
phoneNumber: /^(010)(\d{7,8})$/, | ||
birthday: /^(0-9)$/, | ||
}; | ||
|
||
export const LIMITED_LENGTH = { | ||
userId: 20, | ||
password_min: 8, | ||
password_max: 16, | ||
year: 4, | ||
age_min: 15, | ||
age_max: 99, | ||
}; | ||
|
||
export const FORM_ID = { | ||
userId: "#userId", | ||
password: "#password", | ||
checkPassword: "#check-password", | ||
email: "#email", | ||
phoneNumber: "#phoneNumber", | ||
name: "#name", | ||
year: "#year", | ||
month: "#month", | ||
day: "#day", | ||
gender: "#gender", | ||
interest: "#interest", | ||
}; | ||
|
||
export const ERROR_MSG_ID = { | ||
userId: "#error-msg-id", | ||
password: "#error-msg-password", | ||
checkPassword: "#error-msg-check-password", | ||
email: "#error-msg-email", | ||
phoneNumber: "#error-msg-phone", | ||
birthday: "#error-msg-birthday", | ||
interest: "#error-msg-interest", | ||
}; | ||
|
||
export const TOGGLE_CLASS = { | ||
pass: "pass", | ||
error: "error", | ||
focus: "forus", | ||
hidden: "hidden", | ||
disabled: "disabled", | ||
}; | ||
|
||
export const NUM_KEY_CODE_ZERO = 48; | ||
|
||
export const NUM_KEY_CODE_NINE = 57; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
import { PATTERN, FORM_ID, LIMITED_LENGTH, ERROR_MSG_ID } from "./constants.js"; | ||
import app from "./server.js"; | ||
import { _q, daysInMonth } from "./util.js"; | ||
|
||
export default { | ||
userId: { | ||
inputElement: _q(FORM_ID.userId), | ||
timeout: null, | ||
selectErrorMessage() { | ||
if (!this.isFieldValid()) return this.errorMessage.misMatch; | ||
if (this.isDuplicate()) return this.errorMessage.duplicate; | ||
return null; | ||
}, | ||
isFieldValid() { | ||
const userId = this.inputElement.value; | ||
const userIdRegex = PATTERN.userId; | ||
return userId !== "" && userIdRegex.test(userId); | ||
}, | ||
isDuplicate() { | ||
return app.checkDuplicate(this.inputElement.value); | ||
}, | ||
errorMessage: { | ||
misMatch: "5~20자의 영문 소문자, 숫자와 특수기호(_)(-) 만 사용 가능합니다.", | ||
duplicate: "이미 사용중인 아이디입니다.", | ||
}, | ||
errorMessageElement: _q(ERROR_MSG_ID.userId), | ||
passMessage: "사용 가능한 아이디입니다.", | ||
}, | ||
|
||
password: { | ||
inputElement: _q(FORM_ID.password), | ||
selectErrorMessage() { | ||
const password = this.inputElement.value; | ||
if (password.length < LIMITED_LENGTH.password_min || password.length > LIMITED_LENGTH.password_max) { | ||
return this.errorMessage.range; | ||
} | ||
if (!PATTERN.password.upperCase.test(password)) { | ||
return this.errorMessage.upperCase; | ||
} | ||
if (!PATTERN.password.number.test(password)) { | ||
return this.errorMessage.number; | ||
} | ||
if (!PATTERN.password.sign.test(password)) { | ||
return this.errorMessage.sign; | ||
} | ||
return null; | ||
}, | ||
errorMessage: { | ||
range: "8자 이상 16자 이하로 입력해주세요.", | ||
upperCase: "영문 대문자를 최소 1자 이상 포함해주세요.", | ||
number: "숫자를 최소 1자 이상 포함해주세요.", | ||
sign: "특수문자를 최소 1자 이상 포함해주세요.", | ||
}, | ||
errorMessageElement: _q(ERROR_MSG_ID.password), | ||
passMessage: "안전한 비밀번호입니다.", | ||
}, | ||
|
||
checkPassword: { | ||
inputElement: _q(FORM_ID.checkPassword), | ||
isFieldValid() { | ||
const password = _q(FORM_ID.password).value; | ||
const checkPassword = this.inputElement.value; | ||
return password === checkPassword; | ||
}, | ||
selectErrorMessage() { | ||
if (!this.isFieldValid()) return this.errorMessage; | ||
return null; | ||
}, | ||
errorMessageElement: _q(ERROR_MSG_ID.checkPassword), | ||
errorMessage: "비밀번호가 일치하지 않습니다.", | ||
passMessage: "비밀번호가 일치합니다.", | ||
}, | ||
|
||
birthDay: { | ||
inputElement: { | ||
year: _q(FORM_ID.year), | ||
month: _q(FORM_ID.month), | ||
day: _q(FORM_ID.day), | ||
}, | ||
selectErrorMessage() { | ||
const year = this.inputElement.year.value; | ||
const month = this.inputElement.month.value; | ||
const day = this.inputElement.day.value; | ||
const today = new Date(); | ||
const thisYear = today.getFullYear(); | ||
const age = thisYear - year + 1; | ||
if (!this.isValidYear(age)) return this.errorMessage.year; | ||
if (!this.isValidAge(age, month)) return this.errorMessage.age; | ||
if (this.isValidDayinMonth(month, day)) return this.errorMessage.day; | ||
return null; | ||
}, | ||
isValidYear(age) { | ||
if (age >= LIMITED_LENGTH.age_min && age <= LIMITED_LENGTH.age_max) return true; | ||
return false; | ||
}, | ||
isValidAge(age, month) { | ||
if (age >= LIMITED_LENGTH.age_min) return true; | ||
return false; | ||
}, | ||
isValidDayinMonth(month, day) { | ||
const validDay = daysInMonth(month); | ||
if (day < 1 || day > validDay) return true; | ||
return false; | ||
}, | ||
errorMessageElement: _q(ERROR_MSG_ID.birthday), | ||
errorMessage: { | ||
year: "태어난 년도 4자리를 정확하게 입력하세요.", | ||
age: "만 14세 이상만 가입 가능합니다.", | ||
day: "태어난 날짜를 다시 확인해주세요.", | ||
}, | ||
passMessage: "", | ||
}, | ||
|
||
name: { | ||
inputElement: _q(FORM_ID.name), | ||
selectErrorMessage() { | ||
return null; | ||
}, | ||
}, | ||
|
||
email: { | ||
inputElement: _q(FORM_ID.email), | ||
selectErrorMessage() { | ||
if (!this.isFieldValid()) return this.errorMessage; | ||
return null; | ||
}, | ||
isFieldValid() { | ||
const email = this.inputElement.value; | ||
const emailRegexp = PATTERN.email; | ||
return email !== "" && emailRegexp.test(email); | ||
}, | ||
errorMessageElement: _q(ERROR_MSG_ID.email), | ||
errorMessage: "이메일 주소를 다시 확인해주세요.", | ||
passMessage: "", | ||
}, | ||
|
||
phoneNumber: { | ||
inputElement: _q(FORM_ID.phoneNumber), | ||
selectErrorMessage() { | ||
if (!this.isFieldValid()) return this.errorMessage; | ||
return null; | ||
}, | ||
isFieldValid() { | ||
const phoneNumber = this.inputElement.value; | ||
const phoneNumberRegexp = PATTERN.phoneNumber; | ||
return phoneNumber !== "" && phoneNumberRegexp.test(phoneNumber); | ||
}, | ||
errorMessageElement: _q(ERROR_MSG_ID.phoneNumber), | ||
errorMessage: "형식에 맞지 않는 번호입니다.", | ||
passMessage: "", | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
const fetch = require("node-fetch"); | ||
|
||
const URL = "https://test-codesquad-team1-sign-up.herokuapp.com/"; | ||
|
||
export default { | ||
checkDuplicate: value => { | ||
fetch(`${URL}users/duplicate/id/${value}`, { | ||
mode: "no-cors", | ||
}) | ||
.then(response => response.json()) | ||
.then(json => console.log(json)); | ||
}, | ||
send: userData => { | ||
fetch(`${URL}api/users/create`, { | ||
method: "POST", | ||
mode: "no-cors", | ||
body: JSON.stringify(userData), | ||
headers: { | ||
"Content-Type": "application/json", | ||
}, | ||
}) | ||
.then(res => res.json()) | ||
.then(response => console.log("Success:", JSON.stringify(response))) | ||
.catch(error => console.error("Error:", error)); | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
export default new Map([ | ||
["userId", null], | ||
["password", null], | ||
["checkPassword", null], | ||
["name", null], | ||
["year", null], | ||
["month", null], | ||
["day", null], | ||
["birthDay", null], | ||
["gender", null], | ||
["email", null], | ||
["phoneNumber", null], | ||
["interest", null], | ||
["terms", null], | ||
]); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
export const _q = str => { | ||
return document.querySelector(str); | ||
}; | ||
|
||
export const _qa = str => { | ||
return document.querySelectorAll(str); | ||
}; | ||
|
||
export const pipe = (...fns) => value => fns.reduce((acc, fn) => fn(acc), value); | ||
|
||
export const daysInMonth = num => { | ||
switch (num) { | ||
case "2": | ||
return 28; | ||
case "4": | ||
case "6": | ||
case "9": | ||
case "11": | ||
return 30; | ||
default: | ||
return 31; | ||
} | ||
}; | ||
|
||
export const toggleClass = (target = null, addClassName, removeClassName) => { | ||
if (!target || target.classList.contains(addClassName)) return; | ||
target.classList.add(addClassName); | ||
target.classList.remove(removeClassName); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import inputFields from "./inputFields.js"; | ||
import userData from "./userData.js"; | ||
import { _q, toggleClass } from "./util.js"; | ||
import { NUM_KEY_CODE_ZERO, NUM_KEY_CODE_NINE, TOGGLE_CLASS } from "./constants.js"; | ||
|
||
const generateErrorMessage = (element = null, message) => { | ||
if (!element) return; | ||
element.innerHTML = message; | ||
}; | ||
|
||
const setUserData = (key, value) => { | ||
return userData.set(key, value); | ||
}; | ||
|
||
const validateInputForms = event => { | ||
Object.keys(inputFields).forEach(field => { | ||
const currentField = inputFields[field]; | ||
if (event.target === currentField.inputElement) { | ||
let errorMessage = currentField.selectErrorMessage(); | ||
const messageElement = currentField.errorMessageElement; | ||
if (errorMessage === null) { | ||
const inputValue = currentField.inputElement.value; | ||
const { passMessage } = currentField; | ||
errorMessage = passMessage; | ||
setUserData(field, inputValue); | ||
toggleClass(messageElement, TOGGLE_CLASS.pass, TOGGLE_CLASS.error); | ||
} else { | ||
setUserData(field, null); | ||
toggleClass(messageElement, TOGGLE_CLASS.error, TOGGLE_CLASS.pass); | ||
} | ||
generateErrorMessage(messageElement, errorMessage); | ||
} | ||
}); | ||
}; | ||
|
||
const preventKeypressExceptNum = event => { | ||
const { year } = inputFields.birthDay.inputElement; | ||
const { day } = inputFields.birthDay.inputElement; | ||
const phoneNumber = inputFields.phoneNumber.inputElement; | ||
if (event.target === year || event.target === day || event.target === phoneNumber) { | ||
if (event.keyCode < NUM_KEY_CODE_ZERO || event.keyCode > NUM_KEY_CODE_NINE) { | ||
event.returnValue = false; | ||
} | ||
} | ||
}; | ||
|
||
const signupForm = _q("form"); | ||
const buttons = _q(".btn-wrap"); | ||
|
||
signupForm.addEventListener("input", event => validateInputForms(event)); | ||
signupForm.addEventListener("keypress", event => preventKeypressExceptNum(event)); | ||
|
||
buttons.addEventListener("click", event => { | ||
event.preventDefault(); | ||
if (event.target === _q(".submit-btn")) console.log(userData); | ||
}); |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
@import "./main.scss"; | ||
|
||
.signout-btn { | ||
margin-top: $input-gap * 4; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,8 +9,6 @@ | |
top: 0; | ||
left: 0; | ||
z-index: 1; | ||
opacity: 1; | ||
transition: opacity 0.2s ease; | ||
} | ||
|
||
.modal { | ||
|
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
@import "./main.scss"; | ||
|
||
.signin-btn { | ||
margin-top: $input-gap * 4; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,8 +11,7 @@ | |
} | ||
|
||
.hidden { | ||
visibility: hidden; | ||
opacity: 0; | ||
display: none; | ||
} | ||
|
||
.disabled { | ||
|
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
import "./scss/signin.scss"; |
Oops, something went wrong.