Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
43 changes: 21 additions & 22 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
<header>
<div class="header-content">
<a href="/">
<img src="./src/assets/icons/판다 마켓 로고.svg" alt="판다 마켓 로고" />
<img src="./src/assets/icons/panda-market-logo.svg" alt="판다 마켓 로고" />
Copy link
Collaborator

Choose a reason for hiding this comment

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

굿굿 ! 파일명에 띄어쓰기, 한글이 없어졌군요. 👍

</a>
<a href="./src/pages/login.html">
<button class="button--active login-button">로그인</button>
<button class="primary-button login-button">로그인</button>
</a>
</div>
</header>
Expand All @@ -30,7 +30,7 @@ <h1 class="main-title-h1">
거래해 보세요
</h1>
<a href="./src/pages/items.html">
<button class="button--active visit-button">구경하러 가기</button>
<button class="primary-button visit-button">구경하러 가기</button>
</a>
</div>
<div class="main-title-content-right">
Expand All @@ -44,34 +44,34 @@ <h1 class="main-title-h1">
<img src="./src/assets/images/popular-items.png" alt="인기 상품 검색" />
</div>
<div class="main-content-right-text">
<div class="main-content-text-header">
<p class="main-content-text-header">
Hot item
</div>
<div class="main-content-text-title">
</p>
<p class="main-content-text-title">
인기 상품을 <br />
확인해 보세요
</div>
<div class="main-content-text-detail">
</p>
<p class="main-content-text-detail">
가장 HOT한 중고거래 물품을 <br />
판다 마켓에서 확인해 보세요
</div>
</p>
Comment on lines +47 to +57
Copy link
Collaborator

Choose a reason for hiding this comment

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

(의견/제안) h 태그를 활용해볼 수도 있을 것 같아요 !

기존의미는 다음과 같습니다:
내용: 인기 상품을 확인해 보세요
내용: 가장 HOT한 중고거래 물품을 판다 마켓에서 확인해 보세요


그리고 h를 적용한다면 의미가 다음과 같아집니다:
제목: 인기 상품을 확인해 보세요
내용: 가장 HOT한 중고거래 물품을 판다 마켓에서 확인해 보세요


어떤 의미가 효준님께서 나타내시고 싶은 내용인지 한 번 고민해보세요 ! 😊

</div>
</div>
</div>
<div class="main-block">
<div class="main-content">
<div class="main-content-left-text">
<div class="main-content-text-header">
<p class="main-content-text-header">
Search
</div>
<div class="main-content-text-title">
</p>
<p class="main-content-text-title">
구매를 원하는 <br />
상품을 검색하세요
</div>
<div class="main-content-text-detail">
</p>
<p class="main-content-text-detail">
구매하고 싶은 물품은 검색해서 <br />
쉽게 찾아보세요
</div>
</p>
</div>
<div class="main-content-picture">
<img src="./src/assets/images/search.png" alt="상품 검색" />
Expand All @@ -84,18 +84,17 @@ <h1 class="main-title-h1">
<img src="./src/assets/images/register.png" alt="상품 등록" />
</div>
<div class="main-content-right-text">
<div class="main-content-text-header">
<p class="main-content-text-header">
Register
</div>
<div class="main-content-text-title">
</p>
<p class="main-content-text-title">
판매를 원하는<br />
상품을 등록하세요
</div>
<div class="main-content-text-detail">
<!--figma에서 시킨대로 한 거 같은데 글자가 다 들어가지 못하는 거 같습니다! 어떻게 해결하면 좋을지 조언 부탁드립니다!-->
</p>
<p class="main-content-text-detail">
어떤 물건이든 판매하고 싶은 상품을 </br />
쉽게 등록하세요
</div>
</p>
</div>
</div>
</div>
Expand Down
Binary file added src/assets/icons/google_icon.png
Copy link
Collaborator

Choose a reason for hiding this comment

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

벡터 이미지는 svg로 저장하시는걸 추천드려요 !

이하 MDN
SVG(Scalable Vector Graphics)는 2차원 벡터 그래픽을 서술하는 XML 기반의 마크업 언어입니다. SVG는 텍스트 기반의 열린 웹 표준 중 하나로, 모든 사이즈에서 깔끔하게 렌더링 되는 이미지를 서술하며 CSS, DOM, JavaScript, SMIL (en-US) 등 다른 웹 표준과도 잘 동작하도록 설계됐습니다. SVG는 달리 말하자면 HTML과 텍스트의 관계를 그래픽에 적용한 것입니다

image

