diff --git a/img/favicon.ico b/img/favicon.ico new file mode 100644 index 00000000..32b7375f Binary files /dev/null and b/img/favicon.ico differ diff --git a/index.html b/index.html index b8569267..c4862417 100644 --- a/index.html +++ b/index.html @@ -9,11 +9,43 @@ crossorigin href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.min.css" /> + - 판다마켓 + + 판다 마켓 + + + + + + + + + + + + + + + + + + @@ -33,7 +65,11 @@
-

일상의 모든 물건을
거래해 보세요

+

+ 일상의 모든 물건을 +
+ 거래해 보세요 +

구경하러 가기
Hot item
- 인기 상품을
+ 인기 상품을 +
확인해 보세요

- 가장 HOT한 중고거래 물품을
+ 가장 HOT한 중고거래 물품을 +
판다 마켓에서 확인해 보세요

@@ -67,11 +105,13 @@
Search
- 구매를 원하는
+ 구매를 원하는 +
상품을 검색하세요

- 구매하고 싶은 물품은 검색해서
+ 구매하고 싶은 물품은 검색해서 +
쉽게 찾아보세요

@@ -92,11 +132,13 @@
Register
- 판매를 원하는
+ 판매를 원하는 +
상품을 등록하세요

- 어떤 물건이든 판매하고 싶은 상품을
+ 어떤 물건이든 판매하고 싶은 상품을 +
쉽게 등록하세요

@@ -106,7 +148,8 @@

- 믿을 수 있는
+ 믿을 수 있는 +
판다마켓 중고 거래

