From 11c93edff43c7c7a248234cd4f2993019806a04c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EC=9D=B4=EC=84=9C=EC=A4=80?=
<104981505+xeoxxn@users.noreply.github.com>
Date: Tue, 8 Sep 2026 12:53:02 +0900
Subject: [PATCH 1/7] =?UTF-8?q?feat:=20=EB=B9=8C=EB=A6=B4=EA=B2=8C=20?=
=?UTF-8?q?=EB=AC=BC=ED=92=88=20=EB=B0=8F=20Bottom=20Nav=20=EC=95=84?=
=?UTF-8?q?=EC=9D=B4=EC=BD=98=20asset=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Figma에서 물품 아이콘 16종, Bottom Nav 선택 상태 아이콘 4종, 스테퍼 아이콘 2종을 내려받아 추가한다
---
.../icons/bottom-nav/board-selected.svg | 12 ++++++++
.../icons/bottom-nav/event-selected.svg | 5 ++++
src/assets/icons/bottom-nav/home-selected.svg | 5 ++++
.../icons/bottom-nav/rental-selected.svg | 16 ++++++++++
src/assets/icons/circle-minus-fill.svg | 5 ++++
src/assets/icons/circle-plus-fill.svg | 5 ++++
.../icons/rental-items/8pin-charger.svg | 30 +++++++++++++++++++
.../icons/rental-items/alcohol-swab.svg | 24 +++++++++++++++
src/assets/icons/rental-items/band-aid.svg | 20 +++++++++++++
.../icons/rental-items/curling-iron.svg | 22 ++++++++++++++
src/assets/icons/rental-items/default.svg | 14 +++++++++
src/assets/icons/rental-items/eye-drops.svg | 21 +++++++++++++
src/assets/icons/rental-items/hair-dryer.svg | 21 +++++++++++++
.../icons/rental-items/laptop-charger.svg | 22 ++++++++++++++
src/assets/icons/rental-items/mask.svg | 23 ++++++++++++++
src/assets/icons/rental-items/ointment.svg | 21 +++++++++++++
.../icons/rental-items/pain-relief-patch.svg | 25 ++++++++++++++++
src/assets/icons/rental-items/pill.svg | 21 +++++++++++++
src/assets/icons/rental-items/power-bank.svg | 21 +++++++++++++
.../icons/rental-items/sanitary-pad.svg | 21 +++++++++++++
src/assets/icons/rental-items/umbrella.svg | 22 ++++++++++++++
.../icons/rental-items/usb-c-charger.svg | 23 ++++++++++++++
22 files changed, 399 insertions(+)
create mode 100644 src/assets/icons/bottom-nav/board-selected.svg
create mode 100644 src/assets/icons/bottom-nav/event-selected.svg
create mode 100644 src/assets/icons/bottom-nav/home-selected.svg
create mode 100644 src/assets/icons/bottom-nav/rental-selected.svg
create mode 100644 src/assets/icons/circle-minus-fill.svg
create mode 100644 src/assets/icons/circle-plus-fill.svg
create mode 100644 src/assets/icons/rental-items/8pin-charger.svg
create mode 100644 src/assets/icons/rental-items/alcohol-swab.svg
create mode 100644 src/assets/icons/rental-items/band-aid.svg
create mode 100644 src/assets/icons/rental-items/curling-iron.svg
create mode 100644 src/assets/icons/rental-items/default.svg
create mode 100644 src/assets/icons/rental-items/eye-drops.svg
create mode 100644 src/assets/icons/rental-items/hair-dryer.svg
create mode 100644 src/assets/icons/rental-items/laptop-charger.svg
create mode 100644 src/assets/icons/rental-items/mask.svg
create mode 100644 src/assets/icons/rental-items/ointment.svg
create mode 100644 src/assets/icons/rental-items/pain-relief-patch.svg
create mode 100644 src/assets/icons/rental-items/pill.svg
create mode 100644 src/assets/icons/rental-items/power-bank.svg
create mode 100644 src/assets/icons/rental-items/sanitary-pad.svg
create mode 100644 src/assets/icons/rental-items/umbrella.svg
create mode 100644 src/assets/icons/rental-items/usb-c-charger.svg
diff --git a/src/assets/icons/bottom-nav/board-selected.svg b/src/assets/icons/bottom-nav/board-selected.svg
new file mode 100644
index 0000000..2e82950
--- /dev/null
+++ b/src/assets/icons/bottom-nav/board-selected.svg
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/icons/bottom-nav/event-selected.svg b/src/assets/icons/bottom-nav/event-selected.svg
new file mode 100644
index 0000000..6648b26
--- /dev/null
+++ b/src/assets/icons/bottom-nav/event-selected.svg
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/src/assets/icons/bottom-nav/home-selected.svg b/src/assets/icons/bottom-nav/home-selected.svg
new file mode 100644
index 0000000..e9e47dc
--- /dev/null
+++ b/src/assets/icons/bottom-nav/home-selected.svg
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/src/assets/icons/bottom-nav/rental-selected.svg b/src/assets/icons/bottom-nav/rental-selected.svg
new file mode 100644
index 0000000..cb2392d
--- /dev/null
+++ b/src/assets/icons/bottom-nav/rental-selected.svg
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/icons/circle-minus-fill.svg b/src/assets/icons/circle-minus-fill.svg
new file mode 100644
index 0000000..ad62883
--- /dev/null
+++ b/src/assets/icons/circle-minus-fill.svg
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/src/assets/icons/circle-plus-fill.svg b/src/assets/icons/circle-plus-fill.svg
new file mode 100644
index 0000000..b00fa3a
--- /dev/null
+++ b/src/assets/icons/circle-plus-fill.svg
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/src/assets/icons/rental-items/8pin-charger.svg b/src/assets/icons/rental-items/8pin-charger.svg
new file mode 100644
index 0000000..481c548
--- /dev/null
+++ b/src/assets/icons/rental-items/8pin-charger.svg
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/icons/rental-items/alcohol-swab.svg b/src/assets/icons/rental-items/alcohol-swab.svg
new file mode 100644
index 0000000..ec57d64
--- /dev/null
+++ b/src/assets/icons/rental-items/alcohol-swab.svg
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/icons/rental-items/band-aid.svg b/src/assets/icons/rental-items/band-aid.svg
new file mode 100644
index 0000000..5456739
--- /dev/null
+++ b/src/assets/icons/rental-items/band-aid.svg
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/icons/rental-items/curling-iron.svg b/src/assets/icons/rental-items/curling-iron.svg
new file mode 100644
index 0000000..a13d2e6
--- /dev/null
+++ b/src/assets/icons/rental-items/curling-iron.svg
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/icons/rental-items/default.svg b/src/assets/icons/rental-items/default.svg
new file mode 100644
index 0000000..8cae4eb
--- /dev/null
+++ b/src/assets/icons/rental-items/default.svg
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/icons/rental-items/eye-drops.svg b/src/assets/icons/rental-items/eye-drops.svg
new file mode 100644
index 0000000..5a82cbd
--- /dev/null
+++ b/src/assets/icons/rental-items/eye-drops.svg
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/icons/rental-items/hair-dryer.svg b/src/assets/icons/rental-items/hair-dryer.svg
new file mode 100644
index 0000000..6578d26
--- /dev/null
+++ b/src/assets/icons/rental-items/hair-dryer.svg
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/icons/rental-items/laptop-charger.svg b/src/assets/icons/rental-items/laptop-charger.svg
new file mode 100644
index 0000000..20df526
--- /dev/null
+++ b/src/assets/icons/rental-items/laptop-charger.svg
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/icons/rental-items/mask.svg b/src/assets/icons/rental-items/mask.svg
new file mode 100644
index 0000000..b1c90a6
--- /dev/null
+++ b/src/assets/icons/rental-items/mask.svg
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/icons/rental-items/ointment.svg b/src/assets/icons/rental-items/ointment.svg
new file mode 100644
index 0000000..2820271
--- /dev/null
+++ b/src/assets/icons/rental-items/ointment.svg
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/icons/rental-items/pain-relief-patch.svg b/src/assets/icons/rental-items/pain-relief-patch.svg
new file mode 100644
index 0000000..decb03d
--- /dev/null
+++ b/src/assets/icons/rental-items/pain-relief-patch.svg
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/icons/rental-items/pill.svg b/src/assets/icons/rental-items/pill.svg
new file mode 100644
index 0000000..f399c53
--- /dev/null
+++ b/src/assets/icons/rental-items/pill.svg
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/icons/rental-items/power-bank.svg b/src/assets/icons/rental-items/power-bank.svg
new file mode 100644
index 0000000..d2c4340
--- /dev/null
+++ b/src/assets/icons/rental-items/power-bank.svg
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/icons/rental-items/sanitary-pad.svg b/src/assets/icons/rental-items/sanitary-pad.svg
new file mode 100644
index 0000000..69382ab
--- /dev/null
+++ b/src/assets/icons/rental-items/sanitary-pad.svg
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/icons/rental-items/umbrella.svg b/src/assets/icons/rental-items/umbrella.svg
new file mode 100644
index 0000000..fbd0e6a
--- /dev/null
+++ b/src/assets/icons/rental-items/umbrella.svg
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/icons/rental-items/usb-c-charger.svg b/src/assets/icons/rental-items/usb-c-charger.svg
new file mode 100644
index 0000000..b8ec969
--- /dev/null
+++ b/src/assets/icons/rental-items/usb-c-charger.svg
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
From 6f5f829ca6f1a27bc5b70a15d5248602feaae194 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EC=9D=B4=EC=84=9C=EC=A4=80?=
<104981505+xeoxxn@users.noreply.github.com>
Date: Tue, 8 Sep 2026 12:53:10 +0900
Subject: [PATCH 2/7] =?UTF-8?q?feat:=20RentalItemCard,=20=EC=B9=B4?=
=?UTF-8?q?=ED=85=8C=EA=B3=A0=EB=A6=AC=20=ED=95=84=ED=84=B0=20=EC=BB=B4?=
=?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EB=B0=8F=20=EB=AC=BC=ED=92=88=20?=
=?UTF-8?q?=EB=AA=A9=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
WDS Button(size=small)에 색상만 보정한 대여 신청 버튼 포함 RentalItemCard,
Stream 로컬 카테고리 필터 칩, Figma Item Grid 기준 물품 19종 목데이터를 추가한다
---
.../components/RentalCategoryFilter.tsx | 40 +++++++++
.../rental/components/RentalItemCard.tsx | 90 +++++++++++++++++++
src/features/rental/constants/rentalItems.ts | 75 ++++++++++++++++
3 files changed, 205 insertions(+)
create mode 100644 src/features/rental/components/RentalCategoryFilter.tsx
create mode 100644 src/features/rental/components/RentalItemCard.tsx
create mode 100644 src/features/rental/constants/rentalItems.ts
diff --git a/src/features/rental/components/RentalCategoryFilter.tsx b/src/features/rental/components/RentalCategoryFilter.tsx
new file mode 100644
index 0000000..d34d04b
--- /dev/null
+++ b/src/features/rental/components/RentalCategoryFilter.tsx
@@ -0,0 +1,40 @@
+const RENTAL_CATEGORIES = [
+ "전체",
+ "전자기기",
+ "생활잡화",
+ "상비약",
+ "위생용품",
+];
+
+interface RentalCategoryFilterProps {
+ value: string;
+ onChange: (category: string) => void;
+}
+
+// Figma: 빌릴게 Filter Row (nodeId 1243:73337) — WDS Chip이 아니라 Stream 로컬 커스텀 칩.
+// 카테고리·물품 매핑 API가 아직 없어 필터링 없이 선택 상태만 표시한다.
+function RentalCategoryFilter({ value, onChange }: RentalCategoryFilterProps) {
+ return (
+
+ {RENTAL_CATEGORIES.map((category) => {
+ const active = category === value;
+ return (
+ onChange(category)}
+ type="button"
+ >
+ {category}
+
+ );
+ })}
+
+ );
+}
+
+export default RentalCategoryFilter;
diff --git a/src/features/rental/components/RentalItemCard.tsx b/src/features/rental/components/RentalItemCard.tsx
new file mode 100644
index 0000000..3e8a65b
--- /dev/null
+++ b/src/features/rental/components/RentalItemCard.tsx
@@ -0,0 +1,90 @@
+// Figma: Rental Item Card (nodeId 1041:61407)
+import { Button } from "@wanteddev/wds";
+
+import circleMinusFill from "@/assets/icons/circle-minus-fill.svg";
+import circlePlusFill from "@/assets/icons/circle-plus-fill.svg";
+
+interface RentalItemCardProps {
+ icon: string;
+ itemName: string;
+ quantity: number;
+ trailingControl?: "button" | "stepper";
+ onRentRequest?: () => void;
+ stepperValue?: number;
+ onStepperDecrease?: () => void;
+ onStepperIncrease?: () => void;
+}
+
+// "대여 신청" 버튼은 Figma상 `Menu/Resource/Action Area/Trailing Content/Button`(WDS) 인스턴스지만,
+// 그 이름과 1:1 대응하는 코드 export는 없다 — 대신 WDS `Button`(size="small")이 padding(7px/14px)·
+// radius(8px)·타이포(label2)까지 정확히 일치해서 그걸 쓰고, Button 공개 variant엔 없는 "연한 파랑 배경
+// + 파랑 텍스트" 조합만 sx로 보정했다. 스테퍼 +/- 아이콘은 여전히 WDS 미확정이라 하드코딩 — docs/plans 참고.
+function RentalItemCard({
+ icon,
+ itemName,
+ quantity,
+ trailingControl = "button",
+ onRentRequest,
+ stepperValue = 1,
+ onStepperDecrease,
+ onStepperIncrease,
+}: RentalItemCardProps) {
+ const isStepper = trailingControl === "stepper";
+
+ return (
+
+
+
+
+
+
+ {itemName}
+
+
수량 {quantity}
+
+
+
+ {!isStepper && (
+
+ 대여 신청
+
+ )}
+
+ {isStepper && (
+
+
+
+
+
+ {stepperValue}
+
+
+
+
+
+ )}
+
+
+ );
+}
+
+export default RentalItemCard;
diff --git a/src/features/rental/constants/rentalItems.ts b/src/features/rental/constants/rentalItems.ts
new file mode 100644
index 0000000..c3680f9
--- /dev/null
+++ b/src/features/rental/constants/rentalItems.ts
@@ -0,0 +1,75 @@
+import eightPinCharger from "@/assets/icons/rental-items/8pin-charger.svg";
+import alcoholSwab from "@/assets/icons/rental-items/alcohol-swab.svg";
+import bandAid from "@/assets/icons/rental-items/band-aid.svg";
+import curlingIron from "@/assets/icons/rental-items/curling-iron.svg";
+import eyeDrops from "@/assets/icons/rental-items/eye-drops.svg";
+import hairDryer from "@/assets/icons/rental-items/hair-dryer.svg";
+import laptopCharger from "@/assets/icons/rental-items/laptop-charger.svg";
+import mask from "@/assets/icons/rental-items/mask.svg";
+import ointment from "@/assets/icons/rental-items/ointment.svg";
+import painReliefPatch from "@/assets/icons/rental-items/pain-relief-patch.svg";
+import pill from "@/assets/icons/rental-items/pill.svg";
+import powerBank from "@/assets/icons/rental-items/power-bank.svg";
+import sanitaryPad from "@/assets/icons/rental-items/sanitary-pad.svg";
+import umbrella from "@/assets/icons/rental-items/umbrella.svg";
+import usbCCharger from "@/assets/icons/rental-items/usb-c-charger.svg";
+
+export interface RentalItem {
+ id: string;
+ name: string;
+ quantity: number;
+ icon: string;
+}
+
+// Figma: 빌릴게 Item Grid (nodeId 1243:73343) 순서·물품명·수량을 그대로 옮긴 목데이터 — 실 API 연동 전까지 사용
+export const RENTAL_ITEMS: RentalItem[] = [
+ { icon: curlingIron, id: "curling-iron", name: "고데기", quantity: 28 },
+ {
+ icon: laptopCharger,
+ id: "laptop-charger",
+ name: "노트북 충전기(C타입)",
+ quantity: 28,
+ },
+ { icon: hairDryer, id: "hair-dryer", name: "드라이기", quantity: 28 },
+ { icon: mask, id: "mask", name: "마스크", quantity: 28 },
+ { icon: bandAid, id: "band-aid", name: "밴드", quantity: 28 },
+ { icon: powerBank, id: "power-bank", name: "보조배터리", quantity: 28 },
+ {
+ icon: sanitaryPad,
+ id: "sanitary-pad-large",
+ name: "생리대(대형)",
+ quantity: 28,
+ },
+ {
+ icon: sanitaryPad,
+ id: "sanitary-pad-small",
+ name: "생리대(소형)",
+ quantity: 28,
+ },
+ { icon: alcoholSwab, id: "alcohol-swab", name: "알콜스왑", quantity: 28 },
+ { icon: umbrella, id: "umbrella", name: "우산", quantity: 28 },
+ { icon: pill, id: "stomach-medicine", name: "위장약", quantity: 28 },
+ { icon: pill, id: "easyen-6", name: "이지엔6", quantity: 28 },
+ { icon: eyeDrops, id: "eye-drops", name: "인공눈물", quantity: 28 },
+ { icon: pill, id: "cold-medicine", name: "종합감기약", quantity: 28 },
+ {
+ icon: usbCCharger,
+ id: "usb-c-cable",
+ name: "케이블(C to C)",
+ quantity: 28,
+ },
+ { icon: pill, id: "tylenol", name: "타이레놀", quantity: 28 },
+ {
+ icon: painReliefPatch,
+ id: "pain-relief-patch",
+ name: "파스",
+ quantity: 28,
+ },
+ { icon: ointment, id: "ointment", name: "후시딘", quantity: 28 },
+ {
+ icon: eightPinCharger,
+ id: "8pin-charger",
+ name: "8핀 충전기",
+ quantity: 28,
+ },
+];
From 44a4d6b6b047d54fbdfb8a735a9add13ec526b80 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EC=9D=B4=EC=84=9C=EC=A4=80?=
<104981505+xeoxxn@users.noreply.github.com>
Date: Tue, 8 Sep 2026 12:53:18 +0900
Subject: [PATCH 3/7] =?UTF-8?q?feat:=20Bottom=20Nav=20=EC=BB=B4=ED=8F=AC?=
=?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
WDS BottomNavigation은 iOS 반투명 배경과 body 스크롤 감지 로직이 내부 스크롤
레이아웃과 안 맞아서 대신 Stream 로컬 컴포넌트로 홈/행사/게시판/빌릴게 4탭을 구현한다
---
src/components/ui/BottomNav.tsx | 94 +++++++++++++++++++++++++++++++++
1 file changed, 94 insertions(+)
create mode 100644 src/components/ui/BottomNav.tsx
diff --git a/src/components/ui/BottomNav.tsx b/src/components/ui/BottomNav.tsx
new file mode 100644
index 0000000..8bfe241
--- /dev/null
+++ b/src/components/ui/BottomNav.tsx
@@ -0,0 +1,94 @@
+import {
+ IconHome,
+ IconList,
+ IconStorage,
+ IconTicket,
+} from "@wanteddev/wds-icon";
+
+import boardSelected from "@/assets/icons/bottom-nav/board-selected.svg";
+import eventSelected from "@/assets/icons/bottom-nav/event-selected.svg";
+import homeSelected from "@/assets/icons/bottom-nav/home-selected.svg";
+import rentalSelected from "@/assets/icons/bottom-nav/rental-selected.svg";
+
+export type BottomNavValue = "home" | "event" | "board" | "rental";
+
+interface BottomNavProps {
+ value: BottomNavValue;
+ onValueChange: (value: BottomNavValue) => void;
+}
+
+interface BottomNavTab {
+ value: BottomNavValue;
+ label: string;
+ NormalIcon: typeof IconHome;
+ selectedIcon: string;
+}
+
+// WDS에 선택 상태용 filled 아이콘이 없는 탭(게시판)이 있어, 4개 전부 Figma에서 내려받은 selected 아이콘으로 통일했다.
+const TABS: BottomNavTab[] = [
+ {
+ NormalIcon: IconHome,
+ label: "홈",
+ selectedIcon: homeSelected,
+ value: "home",
+ },
+ {
+ NormalIcon: IconTicket,
+ label: "행사",
+ selectedIcon: eventSelected,
+ value: "event",
+ },
+ {
+ NormalIcon: IconList,
+ label: "게시판",
+ selectedIcon: boardSelected,
+ value: "board",
+ },
+ {
+ NormalIcon: IconStorage,
+ label: "빌릴게",
+ selectedIcon: rentalSelected,
+ value: "rental",
+ },
+];
+
+// Figma: Bottom Nav (nodeId 985:39948, Selected=Home/Event/Board/Rental) — WDS `BottomNavigation`은
+// iOS 반투명 배경 + body 스크롤 기준 투명 전환 로직이 있어 우리 레이아웃(내부 스크롤)과 안 맞아서 쓰지 않고
+// Stream 로컬 컴포넌트로 새로 만들었다.
+// 상단 border 색은 Figma 스펙(Background/Elevated/Alternative, #f7f7f8)이 바로 위 스크롤 영역 배경과 완전히
+// 같은 색이라 실제로는 안 보여서, 눈에 보이는 구분선이 되도록 Line/Solid/Neutral로 바꿨다.
+function BottomNav({ value, onValueChange }: BottomNavProps) {
+ return (
+
+
+ {TABS.map(({ value: tabValue, label, NormalIcon, selectedIcon }) => {
+ const isSelected = tabValue === value;
+ return (
+
onValueChange(tabValue)}
+ type="button"
+ >
+ {isSelected ? (
+
+ ) : (
+
+ )}
+
+ {label}
+
+
+ );
+ })}
+
+
+
+ );
+}
+
+export default BottomNav;
From ae2e1237e93b247d444e8e2012e00bc1614ae8a3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EC=9D=B4=EC=84=9C=EC=A4=80?=
<104981505+xeoxxn@users.noreply.github.com>
Date: Tue, 8 Sep 2026 12:53:28 +0900
Subject: [PATCH 4/7] =?UTF-8?q?feat:=20=EB=B9=8C=EB=A6=B4=EA=B2=8C=20?=
=?UTF-8?q?=EB=8C=80=EC=97=AC=20=EB=AA=A9=EB=A1=9D=20=ED=99=94=EB=A9=B4=20?=
=?UTF-8?q?=EC=A1=B0=EB=A6=BD=20=EB=B0=8F=20=EC=83=89=EC=83=81=20=EB=94=94?=
=?UTF-8?q?=EC=9E=90=EC=9D=B8=20=ED=86=A0=ED=81=B0=20=EC=A0=81=EC=9A=A9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Top Navigation·Bottom Nav 고정 + 내부 스크롤 레이아웃(375x812)으로 화면을
조립하고, WDS semantic 변수를 Tailwind 색상 토큰으로 별칭 연결해 하드코딩
hex 없이 쓰도록 한다. 라우팅이 없어 App.tsx가 임시로 이 화면을 직접 렌더링한다
---
src/app/App.tsx | 9 ++-
src/features/rental/RentalListScreen.tsx | 82 ++++++++++++++++++++++++
src/index.css | 21 +++++-
src/main.tsx | 1 -
4 files changed, 108 insertions(+), 5 deletions(-)
create mode 100644 src/features/rental/RentalListScreen.tsx
diff --git a/src/app/App.tsx b/src/app/App.tsx
index d347dd4..6b9a3d1 100644
--- a/src/app/App.tsx
+++ b/src/app/App.tsx
@@ -1,8 +1,11 @@
+import RentalListScreen from "@/features/rental/RentalListScreen";
+
+// 라우팅 도입 전까지 임시로 이 화면만 렌더링한다. 데스크톱에서 보기 좋게 아이폰 화면 크기로 가운데 정렬만 해준다.
function App() {
return (
-
- STREAM
-
+
+
+
);
}
diff --git a/src/features/rental/RentalListScreen.tsx b/src/features/rental/RentalListScreen.tsx
new file mode 100644
index 0000000..e02b10e
--- /dev/null
+++ b/src/features/rental/RentalListScreen.tsx
@@ -0,0 +1,82 @@
+import {
+ SegmentedControl,
+ SegmentedControlItem,
+ TopNavigation,
+ TopNavigationButton,
+} from "@wanteddev/wds";
+import { IconBell, IconSearch } from "@wanteddev/wds-icon";
+import { useState } from "react";
+
+import BottomNav, { type BottomNavValue } from "@/components/ui/BottomNav";
+import RentalCategoryFilter from "@/features/rental/components/RentalCategoryFilter";
+import RentalItemCard from "@/features/rental/components/RentalItemCard";
+import { RENTAL_ITEMS } from "@/features/rental/constants/rentalItems";
+
+// Figma: 빌릴게 (nodeId 1243:73331)
+function RentalListScreen() {
+ const [tab, setTab] = useState("rent");
+ const [category, setCategory] = useState("전체");
+ const [bottomNavValue, setBottomNavValue] =
+ useState("rental");
+
+ return (
+
+
+ {/* background 기본값(true)은 iOS 반투명 스타일이라 뒤 배경이 비쳐 보인다. Figma는 별도 배경 없이 화면 배경을 그대로 쓴다. */}
+
+
+ 대여
+ 반납
+
+
+ }
+ trailingContent={
+ <>
+
+
+
+
+
+
+ >
+ }
+ variant="display"
+ >
+ 빌릴게
+
+
+
+
+
+
+
+
+ {tab === "rent" ? (
+
+ {RENTAL_ITEMS.map((item) => (
+
+ ))}
+
+ ) : (
+
+ 반납 화면은 아직 준비 중이에요
+
+ )}
+
+
+
+
+
+
+ );
+}
+
+export default RentalListScreen;
diff --git a/src/index.css b/src/index.css
index a3e7293..509d881 100644
--- a/src/index.css
+++ b/src/index.css
@@ -1,5 +1,24 @@
@import "tailwindcss";
+@import "@wanteddev/wds/global.css" layer(base);
@theme {
- /* 디자인 시스템 토큰 자리 — 디자인이 정해지면 색상·타이포그래피·간격 등을 여기에 채운다 */
+ /* WDS(@wanteddev/wds/global.css)의 semantic/atomic CSS 변수를 Tailwind 색상 토큰으로 별칭 연결. */
+ /* 값을 새로 정의하지 않고 WDS 걸 그대로 참조하므로 다크 테마(html[data-theme=dark])도 자동 반영된다. */
+ /* Figma get_variable_defs로 뽑은 실제 값과 대조해서 확정함(빌릴게 화면, nodeId 1243:73331 기준). */
+ --color-label-strong: var(--semantic-label-strong);
+ --color-label-normal: var(--semantic-label-normal);
+ --color-label-alternative: var(--semantic-label-alternative);
+ --color-label-assistive: var(--semantic-label-assistive);
+
+ --color-background-normal: var(--semantic-background-normal-normal);
+ --color-background-alternative: var(--semantic-background-normal-alternative);
+
+ --color-line-solid-neutral: var(--semantic-line-solid-neutral);
+ --color-line-normal-neutral: var(--semantic-line-normal-neutral);
+
+ --color-primary: var(--semantic-primary-normal);
+ --color-primary-subtle: var(--atomic-blue-95);
+
+ /* WDS 시맨틱 세트에 없는 값(Figma "Icons/Primary") — 홈 인디케이터 전용, 값 자체는 Figma에서 확인됨 */
+ --color-icons-primary: #0f172a;
}
diff --git a/src/main.tsx b/src/main.tsx
index c19e66d..cd7e812 100644
--- a/src/main.tsx
+++ b/src/main.tsx
@@ -3,7 +3,6 @@ import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import App from "./app/App.tsx";
import "./index.css";
-import "@wanteddev/wds/global.css";
createRoot(document.getElementById("root")!).render(
From 89418061270cc02d1268c577900ba6456bbc531f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EC=9D=B4=EC=84=9C=EC=A4=80?=
<104981505+xeoxxn@users.noreply.github.com>
Date: Tue, 8 Sep 2026 13:04:06 +0900
Subject: [PATCH 5/7] =?UTF-8?q?fix:=20PR=20=EB=B2=94=EC=9C=84=EB=A5=BC=20?=
=?UTF-8?q?=EA=B3=B5=ED=86=B5=20=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83(375x8?=
=?UTF-8?q?12)+Bottom=20Nav=EB=A1=9C=20=EC=A2=81=ED=9E=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
행사 등 다른 화면과 대조해보니 375x812 프레임 비율과 Bottom Nav 외에는
Top Navigation 구성·필터·리스트 등이 화면마다 달라 공통 레이아웃이 아니었다.
빌릴게 전용 컴포넌트(RentalItemCard, RentalCategoryFilter, 목데이터, 물품
아이콘)는 이 브랜치에서 빼고, header/children 슬롯만 받는 ScreenLayout으로
공통 뼈대만 남긴다. 빌릴게 화면 전용 작업은 별도 이슈로 다시 진행한다
---
src/app/App.tsx | 24 ++++-
src/assets/icons/circle-minus-fill.svg | 5 --
src/assets/icons/circle-plus-fill.svg | 5 --
.../icons/rental-items/8pin-charger.svg | 30 -------
.../icons/rental-items/alcohol-swab.svg | 24 -----
src/assets/icons/rental-items/band-aid.svg | 20 -----
.../icons/rental-items/curling-iron.svg | 22 -----
src/assets/icons/rental-items/default.svg | 14 ---
src/assets/icons/rental-items/eye-drops.svg | 21 -----
src/assets/icons/rental-items/hair-dryer.svg | 21 -----
.../icons/rental-items/laptop-charger.svg | 22 -----
src/assets/icons/rental-items/mask.svg | 23 -----
src/assets/icons/rental-items/ointment.svg | 21 -----
.../icons/rental-items/pain-relief-patch.svg | 25 ------
src/assets/icons/rental-items/pill.svg | 21 -----
src/assets/icons/rental-items/power-bank.svg | 21 -----
.../icons/rental-items/sanitary-pad.svg | 21 -----
src/assets/icons/rental-items/umbrella.svg | 22 -----
.../icons/rental-items/usb-c-charger.svg | 23 -----
src/components/ui/ScreenLayout.tsx | 35 ++++++++
src/features/rental/RentalListScreen.tsx | 82 -----------------
.../components/RentalCategoryFilter.tsx | 40 ---------
.../rental/components/RentalItemCard.tsx | 90 -------------------
src/features/rental/constants/rentalItems.ts | 75 ----------------
24 files changed, 56 insertions(+), 651 deletions(-)
delete mode 100644 src/assets/icons/circle-minus-fill.svg
delete mode 100644 src/assets/icons/circle-plus-fill.svg
delete mode 100644 src/assets/icons/rental-items/8pin-charger.svg
delete mode 100644 src/assets/icons/rental-items/alcohol-swab.svg
delete mode 100644 src/assets/icons/rental-items/band-aid.svg
delete mode 100644 src/assets/icons/rental-items/curling-iron.svg
delete mode 100644 src/assets/icons/rental-items/default.svg
delete mode 100644 src/assets/icons/rental-items/eye-drops.svg
delete mode 100644 src/assets/icons/rental-items/hair-dryer.svg
delete mode 100644 src/assets/icons/rental-items/laptop-charger.svg
delete mode 100644 src/assets/icons/rental-items/mask.svg
delete mode 100644 src/assets/icons/rental-items/ointment.svg
delete mode 100644 src/assets/icons/rental-items/pain-relief-patch.svg
delete mode 100644 src/assets/icons/rental-items/pill.svg
delete mode 100644 src/assets/icons/rental-items/power-bank.svg
delete mode 100644 src/assets/icons/rental-items/sanitary-pad.svg
delete mode 100644 src/assets/icons/rental-items/umbrella.svg
delete mode 100644 src/assets/icons/rental-items/usb-c-charger.svg
create mode 100644 src/components/ui/ScreenLayout.tsx
delete mode 100644 src/features/rental/RentalListScreen.tsx
delete mode 100644 src/features/rental/components/RentalCategoryFilter.tsx
delete mode 100644 src/features/rental/components/RentalItemCard.tsx
delete mode 100644 src/features/rental/constants/rentalItems.ts
diff --git a/src/app/App.tsx b/src/app/App.tsx
index 6b9a3d1..3b6b0c1 100644
--- a/src/app/App.tsx
+++ b/src/app/App.tsx
@@ -1,10 +1,28 @@
-import RentalListScreen from "@/features/rental/RentalListScreen";
+import { useState } from "react";
-// 라우팅 도입 전까지 임시로 이 화면만 렌더링한다. 데스크톱에서 보기 좋게 아이폰 화면 크기로 가운데 정렬만 해준다.
+import type { BottomNavValue } from "@/components/ui/BottomNav";
+import ScreenLayout from "@/components/ui/ScreenLayout";
+
+// 라우팅 도입 전까지 ScreenLayout 뼈대 확인용 임시 화면. 실제 화면 콘텐츠는 각 기능 작업에서 채운다.
+// 데스크톱에서 보기 좋게 아이폰 화면 크기로 가운데 정렬만 해준다.
function App() {
+ const [bottomNavValue, setBottomNavValue] = useState("home");
+
return (
-
+
+ STREAM
+
+ }
+ onBottomNavValueChange={setBottomNavValue}
+ >
+
+ 화면 콘텐츠는 각 기능에서 채운다
+
+
);
}
diff --git a/src/assets/icons/circle-minus-fill.svg b/src/assets/icons/circle-minus-fill.svg
deleted file mode 100644
index ad62883..0000000
--- a/src/assets/icons/circle-minus-fill.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
diff --git a/src/assets/icons/circle-plus-fill.svg b/src/assets/icons/circle-plus-fill.svg
deleted file mode 100644
index b00fa3a..0000000
--- a/src/assets/icons/circle-plus-fill.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
diff --git a/src/assets/icons/rental-items/8pin-charger.svg b/src/assets/icons/rental-items/8pin-charger.svg
deleted file mode 100644
index 481c548..0000000
--- a/src/assets/icons/rental-items/8pin-charger.svg
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/assets/icons/rental-items/alcohol-swab.svg b/src/assets/icons/rental-items/alcohol-swab.svg
deleted file mode 100644
index ec57d64..0000000
--- a/src/assets/icons/rental-items/alcohol-swab.svg
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/assets/icons/rental-items/band-aid.svg b/src/assets/icons/rental-items/band-aid.svg
deleted file mode 100644
index 5456739..0000000
--- a/src/assets/icons/rental-items/band-aid.svg
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/assets/icons/rental-items/curling-iron.svg b/src/assets/icons/rental-items/curling-iron.svg
deleted file mode 100644
index a13d2e6..0000000
--- a/src/assets/icons/rental-items/curling-iron.svg
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/assets/icons/rental-items/default.svg b/src/assets/icons/rental-items/default.svg
deleted file mode 100644
index 8cae4eb..0000000
--- a/src/assets/icons/rental-items/default.svg
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/assets/icons/rental-items/eye-drops.svg b/src/assets/icons/rental-items/eye-drops.svg
deleted file mode 100644
index 5a82cbd..0000000
--- a/src/assets/icons/rental-items/eye-drops.svg
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/assets/icons/rental-items/hair-dryer.svg b/src/assets/icons/rental-items/hair-dryer.svg
deleted file mode 100644
index 6578d26..0000000
--- a/src/assets/icons/rental-items/hair-dryer.svg
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/assets/icons/rental-items/laptop-charger.svg b/src/assets/icons/rental-items/laptop-charger.svg
deleted file mode 100644
index 20df526..0000000
--- a/src/assets/icons/rental-items/laptop-charger.svg
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/assets/icons/rental-items/mask.svg b/src/assets/icons/rental-items/mask.svg
deleted file mode 100644
index b1c90a6..0000000
--- a/src/assets/icons/rental-items/mask.svg
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/assets/icons/rental-items/ointment.svg b/src/assets/icons/rental-items/ointment.svg
deleted file mode 100644
index 2820271..0000000
--- a/src/assets/icons/rental-items/ointment.svg
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/assets/icons/rental-items/pain-relief-patch.svg b/src/assets/icons/rental-items/pain-relief-patch.svg
deleted file mode 100644
index decb03d..0000000
--- a/src/assets/icons/rental-items/pain-relief-patch.svg
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/assets/icons/rental-items/pill.svg b/src/assets/icons/rental-items/pill.svg
deleted file mode 100644
index f399c53..0000000
--- a/src/assets/icons/rental-items/pill.svg
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/assets/icons/rental-items/power-bank.svg b/src/assets/icons/rental-items/power-bank.svg
deleted file mode 100644
index d2c4340..0000000
--- a/src/assets/icons/rental-items/power-bank.svg
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/assets/icons/rental-items/sanitary-pad.svg b/src/assets/icons/rental-items/sanitary-pad.svg
deleted file mode 100644
index 69382ab..0000000
--- a/src/assets/icons/rental-items/sanitary-pad.svg
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/assets/icons/rental-items/umbrella.svg b/src/assets/icons/rental-items/umbrella.svg
deleted file mode 100644
index fbd0e6a..0000000
--- a/src/assets/icons/rental-items/umbrella.svg
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/assets/icons/rental-items/usb-c-charger.svg b/src/assets/icons/rental-items/usb-c-charger.svg
deleted file mode 100644
index b8ec969..0000000
--- a/src/assets/icons/rental-items/usb-c-charger.svg
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/components/ui/ScreenLayout.tsx b/src/components/ui/ScreenLayout.tsx
new file mode 100644
index 0000000..8fc52b6
--- /dev/null
+++ b/src/components/ui/ScreenLayout.tsx
@@ -0,0 +1,35 @@
+import type { ReactNode } from "react";
+
+import BottomNav, { type BottomNavValue } from "@/components/ui/BottomNav";
+
+interface ScreenLayoutProps {
+ header: ReactNode;
+ children: ReactNode;
+ bottomNavValue: BottomNavValue;
+ onBottomNavValueChange: (value: BottomNavValue) => void;
+}
+
+// 홈/행사/게시판/빌릴게 등 모든 화면이 공유하는 뼈대 — 고정 크기(375x812) 프레임 안에서
+// header·Bottom Nav는 고정, 본문만 스크롤된다. Top Navigation·필터·리스트 등 화면마다
+// 다른 내용은 header/children으로 각 화면이 채운다(공통인 건 프레임 비율과 Bottom Nav뿐).
+function ScreenLayout({
+ header,
+ children,
+ bottomNavValue,
+ onBottomNavValueChange,
+}: ScreenLayoutProps) {
+ return (
+
+
{header}
+
{children}
+
+
+
+
+ );
+}
+
+export default ScreenLayout;
diff --git a/src/features/rental/RentalListScreen.tsx b/src/features/rental/RentalListScreen.tsx
deleted file mode 100644
index e02b10e..0000000
--- a/src/features/rental/RentalListScreen.tsx
+++ /dev/null
@@ -1,82 +0,0 @@
-import {
- SegmentedControl,
- SegmentedControlItem,
- TopNavigation,
- TopNavigationButton,
-} from "@wanteddev/wds";
-import { IconBell, IconSearch } from "@wanteddev/wds-icon";
-import { useState } from "react";
-
-import BottomNav, { type BottomNavValue } from "@/components/ui/BottomNav";
-import RentalCategoryFilter from "@/features/rental/components/RentalCategoryFilter";
-import RentalItemCard from "@/features/rental/components/RentalItemCard";
-import { RENTAL_ITEMS } from "@/features/rental/constants/rentalItems";
-
-// Figma: 빌릴게 (nodeId 1243:73331)
-function RentalListScreen() {
- const [tab, setTab] = useState("rent");
- const [category, setCategory] = useState("전체");
- const [bottomNavValue, setBottomNavValue] =
- useState("rental");
-
- return (
-
-
- {/* background 기본값(true)은 iOS 반투명 스타일이라 뒤 배경이 비쳐 보인다. Figma는 별도 배경 없이 화면 배경을 그대로 쓴다. */}
-
-
- 대여
- 반납
-
-
- }
- trailingContent={
- <>
-
-
-
-
-
-
- >
- }
- variant="display"
- >
- 빌릴게
-
-
-
-
-
-
-
-
- {tab === "rent" ? (
-
- {RENTAL_ITEMS.map((item) => (
-
- ))}
-
- ) : (
-
- 반납 화면은 아직 준비 중이에요
-
- )}
-
-
-
-
-
-
- );
-}
-
-export default RentalListScreen;
diff --git a/src/features/rental/components/RentalCategoryFilter.tsx b/src/features/rental/components/RentalCategoryFilter.tsx
deleted file mode 100644
index d34d04b..0000000
--- a/src/features/rental/components/RentalCategoryFilter.tsx
+++ /dev/null
@@ -1,40 +0,0 @@
-const RENTAL_CATEGORIES = [
- "전체",
- "전자기기",
- "생활잡화",
- "상비약",
- "위생용품",
-];
-
-interface RentalCategoryFilterProps {
- value: string;
- onChange: (category: string) => void;
-}
-
-// Figma: 빌릴게 Filter Row (nodeId 1243:73337) — WDS Chip이 아니라 Stream 로컬 커스텀 칩.
-// 카테고리·물품 매핑 API가 아직 없어 필터링 없이 선택 상태만 표시한다.
-function RentalCategoryFilter({ value, onChange }: RentalCategoryFilterProps) {
- return (
-
- {RENTAL_CATEGORIES.map((category) => {
- const active = category === value;
- return (
- onChange(category)}
- type="button"
- >
- {category}
-
- );
- })}
-
- );
-}
-
-export default RentalCategoryFilter;
diff --git a/src/features/rental/components/RentalItemCard.tsx b/src/features/rental/components/RentalItemCard.tsx
deleted file mode 100644
index 3e8a65b..0000000
--- a/src/features/rental/components/RentalItemCard.tsx
+++ /dev/null
@@ -1,90 +0,0 @@
-// Figma: Rental Item Card (nodeId 1041:61407)
-import { Button } from "@wanteddev/wds";
-
-import circleMinusFill from "@/assets/icons/circle-minus-fill.svg";
-import circlePlusFill from "@/assets/icons/circle-plus-fill.svg";
-
-interface RentalItemCardProps {
- icon: string;
- itemName: string;
- quantity: number;
- trailingControl?: "button" | "stepper";
- onRentRequest?: () => void;
- stepperValue?: number;
- onStepperDecrease?: () => void;
- onStepperIncrease?: () => void;
-}
-
-// "대여 신청" 버튼은 Figma상 `Menu/Resource/Action Area/Trailing Content/Button`(WDS) 인스턴스지만,
-// 그 이름과 1:1 대응하는 코드 export는 없다 — 대신 WDS `Button`(size="small")이 padding(7px/14px)·
-// radius(8px)·타이포(label2)까지 정확히 일치해서 그걸 쓰고, Button 공개 variant엔 없는 "연한 파랑 배경
-// + 파랑 텍스트" 조합만 sx로 보정했다. 스테퍼 +/- 아이콘은 여전히 WDS 미확정이라 하드코딩 — docs/plans 참고.
-function RentalItemCard({
- icon,
- itemName,
- quantity,
- trailingControl = "button",
- onRentRequest,
- stepperValue = 1,
- onStepperDecrease,
- onStepperIncrease,
-}: RentalItemCardProps) {
- const isStepper = trailingControl === "stepper";
-
- return (
-
-
-
-
-
-
- {itemName}
-
-
수량 {quantity}
-
-
-
- {!isStepper && (
-
- 대여 신청
-
- )}
-
- {isStepper && (
-
-
-
-
-
- {stepperValue}
-
-
-
-
-
- )}
-
-
- );
-}
-
-export default RentalItemCard;
diff --git a/src/features/rental/constants/rentalItems.ts b/src/features/rental/constants/rentalItems.ts
deleted file mode 100644
index c3680f9..0000000
--- a/src/features/rental/constants/rentalItems.ts
+++ /dev/null
@@ -1,75 +0,0 @@
-import eightPinCharger from "@/assets/icons/rental-items/8pin-charger.svg";
-import alcoholSwab from "@/assets/icons/rental-items/alcohol-swab.svg";
-import bandAid from "@/assets/icons/rental-items/band-aid.svg";
-import curlingIron from "@/assets/icons/rental-items/curling-iron.svg";
-import eyeDrops from "@/assets/icons/rental-items/eye-drops.svg";
-import hairDryer from "@/assets/icons/rental-items/hair-dryer.svg";
-import laptopCharger from "@/assets/icons/rental-items/laptop-charger.svg";
-import mask from "@/assets/icons/rental-items/mask.svg";
-import ointment from "@/assets/icons/rental-items/ointment.svg";
-import painReliefPatch from "@/assets/icons/rental-items/pain-relief-patch.svg";
-import pill from "@/assets/icons/rental-items/pill.svg";
-import powerBank from "@/assets/icons/rental-items/power-bank.svg";
-import sanitaryPad from "@/assets/icons/rental-items/sanitary-pad.svg";
-import umbrella from "@/assets/icons/rental-items/umbrella.svg";
-import usbCCharger from "@/assets/icons/rental-items/usb-c-charger.svg";
-
-export interface RentalItem {
- id: string;
- name: string;
- quantity: number;
- icon: string;
-}
-
-// Figma: 빌릴게 Item Grid (nodeId 1243:73343) 순서·물품명·수량을 그대로 옮긴 목데이터 — 실 API 연동 전까지 사용
-export const RENTAL_ITEMS: RentalItem[] = [
- { icon: curlingIron, id: "curling-iron", name: "고데기", quantity: 28 },
- {
- icon: laptopCharger,
- id: "laptop-charger",
- name: "노트북 충전기(C타입)",
- quantity: 28,
- },
- { icon: hairDryer, id: "hair-dryer", name: "드라이기", quantity: 28 },
- { icon: mask, id: "mask", name: "마스크", quantity: 28 },
- { icon: bandAid, id: "band-aid", name: "밴드", quantity: 28 },
- { icon: powerBank, id: "power-bank", name: "보조배터리", quantity: 28 },
- {
- icon: sanitaryPad,
- id: "sanitary-pad-large",
- name: "생리대(대형)",
- quantity: 28,
- },
- {
- icon: sanitaryPad,
- id: "sanitary-pad-small",
- name: "생리대(소형)",
- quantity: 28,
- },
- { icon: alcoholSwab, id: "alcohol-swab", name: "알콜스왑", quantity: 28 },
- { icon: umbrella, id: "umbrella", name: "우산", quantity: 28 },
- { icon: pill, id: "stomach-medicine", name: "위장약", quantity: 28 },
- { icon: pill, id: "easyen-6", name: "이지엔6", quantity: 28 },
- { icon: eyeDrops, id: "eye-drops", name: "인공눈물", quantity: 28 },
- { icon: pill, id: "cold-medicine", name: "종합감기약", quantity: 28 },
- {
- icon: usbCCharger,
- id: "usb-c-cable",
- name: "케이블(C to C)",
- quantity: 28,
- },
- { icon: pill, id: "tylenol", name: "타이레놀", quantity: 28 },
- {
- icon: painReliefPatch,
- id: "pain-relief-patch",
- name: "파스",
- quantity: 28,
- },
- { icon: ointment, id: "ointment", name: "후시딘", quantity: 28 },
- {
- icon: eightPinCharger,
- id: "8pin-charger",
- name: "8핀 충전기",
- quantity: 28,
- },
-];
From 1a5cb907a1e55a5c6bee307f1d2bd083e491a69e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EC=9D=B4=EC=84=9C=EC=A4=80?=
<104981505+xeoxxn@users.noreply.github.com>
Date: Tue, 8 Sep 2026 13:38:35 +0900
Subject: [PATCH 6/7] =?UTF-8?q?chore:=20react-router-dom=20=EB=8F=84?=
=?UTF-8?q?=EC=9E=85?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
BrowserRouter로 감싸 라우팅 기반을 마련한다
---
package.json | 3 +-
pnpm-lock.yaml | 45 ++++++++++
src/assets/icons/circle-minus-fill.svg | 5 ++
src/assets/icons/circle-plus-fill.svg | 5 ++
.../icons/rental-items/8pin-charger.svg | 30 +++++++
.../icons/rental-items/alcohol-swab.svg | 24 +++++
src/assets/icons/rental-items/band-aid.svg | 20 +++++
.../icons/rental-items/curling-iron.svg | 22 +++++
src/assets/icons/rental-items/default.svg | 14 +++
src/assets/icons/rental-items/eye-drops.svg | 21 +++++
src/assets/icons/rental-items/hair-dryer.svg | 21 +++++
.../icons/rental-items/laptop-charger.svg | 22 +++++
src/assets/icons/rental-items/mask.svg | 23 +++++
src/assets/icons/rental-items/ointment.svg | 21 +++++
.../icons/rental-items/pain-relief-patch.svg | 25 ++++++
src/assets/icons/rental-items/pill.svg | 21 +++++
src/assets/icons/rental-items/power-bank.svg | 21 +++++
.../icons/rental-items/sanitary-pad.svg | 21 +++++
src/assets/icons/rental-items/umbrella.svg | 22 +++++
.../icons/rental-items/usb-c-charger.svg | 23 +++++
src/features/rental/RentalListScreen.tsx | 82 +++++++++++++++++
.../components/RentalCategoryFilter.tsx | 40 +++++++++
.../rental/components/RentalItemCard.tsx | 90 +++++++++++++++++++
src/features/rental/constants/rentalItems.ts | 75 ++++++++++++++++
src/main.tsx | 5 +-
25 files changed, 699 insertions(+), 2 deletions(-)
create mode 100644 src/assets/icons/circle-minus-fill.svg
create mode 100644 src/assets/icons/circle-plus-fill.svg
create mode 100644 src/assets/icons/rental-items/8pin-charger.svg
create mode 100644 src/assets/icons/rental-items/alcohol-swab.svg
create mode 100644 src/assets/icons/rental-items/band-aid.svg
create mode 100644 src/assets/icons/rental-items/curling-iron.svg
create mode 100644 src/assets/icons/rental-items/default.svg
create mode 100644 src/assets/icons/rental-items/eye-drops.svg
create mode 100644 src/assets/icons/rental-items/hair-dryer.svg
create mode 100644 src/assets/icons/rental-items/laptop-charger.svg
create mode 100644 src/assets/icons/rental-items/mask.svg
create mode 100644 src/assets/icons/rental-items/ointment.svg
create mode 100644 src/assets/icons/rental-items/pain-relief-patch.svg
create mode 100644 src/assets/icons/rental-items/pill.svg
create mode 100644 src/assets/icons/rental-items/power-bank.svg
create mode 100644 src/assets/icons/rental-items/sanitary-pad.svg
create mode 100644 src/assets/icons/rental-items/umbrella.svg
create mode 100644 src/assets/icons/rental-items/usb-c-charger.svg
create mode 100644 src/features/rental/RentalListScreen.tsx
create mode 100644 src/features/rental/components/RentalCategoryFilter.tsx
create mode 100644 src/features/rental/components/RentalItemCard.tsx
create mode 100644 src/features/rental/constants/rentalItems.ts
diff --git a/package.json b/package.json
index 24403c2..93b6b61 100644
--- a/package.json
+++ b/package.json
@@ -16,7 +16,8 @@
"@wanteddev/wds": "^3.12.0",
"@wanteddev/wds-icon": "^3.12.0",
"react": "^19.2.8",
- "react-dom": "^19.2.8"
+ "react-dom": "^19.2.8",
+ "react-router-dom": "^7.18.3"
},
"devDependencies": {
"@biomejs/biome": "^2.5.11",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 891564d..6eb849c 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -20,6 +20,9 @@ importers:
react-dom:
specifier: ^19.2.8
version: 19.2.8(react@19.2.8)
+ react-router-dom:
+ specifier: ^7.18.3
+ version: 7.18.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
devDependencies:
'@biomejs/biome':
specifier: ^2.5.11
@@ -774,6 +777,10 @@ packages:
convert-source-map@1.9.0:
resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==}
+ cookie@1.1.1:
+ resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==}
+ engines: {node: '>=18'}
+
cosmiconfig@7.1.0:
resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==}
engines: {node: '>=10'}
@@ -1101,6 +1108,23 @@ packages:
'@types/react':
optional: true
+ react-router-dom@7.18.3:
+ resolution: {integrity: sha512-ytVbyBBM7vMfRCam25r0WMhSVSom909A8p+8m0/f1w853dz/xfFu6etAT2SEbVoSnI+ZoPRDqIsQXVT89gp7kg==}
+ engines: {node: '>=20.0.0'}
+ peerDependencies:
+ react: '>=18'
+ react-dom: '>=18'
+
+ react-router@7.18.3:
+ resolution: {integrity: sha512-gyXgtdr5uACJ5b1Q4udzjVV+tb/rlHIMJKuJ0e89R4Kzgz47z/rgP0dIKxktqIEUhDHluGTPJJH/wRha7CyqsA==}
+ engines: {node: '>=20.0.0'}
+ peerDependencies:
+ react: '>=18'
+ react-dom: '>=18'
+ peerDependenciesMeta:
+ react-dom:
+ optional: true
+
react-style-singleton@2.2.3:
resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==}
engines: {node: '>=10'}
@@ -1132,6 +1156,9 @@ packages:
scheduler@0.27.0:
resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==}
+ set-cookie-parser@2.7.2:
+ resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==}
+
source-map-js@1.2.1:
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
engines: {node: '>=0.10.0'}
@@ -1891,6 +1918,8 @@ snapshots:
convert-source-map@1.9.0: {}
+ cookie@1.1.1: {}
+
cosmiconfig@7.1.0:
dependencies:
'@types/parse-json': 4.0.2
@@ -2132,6 +2161,20 @@ snapshots:
optionalDependencies:
'@types/react': 19.2.18
+ react-router-dom@7.18.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8):
+ dependencies:
+ react: 19.2.8
+ react-dom: 19.2.8(react@19.2.8)
+ react-router: 7.18.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
+
+ react-router@7.18.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8):
+ dependencies:
+ cookie: 1.1.1
+ react: 19.2.8
+ set-cookie-parser: 2.7.2
+ optionalDependencies:
+ react-dom: 19.2.8(react@19.2.8)
+
react-style-singleton@2.2.3(@types/react@19.2.18)(react@19.2.8):
dependencies:
get-nonce: 1.0.1
@@ -2174,6 +2217,8 @@ snapshots:
scheduler@0.27.0: {}
+ set-cookie-parser@2.7.2: {}
+
source-map-js@1.2.1: {}
source-map@0.5.7: {}
diff --git a/src/assets/icons/circle-minus-fill.svg b/src/assets/icons/circle-minus-fill.svg
new file mode 100644
index 0000000..ad62883
--- /dev/null
+++ b/src/assets/icons/circle-minus-fill.svg
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/src/assets/icons/circle-plus-fill.svg b/src/assets/icons/circle-plus-fill.svg
new file mode 100644
index 0000000..b00fa3a
--- /dev/null
+++ b/src/assets/icons/circle-plus-fill.svg
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/src/assets/icons/rental-items/8pin-charger.svg b/src/assets/icons/rental-items/8pin-charger.svg
new file mode 100644
index 0000000..481c548
--- /dev/null
+++ b/src/assets/icons/rental-items/8pin-charger.svg
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/icons/rental-items/alcohol-swab.svg b/src/assets/icons/rental-items/alcohol-swab.svg
new file mode 100644
index 0000000..ec57d64
--- /dev/null
+++ b/src/assets/icons/rental-items/alcohol-swab.svg
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/icons/rental-items/band-aid.svg b/src/assets/icons/rental-items/band-aid.svg
new file mode 100644
index 0000000..5456739
--- /dev/null
+++ b/src/assets/icons/rental-items/band-aid.svg
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/icons/rental-items/curling-iron.svg b/src/assets/icons/rental-items/curling-iron.svg
new file mode 100644
index 0000000..a13d2e6
--- /dev/null
+++ b/src/assets/icons/rental-items/curling-iron.svg
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/icons/rental-items/default.svg b/src/assets/icons/rental-items/default.svg
new file mode 100644
index 0000000..8cae4eb
--- /dev/null
+++ b/src/assets/icons/rental-items/default.svg
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/icons/rental-items/eye-drops.svg b/src/assets/icons/rental-items/eye-drops.svg
new file mode 100644
index 0000000..5a82cbd
--- /dev/null
+++ b/src/assets/icons/rental-items/eye-drops.svg
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/icons/rental-items/hair-dryer.svg b/src/assets/icons/rental-items/hair-dryer.svg
new file mode 100644
index 0000000..6578d26
--- /dev/null
+++ b/src/assets/icons/rental-items/hair-dryer.svg
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/icons/rental-items/laptop-charger.svg b/src/assets/icons/rental-items/laptop-charger.svg
new file mode 100644
index 0000000..20df526
--- /dev/null
+++ b/src/assets/icons/rental-items/laptop-charger.svg
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/icons/rental-items/mask.svg b/src/assets/icons/rental-items/mask.svg
new file mode 100644
index 0000000..b1c90a6
--- /dev/null
+++ b/src/assets/icons/rental-items/mask.svg
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/icons/rental-items/ointment.svg b/src/assets/icons/rental-items/ointment.svg
new file mode 100644
index 0000000..2820271
--- /dev/null
+++ b/src/assets/icons/rental-items/ointment.svg
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/icons/rental-items/pain-relief-patch.svg b/src/assets/icons/rental-items/pain-relief-patch.svg
new file mode 100644
index 0000000..decb03d
--- /dev/null
+++ b/src/assets/icons/rental-items/pain-relief-patch.svg
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/icons/rental-items/pill.svg b/src/assets/icons/rental-items/pill.svg
new file mode 100644
index 0000000..f399c53
--- /dev/null
+++ b/src/assets/icons/rental-items/pill.svg
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/icons/rental-items/power-bank.svg b/src/assets/icons/rental-items/power-bank.svg
new file mode 100644
index 0000000..d2c4340
--- /dev/null
+++ b/src/assets/icons/rental-items/power-bank.svg
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/icons/rental-items/sanitary-pad.svg b/src/assets/icons/rental-items/sanitary-pad.svg
new file mode 100644
index 0000000..69382ab
--- /dev/null
+++ b/src/assets/icons/rental-items/sanitary-pad.svg
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/icons/rental-items/umbrella.svg b/src/assets/icons/rental-items/umbrella.svg
new file mode 100644
index 0000000..fbd0e6a
--- /dev/null
+++ b/src/assets/icons/rental-items/umbrella.svg
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/icons/rental-items/usb-c-charger.svg b/src/assets/icons/rental-items/usb-c-charger.svg
new file mode 100644
index 0000000..b8ec969
--- /dev/null
+++ b/src/assets/icons/rental-items/usb-c-charger.svg
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/features/rental/RentalListScreen.tsx b/src/features/rental/RentalListScreen.tsx
new file mode 100644
index 0000000..e02b10e
--- /dev/null
+++ b/src/features/rental/RentalListScreen.tsx
@@ -0,0 +1,82 @@
+import {
+ SegmentedControl,
+ SegmentedControlItem,
+ TopNavigation,
+ TopNavigationButton,
+} from "@wanteddev/wds";
+import { IconBell, IconSearch } from "@wanteddev/wds-icon";
+import { useState } from "react";
+
+import BottomNav, { type BottomNavValue } from "@/components/ui/BottomNav";
+import RentalCategoryFilter from "@/features/rental/components/RentalCategoryFilter";
+import RentalItemCard from "@/features/rental/components/RentalItemCard";
+import { RENTAL_ITEMS } from "@/features/rental/constants/rentalItems";
+
+// Figma: 빌릴게 (nodeId 1243:73331)
+function RentalListScreen() {
+ const [tab, setTab] = useState("rent");
+ const [category, setCategory] = useState("전체");
+ const [bottomNavValue, setBottomNavValue] =
+ useState("rental");
+
+ return (
+
+
+ {/* background 기본값(true)은 iOS 반투명 스타일이라 뒤 배경이 비쳐 보인다. Figma는 별도 배경 없이 화면 배경을 그대로 쓴다. */}
+
+
+ 대여
+ 반납
+
+
+ }
+ trailingContent={
+ <>
+
+
+
+
+
+
+ >
+ }
+ variant="display"
+ >
+ 빌릴게
+
+
+
+
+
+
+
+
+ {tab === "rent" ? (
+
+ {RENTAL_ITEMS.map((item) => (
+
+ ))}
+
+ ) : (
+
+ 반납 화면은 아직 준비 중이에요
+
+ )}
+
+
+
+
+
+
+ );
+}
+
+export default RentalListScreen;
diff --git a/src/features/rental/components/RentalCategoryFilter.tsx b/src/features/rental/components/RentalCategoryFilter.tsx
new file mode 100644
index 0000000..d34d04b
--- /dev/null
+++ b/src/features/rental/components/RentalCategoryFilter.tsx
@@ -0,0 +1,40 @@
+const RENTAL_CATEGORIES = [
+ "전체",
+ "전자기기",
+ "생활잡화",
+ "상비약",
+ "위생용품",
+];
+
+interface RentalCategoryFilterProps {
+ value: string;
+ onChange: (category: string) => void;
+}
+
+// Figma: 빌릴게 Filter Row (nodeId 1243:73337) — WDS Chip이 아니라 Stream 로컬 커스텀 칩.
+// 카테고리·물품 매핑 API가 아직 없어 필터링 없이 선택 상태만 표시한다.
+function RentalCategoryFilter({ value, onChange }: RentalCategoryFilterProps) {
+ return (
+
+ {RENTAL_CATEGORIES.map((category) => {
+ const active = category === value;
+ return (
+ onChange(category)}
+ type="button"
+ >
+ {category}
+
+ );
+ })}
+
+ );
+}
+
+export default RentalCategoryFilter;
diff --git a/src/features/rental/components/RentalItemCard.tsx b/src/features/rental/components/RentalItemCard.tsx
new file mode 100644
index 0000000..3e8a65b
--- /dev/null
+++ b/src/features/rental/components/RentalItemCard.tsx
@@ -0,0 +1,90 @@
+// Figma: Rental Item Card (nodeId 1041:61407)
+import { Button } from "@wanteddev/wds";
+
+import circleMinusFill from "@/assets/icons/circle-minus-fill.svg";
+import circlePlusFill from "@/assets/icons/circle-plus-fill.svg";
+
+interface RentalItemCardProps {
+ icon: string;
+ itemName: string;
+ quantity: number;
+ trailingControl?: "button" | "stepper";
+ onRentRequest?: () => void;
+ stepperValue?: number;
+ onStepperDecrease?: () => void;
+ onStepperIncrease?: () => void;
+}
+
+// "대여 신청" 버튼은 Figma상 `Menu/Resource/Action Area/Trailing Content/Button`(WDS) 인스턴스지만,
+// 그 이름과 1:1 대응하는 코드 export는 없다 — 대신 WDS `Button`(size="small")이 padding(7px/14px)·
+// radius(8px)·타이포(label2)까지 정확히 일치해서 그걸 쓰고, Button 공개 variant엔 없는 "연한 파랑 배경
+// + 파랑 텍스트" 조합만 sx로 보정했다. 스테퍼 +/- 아이콘은 여전히 WDS 미확정이라 하드코딩 — docs/plans 참고.
+function RentalItemCard({
+ icon,
+ itemName,
+ quantity,
+ trailingControl = "button",
+ onRentRequest,
+ stepperValue = 1,
+ onStepperDecrease,
+ onStepperIncrease,
+}: RentalItemCardProps) {
+ const isStepper = trailingControl === "stepper";
+
+ return (
+
+
+
+
+
+
+ {itemName}
+
+
수량 {quantity}
+
+
+
+ {!isStepper && (
+
+ 대여 신청
+
+ )}
+
+ {isStepper && (
+
+
+
+
+
+ {stepperValue}
+
+
+
+
+
+ )}
+
+
+ );
+}
+
+export default RentalItemCard;
diff --git a/src/features/rental/constants/rentalItems.ts b/src/features/rental/constants/rentalItems.ts
new file mode 100644
index 0000000..c3680f9
--- /dev/null
+++ b/src/features/rental/constants/rentalItems.ts
@@ -0,0 +1,75 @@
+import eightPinCharger from "@/assets/icons/rental-items/8pin-charger.svg";
+import alcoholSwab from "@/assets/icons/rental-items/alcohol-swab.svg";
+import bandAid from "@/assets/icons/rental-items/band-aid.svg";
+import curlingIron from "@/assets/icons/rental-items/curling-iron.svg";
+import eyeDrops from "@/assets/icons/rental-items/eye-drops.svg";
+import hairDryer from "@/assets/icons/rental-items/hair-dryer.svg";
+import laptopCharger from "@/assets/icons/rental-items/laptop-charger.svg";
+import mask from "@/assets/icons/rental-items/mask.svg";
+import ointment from "@/assets/icons/rental-items/ointment.svg";
+import painReliefPatch from "@/assets/icons/rental-items/pain-relief-patch.svg";
+import pill from "@/assets/icons/rental-items/pill.svg";
+import powerBank from "@/assets/icons/rental-items/power-bank.svg";
+import sanitaryPad from "@/assets/icons/rental-items/sanitary-pad.svg";
+import umbrella from "@/assets/icons/rental-items/umbrella.svg";
+import usbCCharger from "@/assets/icons/rental-items/usb-c-charger.svg";
+
+export interface RentalItem {
+ id: string;
+ name: string;
+ quantity: number;
+ icon: string;
+}
+
+// Figma: 빌릴게 Item Grid (nodeId 1243:73343) 순서·물품명·수량을 그대로 옮긴 목데이터 — 실 API 연동 전까지 사용
+export const RENTAL_ITEMS: RentalItem[] = [
+ { icon: curlingIron, id: "curling-iron", name: "고데기", quantity: 28 },
+ {
+ icon: laptopCharger,
+ id: "laptop-charger",
+ name: "노트북 충전기(C타입)",
+ quantity: 28,
+ },
+ { icon: hairDryer, id: "hair-dryer", name: "드라이기", quantity: 28 },
+ { icon: mask, id: "mask", name: "마스크", quantity: 28 },
+ { icon: bandAid, id: "band-aid", name: "밴드", quantity: 28 },
+ { icon: powerBank, id: "power-bank", name: "보조배터리", quantity: 28 },
+ {
+ icon: sanitaryPad,
+ id: "sanitary-pad-large",
+ name: "생리대(대형)",
+ quantity: 28,
+ },
+ {
+ icon: sanitaryPad,
+ id: "sanitary-pad-small",
+ name: "생리대(소형)",
+ quantity: 28,
+ },
+ { icon: alcoholSwab, id: "alcohol-swab", name: "알콜스왑", quantity: 28 },
+ { icon: umbrella, id: "umbrella", name: "우산", quantity: 28 },
+ { icon: pill, id: "stomach-medicine", name: "위장약", quantity: 28 },
+ { icon: pill, id: "easyen-6", name: "이지엔6", quantity: 28 },
+ { icon: eyeDrops, id: "eye-drops", name: "인공눈물", quantity: 28 },
+ { icon: pill, id: "cold-medicine", name: "종합감기약", quantity: 28 },
+ {
+ icon: usbCCharger,
+ id: "usb-c-cable",
+ name: "케이블(C to C)",
+ quantity: 28,
+ },
+ { icon: pill, id: "tylenol", name: "타이레놀", quantity: 28 },
+ {
+ icon: painReliefPatch,
+ id: "pain-relief-patch",
+ name: "파스",
+ quantity: 28,
+ },
+ { icon: ointment, id: "ointment", name: "후시딘", quantity: 28 },
+ {
+ icon: eightPinCharger,
+ id: "8pin-charger",
+ name: "8핀 충전기",
+ quantity: 28,
+ },
+];
diff --git a/src/main.tsx b/src/main.tsx
index cd7e812..3a3dd4d 100644
--- a/src/main.tsx
+++ b/src/main.tsx
@@ -1,13 +1,16 @@
import { ThemeProvider } from "@wanteddev/wds";
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
+import { BrowserRouter } from "react-router-dom";
import App from "./app/App.tsx";
import "./index.css";
createRoot(document.getElementById("root")!).render(
-
+
+
+
,
);
From f9b37718ee90594f73533cf3382eff1075bea664 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EC=9D=B4=EC=84=9C=EC=A4=80?=
<104981505+xeoxxn@users.noreply.github.com>
Date: Tue, 8 Sep 2026 13:38:59 +0900
Subject: [PATCH 7/7] =?UTF-8?q?feat:=20=EB=B9=8C=EB=A6=B4=EA=B2=8C=20?=
=?UTF-8?q?=ED=99=94=EB=A9=B4=EC=9D=84=20ScreenLayout=20=EA=B8=B0=EB=B0=98?=
=?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=97=B0=EA=B2=B0=ED=95=98=EA=B3=A0=20?=
=?UTF-8?q?=EB=9D=BC=EC=9A=B0=ED=8A=B8=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RentalListScreen이 자체 375x812/BottomNav 대신 공용 ScreenLayout을 쓰도록
리팩터링하고, HomeScreen을 추가해 '/'와 '/rental' 라우트를 연결한다.
Bottom Nav 탭 클릭 시 해당 라우트로 이동하도록 연결한다
---
src/app/App.tsx | 26 +++-------
src/features/home/HomeScreen.tsx | 41 +++++++++++++++
src/features/rental/RentalListScreen.tsx | 66 +++++++++++++-----------
3 files changed, 84 insertions(+), 49 deletions(-)
create mode 100644 src/features/home/HomeScreen.tsx
diff --git a/src/app/App.tsx b/src/app/App.tsx
index 3b6b0c1..8dd6739 100644
--- a/src/app/App.tsx
+++ b/src/app/App.tsx
@@ -1,28 +1,16 @@
-import { useState } from "react";
+import { Route, Routes } from "react-router-dom";
-import type { BottomNavValue } from "@/components/ui/BottomNav";
-import ScreenLayout from "@/components/ui/ScreenLayout";
+import HomeScreen from "@/features/home/HomeScreen";
+import RentalListScreen from "@/features/rental/RentalListScreen";
-// 라우팅 도입 전까지 ScreenLayout 뼈대 확인용 임시 화면. 실제 화면 콘텐츠는 각 기능 작업에서 채운다.
// 데스크톱에서 보기 좋게 아이폰 화면 크기로 가운데 정렬만 해준다.
function App() {
- const [bottomNavValue, setBottomNavValue] = useState("home");
-
return (
-
- STREAM
-
- }
- onBottomNavValueChange={setBottomNavValue}
- >
-
- 화면 콘텐츠는 각 기능에서 채운다
-
-
+
+ } path="/" />
+ } path="/rental" />
+
);
}
diff --git a/src/features/home/HomeScreen.tsx b/src/features/home/HomeScreen.tsx
new file mode 100644
index 0000000..7a89447
--- /dev/null
+++ b/src/features/home/HomeScreen.tsx
@@ -0,0 +1,41 @@
+import { useState } from "react";
+import { Link, useNavigate } from "react-router-dom";
+
+import type { BottomNavValue } from "@/components/ui/BottomNav";
+import ScreenLayout from "@/components/ui/ScreenLayout";
+
+// 홈 화면 콘텐츠는 아직 없어서, 라우팅이 실제로 동작하는지 확인할 placeholder만 둔다.
+function HomeScreen() {
+ const [bottomNavValue, setBottomNavValue] = useState("home");
+ const navigate = useNavigate();
+
+ const handleBottomNavValueChange = (value: BottomNavValue) => {
+ setBottomNavValue(value);
+ if (value === "rental") {
+ navigate("/rental");
+ }
+ };
+
+ return (
+
+ STREAM
+
+ }
+ onBottomNavValueChange={handleBottomNavValueChange}
+ >
+
+
+ 홈 화면은 아직 준비 중이에요
+
+
+ 빌릴게 화면 보기
+
+
+
+ );
+}
+
+export default HomeScreen;
diff --git a/src/features/rental/RentalListScreen.tsx b/src/features/rental/RentalListScreen.tsx
index e02b10e..25e9086 100644
--- a/src/features/rental/RentalListScreen.tsx
+++ b/src/features/rental/RentalListScreen.tsx
@@ -6,8 +6,10 @@ import {
} from "@wanteddev/wds";
import { IconBell, IconSearch } from "@wanteddev/wds-icon";
import { useState } from "react";
+import { useNavigate } from "react-router-dom";
-import BottomNav, { type BottomNavValue } from "@/components/ui/BottomNav";
+import type { BottomNavValue } from "@/components/ui/BottomNav";
+import ScreenLayout from "@/components/ui/ScreenLayout";
import RentalCategoryFilter from "@/features/rental/components/RentalCategoryFilter";
import RentalItemCard from "@/features/rental/components/RentalItemCard";
import { RENTAL_ITEMS } from "@/features/rental/constants/rentalItems";
@@ -18,11 +20,20 @@ function RentalListScreen() {
const [category, setCategory] = useState("전체");
const [bottomNavValue, setBottomNavValue] =
useState("rental");
+ const navigate = useNavigate();
+
+ const handleBottomNavValueChange = (value: BottomNavValue) => {
+ setBottomNavValue(value);
+ if (value === "home") {
+ navigate("/");
+ }
+ };
return (
-
-
- {/* background 기본값(true)은 iOS 반투명 스타일이라 뒤 배경이 비쳐 보인다. Figma는 별도 배경 없이 화면 배경을 그대로 쓴다. */}
+
빌릴게
+ }
+ onBottomNavValueChange={handleBottomNavValueChange}
+ >
+
+
-
-
-
+ {tab === "rent" ? (
+
+ {RENTAL_ITEMS.map((item) => (
+
+ ))}
-
- {tab === "rent" ? (
-
- {RENTAL_ITEMS.map((item) => (
-
- ))}
-
- ) : (
-
- 반납 화면은 아직 준비 중이에요
-
- )}
-
-
-
-
-
-
+ ) : (
+
+ 반납 화면은 아직 준비 중이에요
+
+ )}
+
);
}