이미지 파일은 최소 단위가 픽셀로 되어있으며 확대했을 때 이미지가 깨질 수 있어요 !
피그마에서 export하실 때에 svgexport할 수 있습니다 😊

Rester vs Vector

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 src/assets/icons/kakaotalk_icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/assets/icons/visibility_off_btn.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions src/assets/icons/visibility_on_btn.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
43 changes: 41 additions & 2 deletions src/pages/login.html
Original file line number Diff line number Diff line change
@@ -1,11 +1,50 @@
<!DOCTYPE html>
<html lang="en">
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!--pretendard 폰트-->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css">
<link rel="stylesheet" href="/src/styles/reset.css">
<link rel="stylesheet" href="/src/styles/global.css">
<link rel="stylesheet" href="/src/styles/pages/login.css">
<title>login</title>
</head>
<body>
login!
<main>
<a href="/index.html">
<img src="/src/assets/icons/panda-market-logo.svg" alt="판다 마켓 로고" class="logo">
</a>
<div class="content-wrapper">
<div class="form-structure">
<label for="email" class="form-label">이메일</label>
<input id="email" class="form-input" type="email" placeholder="이메일을 입력해주세요">
Comment on lines +20 to +21
Copy link
Collaborator

Choose a reason for hiding this comment

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

굿굿 ! 라벨과 인풋이 적절히 작성되었군요 !!

type, id 그리고 placeholder 등 속성들 또한 적절합니다 !
추가적으로 namerequired도 고려해볼 수 있겠네요 !

  • name: name<form>을 사용해서 추 후 submit을 사용하여 접근할 때 사용될 수 있습니다.
  • required: required<form> 내부에서 서식을 작성하지 않았을 때 브라우저에서 유저에게 피드백을 줄 수 있습니다.

Copy link
Collaborator

Choose a reason for hiding this comment

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

<input>에 대한 속성과 관련하여

<input>에는 용이한 속성들이 상당히 많습니다 !

  • 숫자의 범위를 지정하는 max, min
  • 글자 수를 제한하는 maxLenght, minLenght
  • 그 외 의외의 typedate, email, file, image ...
    제공되는 유용한 속성들을 모르고 개발하게 되면 자바스크립트로 만들게 되는 경우도 있어요.

예를 들어서 max라는 속성을 모르면 input 값이 입력되었을 때 값에 대한 유효성 검사를 하고 input에 값을 넣어주는 번거로운 일도 할 수도 있어요.
(제가 처음 개발할 때 그랬습니다... 🥲)

특히 리액트로 넘어가게되면 javascript가 html 접근하는 허들이 낮아지면서 위와 같은 사례가 종종 보여요.

그래서 특히 input과 관련하여서는 꼭 한번 즈음 mdn 공식 문서를 처음부터 끝까지 러프하게라도 읽어보시는걸 추천드려요.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

넵 추천 감사합니다!

