Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
b7a00e9
prettier 사용
leeetaesik Mar 20, 2025
912c5d2
login.css와 signup.css를 auth.css로 병합
leeetaesik Mar 20, 2025
4eff2e6
이미지명 수정
leeetaesik Mar 21, 2025
798548c
logo_lg를 여백 없는 이미지로 변경
leeetaesik Mar 21, 2025
1b0fc3d
reset.css와 utility.css의 일부를 common.css로 분리
leeetaesik Mar 21, 2025
4096a89
회원가입 버튼의 type 명시적으로 작성
leeetaesik Mar 21, 2025
bcc5eaa
눈 이미지 버튼으로 감싸줌
leeetaesik Mar 21, 2025
abca9e0
로그인 및 회원가입 input에 placeholder 추가
leeetaesik Mar 21, 2025
48e027d
로그인, 회원가입 페이지 모바일 반응형 디자인 적용
leeetaesik Mar 21, 2025
36f03c4
logo_sm 여백 제거, logo_typo 추가
leeetaesik Mar 21, 2025
91972a9
메인 페이지 반응형 디자인 적용
leeetaesik Mar 22, 2025
48a9717
og 메타태그 설정
leeetaesik Mar 22, 2025
df02d92
error color 추가
leeetaesik Mar 23, 2025
aaeb50d
auth.js파일 추가
leeetaesik Mar 23, 2025
973dc71
input에 값이 없다면 error테두리 적용
leeetaesik Mar 23, 2025
722efb8
input 값이 없을 경우 에러 메세지 추가
leeetaesik Mar 23, 2025
80a490d
이메일 형식에 맞지 않는 경우 추가
leeetaesik Mar 23, 2025
eadc1ba
비밀번호가 8자 미만인 경우 추가
leeetaesik Mar 23, 2025
8d84d0f
id명 checkPassword를 passwordCheck로 변경
leeetaesik Mar 23, 2025
e955c5a
비밀번호 일치 여부 확인 추가
leeetaesik Mar 23, 2025
5e9e5d9
input이 유효하면 파란 테두리 추가
leeetaesik Mar 23, 2025
1f39a24
버튼태그에는 이벤트가 적용되지 않게 함
leeetaesik Mar 23, 2025
c7c098f
버튼 활성화 추가
leeetaesik Mar 23, 2025
9592767
checkPassword 함수 업데이트
leeetaesik Mar 25, 2025
c97bd5f
로그인, 회원가입 버튼에 disabled 속성 추가
leeetaesik Mar 25, 2025
7e1f93e
활성화된 버튼 클릭시 페이지 이동 추가
leeetaesik Mar 25, 2025
26a13b2
눈 모양 아이콘 동작 추가
leeetaesik Mar 26, 2025
9c67c37
회원가입 버튼 경로 수정
leeetaesik Mar 26, 2025
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
75 changes: 59 additions & 16 deletions signup.css → auth.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,54 +2,84 @@ html {
color: var(--gray800);
}

body {
padding: 10vh 0;
}

.wrap {
max-width: 640px;
width: 100%;
margin: 0 auto;
}

.logo {
margin-top: 240px;
}

