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/app/App.tsx b/src/app/App.tsx
index d347dd4..8dd6739 100644
--- a/src/app/App.tsx
+++ b/src/app/App.tsx
@@ -1,8 +1,17 @@
+import { Route, Routes } from "react-router-dom";
+
+import HomeScreen from "@/features/home/HomeScreen";
+import RentalListScreen from "@/features/rental/RentalListScreen";
+
+// 데스크톱에서 보기 좋게 아이폰 화면 크기로 가운데 정렬만 해준다.
function App() {
return (
-
- STREAM
-
+
+
+ } path="/" />
+ } path="/rental" />
+
+
);
}
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 @@
+
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 (
+
+ );
+ })}
+
+
+
+ );
+}
+
+export default BottomNav;
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/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
new file mode 100644
index 0000000..25e9086
--- /dev/null
+++ b/src/features/rental/RentalListScreen.tsx
@@ -0,0 +1,88 @@
+import {
+ SegmentedControl,
+ SegmentedControlItem,
+ TopNavigation,
+ TopNavigationButton,
+} from "@wanteddev/wds";
+import { IconBell, IconSearch } from "@wanteddev/wds-icon";
+import { useState } from "react";
+import { useNavigate } from "react-router-dom";
+
+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";
+
+// Figma: 빌릴게 (nodeId 1243:73331)
+function RentalListScreen() {
+ const [tab, setTab] = useState("rent");
+ const [category, setCategory] = useState("전체");
+ const [bottomNavValue, setBottomNavValue] =
+ useState("rental");
+ const navigate = useNavigate();
+
+ const handleBottomNavValueChange = (value: BottomNavValue) => {
+ setBottomNavValue(value);
+ if (value === "home") {
+ navigate("/");
+ }
+ };
+
+ return (
+
+
+ 대여
+ 반납
+
+
+ }
+ trailingContent={
+ <>
+
+
+
+
+
+
+ >
+ }
+ variant="display"
+ >
+ 빌릴게
+
+ }
+ onBottomNavValueChange={handleBottomNavValueChange}
+ >
+
+
+
+
+ {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 (
+
+ );
+ })}
+
+ );
+}
+
+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/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..3a3dd4d 100644
--- a/src/main.tsx
+++ b/src/main.tsx
@@ -1,14 +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";
-import "@wanteddev/wds/global.css";
createRoot(document.getElementById("root")!).render(
-
+
+
+
,
);