</div>
<div class="form-structure">
<label for="password" class="form-label">비밀번호</label>
<div class="input-wrapper">
<input id="password" class="form-input" type="password" placeholder="비밀번호를 입력해주세요">
<img class="input-icon" src="/src/assets/icons/visibility_on_btn.svg" alt="비밀번호 보기">
</div>
</div>
<button class="primary-button login-button" disabled>로그인</button>
<div class="social-login">
<p>간편 로그인하기</p>
<ul class="icon-list">
<a href="https://www.google.com" class="circle white-background">
<img class="google-icon" src="/src/assets/icons/google_icon.png" alt="구글 로그인">
</a>
<a href="https://www.kakaocorp.com/page/" class="circle kakao-background">
<img class="kakao-icon" src="/src/assets/icons/kakaotalk_icon.png" alt="카카오 로그인">
</a>
</ul>
</div>
<div class="signup-prompt">
<span>판다마켓이 처음이신가요?</span>
<a href="/src/pages/signup.html">회원가입</a>
</div>
</div>
</main>
<script type="module" src="/src/scripts/pages/login.js"></script>
</body>
</html>
61 changes: 61 additions & 0 deletions src/pages/signup.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!--pretendard 폰트-->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css">
<link rel="stylesheet" href="/src/styles/reset.css">
<link rel="stylesheet" href="/src/styles/global.css">
<link rel="stylesheet" href="/src/styles/pages/signup.css">
<title>signup</title>
</head>
<body>
<main>
<a href="/index.html">
<img src="/src/assets/icons/panda-market-logo.svg" alt="판다 마켓 로고" class="logo">
</a>
<div class="content-wrapper">
<div class="form-structure">
<label for="email" class="form-label">이메일</label>
<input id="email" class="form-input" type="email" placeholder="이메일을 입력해주세요">
</div>
<div class="form-structure">
<label for="nickname" class="form-label">닉네임</label>
<input id="nickname" class="form-input" type="text" placeholder="닉네임을 입력해주세요">
</div>
<div class="form-structure">
<label for="password" class="form-label">비밀번호</label>
<div class="input-wrapper">
<input id="password" class="form-input" type="password" placeholder="비밀번호를 입력해주세요">
<img class="input-icon" src="/src/assets/icons/visibility_on_btn.svg" alt="비밀번호 보기">
</div>
</div>
<div class="form-structure">
<label for="password" class="form-label">비밀번호 확인</label>
<div class="input-wrapper">
<input id="password" class="form-input" type="password" placeholder="비밀번호를 입력해주세요">
<img class="input-icon" src="/src/assets/icons/visibility_on_btn.svg" alt="비밀번호 보기">
</div>
</div>
<button class="primary-button login-button" disabled>회원가입</button>
<div class="social-login">
<p>간편 로그인하기</p>
<ul class="icon-list">
<a href="https://www.google.com" class="circle white-background">
<img class="google-icon" src="/src/assets/icons/google_icon.png" alt="구글 로그인">
</a>
<a href="https://www.kakaocorp.com/page/" class="circle kakao-background">
<img class="kakao-icon" src="/src/assets/icons/kakaotalk_icon.png" alt="카카오 로그인">
</a>
</ul>
</div>
<div class="login-prompt">
<span>이미 회원이신가요?</span>
<a href="/src/pages/login.html">로그인</a>
</div>
</div>
</main>
<script type="module" src="/src/scripts/pages/signup.js"></script>
</body>
</html>
49 changes: 49 additions & 0 deletions src/scripts/global.js
Copy link
Collaborator

Choose a reason for hiding this comment

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

(의견) global.js라고 하기에는 특정 리소스에 영향을 주는 것 같아요 !

아마도, 로그인과 회원가입 두 스크립트에서 사용하기에 global.js가 된 것 같아요. 다만, global이라는 키워드로 하기에는 특정 사용자 플로우에 더욱 가까운 것 같습니다 !
auth라는 키워드가 더 적합하지 않을까 싶어요 !

Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
export function setVisibilityToggle(inputWrapperSelector) {
const inputWrapperList = document.querySelectorAll(inputWrapperSelector);

inputWrapperList.forEach((wrapper) => {
wrapper.addEventListener("click", event => {
const target = event.target;
if(target.classList.contains("input-icon")) {
const input = wrapper.querySelector("input");
const icon = target;

if (input.type === "password")
{
input.type = "text";
icon.src = "/src/assets/icons/visibility_off_btn.svg";
icon.alt = "비밀번호 숨기기";
}
else
{
input.type = "password";
icon.src = "/src/assets/icons/visibility_on_btn.svg";
icon.alt = "비밀번호 보기";
}
Comment on lines +11 to +22
Copy link
Collaborator

Choose a reason for hiding this comment

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

Guard Clause 패턴을 사용해볼까요?:

Suggested change
if (input.type === "password")
{
input.type = "text";
icon.src = "/src/assets/icons/visibility_off_btn.svg";
icon.alt = "비밀번호 숨기기";
}
else
{
input.type = "password";
icon.src = "/src/assets/icons/visibility_on_btn.svg";
icon.alt = "비밀번호 보기";
}
if (input.type === "password") {
input.type = "text";
icon.src = "/src/assets/icons/visibility_off_btn.svg";
icon.alt = "비밀번호 숨기기";
return;
}
input.type = "password";
icon.src = "/src/assets/icons/visibility_on_btn.svg";
icon.alt = "비밀번호 보기";

Guard Clause을 사용하게 되면 조건부를 조기에 처리할 수 있게 되어 핵심 로직을 구분할 수 있다는 장점이 있습니다. 따라서 가독성을 향상시킬 수 있어요.

또한, 미리 조건에 따라서 데이터의 범위를 좁힐 수 있기에 핵심 로직에서는 보장받은 데이터를 편리하게 사용할 수 있다는 장점도 있어요 😊

Guard Clause ?

다음과 같이 조기에 함수를 끝내는 기법을 의미합니다:

function calculateDiscount(price, discountRate) {
  // Guard Clause: 가격이나 할인율이 유효하지 않으면 함수 종료
  if (price <= 0 || discountRate <= 0 || discountRate > 1) {
    console.error("Invalid price or discount rate");
    return;
  }

  // 할인된 가격 계산
  const discountedPrice = price * (1 - discountRate);
  return discountedPrice;
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

제가 Guard Clause 패턴 사용을 권하신 이유에 대해 이해가 덜 된 거 같아 코멘트 남깁니다!
if else 문은 toggle을 시키는 부분으로 둘 다 핵심 로직이고 데이터의 범위와 상관없다 생각하여 제안해주신 코드가 잘 이해가 되지 않습니다!
조금 더 자세한 설명 부탁드려도 될까요???

Copy link
Collaborator

@kiJu2 kiJu2 Dec 31, 2024

Choose a reason for hiding this comment

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

지금처럼 if ... else로 하셔도 됩니다 ~!
지금처럼 하시든 Guard Clause를 사용하시든 논리적으로 같은 결과가 나오게 됩니다.

if (input.type === "password") { ... }
else if (input.type === "email") { ... }
else if (input.type === "tel") { ... }
else if (input.type === "number") { 
  if (number < 18) { ... }
  if (number > 24) { ... }
}
else { ... }

위와 같이 복잡한 if로 추가 확장될 수 있을 경우 코드를 간결히 하기 위해서 Guard Clause를 사용하곤 합니다.
근데 효준님의 함수의 경우 "인풋의 패스워드와 텍스트 타입을 변경하기 위한 함수"이므로 제안 정도로 보시고 판단 하에 적용하시면 됩니다 =)

}
})
})
}