@@ -121,22 +164,22 @@ diff --git a/js/common.js b/js/common.js new file mode 100644 index 00000000..2fac942e --- /dev/null +++ b/js/common.js @@ -0,0 +1,46 @@ +/* 에러 메시지 처리 */ +function wrongInput(input, span, validateFunction) { + const errorMessage = validateFunction(input); + if (errorMessage) { + input.classList.add("warning"); + input.classList.remove("done"); + span.textContent = errorMessage; + } else { + input.classList.remove("warning"); + input.classList.add("done"); + span.textContent = ""; + } + input.parentElement.appendChild(span); + if (span.textContent === "") { + input.parentElement.removeChild(span); + } +} + +/* 눈모양 버튼 클릭시 비밀번호 보이기 / 가리기 */ +function togglePasswordVisibility(button) { + const passwordInput = button.previousElementSibling; + if (passwordInput.type === "password") { + passwordInput.type = "text"; + button.classList.add("visible"); + } else { + passwordInput.type = "password"; + button.classList.remove("visible"); + } +} + +/* inputs에 모두 done 클래스가 있다면 버튼 활성화 */ +function activateButton(button, inputs) { + if (inputs.every((input) => input.classList.contains("done"))) { + button.disabled = false; + } else { + button.disabled = true; + } +} + +// 버튼 클릭시 특정 페이지로 이동 +function redirectToPage(event, redirectUrl) { + event.preventDefault(); + window.location.href = redirectUrl; +} + +export { wrongInput, togglePasswordVisibility, activateButton, redirectToPage }; diff --git a/js/login.js b/js/login.js new file mode 100644 index 00000000..2c6b7be3 --- /dev/null +++ b/js/login.js @@ -0,0 +1,76 @@ +import { + wrongInput, + togglePasswordVisibility, + activateButton, + redirectToPage, +} from "./common.js"; + +const emailInput = document.querySelector("#input-email"); +const passwordInput = document.querySelector("#input-password"); +const loginButton = document.querySelector(".login-page .submit-button"); +const loginForm = document.querySelector(".login-page .form-container"); + +const wrongEmail = document.createElement("span"); +const wrongPassword = document.createElement("span"); + +const inputArray = [emailInput, passwordInput]; + +wrongEmail.classList.add("error-message"); +wrongPassword.classList.add("error-message"); + +loginButton.disabled = true; + +function validateEmail(input) { + if (input.value === "") { + return "이메일을 입력해주세요."; + } else if (!input.checkValidity()) { + return "잘못된 이메일 형식입니다."; + } +} + +function validatePassword(input) { + if (input.value === "") { + return "비밀번호를 입력해주세요."; + } else if (input.value.length < 8) { + return "비밀번호를 8자 이상 입력해주세요."; + } +} + +/* email 에러 메시지 처리 */ +emailInput.addEventListener("focusout", () => + wrongInput(emailInput, wrongEmail, validateEmail) +); +emailInput.addEventListener("input", () => + wrongInput(emailInput, wrongEmail, validateEmail) +); + +/* password 에러 메시지 처리 */ +passwordInput.addEventListener("focusout", () => + wrongInput(passwordInput, wrongPassword, validatePassword) +); +passwordInput.addEventListener("input", () => + wrongInput(passwordInput, wrongPassword, validatePassword) +); + +/* email, password에 유효한 값이 입력되면 로그인 페이지 버튼 활성화 */ +inputArray.forEach((input) => { + input.addEventListener("input", () => + activateButton(loginButton, inputArray) + ); +}); + +inputArray.forEach((input) => { + input.addEventListener("focusout", () => + activateButton(loginButton, inputArray) + ); +}); + +/* 로그인 버튼 클릭시 items 페이지로 이동 */ +loginForm.addEventListener("submit", (event) => + redirectToPage(event, "/items.html") +); + +/* 눈모양 버튼 클릭시 */ +document.querySelectorAll(".visibility").forEach((button) => { + button.addEventListener("click", () => togglePasswordVisibility(button)); +}); diff --git a/js/signup.js b/js/signup.js new file mode 100644 index 00000000..b1895b92 --- /dev/null +++ b/js/signup.js @@ -0,0 +1,125 @@ +import { + wrongInput, + togglePasswordVisibility, + activateButton, + redirectToPage, +} from "./common.js"; + +const emailInput = document.querySelector("#input-email"); +const nicknameInput = document.querySelector("#input-nickname"); +const passwordInput = document.querySelector("#input-password"); +const passwordCheckInput = document.querySelector("#input-password-check"); +const signupButton = document.querySelector(".signup-page .submit-button"); +const signupForm = document.querySelector(".signup-page .form-container"); + +const wrongEmail = document.createElement("span"); +const wrongNickname = document.createElement("span"); +const wrongPassword = document.createElement("span"); +const wrongpasswordCheck = document.createElement("span"); + +const inputArray = [ + emailInput, + nicknameInput, + passwordInput, + passwordCheckInput, +]; + +wrongEmail.classList.add("error-message"); +wrongNickname.classList.add("error-message"); +wrongPassword.classList.add("error-message"); +wrongpasswordCheck.classList.add("error-message"); + +signupButton.disabled = true; + +function validateEmail(input) { + if (input.value === "") { + return "이메일을 입력해주세요."; + } else if (!input.checkValidity()) { + return "잘못된 이메일 형식입니다."; + } +} + +function validateNickname(input) { + if (input.value === "") { + return "닉네임을 입력해주세요."; + } +} + +function validatePassword(input) { + if (input.value === "") { + return "비밀번호를 입력해주세요."; + } else if (input.value.length < 8) { + return "비밀번호를 8자 이상 입력해주세요."; + } +} + +function wrongPasswordCheckEvent() { + if (passwordCheckInput.value === "") { + wrongpasswordCheck.textContent = ""; + passwordCheckInput.classList.remove("warning", "done"); + } else if (passwordCheckInput.value !== passwordInput.value) { + passwordCheckInput.classList.add("warning"); + passwordCheckInput.classList.remove("done"); + wrongpasswordCheck.textContent = "비밀번호가 일치하지 않습니다."; + } else { + passwordCheckInput.classList.remove("warning"); + passwordCheckInput.classList.add("done"); + wrongpasswordCheck.textContent = ""; + } + passwordCheckInput.parentElement.appendChild(wrongpasswordCheck); + if (wrongpasswordCheck.textContent === "") { + passwordCheckInput.parentElement.removeChild(wrongpasswordCheck); + } +} + +/* email 에러 메시지 처리 */ +emailInput.addEventListener("focusout", () => + wrongInput(emailInput, wrongEmail, validateEmail) +); +emailInput.addEventListener("input", () => + wrongInput(emailInput, wrongEmail, validateEmail) +); + +/* nickname 에러 메시지 처리 */ +nicknameInput.addEventListener("focusout", () => + wrongInput(nicknameInput, wrongNickname, validateNickname) +); +nicknameInput.addEventListener("input", () => + wrongInput(nicknameInput, wrongNickname, validateNickname) +); + +/* password 에러 메시지 처리 */ +passwordInput.addEventListener("focusout", () => + wrongInput(passwordInput, wrongPassword, validatePassword) +); +passwordInput.addEventListener("input", () => + wrongInput(passwordInput, wrongPassword, validatePassword) +); + +/* password-check 에러 메시지 처리 */ +passwordInput.addEventListener("input", wrongPasswordCheckEvent); // password가 변경되어도 즉시 password-check과 비교 +passwordCheckInput.addEventListener("focusout", wrongPasswordCheckEvent); +passwordCheckInput.addEventListener("input", wrongPasswordCheckEvent); + +/* email, nickname, password, password-check에 유효한 값이 입력되면 회원가입 페이지 버튼 활성화 */ +inputArray.forEach((input) => { + input.addEventListener("input", () => + activateButton(signupButton, inputArray) + ); +}); + +inputArray.forEach((input) => { + input.addEventListener("focusout", () => + activateButton(signupButton, inputArray) + ); +}); + +/* 회원가입 버튼 클릭시 로그인 페이지로 이동 */ +signupForm.addEventListener("submit", (event) => + redirectToPage(event, "/login.html") +); + +/* 눈모양 버튼 클릭시 */ +document.querySelectorAll(".visibility").forEach((button) => { + button.addEventListener("click", () => togglePasswordVisibility(button)); +}); diff --git a/login.html b/login.html index bf4f0aaf..13caa5f4 100644 --- a/login.html +++ b/login.html @@ -3,20 +3,13 @@ - - - - - + @@ -25,21 +18,23 @@
@@ -60,18 +55,19 @@
@@ -79,6 +75,8 @@

