-
Notifications
You must be signed in to change notification settings - Fork 9
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
[1단계 미션] 배강현 미션 제출합니다 #24
base: bae-kh
Are you sure you want to change the base?
Changes from all commits
02f16cc
f6ebc31
80042c5
4337856
9b30b6f
a507d5c
5101e36
b0cb37c
6a3c641
7a541c7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
* { | ||
padding: 0; | ||
margin: 0; | ||
box-sizing: border-box; | ||
} | ||
|
||
ul, | ||
li { | ||
list-style: none; | ||
} | ||
|
||
html, | ||
body { | ||
font-family: sans-serif; | ||
font-size: 16px; | ||
} | ||
|
||
/* Colors *****************************************/ | ||
:root { | ||
--primary-color: #ec4a0a; | ||
--lighten-color: #f6a88a; | ||
--grey-100: #ffffff; | ||
--grey-200: #d0d5dd; | ||
--grey-300: #667085; | ||
--grey-400: #344054; | ||
--grey-500: #000000; | ||
} | ||
|
||
/* Typography *************************************/ | ||
.text-title { | ||
font-size: 20px; | ||
line-height: 24px; | ||
font-weight: 600; | ||
} | ||
|
||
.text-subtitle { | ||
font-size: 18px; | ||
line-height: 28px; | ||
font-weight: 600; | ||
} | ||
|
||
.text-body { | ||
font-size: 16px; | ||
line-height: 24px; | ||
font-weight: 400; | ||
} | ||
|
||
.text-caption { | ||
font-size: 14px; | ||
line-height: 20px; | ||
font-weight: 400; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,26 @@ | ||
import "./App.css"; | ||
import Header from "./header/Header.jsx"; | ||
import CategoryFilter from "./mainbody/CategoryFilter.jsx"; | ||
import RestaurantList from "./mainbody/RestaurantList.jsx"; | ||
import RestaurantDetailModal from "./aside/RestaurantDetailModal.jsx"; | ||
import AddRestaurantModal from "./aside/AddRestaurantModal.jsx"; | ||
|
||
|
||
function App() { | ||
return <h1>Self-Paced React</h1>; | ||
return ( | ||
<> | ||
<Header /> | ||
<main> | ||
<CategoryFilter /> | ||
<RestaurantList /> | ||
</main> | ||
<aside> | ||
<RestaurantDetailModal /> | ||
<AddRestaurantModal /> | ||
</aside> | ||
</> | ||
); | ||
} | ||
|
||
|
||
export default App; |
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. 오, css module를 잘 활용해 주셨네요 😊 선택사항인데 수고 많으셨어요 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. 처음에 css module을 사용하게 된 이유는 선택사항에 있어서 그냥 무턱대고 해봤습니다. 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. 맞습니다. 컴포넌트가 어떤 단점들을 해결하기 위해 탄생했는지, 컴포넌트로 챙길 수 있는 장점들이 무엇인지를 고민해 보시면 더 와닿을 수 있을 거라고 생각합니다. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import styles from "../css/RestaurantDetailModal.module.css"; | ||
import { options } from "../datas/RestaurantData"; | ||
|
||
function AddRestaurantModal() { | ||
return ( | ||
<div className={`${styles.modal} ${styles.modalOpen}`}> | ||
<div className={styles.modalBackdrop}></div> | ||
<div className={styles.modalContainer}> | ||
<h2 className={`${styles.modalTitle} text-title`}>새로운 음식점</h2> | ||
<form> | ||
{/* <!-- 카테고리 --> */} | ||
<div className={`${styles.formItem} ${styles.formItemRequired}`}> | ||
<label htmlFor="category" className="text-caption">카테고리</label> | ||
<select name="category" id="category" required> | ||
{options.map((option, index) => ( | ||
<option key={index} value={option}> | ||
{option} | ||
</option> | ||
))} | ||
</select> | ||
</div> | ||
|
||
{/* <!-- 음식점 이름 --> */} | ||
<div className={`${styles.formItem} ${styles.formItemRequired}`}> | ||
<label htmlFor="name" className="text-caption">이름</label> | ||
<input type="text" name="name" id="name" required /> | ||
</div> | ||
|
||
{/* <!-- 설명 --> */} | ||
<div className={styles.formItem}> | ||
<label htmlFor="description" className="text-caption">설명</label> | ||
<textarea name="description" id="description" cols="30" rows="5"></textarea> | ||
<span className="help-text text-caption">메뉴 등 추가 정보를 입력해 주세요.</span> | ||
</div> | ||
|
||
{/* <!-- 추가 버튼 --> */} | ||
<div className={styles.buttonContainer}> | ||
<button className={`${styles.button} ${styles.buttonPrimary} text-caption`}> | ||
추가하기 | ||
</button> | ||
</div> | ||
</form> | ||
</div> | ||
</div> | ||
); | ||
} | ||
|
||
export default AddRestaurantModal; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import styles from "../css/RestaurantDetailModal.module.css"; | ||
|
||
function RestaurantDetailModal() { | ||
return ( | ||
<div className={`${styles.modal} ${styles["modal--open"]}`}> | ||
<div className={styles["modal-backdrop"]}></div> | ||
<div className={styles["modal-container"]}> | ||
<h2 className={`${styles["modal-title"]} text-title`}>음식점 이름</h2> | ||
<div className={styles["restaurant-info"]}> | ||
<p className={`${styles["restaurant-info__description"]} text-body`}> | ||
음식점 소개 문구 | ||
</p> | ||
</div> | ||
|
||
<div className={styles["button-container"]}> | ||
<button className={`${styles.button} ${styles["button--primary"]} text-caption`}> | ||
닫기 | ||
</button> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
} | ||
|
||
export default RestaurantDetailModal; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
.restaurant-filter-container { | ||
display: flex; | ||
justify-content: space-between; | ||
|
||
padding: 0 16px; | ||
margin-top: 24px; | ||
} | ||
|
||
.restaurant-filter-container select { | ||
height: 44px; | ||
min-width: 125px; | ||
|
||
border: 1px solid #d0d5dd; | ||
border-radius: 8px; | ||
background: transparent; | ||
|
||
font-size: 16px; | ||
} | ||
|
||
.restaurant-filter { | ||
padding: 8px; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
.gnb { | ||
display: flex; | ||
justify-content: space-between; | ||
align-items: center; | ||
height: 64px; | ||
|
||
padding: 0 16px; | ||
|
||
background-color: var(--primary-color); | ||
} | ||
|
||
.gnb__title { | ||
color: #fcfcfd; | ||
} | ||
|
||
.gnb__button { | ||
height: 40px; | ||
|
||
border: none; | ||
border-radius: 8px; | ||
background: transparent; | ||
|
||
font-size: 24px; | ||
cursor: pointer; | ||
} | ||
|
||
.gnb__button img { | ||
display: block; | ||
width: 40px; | ||
height: 40px; | ||
object-fit: contain; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
.modal { | ||
display: none; | ||
} | ||
|
||
.modal--open { | ||
display: none; | ||
} | ||
|
||
.modal-backdrop { | ||
position: fixed; | ||
top: 0; | ||
right: 0; | ||
bottom: 0; | ||
left: 0; | ||
|
||
background: rgba(0, 0, 0, 0.35); | ||
} | ||
|
||
.modal-container { | ||
position: fixed; | ||
bottom: 0; | ||
width: 100%; | ||
|
||
padding: 32px 16px; | ||
|
||
border-radius: 8px 8px 0px 0px; | ||
background: var(--grey-100); | ||
} | ||
|
||
.modal-title { | ||
margin-bottom: 36px; | ||
} | ||
|
||
.form-item { | ||
display: flex; | ||
flex-direction: column; | ||
|
||
margin-bottom: 36px; | ||
} | ||
|
||
.form-item label { | ||
color: var(--grey-400); | ||
font-size: 14px; | ||
} | ||
|
||
.form-item--required label::after { | ||
padding-left: 4px; | ||
|
||
color: var(--primary-color); | ||
content: "*"; | ||
} | ||
|
||
.form-item .help-text { | ||
color: var(--grey-300); | ||
} | ||
|
||
.form-item input, | ||
.form-item textarea, | ||
.form-item select { | ||
padding: 8px; | ||
margin: 6px 0; | ||
|
||
border: 1px solid var(--grey-200); | ||
border-radius: 8px; | ||
|
||
font-size: 16px; | ||
} | ||
|
||
.form-item textarea { | ||
resize: none; | ||
} | ||
|
||
.form-item select { | ||
height: 44px; | ||
|
||
padding: 8px; | ||
|
||
border: 1px solid var(--grey-200); | ||
border-radius: 8px; | ||
|
||
color: var(--grey-300); | ||
} | ||
|
||
input[name="name"], | ||
input[name="link"] { | ||
height: 44px; | ||
} | ||
|
||
.button-container { | ||
display: flex; | ||
} | ||
|
||
.button { | ||
width: 100%; | ||
height: 44px; | ||
|
||
margin-right: 16px; | ||
|
||
border: none; | ||
border-radius: 8px; | ||
|
||
font-weight: 600; | ||
cursor: pointer; | ||
} | ||
|
||
.button:last-child { | ||
margin-right: 0; | ||
} | ||
|
||
.button--secondary { | ||
border: 1px solid var(--grey-300); | ||
background: transparent; | ||
|
||
color: var(--grey-300); | ||
} | ||
|
||
.button--primary { | ||
background: var(--primary-color); | ||
|
||
color: var(--grey-100); | ||
} | ||
|
||
.restaurant-info { | ||
margin-bottom: 24px; | ||
} |
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.
다른 여러 컨벤션에서는 함수는 카멜 케이스를 사용하는 것이 관례라고 적혀 있을텐데, 여기에서 import하는
Header
,CategoryFilter
, ... 는 모두 파스칼 케이스에요. 비록 코드를 가져오는 작업에 가깝지만 의문이 혹시 들지는 않으셨나요?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.
아 약간 적혀있는데로 가져오는 바람에 거기까진 생각 못해봤네요.. 다음부턴 항상 의식하면서 짜야겠네요!
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.
위에 import하는 것은 함수형 컴포넌트이므로 파스칼케이스로 작성하는게 맞는것같다고 생각합니다!