.logo a{
.logo a {
display: flex;
justify-content: center;
}

.logo img {
.logo img {
width: 60%;
}

.signup-form{
.login-form,
.signup-form {
display: flex;
flex-direction: column;
gap: 24px;
margin-top: 40px;
margin-top: 55px;
}

.input-group{
.input-group {
display: flex;
flex-direction: column;
gap: 16px;
position: relative;
}

.input-group input{
.input-group input {
padding: 16px 24px;
background-color: var(--gray100);
border-width: 0;
border-radius: 12px;
}

.input-group img {
.input-error {
outline: var(--error) solid 1.5px;
}

.input-valid {
outline: var(--blue) solid 1.5px;
}

.error-message {
color: var(--error);
padding-left: 16px;
}

.input-group button {
position: absolute;
right: 24px;
bottom: 16px;
top: 54px;
width: 24px;
height: 24px;
padding: 0px;
background-color: transparent;
}

.simple-login{
.input-group img {
width: 100%;
}

.button-disabled {
background-color: var(--gray400);
}

.button-disabled:active,
.button-disabled:hover {
background-color: var(--gray400)
}

.simple-login {
display: flex;
justify-content: space-between;
align-items: center;
Expand All @@ -59,22 +89,35 @@ html {
background-color: #E6F2FF;
}

.simple-login ul{
.simple-login ul {
display: flex;
gap: 16px;
}

.simple-login ul li img{
.simple-login ul li img {
width: 42px;
}

.to-login{
.to-signup,
.to-login {
display: flex;
justify-content: center;
gap: 4px;
margin-top: 24px;
}

.to-signup a,
.to-login a {
text-decoration: underline;
}

/* Mobile */
@media (min-width:375px) and (max-width:767px) {
body {
padding: 10vh 16px;
}

.wrap {
max-width: 400px;
}
}
174 changes: 174 additions & 0 deletions auth.js
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💊 제안
한 파일에서 로그인, 회원가입 공용으로 JS를 작성해주셨네요~
둘이 공통되는 부분이 많이 이렇게 해주신 것 같아요.
다만 그렇게 되면 코드가 복잡해져서 유지보수성이 떨어지고 로그인 페이지의 경우 불필요한 코드까지 알아야합니다~
가능하면 공통 로직들은 분리해주시고 각 페이지별 JS를 따로 만드시는 것을 추천드려요!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💊 제안
코드는 일정한 순서를 유지하는 것이 가독성을 높이는 데 도움이 됩니다.
현재 코드에서는 변수 선언과 함수 선언이 번갈아가며 작성되어 있어 흐름을 따라가기 어려울 수 있습니다.
일반적으로 변수 선언 → 함수 선언 → 실행 코드 순으로 작성하는 것이 읽기 쉽고 유지보수하기 좋습니다.

Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
const loginForm = document.querySelector(".login-form");
const signupForm = document.querySelector(".signup-form");

const setInputError = (event) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❗️ 수정요청
한 함수안에서 모든 인풋의 에러처리를 하고 있어 가독성이 많이 떨어집니다!
인풋 별 에러처리 로직을 분리하셔서 가독성을 높여보세요.

const setInputError = (event) => {
  if (event.target.closest("button")) return;

  const { id, value, validationMessage, nextElementSibling } = event.target;
  nextElementSibling?.remove();

  if (id === "useremail") {
    handleUserEmailError(event.target, validationMessage);
    return;
  }
  
  if (id === "password") {
    handlePasswordError(event.target, value);
    return;
  }
  
  if (id === "passwordCheck") {
    handlePasswordCheckError(event.target, value);
    return;
  }

  handleDefaultError(event.target, value);
};

if (event.target.closest("button")) {
return;
}
if (event.target.value === "") {
event.target.nextElementSibling?.remove();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💊 제안
이렇게 접근하시는 것도 나쁘지 않지만 이는 HTML 구조와 긴밀하게 연관되게 되므로,
HTML에서 위치만 변경되어도 작동되지 않을 위험이 커집니다~
가능하면 부모요소로 접근해 해당 요소 내에서 재탐색을 해보세요.

event.target.classList.add("input-error");
setErrorMessage(event.target, "empty");
} else if (event.target.id === "useremail") {
event.target.nextElementSibling?.remove();
if (event.target.validationMessage) {
event.target.classList.add("input-error");
setErrorMessage(event.target, "email");
} else {
event.target.classList.remove("input-error");
}
} else if (
event.target.id === "password" ||
event.target.id === "passwordCheck"
) {
event.target.nextElementSibling?.remove();
if (event.target.value.length < 8) {
event.target.classList.add("input-error");
setErrorMessage(event.target, "password");
} else {
event.target.classList.remove("input-error");
checkPassword();
}
} else {
event.target.classList.remove("input-error");
event.target.nextElementSibling?.remove();
}
};

const checkPassword = () => {
const password = document.querySelector("#password");
const passwordCheck = document.querySelector("#passwordCheck");
if (
password.value !== passwordCheck?.value &&
passwordCheck?.value.length >= 8
) {
passwordCheck.nextElementSibling?.remove();
passwordCheck.classList.add("input-error");
passwordCheck.classList.remove("input-valid");
setErrorMessage(passwordCheck, "passwordCheck");
} else if (password.value === passwordCheck?.value) {
passwordCheck.nextElementSibling?.remove();
passwordCheck.classList.remove("input-error");
passwordCheck.classList.add("input-valid");
}
};

const setErrorMessage = (element, type) => {
const errorMessage = document.createElement("p");
errorMessage.classList.add("error-message", "text-lg", "semibold");
if (type === "empty") {
if (!element.nextElementSibling) {
Comment on lines +59 to +60
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💊 제안
if문의 중첩은 가독성에 좋지 않으니 지금의 경우 아래처럼 하시면 더 좋을 것 같습니다.

Suggested change
if (type === "empty") {
if (!element.nextElementSibling) {
if (element.nextElementSibling) return; // 이 조건의 해당할 경우 아래 로직이 실행되지 않음
if (type === "empty") {

switch (element.id) {
case "useremail":
errorMessage.textContent = "이메일을 입력해주세요.";
break;
case "password":
errorMessage.textContent = "비밀번호를 입력해주세요.";
break;
case "nickname":
errorMessage.textContent = "닉네임을 입력해주세요.";
break;
case "passwordCheck":
errorMessage.textContent = "비밀번호 확인을 입력해주세요.";
break;
}
element.after(errorMessage);
}
} else if (type === "email") {
errorMessage.textContent = "잘못된 이메일 형식입니다.";
element.after(errorMessage);
} else if (type === "password") {
errorMessage.textContent = "비밀번호를 8자 이상 입력해주세요.";
element.after(errorMessage);
} else if (type === "passwordCheck") {
errorMessage.textContent = "비밀번호가 일치하지 않습니다.";
element.after(errorMessage);
}
};

const setInputValid = (event) => {
if (event.target.closest("button")) {
return;
}
if (!event.target.classList.contains("input-error")) {
event.target.classList.add("input-valid");
} else {
event.target.classList.remove("input-valid");
}
};

const isValidForm = (event) => {
for (let e of event.currentTarget) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💊 제안
for of 문을 쓰실때 재할당하는 것이 아니라면 const 로 선언해주세요!

Suggested change
for (let e of event.currentTarget) {
for (const target of event.currentTarget) {

if (e.tagName === "INPUT" && !e.classList.contains("input-valid")) {
return false;
}
}
return true;
};

const loginButton = document.querySelector(".login-button");
const signupButton = document.querySelector(".signup-button");

const toItems = (e) => {
e.preventDefault();
location.href = "./items.html";
};

const toLogin = (e) => {
e.preventDefault();
location.href = "./login.html";
};

const setLoginButton = (event) => {
if (isValidForm(event)) {
loginButton.disabled = false;
loginButton.classList.remove("button-disabled");
loginButton.addEventListener("click", toItems);
} else {
loginButton.disabled = true;
loginButton.classList.add("button-disabled");
loginButton.removeEventListener("click", toItems);
}
};

const setSignupButton = (event) => {
if (isValidForm(event)) {
signupButton.disabled = false;
signupButton.classList.remove("button-disabled");
signupButton.addEventListener("click", toLogin);
} else {
signupButton.disabled = true;
signupButton.classList.add("button-disabled");
signupButton.removeEventListener("click", toLogin);
}
};

const visibilityBtn = document.querySelectorAll(".visibility-btn");
let isVisible = false;
const toggleVisibility = (event) => {
if (isVisible) {
event.target.alt = "눈감음";
event.target.src = "images/ic_visibility_off.png";
event.target.parentElement.nextElementSibling.nextElementSibling.type =
"password";
} else {
event.target.alt = "눈 뜸";
event.target.src = "images/ic_visibility_on.png";
event.target.parentElement.nextElementSibling.nextElementSibling.type =
"text";
}
isVisible = !isVisible;
};
console.log(visibilityBtn);
for (let ele of visibilityBtn) {
console.log(ele);
ele.addEventListener("click", toggleVisibility);
}

loginForm?.addEventListener("focusout", setInputError);
loginForm?.addEventListener("focusout", setInputValid);
loginForm?.addEventListener("focusout", setLoginButton);

signupForm?.addEventListener("focusout", setInputError);
signupForm?.addEventListener("focusout", setInputValid);
signupForm?.addEventListener("focusout", setSignupButton);
22 changes: 22 additions & 0 deletions common.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
* {
box-sizing: border-box;
}

html {
font-family: Pretendard, sans-serif;
font-size: 16px;
}

:root {
--gray900: #111827;
--gray800: #1F2937;
--gray700: #374151;
--gray600: #4B5563;
--gray500: #6B7280;
--gray400: #9CA3AF;
--gray200: #E5E7EB;
--gray100: #F3F4F6;
--gray50: #F9FAFB;
--blue: #3692FF;
--error: #F74747;
}
File renamed without changes
File renamed without changes
Binary file modified images/logo_lg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/logo_sm.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/logo_typo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/og_image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading