diff --git a/03-modal/README.md b/03-modal/README.md deleted file mode 100644 index 6a97651..0000000 --- a/03-modal/README.md +++ /dev/null @@ -1,29 +0,0 @@ -# 03. 모달 UI 구현하기: side-effect(feat. event handler) - -## 🎯 요구 사항 - -- `RestaurantList` 의 아이템을 클릭하면, 클릭한 아이템의 정보를 보여주는 모달이 뜨도록 변경해 주세요. '확인' 버튼을 클릭하거나 모달 뒤의 backdrop을 클릭하면 모달이 닫혀야 합니다. - - (작은 단계로 구현해보기 1) 아이템을 클릭하면 정해진 텍스트를 그대로 보여주는 모달을 열고 닫습니다. - - (작은 단계로 구현해보기 2) 클릭한 아이템의 정보를 모달에 내려줄 수 있도록 개선합니다. - -### 구현 결과 예시 - -```javascript -// App.jsx -{isModalOpen && } -``` - -## ✅ 키워드 - -- event handler (feat. side effect) -- conditional rendering -- lifting state up - -## 🧙‍♀️ 진행 가이드 - -- 진행 시간: 1시간 내에 완료하는 것을 목표로 합니다. - -## 🔗 참고 문서 - -- [Thinking in React](https://react.dev/learn/thinking-in-react)의 Step5 -- [Responding to Events](https://react.dev/learn/responding-to-events) diff --git a/04-form/README.md b/04-form/README.md new file mode 100644 index 0000000..6518ccb --- /dev/null +++ b/04-form/README.md @@ -0,0 +1,42 @@ +# 04. 폼 UI 구현하기: controlled vs uncontrolled + +## 🎯 요구 사항 + +- `Header`의 레스토랑 추가 버튼을 클릭하면 레스토랑 추가 폼이 모달로 뜨도록 구현해 주세요 + - 이전 단계에서 만들어두었던 `AddRestaurantModal`을 그대로 사용합니다. +- 카테고리를 선택하고, ``, ` + - - - - {/* 음식점 이름 */} -
+
+ {/* 추가 버튼 */} +
+
- {/* 설명 */} -
- - - - 메뉴 등 추가 정보를 입력해 주세요. - -
- {/* 추가 버튼 */} -
- -
- - - + 추가하기 + + + + ); } diff --git a/src/components/Modal/Modal.jsx b/src/components/Modal/Modal.jsx new file mode 100644 index 0000000..456873b --- /dev/null +++ b/src/components/Modal/Modal.jsx @@ -0,0 +1,13 @@ +import modalStyles from "./Modal.module.css"; + +export default function Modal({ title, onClose, children }) { + return ( + <> +
+
+

{title}

+ {children} +
+ + ); +} diff --git a/src/components/Modal/RestaurantDetailModal.jsx b/src/components/Modal/RestaurantDetailModal.jsx index 51ed8d5..fcc38a3 100644 --- a/src/components/Modal/RestaurantDetailModal.jsx +++ b/src/components/Modal/RestaurantDetailModal.jsx @@ -1,26 +1,21 @@ import styles from "./Modal.module.css"; +import Modal from "./Modal"; export default function RestaurantDetailModal({ clickedRestaurant, onClose }) { return ( -
-
-
-

- {clickedRestaurant.name} -

-
-

{clickedRestaurant.description}

-
- {/* 닫기 버튼 */} -
- -
+ +
+

{clickedRestaurant.description}

-
+ {/* 닫기 버튼 */} +
+ +
+ ); } diff --git a/src/components/RestaurantList/RestaurantList.jsx b/src/components/RestaurantList/RestaurantList.jsx index 30292c2..45ae6c8 100644 --- a/src/components/RestaurantList/RestaurantList.jsx +++ b/src/components/RestaurantList/RestaurantList.jsx @@ -1,38 +1,32 @@ import styles from "./RestaurantList.module.css"; -import { categoryImages } from "../../constants/categoryImages"; +import { CATEGORY_IMAGES } from "../../constants/categoryImages"; export default function RestaurantList({ restaurants, onRestaurantClick }) { return (
    {restaurants.map((restaurant) => ( -
  • onRestaurantClick(restaurant)} - onKeyDown={(e) => { - if (e.key === "Enter" || e.key === " ") { - onRestaurantClick(restaurant); - } - }} - > -
    - {restaurant.category} -
    -
    -

    - {restaurant.name} -

    -

    - {restaurant.description} -

    -
    +
  • +
  • ))}
diff --git a/src/components/RestaurantList/RestaurantList.module.css b/src/components/RestaurantList/RestaurantList.module.css index ffa6c7f..1d91c5d 100644 --- a/src/components/RestaurantList/RestaurantList.module.css +++ b/src/components/RestaurantList/RestaurantList.module.css @@ -7,14 +7,24 @@ } .restaurant { - display: flex; - align-items: flex-start; - padding: 16px 8px; border-bottom: 1px solid #e9eaed; } +.restaurant__button { + display: flex; + align-items: flex-start; + width: 100%; + + background: none; + border: none; + padding: 0; + cursor: pointer; + text-align: left; + font: inherit; +} + .restaurant__category { display: flex; justify-content: center; diff --git a/src/constants/categoryImages.js b/src/constants/categoryImages.js index dd6d29e..daba5dd 100644 --- a/src/constants/categoryImages.js +++ b/src/constants/categoryImages.js @@ -5,7 +5,7 @@ import westernImg from "../assets/category-western.png"; import asianImg from "../assets/category-asian.png"; import etcImg from "../assets/category-etc.png"; -export const categoryImages = { +export const CATEGORY_IMAGES = { 한식: koreanImg, 중식: chineseImg, 일식: japaneseImg, diff --git a/src/constants/restaurants.js b/src/constants/restaurants.js index 30fe97e..7fc92cf 100644 --- a/src/constants/restaurants.js +++ b/src/constants/restaurants.js @@ -1,4 +1,4 @@ -export const restaurants = [ +export const RESTAURANTS = [ { id: "a01", name: "피양콩할마니",