export function setButtonDisable(parent, buttonClass) {
const button = parent.querySelector(buttonClass);

// 초기 상태 및 입력값 검증 함수
function validateInputs() {
const inputs = parent.querySelectorAll("input");
const allFilled = Array.from(inputs).every(input => input.value.trim() !== "");
button.disabled = !allFilled;
Comment on lines +34 to +35
Copy link
Collaborator

Choose a reason for hiding this comment

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

굿굿 ! 조건부를 그대로 사용하지 않고 이름을 붙였군요 !

조건에 이름을 붙임으로서 가독성이 좋습니다 ! 👍👍

}

/*
초기 상태에 button을 disabled로 설정하였으나
안전성과 일관성을 위해 호출
*/
validateInputs();

parent.addEventListener("input", (event) => {
if (event.target.tagName === "INPUT") {
validateInputs();
}
});
}
6 changes: 6 additions & 0 deletions src/scripts/pages/login.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { setVisibilityToggle, setButtonDisable } from "/src/scripts/global.js";

setVisibilityToggle(".input-wrapper");

const contentWrapper = document.querySelector(".content-wrapper");
setButtonDisable(contentWrapper, ".primary-button");
6 changes: 6 additions & 0 deletions src/scripts/pages/signup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { setVisibilityToggle, setButtonDisable } from "/src/scripts/global.js";

setVisibilityToggle(".input-wrapper");

const contentWrapper = document.querySelector(".content-wrapper");
setButtonDisable(contentWrapper, ".primary-button");
24 changes: 20 additions & 4 deletions src/styles/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,27 @@ body {
font-family: 'Pretendard', Arial, sans-serif;
}

/*
* 활성화된 버튼의 배경색 및 글자색 설정
*/
.button--active {
.primary-button {
cursor: pointer;
color: #F3F4F6;
background-color: #3692FF;
text-align: center;
}

.primary-button:disabled {
background-color: #9CA3AF;
opacity: 0.5;
}

.white-background {
background-color: white;
}

.kakao-background {
background-color: #FAE300;
}

/*정사각형 모양임이 확실할 때만 사용가능할 듯*/
.circle {
border-radius: 50%;
}
6 changes: 5 additions & 1 deletion src/styles/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ header {
display: flex;
justify-content: center;
padding: 9px 0;
background-color: white;
position: sticky;
top: 0;
}

.header-content {
Expand Down Expand Up @@ -73,7 +76,6 @@ header {
align-items: center;
padding: 0 24px;
gap: 64px;
width: 988px;
height: 444px;
border-radius: 12px;
background-color: #FCFCFC;
Expand All @@ -90,6 +92,7 @@ header {
.main-content-right-text {
display: flex;
flex-direction: column;
width: 350px;
gap: 12px;
align-items: flex-start;
text-align: left;
Expand All @@ -98,6 +101,7 @@ header {
.main-content-left-text {
display: flex;
flex-direction: column;
width: 350px;
gap: 12px;
align-items: flex-end;
text-align: right;
Expand Down
Loading
Loading