Skip to content

Commit 8f2a34c

Browse files
Merge pull request #7 from nerdinary-hackathon-8th/feat/#3
물품 등록
2 parents f441136 + d9067a4 commit 8f2a34c

File tree

10 files changed

+451
-114
lines changed

10 files changed

+451
-114
lines changed

src/components/FoodList/FoodCard.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ interface FoodCardProps {
4040

4141
export default function FoodCard({ id, name, icon, isSelected, onClick }: FoodCardProps) {
4242
return (
43-
<FoodBox>
43+
<FoodBox onClick={onClick}>
4444
<FoodImage src={FoodExample} />
45-
<FoodName>해산물</FoodName>
45+
<FoodName>{name}</FoodName>
4646
</FoodBox>
4747
);
4848
}

src/components/FoodList/FoodList.module.css

Lines changed: 2 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
border-radius: 20px 20px 0 0;
66
height: 596px;
77
bottom: 0;
8-
9-
108
}
119

1210
.section {
@@ -20,52 +18,7 @@
2018
justify-items: center; /* 아이템 중앙 정렬 */
2119
}
2220

23-
.section::-webkit-scrollbar {
24-
display: none;
25-
}
26-
2721
.title {
28-
font-size: 2.6rem;
29-
font-weight: bold;
30-
margin-bottom: 5rem;
31-
}
32-
33-
.gridViewTitle {
34-
font-size: 2rem;
35-
margin-bottom: 2rem;
36-
}
37-
38-
/* .gridView {
39-
display: grid;
40-
grid-template-columns: repeat(3, 1fr);
41-
gap: 2rem;
42-
} */
43-
44-
.industryItem {
45-
display: flex;
46-
flex-direction: column;
47-
gap: 1rem;
48-
justify-content: center;
49-
align-items: center;
50-
border-radius: 0.8rem;
51-
border: solid 1px;
52-
padding: 2rem;
53-
}
54-
55-
.industryItem:active {
56-
background-color: #4a4a4a;
57-
transform: scale(0.98);
58-
}
59-
60-
.industryItem:hover {
61-
background-color: #4a4a4a;
62-
transform: scale(0.98);
63-
}
64-
65-
.industryItemIcon {
66-
width: 70%;
67-
}
68-
69-
.industryItemText {
70-
font-size: 1.4rem;
22+
font-weight: 700;
23+
font-size: 15px;
7124
}
Lines changed: 42 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,48 @@
1-
import styles from './FoodList.module.css';
2-
import { useState } from 'react';
3-
import { useNavigate } from 'react-router-dom';
4-
import FoodCard from './FoodCard';
5-
1+
import styles from "./FoodList.module.css";
2+
import { useState } from "react";
3+
import { useNavigate } from "react-router-dom";
4+
import FoodCard from "./FoodCard";
65

