-
Notifications
You must be signed in to change notification settings - Fork 15
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 #31 from kirinnim/basic-김주영-sprint3
[김주영] Sprint3
- Loading branch information
Showing
5 changed files
with
262 additions
and
25 deletions.
There are no files selected for viewing
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,95 @@ | ||
# ✨ Sprint mission 1&2 ✨ | ||
|
||
### [🌐 라이브 사이트 확인하기 🌐](https://kirinnim.netlify.app/) | ||
--- | ||
### 😃기본요구사항 바로가기 | ||
#### [공통](#a-1) | [로그인페이지](#a-2) | [회원가입페이지](#a-3) | ||
--- | ||
### 😳심화요구사항 바로가기 | ||
#### [공통](#b-1) | [랜딩페이지](#b-2) | [로그인, 회원가입 페이지 공통](#b-3) | ||
--- | ||
### 📔참고사항/멘토링 | ||
#### [주요변경사항](#c-1) | [스크린샷](#c-2) | 🔥[멘토에게](#c-3)🔥 | ||
----- | ||
|
||
# 요구사항 | ||
|
||
## 기본 요구사항 | ||
### 공통<a id="a-1"></a> | ||
- [X] Github에 스프린트 미션 PR을 만들어 주세요. | ||
로그인, 회원가입 페이지 공통 | ||
- [X] 로그인 및 회원가입 페이지의 이메일, 비밀번호, 비밀번호 확인 input에 필요한 유효성 검증 함수를 만들고 적용해 주세요. | ||
- [ ] 이메일 input에서 focus out 할 때, 값이 없을 경우 input에 빨강색 테두리와 아래에 “이메일을 입력해주세요.” | ||
빨강색 에러 메세지를 보입니다. | ||
- [ ] 이메일 input에서 focus out 할 때, 이메일 형식에 맞지 않는 경우 input에 빨강색 테두리와 | ||
아래에 “잘못된 이메일 형식입니다” 빨강색 에러 메세지를 보입니다. | ||
- [ ] 비밀번호 input에서 focus out 할 때, 값이 없을 경우 아래에 “비밀번호를 입력해주세요.” 에러 메세지를 보입니다 | ||
- [ ] 비밀번호 input에서 focus out 할 때, 값이 8자 미만일 경우 아래에 “비밀번호를 8자 이상 입력해주세요.” 에러 메세지를 보입니다. | ||
- [ ] input 에 빈 값이 있거나 에러 메세지가 있으면 ‘로그인’ 버튼은 비활성화 됩니다. | ||
- [ ] Input 에 유효한 값을 입력하면 ‘로그인' 버튼이 활성화 됩니다. | ||
- [ ] 활성화된 ‘로그인’ 버튼을 누르면 “/items” 로 이동합니다. | ||
<pre> | ||
const USER_DATA = [ | ||
{ email: '[email protected]', password: "codeit101!" }, | ||
{ email: '[email protected]', password: "codeit202!" }, | ||
{ email: '[email protected]', password: "codeit303!" }, | ||
{ email: '[email protected]', password: "codeit404!" }, | ||
{ email: '[email protected]', password: "codeit505!" }, | ||
{ email: '[email protected]', password: "codeit606!" }, | ||
]; | ||
</pre> | ||
|
||
### 로그인페이지<a id="a-2"></a> | ||
- [ ] 이메일과 비밀번호를 입력하고 로그인 버튼을 누른 후, 다음 조건을 참조하여 로그인 성공 여부를 alert 메시지로 출력합니다. | ||
- 만약 입력한 이메일이 데이터베이스(USER_DATA)에 없거나, 이메일은 일치하지만 비밀번호가 틀린 경우, '비밀번호가 일치하지 않습니다.'라는 메시지를 alert로 표시합니다 | ||
- 만약 입력한 이메일이 데이터베이스에 존재하고, 비밀번호도 일치할 경우, “/items”로 이동합니다. | ||
|
||
|
||
### 회원가입 페이지<a id="a-3"></a> | ||
- [ ] 회원가입을 위해 이메일, 닉네임, 비밀번호, 비밀번호 확인을 입력한 뒤, 회원가입 버튼을 클릭하세요. | ||
그 후에는 다음 조건에 따라 회원가입 가능 여부를 alert로 알려주세요. | ||
- 입력한 이메일이 이미 데이터베이스(USER_DATA)에 존재하는 경우, '사용 중인 이메일입니다'라는 메시지를 alert로 표시합니다. | ||
- 입력한 이메일이 데이터베이스(USER_DATA)에 없는 경우, 회원가입이 성공적으로 처리되었으므로 로그인 페이지(”/login”)로 이동합니다. | ||
--- | ||
|
||
## 심화 요구사항<a id="b-t"></a> | ||
### 공통<a id="b-1"></a> | ||
- [ ] 페이스북, 카카오톡, 디스코드, 트위터 등 SNS에서 판다마켓 랜딩 페이지(“/”) 공유 시 미리보기를 볼 수 있도록 | ||
랜딩 페이지 메타 태그를 설정합니다. | ||
- [ ] 미리보기에서 제목은 “판다마켓”, 설명은 “일상에서 모든 물건을 거래해보세요”로 설정합니다. | ||
- [ ] 주소와 이미지는 자유롭게 설정하세요. | ||
- [ ] 로그인, 회원가입 페이지에 공통으로 사용하는 로직이 있다면, 반복하지 않고 공통된 로직을 모듈로 분리해 사용해 주세요. | ||
|
||
### 랜딩페이지<a id="b-2"></a> | ||
- [ ] 브라우저에 현재 보이는 화면의 영역(viewport) 너비를 기준으로 분기되는 반응형 디자인을 적용합니다. | ||
- PC: 1200px 이상 | ||
- Tablet: 744px 이상 ~ 1199px 이하 | ||
- Mobile: 375px 이상 ~ 743px 이하 | ||
- 375px 미만 사이즈의 디자인은 고려하지 않습니다. | ||
- [ ] Tablet 사이즈로 작아질 때 최소 좌우 여백이 “판다마켓” 로고의 왼쪽에 여백 24px, “로그인” 버튼 오른쪽 여백 24px을 유지할 수 있도록 “판다마켓” 로고와 “로그인" 버튼의 간격이 가까워집니다. | ||
- [ ] Mobile 사이즈로 작아질 때 최소 좌우 여백이 “판다마켓” 로고의 왼쪽에 여백 16px, “로그인” 버튼 오른쪽 여백 16px을 유지할 수 있도록 “판다마켓” 로고와 “로그인" 버튼의 간격이 가까워집니다. | ||
- [ ] PC, Tablet 사이즈의 이미지 크기는 고정값을 사용합니다. | ||
- [ ] Mobile 사이즈의 이미지는 좌우 여백 32px을 제외하고 이미지 영역이 꽉 차게 구현합니다. | ||
(이때 가로가 커지는 비율에 맞춰 세로도 커져야 합니다.) | ||
- [ ] Mobile 사이즈 너비가 커지면, “Privacy Policy”, “FAQ”, “codeit-2023”이 있는 영역과 | ||
SNS 아이콘들이 있는 영역의 사이 간격이 커집니다. | ||
|
||
### 로그인, 회원가입 페이지 공통<a id="b-3"></a> | ||
- [ ] Tablet 사이즈에서 내부 디자인은 PC사이즈와 동일합니다. | ||
- [ ] Mobile 사이즈에서 좌우 여백 16px 제외하고 내부 요소들이 너비를 모두 차지합니다. | ||
- [ ] Mobile 사이즈에서 내부 요소들의 너비는 기기의 너비가 커지는 만큼 커지지만 400px을 넘지 않습니다. | ||
- [ ] 오류 메시지 모달을 구현합니다. 모달 내 내용은 alert 메시지와 동일합니다. | ||
- [ ] 비밀번호 및 비밀번호 확인 입력란에 눈 모양 아이콘 클릭 시 비밀번호 표시/숨기기 토글이 가능합니다. | ||
기본 상태는 비밀번호 숨김으로 설정합니다. | ||
|
||
--- | ||
## 기타참고사항 | ||
### 주요 변경사항<a id="c-1"></a> | ||
- null | ||
|
||
### 스크린샷<a id="c-2"></a> | ||
![image]() | ||
|
||
### 멘토에게 <a id="c-3"></a> | ||
- | ||
___ |
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 |
---|---|---|
|
@@ -27,11 +27,22 @@ | |
}; | ||
s.parentNode.insertBefore(tk, s); | ||
})(document); | ||
|
||
// #################################### | ||
// code for login, sign up (start here) | ||
// #################################### | ||
// temporary user data set | ||
const USER_DATA = [ | ||
{ email: '[email protected]', password: "codeit101!" }, | ||
{ email: '[email protected]', password: "codeit202!" }, | ||
{ email: '[email protected]', password: "codeit303!" }, | ||
{ email: '[email protected]', password: "codeit404!" }, | ||
{ email: '[email protected]', password: "codeit505!" }, | ||
{ email: '[email protected]', password: "codeit606!" }, | ||
]; | ||
// login page eye Icon control | ||
function pwShow() { | ||
var elem = document.getElementById("eyeChange"); | ||
var passwordInput = document.getElementById("userPassword"); | ||
const elem = document.getElementById("eyeChange"); | ||
const passwordInput = document.getElementById("userPassword"); | ||
|
||
if (passwordInput.type === "password") { | ||
passwordInput.type = "text"; | ||
|
@@ -42,8 +53,8 @@ function pwShow() { | |
} | ||
} | ||
function pwCheckShow() { | ||
var elem = document.getElementById("eyeChangeCheck"); | ||
var passwordInput = document.getElementById("pwCheck"); | ||
const elem = document.getElementById("eyeChangeCheck"); | ||
const passwordInput = document.getElementById("userPasswordConfirm"); | ||
|
||
if (passwordInput.type === "password") { | ||
passwordInput.type = "text"; | ||
|
@@ -53,3 +64,146 @@ function pwCheckShow() { | |
elem.classList = "fa-regular fa-eye"; | ||
} | ||
} | ||
//login page email check | ||
|
||
/* | ||
MDN DOMContentLoaded event | ||
참조 (https://developer.mozilla.org/ko/docs/Web/API/Document/DOMContentLoaded_event) | ||
*/ | ||
addEventListener("DOMContentLoaded", () => { | ||
document.getElementById('userEmail').addEventListener('focusout', validateEmail); | ||
document.getElementById('userNickname').addEventListener('focusout', validateNickname); | ||
document.getElementById('userPassword').addEventListener('focusout', validatePassword); | ||
document.getElementById('userPasswordConfirm').addEventListener('focusout', validatePasswordConfirm); | ||
document.getElementById('submitButton').addEventListener('click', handleSubmit); | ||
}); | ||
// onDOMContentLoaded = () => { | ||
// document.getElementById('userEmail').addEventListener('focusout', validateEmail); | ||
// }; | ||
|
||
|
||
function validateEmail() { | ||
const emailInput = document.getElementById('userEmail'); | ||
let emailError = document.getElementById('errorEmail'); | ||
|
||
// 에러 메시지 요소가 없으면 생성 | ||
if (!emailError) { | ||
emailError = document.createElement('p'); | ||
emailError.id = 'errorEmail'; | ||
emailError.className = 'errorMessage'; | ||
emailInput.insertAdjacentElement('afterend', emailError); | ||
} | ||
|
||
const emailValue = emailInput.value; | ||
|
||
emailError.innerText = ''; // 오류 메시지 초기화 | ||
emailInput.classList.remove('error-border'); // 빨간 테두리 제거 | ||
|
||
if (!emailValue) { | ||
// 값이 없을 때 | ||
emailError.innerText = '이메일을 입력해주세요.'; | ||
emailInput.classList.add('error-border'); | ||
} else if (!validateEmailFormat(emailValue)) { | ||
// 이메일 형식이 맞지 않을 때 | ||
emailError.innerText = '잘못된 이메일 형식입니다.'; | ||
emailError.style.color = 'red'; | ||
emailInput.classList.add('error-border'); | ||
} | ||
} | ||
// 이메일 형식 검사 함수 | ||
function validateEmailFormat(email) { | ||
const emailPattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/; | ||
return emailPattern.test(email); | ||
} | ||
|
||
// 닉네임 체크 | ||
// [문자열 정규식],{2~10자리}$/; | ||
const nickLength = /^[a-zA-Z0-9._%+-]{4,16}$/; | ||
function validateNickname(){ | ||
const userNickname = document.getElementById('userNickname'); | ||
let nicknameError = document.getElementById('errorNickname'); | ||
// 에러 메시지 요소가 없으면 생성 | ||
if (!nicknameError) { | ||
nicknameError = document.createElement('p'); | ||
nicknameError.id = 'errorNickname'; | ||
nicknameError.className = 'errorMessage'; | ||
userNickname.insertAdjacentElement('afterend', nicknameError); | ||
} | ||
// 닉네임 유효성 검사 | ||
if (!validateNicknameFormat(userNickname.value)) { | ||
nicknameError.textContent = "닉네임은 영문,숫자조합 4~16자리여야 합니다."; | ||
nicknameError.style.color = 'red'; | ||
} else { | ||
nicknameError.textContent = ""; // 에러 메시지 제거 | ||
} | ||
} | ||
// 닉네임 형식 검사 함수 | ||
function validateNicknameFormat(nickname) { | ||
return nickLength.test(nickname); | ||
} | ||
|
||
// 닉네임 입력 시 검사 함수 호출 | ||
document.getElementById('userNickname').addEventListener('input', validateNickname); | ||
|
||
// 비밀번호 유효성 검사 | ||
function validatePassword() { | ||
const passwordInput = document.getElementById('userPassword'); | ||
let passwordError = document.getElementById('errorPassword'); | ||
|
||
if (!passwordError) { | ||
passwordError = document.createElement('p'); | ||
passwordError.id = 'errorPassword'; | ||
passwordError.className = 'errorMessage'; | ||
passwordInput.insertAdjacentElement('afterend', passwordError); | ||
} | ||
|
||
const passwordValue = passwordInput.value; | ||
passwordError.innerText = ''; | ||
|
||
if (passwordValue.length < 8) { | ||
passwordError.innerText = '비밀번호는 최소 8자리여야 합니다.'; | ||
passwordError.style.color = 'red'; | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
// 비밀번호 확인 검사 | ||
function validatePasswordConfirm() { | ||
const passwordInput = document.getElementById('userPassword').value; | ||
const passwordConfirmInput = document.getElementById('userPasswordConfirm'); | ||
let passwordConfirmError = document.getElementById('errorPasswordConfirm'); | ||
|
||
if (!passwordConfirmError) { | ||
passwordConfirmError = document.createElement('p'); | ||
passwordConfirmError.id = 'errorPasswordConfirm'; | ||
passwordConfirmError.className = 'errorMessage'; | ||
passwordConfirmInput.insertAdjacentElement('afterend', passwordConfirmError); | ||
} | ||
|
||
passwordConfirmError.innerText = ''; | ||
|
||
if (passwordConfirmInput.value !== passwordInput) { | ||
passwordConfirmError.innerText = '비밀번호가 일치하지 않습니다.'; | ||
passwordConfirmError.style.color = 'red'; | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
// 최종 서브밋 검사 | ||
function handleSubmit(event) { | ||
event.preventDefault(); | ||
|
||
const isEmailValid = validateEmail(); | ||
const isNicknameValid = validateNickname(); | ||
const isPasswordValid = validatePassword(); | ||
const isPasswordConfirmValid = validatePasswordConfirm(); | ||
|
||
if (isEmailValid && isNicknameValid && isPasswordValid && isPasswordConfirmValid) { | ||
// 모든 검사 통과 시 폼 제출 | ||
document.getElementById('form').submit(); | ||
} else { | ||
alert('모든 필드를 올바르게 입력해주세요.'); | ||
} | ||
} |
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