-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Jsxcard #26
base: develop
Are you sure you want to change the base?
Jsxcard #26
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import React, { useState } from 'react'; | ||
import './Card.scss'; | ||
import "../styles/global.scss"; | ||
|
||
const Card = () => { | ||
const [likeCount, setLikeCount] = useState(0); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 사실 이 부분이 제가 볼 때는 각 이모티콘 옆에 숫자에 대한 부분인 것 같은데, 이 부분은 오히려 카드를 눌러서 무언가를 하는 부분이라기 보다는 post/{id} 부분의 시안에 나와있듯이 Navigation 바로 아래에 이모지 올리는 부분이 있고, 이모지 중 가장 많은 count값이 있는 3개를 보여주는 부분이 있는데, 그 부분과 마찬가지로 3개만 보여주는 그러한 용도라고 볼 수 있어요. 오히려 api를 써서 데이터를 받아오는 부분이라 이 부분은 그냥 통째로 프로퍼티로 해당 부분들을 받아오는 방식으로 구현을 하시거나 임의의 들어간 이모지 데이터에 대해 보여주거나 하는 방식이에요. |
||
const [smileCount, setSmileCount] = useState(0); | ||
const [heartCount, setHeartCount] = useState(0); | ||
|
||
const handleLikeClick = () => { | ||
setLikeCount(likeCount + 1); | ||
}; | ||
|
||
const handleSmileClick = () => { | ||
setSmileCount(smileCount + 1); | ||
}; | ||
|
||
const handleHeartClick = () => { | ||
setHeartCount(heartCount + 1); | ||
}; | ||
|
||
return ( | ||
<div className="card-container"> | ||
<div className="card purple"> | ||
<div className="card-header"> | ||
<h3>To. Sowon</h3> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To.Sowon에서 Sowon도 프로퍼티로 받아와 주셔야 하는 부분이라고 볼 수 있어요. |
||
<div className="profile-info"> | ||
<div className="card-body"> | ||
<p className="author-count" style={{ color: 'black' }}> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. className={cx("author-count")}이렇게 모듈화 할 수 있답니다 |
||
<b>30</b>명이 작성했어요! | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 부분에 들어갈 30 값을 프로퍼티로 받아오면 되는 거였습니다 |
||
</p> | ||
</div> | ||
</div> | ||
</div> | ||
<div className="card-footer"> | ||
<div className="reaction-icons"> | ||
<button id="likeButton" className="icon" onClick={handleLikeClick}> | ||
<i className="like"></i> {likeCount} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 버튼 누를 때 숫자 올라가는 것이 이 부분들에 대해 말씀하신 거였군요 |
||
</button> | ||
<button id="smileButton" className="icon" onClick={handleSmileClick}> | ||
<i className="smile"></i> {smileCount} | ||
</button> | ||
<button id="heartButton" className="icon" onClick={handleHeartClick}> | ||
<i className="heart"></i> {heartCount} | ||
</button> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default Card; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
@import "src/styles/global.scss"; | ||
|
||
.card-container { | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
height: auto; | ||
padding: auto; | ||
} | ||
|
||
.card { | ||
width: 100%; | ||
max-width: 275px; | ||
height: 260px; | ||
border-radius: 16px; | ||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); | ||
overflow: hidden; | ||
display: flex; | ||
flex-direction: column; | ||
|
||
&.purple { | ||
background-color: #ecd9ff; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 색깔에 대해서도 보민님이 만드신 글로벌 스타일을 쓰실 수 있었을 텐데 이렇게 하신 이유가 있을까요? |
||
} | ||
} | ||
|
||
.card-header { | ||
display: flex; | ||
flex-direction: column; | ||
padding: 30px 24px 0 24px; | ||
gap: 43px; | ||
border-bottom: 1px solid rgba(0, 0, 0, 0.12); | ||
flex-grow: 1; | ||
max-width: 227px; | ||
|
||
h3 { | ||
@include font-bold(2.4rem, $color-black, "Pretendard"); | ||
margin: 0; | ||
font-size: 24px; | ||
line-height: 36px; | ||
font-weight: 700; | ||
|
||
} | ||
} | ||
|
||
.profile-info { | ||
display: flex; | ||
align-items: center; | ||
|
||
img { | ||
width: 48px; | ||
height: 48px; | ||
border-radius: 50%; | ||
margin-right: 12px; | ||
} | ||
} | ||
|
||
.author-count { | ||
@include font-bold(1.6rem, $color-gray700, "Pretendard"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 폰트 사이즈에는 rem을 사용하셨군요. 저희 프로젝트 컨벤션에 맞게 잘 사용하셨습니다 |
||
font-weight: 400; | ||
font-size: 16px; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 나머지 부분들에 대해서는 px 값을 쓰셨는데 저희 프로젝트 에서는 rem단위를 사용하고 있어요. 저희 웹페이지 설정상으로는 1rem = 10px입니다. |
||
} | ||
|
||
.card-footer { | ||
padding: 16px; | ||
border-top: 1px solid #ddd; | ||
} | ||
|
||
.reaction-icons { | ||
display: flex; | ||
justify-content: space-between; | ||
gap: 8px; | ||
} | ||
|
||
.icon { | ||
background: rgba(0, 0, 0, 0.54); | ||
border: 1px solid rgba(0, 0, 0, 0.12); | ||
cursor: pointer; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 부분은 처음 부터 글로벌 스타일로 특정 태그에 대해 이 설정을 적용했을 거라고 봅니다. 확인해 보셔도 좋을 거에요 |
||
display: flex; | ||
align-items: center; | ||
color: $color-white; | ||
width: 199px; | ||
height: 36px; | ||
border-radius: 18px; | ||
padding: 0 16px; | ||
justify-content: center; | ||
font-size: 14px; | ||
font-weight: 500; | ||
font-family: 'Noto Sans KR', sans-serif; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 부분은 위와 같이 보민님이 만드신 폰트 탬플릿을 사용해도 되었을 텐데 혹시 디테일한 설정을 일일이 작성하신 이유가 있을까요? |
||
transition: background-color 0.3s ease; | ||
|
||
&:hover { | ||
background-color: rgba(0, 0, 0, 0.04); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
<!DOCTYPE html> | ||
|
||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>Purple Card</title> | ||
<link rel="preconnect" href="https://fonts.googleapis.com"> | ||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | ||
<link | ||
href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:[email protected]&family=Noto+Sans:ital,wght@0,100..900;1,100..900&display=swap" | ||
rel="stylesheet"> | ||
<link rel="stylesheet" href="style.css"> | ||
</head> | ||
|
||
<body> | ||
<div class="card-container"> | ||
<div class="card purple"> | ||
<div class="card-header"> | ||
<h3>To. Sowon</h3> | ||
<div class="profile-info"> | ||
<div class="card-body"> | ||
<p class="author-count" style="color: black;"><b>30</b>명이 작성했어요!</p> | ||
</div> | ||
</div> | ||
</div> | ||
<div class="card-footer"> | ||
<div class="reaction-icons"> | ||
<button id="likeButton" class="icon"> | ||
<i class="like"></i> 0 | ||
</button> | ||
<button id="smileButton" class="icon"> | ||
<i class="smile"></i> 0 | ||
</button> | ||
<button id="heartButton" class="icon"> | ||
<i class="heart"></i> 0 | ||
</button> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
<script src="script.js"></script> | ||
</body> | ||
|
||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
const likeButton = document.getElementById('likeButton'); | ||
const smileButton = document.getElementById('smileButton'); | ||
const heartButton = document.getElementById('heartButton'); | ||
|
||
let likeCount = 0; | ||
let smileCount = 0; | ||
let heartCount = 0; | ||
|
||
likeButton.addEventListener('click', () => { | ||
likeCount++; | ||
likeButton.innerHTML = `<i class="fas fa-thumbs-up"></i> ${likeCount}`; | ||
}); | ||
|
||
smileButton.addEventListener('click', () => { | ||
smileCount++; | ||
smileButton.innerHTML = `<i class="fas fa-smile"></i> ${smileCount}`; | ||
}); | ||
|
||
heartButton.addEventListener('click', () => { | ||
heartCount++; | ||
heartButton.innerHTML = `<i class="fas fa-heart"></i> ${heartCount}`; | ||
}); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
.card-container { | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
height: auto; | ||
padding: auto; | ||
} | ||
|
||
.card { | ||
width: 100%; | ||
max-width: 275px; | ||
height: 260px; | ||
border-radius: 16px; | ||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); | ||
overflow: hidden; | ||
display: flex; | ||
flex-direction: column; | ||
} | ||
|
||
.card.purple { | ||
background-color: #ECD9FF; | ||
} | ||
|
||
.card-header { | ||
display: flex; | ||
flex-direction: column; | ||
padding: 30px 24px 0 24px; | ||
gap: 43px; | ||
border-bottom: 1px solid rgba(0, 0, 0, 0.12); | ||
flex-grow: 1; | ||
max-width: 227px; | ||
/* 경계선 너비 변경이 안됨. */ | ||
} | ||
|
||
.card-header h3 { | ||
margin: 0; | ||
font-size: 24px; | ||
line-height: 36px; | ||
font-weight: 700; | ||
font-family: 'Noto Sans KR', sans-serif; | ||
} | ||
|
||
|
||
.profile-info { | ||
display: flex; | ||
align-items: center; | ||
} | ||
|
||
.profile-info img { | ||
width: 48px; | ||
height: 48px; | ||
border-radius: 50%; | ||
margin-right: 12px; | ||
} | ||
|
||
.author-count { | ||
font-family: 'Noto Sans KR', sans-serif; | ||
font-weight: 400; | ||
font-size: 16px; | ||
} | ||
|
||
.card-footer { | ||
padding: 16px; | ||
border-top: 1px solid #ddd; | ||
} | ||
|
||
.reaction-icons { | ||
display: flex; | ||
justify-content: space-between; | ||
gap: 8px; | ||
} | ||
|
||
.icon { | ||
background: rgba(0, 0, 0, 0.54); | ||
border: 1px solid rgba(0, 0, 0, 0.12); | ||
cursor: pointer; | ||
display: flex; | ||
align-items: center; | ||
color: #ffffff; | ||
width: 199px; | ||
height: 36px; | ||
border-radius: 18px; | ||
padding: 0 16px; | ||
justify-content: center; | ||
font-size: 14px; | ||
font-weight: 500; | ||
font-family: 'Noto Sans KR', sans-serif; | ||
transition: background-color 0.3s ease; | ||
/* 버튼 클릭 효과 */ | ||
} | ||
|
||
|
||
|
||
.icon:hover { | ||
background-color: rgba(0, 0, 0, 0.04); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
<!DOCTYPE html> | ||
|
||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>Purple Card</title> | ||
<link rel="preconnect" href="https://fonts.googleapis.com"> | ||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | ||
<link | ||
href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:[email protected]&family=Noto+Sans:ital,wght@0,100..900;1,100..900&display=swap" | ||
rel="stylesheet"> | ||
<link rel="stylesheet" href="style.css"> | ||
</head> | ||
|
||
<body> | ||
<div class="card-container"> | ||
<div class="card purple"> | ||
<div class="card-header"> | ||
<h3>To. Sowon</h3> | ||
<div class="profile-info"> | ||
<div class="card-body"> | ||
<p class="author-count" style="color: black;"><b>30</b>명이 작성했어요!</p> | ||
</div> | ||
</div> | ||
</div> | ||
<div class="card-footer"> | ||
<div class="reaction-icons"> | ||
<button id="likeButton" class="icon"> | ||
<i class="like"></i> 0 | ||
</button> | ||
<button id="smileButton" class="icon"> | ||
<i class="smile"></i> 0 | ||
</button> | ||
<button id="heartButton" class="icon"> | ||
<i class="heart"></i> 0 | ||
</button> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
<script src="script.js"></script> | ||
</body> | ||
|
||
</html> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
scss의 경우에 이렇게 쓸 수 있어요
import classNames from "classnames/bind";
import styles from "./MessagePage.module.scss";
const cx = classNames.bind(styles);
이렇게 하면 cx라는 이름을 통해 styles의 css속성으로만 접근 가능합니다. 즉, 모듈화를 할 수 있어요. 현재 코드처럼 하시는 경우에 잘못하면 여러 개 scss파일 임포트 할 때 두 파일에 겹치는 클래스 네임이 있다면...? 특히, 저렇게 쓰면 특정 scss가 아니라 전체 관련된 scss의 클래스 이름에 해당하는 모든 스타일이 적용될 거에요.
리액트의 경우에는 App.js의 App 컴포넌트에서 모든 다른 페이지 들 등을 끌어써서 다른 분들이 쓰신 그 어떤 파일이라도, 진석님이 쓴 클래스 이름이 있다면 적용될 수도 있어요