Skip to content

Commit 07a7de7

Browse files
committed
일단 최종 UI 완성 점검 필요
1 parent 461bcc2 commit 07a7de7

17 files changed

Lines changed: 1516 additions & 751 deletions

File tree

src/components/AddIngredientPopup/AddIngredientPopup.jsx

Lines changed: 113 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,63 @@
11
import React, { useState } from "react";
22
import "./style.css";
33

4-
const CATEGORIES = ["육류", "채소류", "가공류", "유제품", "기타"];
4+
// 카테고리 상수는 제거하거나, 백엔드 전송용으로 내부에서만 기본값 처리하면 됩니다.
55

66
export const AddIngredientPopup = ({ onClose, onAdd }) => {
7-
const [name, setName] = useState("");
8-
const [category, setCategory] = useState("채소류");
9-
const [expiryDays, setExpiryDays] = useState("");
10-
11-
// 영수증 분석(1단계) 완료 여부를 체크하는 상태
127
const [isReceiptProcessed, setIsReceiptProcessed] = useState(false);
8+
const [items, setItems] = useState([]);
139

14-
const handleSubmit = (e) => {
10+
// 1단계: 영수증 분석 시뮬레이션
11+
const handleAnalyzeReceipt = (e) => {
1512
e.preventDefault();
13+
console.log("영수증 분석 시작...");
1614

17-
// 1단계: 영수증 등록 버튼을 눌렀을 때 (아직 분석 결과가 안 나왔을 때)
18-
if (!isReceiptProcessed) {
19-
// TODO: 백엔드로 영수증 이미지를 보내고 분석 결과를 받아오는 로직이 들어갈 자리
20-
console.log("영수증 분석 시작...");
21-
22-
// [가상 시나리오] 백엔드에서 분석된 결과가 자동으로 채워진다고 가정
23-
// setName("분석된 양파");
24-
// setExpiryDays("7");
25-
26-
setIsReceiptProcessed(true); // 입력 필드를 보여주도록 상태 변경
27-
return;
28-
}
29-
30-
// 2단계: 최종 등록 버튼을 눌렀을 때
31-
if (!name || !expiryDays) {
32-
alert("모든 필드를 입력해주세요.");
33-
return;
34-
}
15+
const mockAnalyzedData = [
16+
{ id: 1, name: "양파", expiryDays: 7 },
17+
{ id: 2, name: "삼겹살", expiryDays: 3 },
18+
{ id: 3, name: "우유", expiryDays: 10 },
19+
{ id: 4, name: "종량제봉투", expiryDays: 0 },
20+
];
21+
22+
setItems(mockAnalyzedData);
23+
setIsReceiptProcessed(true);
24+
};
25+
26+
const handleItemChange = (id, field, value) => {
27+
setItems(items.map(item =>
28+
item.id === id ? { ...item, [field]: value } : item
29+
));
30+
};
31+
32+
const handleDeleteItem = (id) => {
33+
setItems(items.filter(item => item.id !== id));
34+
};
3535

36-
const newIngredient = {
36+
const handleAddItem = () => {
37+
const newItem = {
3738
id: Date.now(),
38-
name,
39-
category,
40-
expiryDays: parseInt(expiryDays),
41-
image: "https://c.animaapp.com/sjWITF5i/img/ingredientimage-7@2x.png"
39+
name: "",
40+
expiryDays: ""
4241
};
42+
setItems([...items, newItem]);
43+
};
44+
45+
const handleFinalSubmit = () => {
46+
const isValid = items.every(item => item.name && item.expiryDays !== "");
47+
if (!isValid) {
48+
alert("모든 재료의 정보를 입력해주세요.");
49+
return;
50+
}
51+
52+
items.forEach(item => {
53+
onAdd({
54+
...item,
55+
category: "기타", // 백엔드에서 필요하다면 기본값으로 '기타'나 '미분류' 전송
56+
expiryDays: parseInt(item.expiryDays),
57+
image: "https://c.animaapp.com/sjWITF5i/img/ingredientimage-7@2x.png"
58+
});
59+
});
4360

44-
// TODO: Send to backend
45-
console.log("Adding ingredient via receipt:", newIngredient);
46-
onAdd(newIngredient);
4761
onClose();
4862
};
4963

@@ -53,68 +67,75 @@ export const AddIngredientPopup = ({ onClose, onAdd }) => {
5367
<button className="add-ingredient-popup-close" onClick={onClose}>×</button>
5468

5569
<div className="add-ingredient-popup-header">
56-
<h2 className="add-ingredient-popup-title">영수증 등록</h2>
70+
<h2 className="add-ingredient-popup-title">
71+
{isReceiptProcessed ? "분석 결과 확인" : "영수증 등록"}
72+
</h2>
5773
</div>
5874

59-
<form className="add-ingredient-popup-form" onSubmit={handleSubmit}>
60-
<div className="add-ingredient-popup-input-group">
61-
<label className="add-ingredient-popup-label">영수증</label>
62-
<input
63-
type="file"
64-
className="add-ingredient-popup-input"
65-
required={!isReceiptProcessed} // 분석 전에는 필수 입력
66-
disabled={isReceiptProcessed} // 분석 후에는 수정 불가 (선택 사항)
67-
/>
68-
</div>
69-
70-
{/* isReceiptProcessed가 true일 때만 아래 내용 표시 백앤드에서 분석한 결과 표시해주는 곳 사용자 확인용 마음에 안들면 여기서 수정가능 */}
71-
{isReceiptProcessed && (
72-
<>
73-
<div className="add-ingredient-popup-input-group">
74-
<label className="add-ingredient-popup-label">재료명</label>
75-
<input
76-
type="text"
77-
className="add-ingredient-popup-input"
78-
value={name}
79-
onChange={(e) => setName(e.target.value)}
80-
placeholder="예: 양파"
81-
required
82-
/>
83-
</div>
84-
85-
<div className="add-ingredient-popup-input-group">
86-
<label className="add-ingredient-popup-label">카테고리</label>
87-
<select
88-
className="add-ingredient-popup-select"
89-
value={category}
90-
onChange={(e) => setCategory(e.target.value)}
91-
required
92-
>
93-
{CATEGORIES.map((cat) => (
94-
<option key={cat} value={cat}>{cat}</option>
95-
))}
96-
</select>
97-
</div>
75+
{!isReceiptProcessed ? (
76+
<form className="add-ingredient-popup-form" onSubmit={handleAnalyzeReceipt}>
77+
<div className="add-ingredient-popup-input-group">
78+
<label className="add-ingredient-popup-label">영수증 업로드</label>
79+
<input
80+
type="file"
81+
className="add-ingredient-popup-input file-input"
82+
accept="image/*"
83+
required
84+
/>
85+
<p className="helper-text">선명한 영수증 사진을 올려주세요.</p>
86+
</div>
87+
<button type="submit" className="add-ingredient-popup-submit-btn">
88+
분석 시작
89+
</button>
90+
</form>
91+
) : (
92+
<div className="processed-list-container">
93+
{/* 카테고리 헤더 삭제 */}
94+
<div className="processed-list-header">
95+
<span style={{ flex: 3 }}>재료명</span>
96+
<span style={{ flex: 1, textAlign: 'center' }}>기한(일)</span>
97+
<span style={{ width: '28px' }}></span> {/* 삭제버튼 자리 */}
98+
</div>
99+
100+
<div className="processed-list-body">
101+
{items.map((item) => (
102+
<div key={item.id} className="processed-item-row">
103+
{/* 카테고리 Select 삭제, 이름 입력창 확장 */}
104+
<input
105+
type="text"
106+
className="item-input name-input"
107+
value={item.name}
108+
onChange={(e) => handleItemChange(item.id, "name", e.target.value)}
109+
placeholder="재료명"
110+
/>
111+
112+
<input
113+
type="number"
114+
className="item-input date-input"
115+
value={item.expiryDays}
116+
onChange={(e) => handleItemChange(item.id, "expiryDays", e.target.value)}
117+
placeholder="일"
118+
/>
119+
<button
120+
className="item-delete-btn"
121+
onClick={() => handleDeleteItem(item.id)}
122+
title="삭제"
123+
>
124+
125+
</button>
126+
</div>
127+
))}
128+
129+
<button className="add-row-btn" onClick={handleAddItem}>
130+
+ 직접 추가하기
131+
</button>
132+
</div>
98133

99-
<div className="add-ingredient-popup-input-group">
100-
<label className="add-ingredient-popup-label">유통기한 (일)</label>
101-
<input
102-
type="number"
103-
className="add-ingredient-popup-input"
104-
value={expiryDays}
105-
onChange={(e) => setExpiryDays(e.target.value)}
106-
placeholder="예: 7"
107-
min="1"
108-
required
109-
/>
110-
</div>
111-
</>
112-
)}
113-
114-
<button type="submit" className="add-ingredient-popup-submit-btn">
115-
{isReceiptProcessed ? "최종 등록" : "추가하기"}
116-
</button>
117-
</form>
134+
<button onClick={handleFinalSubmit} className="add-ingredient-popup-submit-btn">
135+
{items.length}개 재료 등록하기
136+
</button>
137+
</div>
138+
)}
118139
</div>
119140
</div>
120141
);

0 commit comments

Comments
 (0)