판다마켓이 처음이신가요?

회원가입
+ + diff --git a/signup.html b/signup.html index dc21ec7f..d46f7f8a 100644 --- a/signup.html +++ b/signup.html @@ -9,6 +9,7 @@ crossorigin href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.min.css" /> + @@ -17,33 +18,35 @@
-
- +
+ +
-
@@ -75,18 +78,19 @@

간편 로그인하기

-
@@ -95,5 +99,6 @@ 로그인
+ diff --git a/style/auth.css b/style/auth.css index 45100db7..6f06905f 100644 --- a/style/auth.css +++ b/style/auth.css @@ -11,7 +11,7 @@ display: flex; justify-content: center; padding-bottom: 4rem; - width: 64rem; + max-width: 64rem; } .logo { @@ -63,10 +63,13 @@ gap: 1.6rem; } +.email-input input, +.nickname-input input { + width: 100%; +} + .password-input { position: relative; - display: inline-block; - width: 100%; } .password-input input { @@ -74,6 +77,20 @@ padding-right: 4.8rem; } +.form-container .warning { + border: 1px solid var(--red); +} + +.error-message { + display: inline-block; + margin-left: 16px; + margin-top: 8px; + font-size: 14px; + font-weight: 600; + line-height: 24px; + color: var(--red); +} + .visibility { position: absolute; right: 2.4rem; @@ -86,17 +103,25 @@ background-color: transparent; } +.visible { + background-image: url("../img/login/btn_visibility_on.png"); +} + .submit-button { height: 5.6rem; border: none; border-radius: 40px; - background-color: var(--blue); + background-color: var(--blue100); color: var(--gray100); font-size: 2rem; font-weight: 600; line-height: 3.2rem; } +.submit-button:disabled { + background-color: var(--gray400); +} + .social-login { background-color: #e6f2ff; display: flex; @@ -110,16 +135,16 @@ border-radius: 8px; } -ul { +.social-list { display: flex; gap: 1.6rem; } -li a { +.social-list a { display: flex; } -li img { +.social-list img { width: 4.2rem; } diff --git a/style/base.css b/style/base.css index 1ce7d201..b6a4c6bc 100644 --- a/style/base.css +++ b/style/base.css @@ -8,7 +8,10 @@ --gray700: #374151; --gray800: #1f2937; --gray900: #111827; - --blue: #3692ff; + --blue100: #3692ff; + --blue200: #1967d6; + --blue300: #1251aa; + --red: #f74747; } * { diff --git a/style/home.css b/style/home.css index 4c459a7e..a2d31908 100644 --- a/style/home.css +++ b/style/home.css @@ -21,7 +21,7 @@ nav { font-size: 1.6rem; font-weight: 600; color: #ffffff; - background-color: var(--blue); + background-color: var(--blue100); border-radius: 8px; padding: 12px 23px; } @@ -80,7 +80,7 @@ nav { font-size: 2rem; font-weight: 600; color: #ffffff; - background-color: var(--blue); + background-color: var(--blue100); padding: 16px 124px; border-radius: 40px; margin-top: 3.2rem; @@ -123,7 +123,7 @@ nav { font-size: 1.8rem; font-weight: 700; line-height: 5.6rem; - color: var(--blue); + color: var(--blue100); } .big-text { diff --git a/style/home_media.css b/style/home_media.css index 1ad4cace..f94126ac 100644 --- a/style/home_media.css +++ b/style/home_media.css @@ -1,4 +1,4 @@ -/* Tablet: 768px 이상 ~ 1199px 이하 */ +/* Tablet: 1199px 까지 적용 */ @media screen and (max-width: 1199px) { html { font-size: 8px; @@ -85,7 +85,7 @@ } } -/* Mobile: 375px 이상 ~ 767px 이하 */ +/* Mobile: 767px 이하까지 적용 */ @media screen and (max-width: 767px) { html { font-size: 6px;