Skip to content

Commit 2444061

Browse files
committed
design: fix shopping layout
1 parent 011e4e5 commit 2444061

14 files changed

+178
-118
lines changed

src/api/UserContext.jsx

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export const UserProvider = ({ children }) => {
3737
if (response.ok) {
3838
const data = await response.json();
3939
setUser(data.user);
40+
console.log(data.user);
4041
setIsLoggedin(true);
4142
setToken(data.token);
4243
// 로컬 스토리지에 토큰과 사용자 정보 저장

src/components/Button.jsx

+6
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ const StyledButton = styled.button`
3333
border: 1px solid #48582f;
3434
}
3535
36+
&.smallgreen {
37+
min-width: 70px;
38+
background-color: #48582f;
39+
border: 1px solid #48582f;
40+
}
41+
3642
&.red {
3743
min-width: 135px;
3844
background-color: #d53d3d;

src/components/price/CurrentPriceItem.jsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,17 @@ const Text = styled.div`
2222
white-space: pre-wrap;
2323
2424
&.title {
25-
font-size: 13px;
25+
font-size: 21px;
2626
font-weight: 700;
2727
}
2828
2929
&.sub {
30-
font-size: 13px;
30+
font-size: 19px;
3131
font-weight: 400;
3232
}
3333
3434
&.dosage {
35-
font-size: 10px;
35+
font-size: 17px;
3636
font-weight: 400;
3737
color: #979797;
3838
}
@@ -54,7 +54,7 @@ function CurrentPriceItem(props) {
5454
{price_decline ? price_decline : "변동률"}
5555
</Text>
5656
</TextContainer>
57-
<Button className="green" title="추가" onClick={handler} />
57+
<Button className="smallgreen" title="추가" onClick={handler} />
5858
</Container>
5959
);
6060
}

src/components/price/PriceItem.jsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ function PriceItem(props) {
8888
} = props;
8989

9090
const [count, setCount] = useState(1);
91-
const token = useUser();
91+
const { token } = useUser();
9292

9393
const handleAddToCart = async () => {
9494
try {

src/components/shopping/ShoppingBudget.jsx

+41-35
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ import Button from "../Button";
55
import { useUser } from "../../api/UserContext";
66

77
const Container = styled.div`
8-
width: 100%;
8+
width: 520px;
99
height: 180px;
1010
padding: 10px;
11+
margin-top: 20px;
1112
display: flex;
1213
flex-direction: column;
1314
align-items: center;
@@ -97,9 +98,9 @@ const BudgetInput = styled.input`
9798

9899
function ShoppingBudget({ budget, present, hideButtons }) {
99100
const [isEditing, setIsEditing] = useState(false);
100-
const [newBudget, setNewBudget] = useState("");
101-
const state = budget - present;
102-
const token = useUser();
101+
const [newBudget, setNewBudget] = useState();
102+
const state = budget === 0 ? 0 : budget - present;
103+
const { token } = useUser();
103104

104105
const handleSetBudget = async () => {
105106
if (!newBudget || isNaN(newBudget)) {
@@ -132,7 +133,7 @@ function ShoppingBudget({ budget, present, hideButtons }) {
132133
}
133134
};
134135

135-
if (budget == null && !hideButtons) {
136+
if (!hideButtons) {
136137
return (
137138
<>
138139
{isEditing ? (
@@ -151,14 +152,42 @@ function ShoppingBudget({ budget, present, hideButtons }) {
151152
/>
152153
</BudgetInputContainer>
153154
) : (
154-
<Button
155-
title="예산 설정하기"
156-
className="green"
157-
onClick={() => setIsEditing(true)}
158-
/>
155+
<>
156+
<Button
157+
title="예산 설정하기"
158+
className="green"
159+
onClick={() => setIsEditing(true)}
160+
/>
161+
{budget === 0 && (
162+
<>
163+
<TextMain className="title">등록된 예산이 없습니다</TextMain>
164+
<TextMain className="sub">내 예산을 설정해보세요!</TextMain>
165+
</>
166+
)}
167+
{budget !== 0 && (
168+
<Container>
169+
<ContentContainer>
170+
<FiDollarSign color="#daa520" size={32} />
171+
<Text className="budget">예산</Text>
172+
<Text className="money">{`${budget}`}</Text>
173+
</ContentContainer>
174+
<ContentContainer>
175+
<FiDollarSign color="#47572f" size={32} />
176+
<Text className="present">현재</Text>
177+
<Text className="money">{`${present}`}</Text>
178+
</ContentContainer>
179+
<hr color="#432a00" width="520px" height="1px" />
180+
<ContentContainer>
181+
<FiDollarSign color="#432a00" size={32} />
182+
<Text className={state >= 0 ? "stable" : "warning"}>
183+
{state >= 0 ? "안정" : "초과"}
184+
</Text>
185+
<Text className="money">{state}</Text>
186+
</ContentContainer>
187+
</Container>
188+
)}
189+
</>
159190
)}
160-
<TextMain className="title">등록된 예산이 없습니다</TextMain>
161-
<TextMain className="sub">내 예산을 설정해보세요!</TextMain>
162191
</>
163192
);
164193
}
@@ -169,30 +198,7 @@ function ShoppingBudget({ budget, present, hideButtons }) {
169198
<FiDollarSign color="#daa520" size={32} />
170199
<Text className="budget">예산</Text>
171200
<Text className="money">{`${budget}`}</Text>
172-
{!hideButtons && (
173-
<Button
174-
title="수정"
175-
className="green"
176-
onClick={() => setIsEditing(true)}
177-
/>
178-
)}
179201
</ContentContainer>
180-
{isEditing && (
181-
<BudgetInputContainer>
182-
<BudgetInput
183-
type="number"
184-
value={newBudget}
185-
onChange={(e) => setNewBudget(e.target.value)}
186-
placeholder="새로운 예산을 입력하세요"
187-
/>
188-
<Button title="설정" className="brown" onClick={handleSetBudget} />
189-
<Button
190-
title="취소"
191-
className="yellow"
192-
onClick={() => setIsEditing(false)}
193-
/>
194-
</BudgetInputContainer>
195-
)}
196202
<ContentContainer>
197203
<FiDollarSign color="#47572f" size={32} />
198204
<Text className="present">현재</Text>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import React, { useState, useEffect } from "react";
2+
import styled from "styled-components";
3+
import ShoppingBudget from "./ShoppingBudget";
4+
import ShoppingList from "./ShoppingList";
5+
import { useUser } from "../../api/UserContext";
6+
7+
const Container = styled.div`
8+
width: calc(100%);
9+
display: flex;
10+
flex-direction: column;
11+
justify-content: center;
12+
align-items: center;
13+
text-align: center;
14+
`;
15+
16+
function ShoppingComponent({ hideButtons }) {
17+
const { token } = useUser();
18+
const [items, setItems] = useState([]);
19+
const [budget, setBudget] = useState(0);
20+
const [present, setPresent] = useState(0);
21+
const [isLoading, setIsLoading] = useState(true);
22+
23+
useEffect(() => {
24+
const fetchShoppingList = async () => {
25+
try {
26+
const response = await fetch(
27+
"https://rw2644hx4c.execute-api.us-east-1.amazonaws.com/api/carts",
28+
{
29+
method: "GET",
30+
headers: {
31+
"Content-Type": "application/json",
32+
Authorization: `Bearer ${token}`,
33+
},
34+
}
35+
);
36+
37+
if (!response.ok) {
38+
throw new Error("리스트 불러오기에 실패했습니다.");
39+
}
40+
41+
const data = await response.json();
42+
setItems(data.cart.cart_items || []);
43+
setBudget(data.cart.budget);
44+
setPresent(data.cart.total_price);
45+
console.log(data);
46+
} catch (error) {
47+
console.error("리스트 불러오기 실패:", error);
48+
} finally {
49+
setIsLoading(false);
50+
}
51+
};
52+
53+
if (token) {
54+
fetchShoppingList();
55+
}
56+
}, [token]);
57+
58+
return (
59+
<Container>
60+
<ShoppingBudget
61+
budget={budget == null ? 0 : budget}
62+
present={present == null ? 0 : present}
63+
hideButtons={hideButtons}
64+
/>
65+
<ShoppingList
66+
items={items}
67+
setItems={setItems}
68+
isLoading={isLoading}
69+
hideButtons={hideButtons}
70+
/>
71+
</Container>
72+
);
73+
}
74+
75+
export default ShoppingComponent;

src/components/shopping/ShoppingItem.jsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import Button from "../Button";
44

55
const Container = styled.div`
66
width: 320px;
7-
height: 79px;
7+
height: 100px;
88
padding: 10px 0;
99
display: flex;
1010
justify-content: space-between;
@@ -23,17 +23,17 @@ const Text = styled.div`
2323
white-space: pre-wrap;
2424
2525
&.title {
26-
font-size: 13px;
26+
font-size: 21px;
2727
font-weight: 700;
2828
}
2929
3030
&.sub {
31-
font-size: 13px;
31+
font-size: 19px;
3232
font-weight: 400;
3333
}
3434
3535
&.dosage {
36-
font-size: 10px;
36+
font-size: 17px;
3737
font-weight: 400;
3838
color: #979797;
3939
}

src/components/shopping/ShoppingList.jsx

+4-38
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState, useEffect } from "react";
1+
import React from "react";
22
import { useNavigate } from "react-router-dom";
33
import { DragDropContext } from "@hello-pangea/dnd";
44
import styled from "styled-components";
@@ -13,43 +13,9 @@ const ListContainer = styled.div`
1313
padding: 20px;
1414
`;
1515

16-
function ShoppingList({ hideButtons }) {
16+
function ShoppingList({ items, setItems, isLoading, hideButtons }) {
1717
const navigate = useNavigate();
1818
const { token } = useUser();
19-
const [items, setItems] = useState([]);
20-
const [isLoading, setIsLoading] = useState(true);
21-
22-
useEffect(() => {
23-
const fetchShoppingList = async () => {
24-
try {
25-
const response = await fetch(
26-
"https://rw2644hx4c.execute-api.us-east-1.amazonaws.com/api/carts",
27-
{
28-
method: "GET",
29-
headers: {
30-
"Content-Type": "application/json",
31-
Authorization: `Bearer ${token}`,
32-
},
33-
}
34-
);
35-
36-
if (!response.ok) {
37-
throw new Error("리스트 불러오기에 실패했습니다.");
38-
}
39-
40-
const data = await response.json();
41-
setItems(data.items || []);
42-
} catch (error) {
43-
console.error("리스트 불러오기 실패:", error);
44-
} finally {
45-
setIsLoading(false);
46-
}
47-
};
48-
49-
if (token) {
50-
fetchShoppingList();
51-
}
52-
}, [token]);
5319

5420
const handleDragEnd = (result) => {
5521
if (!result.destination) return;
@@ -78,7 +44,7 @@ function ShoppingList({ hideButtons }) {
7844
body: JSON.stringify({
7945
items: items.map((item, index) => ({
8046
...item,
81-
order: index,
47+
priority: index,
8248
})),
8349
}),
8450
}
@@ -91,7 +57,7 @@ function ShoppingList({ hideButtons }) {
9157
alert("장바구니가 저장되었습니다.");
9258
} catch (error) {
9359
console.error("저장 실패:", error);
94-
alert("저장에 실패했습니다. 다시 시도해주��요.");
60+
alert("저장에 실패했습니다. 다시 시도해주세요.");
9561
}
9662
};
9763

src/components/shopping/ShoppingListItems.jsx

+24-3
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,33 @@ function ShoppingListItems({ items, onDelete, hideButtons }) {
7272
);
7373
}
7474

75+
if (hideButtons) {
76+
return (
77+
<ItemList className="hide">
78+
{items.map((item, index) => (
79+
<DraggableItem key={item.product_id}>
80+
<ShoppingItem
81+
name={item.product_name}
82+
price={item.price}
83+
num={item.quantity}
84+
hideButtons={hideButtons}
85+
/>
86+
</DraggableItem>
87+
))}
88+
</ItemList>
89+
);
90+
}
91+
7592
return (
7693
<Droppable droppableId="droppable">
7794
{(provided) => (
7895
<ItemList {...provided.droppableProps} ref={provided.innerRef}>
7996
{items.map((item, index) => (
80-
<Draggable key={item.id} draggableId={item.id} index={index}>
97+
<Draggable
98+
key={item.product_id}
99+
draggableId={item.product_id.toString()}
100+
index={index}
101+
>
81102
{(provided, snapshot) => (
82103
<DraggableItem
83104
ref={provided.innerRef}
@@ -88,9 +109,9 @@ function ShoppingListItems({ items, onDelete, hideButtons }) {
88109
<DragHandle />
89110
</div>
90111
<ShoppingItem
91-
name={item.name}
112+
name={item.product_name}
92113
price={item.price}
93-
num={item.num}
114+
num={item.quantity}
94115
handler={() => onDelete(index)}
95116
hideButtons={hideButtons}
96117
/>

0 commit comments

Comments
 (0)