76
export default function FoodList() {
8-
// const navigate = useNavigate();
9-
const [currentId, setCurrentId] = useState<number | null>(null);
10-
11-
// 임시 더미 데이터 (FoodCard를 위한 아이디와 이름 등)
12-
// 필요하면 FoodCard prop에 맞게 수정하세요
13-
const foodCards = [
14-
{ id: 1, name: '해산물', icon: '/path/to/seafood.png' },
15-
{ id: 2, name: '해산물', icon: '/path/to/seafood.png' },
16-
{ id: 3, name: '해산물', icon: '/path/to/seafood.png' },
17-
{ id: 4, name: '해산물', icon: '/path/to/seafood.png' },
18-
{ id: 5, name: '해산물', icon: '/path/to/seafood.png' },
19-
{ id: 6, name: '해산물', icon: '/path/to/seafood.png' },
20-
{ id: 7, name: '해산물', icon: '/path/to/seafood.png' },
21-
{ id: 8, name: '해산물', icon: '/path/to/seafood.png' },
22-
{ id: 9, name: '해산물', icon: '/path/to/seafood.png' },
23-
{ id: 10, name: '해산물', icon: '/path/to/seafood.png' },
24-
{ id: 11, name: '해산물', icon: '/path/to/seafood.png' },
25-
{ id: 12, name: '해산물', icon: '/path/to/seafood.png' },
26-
];
7+
const navigate = useNavigate();
8+
const [currentId, setCurrentId] = useState<number | null>(null);
279

28-
const handleCardClick = (id: number) => {
29-
setCurrentId(id);
30-
// 필요한 추가 로직 가능
31-
};
10+
// 임시 더미 데이터 (FoodCard를 위한 아이디와 이름 등)
11+
// 필요하면 FoodCard prop에 맞게 수정하세요
12+
const foodCards = [
13+
{ id: 1, name: "해산물", icon: "/path/to/seafood.png" },
14+
{ id: 2, name: "축산/계란", icon: "/path/to/seafood.png" },
15+
{ id: 3, name: "채소", icon: "/path/to/seafood.png" },
16+
{ id: 4, name: "과일", icon: "/path/to/seafood.png" },
17+
{ id: 5, name: "유제품", icon: "/path/to/seafood.png" },
18+
{ id: 6, name: "조미료/향신료", icon: "/path/to/seafood.png" },
19+
{ id: 7, name: "과자/시리얼", icon: "/path/to/seafood.png" },
20+
{ id: 8, name: "견과류", icon: "/path/to/seafood.png" },
21+
{ id: 9, name: "간편식/밀키트", icon: "/path/to/seafood.png" },
22+
{ id: 10, name: "가공식품", icon: "/path/to/seafood.png" },
23+
{ id: 11, name: "건강식품", icon: "/path/to/seafood.png" },
24+
{ id: 12, name: "기타", icon: "/path/to/seafood.png" },
25+
];
3226

33-
return (
34-
<div className={styles.page}>
35-
<div className={styles.section}>
36-
<div className={styles.gridView}>
37-
{foodCards.map((card) => (
38-
<FoodCard
39-
key={card.id}
40-
id={card.id}
41-
name={card.name}
42-
icon={card.icon}
43-
isSelected={card.id === currentId}
44-
onClick={() => handleCardClick(card.id)}
45-
/>
46-
))}
27+
return (
28+
<div className={styles.page}>
29+
<p className={styles.title}>카테고리를 클릭하고, 음식을 추가해보세요!</p>
30+
<div className={styles.section}>
31+
<div className={styles.gridView}>
32+
{foodCards.map((card) => (
33+
<FoodCard
34+
key={card.id}
35+
id={card.id}
36+
name={card.name}
37+
icon={card.icon}
38+
isSelected={card.id === currentId}
39+
onClick={() => {
40+
navigate(`/register-food/${card.id}`, { state: card.name });
41+
}}
42+
/>
43+
))}
44+
</div>
45+
</div>
4746
</div>
48-
</div>
49-
</div>
50-
);
47+
);
5148
}
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
import styled from "@emotion/styled";
2+
import { useEffect } from "react";
3+
4+
const Container = styled.div`
5+
display: flex;
6+
flex-direction: column;
7+
gap: 4px;
8+
width: 100%;
9+
`;
10+
11+
const Label = styled.label`
12+
font-weight: 700;
13+
font-size: 15px;
14+
color: black;
15+
margin-bottom: 4px;
16+
`;
17+
18+
const PlaceHolder = styled.p`
19+
font-weight: 500;
20+
font-size: 12px;
21+
color: #c5c5c5;
22+
`;
23+
24+
const InputWrapper = styled.div`
25+
display: flex;
26+
align-items: center;
27+
gap: 8px;
28+
padding-bottom: 4px;
29+
`;
30+
31+
const DateInput = styled.input`
32+
border: none;
33+
outline: none;
34+
background: transparent;
35+
font-size: 14px;
36+
text-align: center;
37+
width: 140px;
38+
`;
39+
40+
const CalendarIcon = styled.span`
41+
display: inline-block;
42+
width: 24px;
43+
height: 24px;
44+
background: url("/icons/calendar.svg") no-repeat center center;
45+
background-size: contain;
46+
`;
47+
48+
const CheckboxWrapper = styled.label`
49+
display: flex;
50+
align-items: center;
51+
gap: 6px;
52+
font-size: 11px;
53+
font-weight: 500;
54+
color: #444;
55+
cursor: pointer;
56+
user-select: none;
57+
`;
58+
59+
interface DateSelect {
60+
label: string;
61+
dateValue: string;
62+
onDateChange: (value: string) => void;
63+
showCheckbox?: boolean;
64+
checkboxLabel?: string;
65+
onCheckboxChange?: (checked: boolean) => void;
66+
checkboxChecked?: boolean;
67+
placeholder: string;
68+
}
69+
70+
export default function DateSelect({
71+
label, // 구매일 or 판매일
72+
dateValue,
73+
onDateChange,
74+
showCheckbox = false,
75+
checkboxLabel = "소비기한이 안적혀있어요.",
76+
onCheckboxChange,
77+
checkboxChecked = false,
78+
placeholder,
79+
}: DateSelect) {
80+
81+
const getTodayDateString = () => {
82+
const today = new Date();
83+
const yyyy = today.getFullYear();
84+
const mm = String(today.getMonth() + 1).padStart(2, "0");
85+
const dd = String(today.getDate()).padStart(2, "0");
86+
return `${yyyy}-${mm}-${dd}`;
87+
};
88+
89+
useEffect(() => {
90+
if (label === "구매일" && !dateValue) {
91+
onDateChange(getTodayDateString());
92+
}
93+
}, [label, dateValue, onDateChange]);
94+
95+
return (
96+
<Container>
97+
<Label>{label}</Label>
98+
<PlaceHolder>{placeholder}</PlaceHolder>
99+
<InputWrapper>
100+
<DateInput
101+
type="date"
102+
min="1900-01-01"
103+
max="2099-12-31"
104+
value={dateValue}
105+
onChange={(e) => onDateChange(e.target.value)}
106+
/>
107+
<CalendarIcon />
108+
</InputWrapper>
109+
{showCheckbox && (
110+
<CheckboxWrapper>
111+
<input
112+
type="checkbox"
113+
checked={checkboxChecked}
114+
onChange={(e) => onCheckboxChange && onCheckboxChange(e.target.checked)}
115+
/>
116+
{checkboxLabel}
117+
</CheckboxWrapper>
118+
)}
119+
</Container>
120+
);
121+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import styled from "@emotion/styled";
2+
3+
const Page = styled.div`
4+
background-color: #57aa33;
5+
height: 100%;
6+
`;
7+
const Container = styled.div`
8+
display: flex;
9+
flex-direction: column;
10+
align-items: center;
11+
padding: 2rem 1rem;
12+
border-radius: 20px 20px 0 0;
13+
background-color: white;
14+
`;
15+
16+
const ImageWrapper = styled.div`
17+
width: 80px;
18+
height: 80px;
19+
border-radius: 20px;
20+
background-color: #f0f0f0;
21+
display: flex;
22+
justify-content: center;
23+
align-items: center;
24+
margin-bottom: 1.2rem;
25+
`;
26+
27+
const Img = styled.img`
28+
width: 50px;
29+
height: 50px;
30+
`;
31+
32+
const Input = styled.input`
33+
width: 100%;
34+
height: 44px;
35+
border-radius: 12px;
36+
border: none;
37+
background-color: #f5f5f5;
38+
padding: 0 1rem;
39+
font-size: 14px;
40+
color: black;
41+
box-sizing: border-box;
42+
43+
&::placeholder {
44+
color: #ccc;
45+
}
46+
`;
47+
48+
interface FoodItemProps {
49+
imgSrc: string;
50+
value?: string;
51+
onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
52+
}
53+
54+
export default function FoodName({ imgSrc, value, onChange }: FoodItemProps) {
55+
return (
56+
<Page>
57+
<Container>
58+
<ImageWrapper>
59+
<Img src={imgSrc} />
60+
</ImageWrapper>
61+
{/* <Label>{label}</Label> */}
62+
<Input
63+
placeholder="식품의 자세한 이름을 적어주세요 (ex. 대파)"
64+
value={value}
65+
onChange={onChange}
66+
/>
67+
</Container>
68+
</Page>
69+
);
70+
}

src/components/RegisterFood/RegisterFood.tsx

Whitespace-only changes.

0 commit comments

Comments
 (0)