Skip to content

Commit 36c41aa

Browse files
authored
Merge pull request #63 from SOPT-all/feat/benefit-component/#55
[feat/#60] 제품 메인정보 페이지 구현
2 parents b2de49d + e064a0f commit 36c41aa

File tree

22 files changed

+317
-12
lines changed

22 files changed

+317
-12
lines changed

src/App.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
1+
import { ProductInfo } from "./pages/product-info/product-info";
2+
import * as styles from "./test.css";
3+
14
function App() {
2-
return <div />;
5+
return (
6+
<div className={styles.test}>
7+
<ProductInfo />
8+
</div>
9+
);
310
}
411

512
export default App;

src/pages/home/components/.gitkeep

Whitespace-only changes.

src/pages/home/constants/.gitkeep

Whitespace-only changes.

src/pages/home/components/carousel/carousel.css.ts renamed to src/pages/product-info/components/carousel/carousel.css.ts

File renamed without changes.
File renamed without changes.
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import { color } from "@/shared/styles/tokens/color.css";
2+
import { style } from "@vanilla-extract/css";
3+
4+
export const container = style({
5+
display: "flex",
6+
flexDirection: "column",
7+
gap: "1.6rem",
8+
width: "100%",
9+
padding: "2.4rem 1rem",
10+
boxShadow: `0 8px 8px 0 rgba(18, 18, 18, 0.02)`,
11+
});
12+
13+
export const mainInfo = style({
14+
display: "flex",
15+
flexDirection: "column",
16+
gap: "0.7rem",
17+
});
18+
19+
export const priceInfo = style({
20+
display: "flex",
21+
flexDirection: "column",
22+
gap: "0.2rem",
23+
});
24+
25+
export const originalPrice = style({
26+
textDecoration: "line-through",
27+
});
28+
29+
export const discountRate = style({
30+
marginRight: "0.4rem",
31+
});
32+
33+
export const discountedPrice = style({
34+
marginRight: "0.2rem",
35+
});
36+
37+
export const benefitInfo = style({
38+
display: "flex",
39+
gap: "0.6rem",
40+
overflowX: "auto",
41+
marginTop: "-0.4rem",
42+
selectors: {
43+
"&::-webkit-scrollbar": {
44+
display: "none",
45+
},
46+
},
47+
});
48+
49+
export const extraInfo = style({
50+
display: "flex",
51+
justifyContent: "space-between",
52+
marginTop: "0.6rem",
53+
});
54+
55+
export const extraInfoItem = style({
56+
display: "flex",
57+
alignItems: "center",
58+
selectors: {
59+
"&:not(:first-child)": {
60+
gap: "0.6rem",
61+
},
62+
"&:not(:last-child)::after": {
63+
content: '""',
64+
display: "block",
65+
width: "0.1rem",
66+
height: "1.2rem",
67+
backgroundColor: color.gray[200],
68+
marginLeft: "0.8rem",
69+
marginRight: "0.8rem",
70+
},
71+
},
72+
});
73+
74+
export const flexRow = style({
75+
display: "flex",
76+
alignItems: "center",
77+
});
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import { MembershipBenefit } from "@/shared/components/benefit/membership-benefit";
2+
import * as styles from "./product-main-info.css";
3+
import { addComma } from "@/shared/utils/add-comma";
4+
import { MEMBERSHIP_DATA, PAY_BENEFITS_DATA } from "@/shared/constants/benefit";
5+
import { PayBenefit } from "@/shared/components/benefit/pay-benefit";
6+
import { MoreBenefit } from "@/shared/components/benefit/more-benefit";
7+
import { ChevronRightRounded, Share } from "@/assets/svg";
8+
import { Text } from "../text/text";
9+
import { getProductStatsList } from "../../utils/get-product-stats";
10+
export interface ProductMainInfoProps {
11+
authorName: string;
12+
productName: string;
13+
originalPrice: number;
14+
discountRate: number;
15+
discountedPrice: number;
16+
averageScore: number;
17+
reviewCount: number;
18+
salesCount: number;
19+
}
20+
21+
export const ProductMainInfo = ({ data }: { data: ProductMainInfoProps }) => {
22+
const statsList = getProductStatsList(data); // 제품 부가정보 데이터 포맷팅 함수
23+
24+
return (
25+
<div className={styles.container}>
26+
{/** 제품 메인 정보 */}
27+
<div className={styles.mainInfo}>
28+
<div className={styles.flexRow}>
29+
<Text type="caption" color="gray-100">
30+
{data.authorName}
31+
</Text>
32+
<ChevronRightRounded />
33+
</div>
34+
<Text type="subTitle" color="black-100">
35+
{data.productName}
36+
</Text>
37+
</div>
38+
39+
{/** 제품 가격 정보 */}
40+
<div className={styles.priceInfo}>
41+
<Text className={styles.originalPrice} type="caption" color="gray-100">
42+
{addComma(String(data.originalPrice))}
43+
</Text>
44+
<div className={styles.flexRow}>
45+
<Text
46+
className={styles.discountRate}
47+
type="subTitle"
48+
color="gray-300">
49+
{data.discountRate}%
50+
</Text>
51+
<div className={styles.flexRow}>
52+
<Text
53+
className={styles.discountedPrice}
54+
type="heading"
55+
color="black-100">
56+
{addComma(String(data.discountedPrice))}
57+
</Text>
58+
<Text type="body" color="black-100">
59+
60+
</Text>
61+
</div>
62+
</div>
63+
</div>
64+
65+
{/** 제품 혜택가 정보 */}
66+
<div className={styles.benefitInfo}>
67+
<MembershipBenefit
68+
description={MEMBERSHIP_DATA.description}
69+
price={MEMBERSHIP_DATA.price}
70+
unit={MEMBERSHIP_DATA.unit}
71+
badges={MEMBERSHIP_DATA.badges}
72+
/>
73+
{PAY_BENEFITS_DATA.map((benefit) => (
74+
<PayBenefit
75+
key={benefit.id}
76+
title={benefit.title}
77+
description={benefit.desc}
78+
/>
79+
))}
80+
<MoreBenefit />
81+
</div>
82+
83+
{/** 제품 부가 정보 */}
84+
<div className={styles.extraInfo}>
85+
<div className={styles.flexRow}>
86+
{statsList.map((stat, index) => (
87+
<div key={index} className={styles.extraInfoItem}>
88+
{typeof stat.label === "string" ? (
89+
<Text type="caption" color="gray-300">
90+
{stat.label}
91+
</Text>
92+
) : (
93+
stat.label
94+
)}
95+
<Text type="caption" color={stat.color}>
96+
{stat.value}
97+
</Text>
98+
</div>
99+
))}
100+
</div>
101+
<button type="button" aria-label="공유하기">
102+
<Share />
103+
</button>
104+
</div>
105+
</div>
106+
);
107+
};

src/pages/home/components/product-summary/product-summary-item/product-summary-item.css.ts renamed to src/pages/product-info/components/product-summary/product-summary-item/product-summary-item.css.ts

File renamed without changes.

src/pages/home/components/product-summary/product-summary-item/product-summary-item.tsx renamed to src/pages/product-info/components/product-summary/product-summary-item/product-summary-item.tsx

File renamed without changes.

src/pages/home/components/product-summary/product-summary.css.ts renamed to src/pages/product-info/components/product-summary/product-summary.css.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ export const container = style({
55
flexDirection: "column",
66
gap: "1rem",
77

8-
padding: "0 1rem",
8+
padding: "2.4rem 1rem",
99
});

0 commit comments

Comments
 (0)