Skip to content

Commit fa58c13

Browse files
authored
[Feat] 상품 상세 페이지 API 연동 (#48)
* chore: 안 쓰는 api 삭제 * feat: 엔드포인트 수정 * feat: 예금 상세 페이지 api 연동 * feat: 적금 상세 페이지 api 연동
1 parent b5fdeab commit fa58c13

File tree

6 files changed

+95
-137
lines changed

6 files changed

+95
-137
lines changed

src/pages/deposit-detail/deposit-detail-page.css.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ export const detailContainer = style({
1313
marginTop: '9rem',
1414
});
1515

16+
export const notFound = style({
17+
fontSize: vars.size.lg,
18+
fontWeight: vars.weight.bold,
19+
color: vars.color.gray800,
20+
});
21+
1622
export const bank = style({
1723
fontSize: vars.size.md,
1824
fontWeight: vars.weight.bold,

src/pages/deposit-detail/deposit-detail-page.tsx

Lines changed: 37 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,19 @@ import { formatLimit } from '../../shared/utils/format';
55
import * as styles from './deposit-detail-page.css';
66
import Header from '../../shared/components/header/header';
77

8-
type Option = {
9-
interestType: string;
10-
saveTerm: number;
11-
baseRate: number;
12-
maxRate: number;
8+
type SimilarProducts = {
9+
productId: number;
10+
optionId: number;
11+
bankName: string;
12+
productName: string;
13+
maxLimitDiff: number;
14+
termDiff: number;
15+
baseRateDiff: number;
16+
maxRateDiff: number;
1317
};
1418

1519
type ProductDetail = {
1620
productId: number;
17-
optionId: number;
1821
bankName: string;
1922
productName: string;
2023
joinDeny: string;
@@ -24,39 +27,18 @@ type ProductDetail = {
2427
etcNote: string;
2528
maxLimit: string;
2629
maturityInterestInfo: string;
27-
options: Option[];
30+
optionId: number;
31+
interestType: string;
32+
saveTerm: number;
33+
baseRate: number;
34+
maxRate: number;
35+
similarProducts: SimilarProducts[];
2836
};
2937

3038
const DepositDetailPage = () => {
3139
const { productId, optionId } = useParams();
3240

33-
// TODO:API 연결 후 mockdata 삭제
34-
const mockDetail: ProductDetail = {
35-
productId: 34,
36-
optionId: 293,
37-
bankName: '주식회사 케이뱅크',
38-
productName: '코드K 정기예금',
39-
joinDeny: '제한없음',
40-
joinMember: '만 17세 이상 실명의 개인 및 개인사업자',
41-
joinWay: '스마트폰',
42-
specialCondition: '우대조건 없음',
43-
etcNote: '가입금액 : 1백만원 이상\n가입기간 : 1개월~36개월',
44-
maxLimit: '제한 없음',
45-
maturityInterestInfo:
46-
'만기 후 \n- 1개월 이내 : 만기시점 기본금리 X 50%\n- 1개월 초과~6개월 이내 : 만기시점 기본금리 X 30%\n- 6개월 초과 : 연 0.20%',
47-
options: [
48-
{
49-
interestType: '단리',
50-
saveTerm: 6,
51-
baseRate: 2.86,
52-
maxRate: 2.86,
53-
},
54-
],
55-
};
56-
57-
// TODO: API 연결 후 주석 삭제
58-
//const [detail, setDetail] = useState<ProductDetail | null>(null);
59-
const [detail, setDetail] = useState<ProductDetail | null>(mockDetail);
41+
const [detail, setDetail] = useState<ProductDetail | null>(null);
6042

6143
useEffect(() => {
6244
if (!productId || !optionId) return;
@@ -66,9 +48,9 @@ const DepositDetailPage = () => {
6648
});
6749
}, [productId, optionId]);
6850

69-
if (!detail) return <div>Loading...</div>;
70-
71-
const option = detail.options[0];
51+
if (!detail) {
52+
return <div className={styles.notFound}>찾으시는 상품이 존재하지 않습니다.</div>;
53+
}
7254

7355
return (
7456
<>
@@ -107,27 +89,25 @@ const DepositDetailPage = () => {
10789
</div>
10890
</div>
10991

110-
{option && (
111-
<div className={styles.optionContainer}>
112-
<h3 className={styles.optionText}>상품 옵션 ⭐</h3>
113-
<div className={styles.optionTextContainer}>
114-
<h4 className={styles.optionTitle}>이자 유형:</h4>
115-
<p className={styles.optionValue}>{option.interestType}</p>
116-
</div>
117-
<div className={styles.optionTextContainer}>
118-
<h4 className={styles.optionTitle}>저축 기간:</h4>
119-
<p className={styles.optionValue}>{option.saveTerm}개월</p>
120-
</div>
121-
<div className={styles.optionTextContainer}>
122-
<h4 className={styles.optionTitle}>기본 금리:</h4>
123-
<p className={styles.optionValue}>{option.baseRate}%</p>
124-
</div>
125-
<div className={styles.optionTextContainer}>
126-
<h4 className={styles.optionTitle}>최대 금리:</h4>
127-
<p className={styles.optionValue}>{option.maxRate}%</p>
128-
</div>
92+
<div className={styles.optionContainer}>
93+
<h3 className={styles.optionText}>상품 옵션 ⭐</h3>
94+
<div className={styles.optionTextContainer}>
95+
<h4 className={styles.optionTitle}>이자 유형:</h4>
96+
<p className={styles.optionValue}>{detail.interestType}</p>
97+
</div>
98+
<div className={styles.optionTextContainer}>
99+
<h4 className={styles.optionTitle}>저축 기간:</h4>
100+
<p className={styles.optionValue}>{detail.saveTerm}개월</p>
101+
</div>
102+
<div className={styles.optionTextContainer}>
103+
<h4 className={styles.optionTitle}>기본 금리:</h4>
104+
<p className={styles.optionValue}>{detail.baseRate}%</p>
129105
</div>
130-
)}
106+
<div className={styles.optionTextContainer}>
107+
<h4 className={styles.optionTitle}>최대 금리:</h4>
108+
<p className={styles.optionValue}>{detail.maxRate}%</p>
109+
</div>
110+
</div>
131111
</div>
132112

133113
{/* TODO: 유사 상품 리스트 API 연결 후 구현 */}

src/pages/savings-detail/savings-detail-page.css.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ export const detailContainer = style({
1313
marginTop: '9rem',
1414
});
1515

16+
export const notFound = style({
17+
fontSize: vars.size.lg,
18+
fontWeight: vars.weight.bold,
19+
color: vars.color.gray800,
20+
});
21+
1622
export const bank = style({
1723
fontSize: vars.size.md,
1824
fontWeight: vars.weight.bold,

src/pages/savings-detail/savings-detail-page.tsx

Lines changed: 42 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,19 @@ import { formatLimit } from '../../shared/utils/format';
55
import * as styles from './savings-detail-page.css';
66
import Header from '../../shared/components/header/header';
77

8-
type Option = {
9-
interestType: string;
10-
reserveType: string;
11-
saveTerm: number;
12-
baseRate: number;
13-
maxRate: number;
8+
type SimilarProducts = {
9+
productId: number;
10+
optionId: number;
11+
bankName: string;
12+
productName: string;
13+
maxLimitDiff: number;
14+
termDiff: number;
15+
baseRateDiff: number;
16+
maxRateDiff: number;
1417
};
1518

1619
type ProductDetail = {
1720
productId: number;
18-
optionId: number;
1921
bankName: string;
2022
productName: string;
2123
joinDeny: string;
@@ -25,41 +27,19 @@ type ProductDetail = {
2527
etcNote: string;
2628
maxLimit: string;
2729
maturityInterestInfo: string;
28-
options: Option[];
30+
optionId: number;
31+
interestType: string;
32+
reserveType: string;
33+
saveTerm: number;
34+
baseRate: number;
35+
maxRate: number;
36+
similarProducts: SimilarProducts[];
2937
};
3038

3139
const SavingsDetailPage = () => {
3240
const { productId, optionId } = useParams();
3341

34-
// TODO:API 연결 후 mockdata 삭제
35-
const mockDetail: ProductDetail = {
36-
productId: 50,
37-
optionId: 167,
38-
bankName: '수협은행',
39-
productName: 'Sh해양플라스틱Zero!적금',
40-
joinDeny: '제한없음',
41-
joinMember: '실명의 개인',
42-
joinWay: '영업점,인터넷,스마트폰',
43-
specialCondition:
44-
'* 최대우대금리:0.5%\n1. 해양플라스틱감축서약 : 0.1% (신규시) \n2. 봉사활동 또는 상품홍보 : 0.2% (만기시) \n3. 입출금통장 최초신규 : 0.2% (만기시)\n4. 자동이체 출금실적 : 0.2% (만기시)\n - 수협신용카드 / 당행 펀드 / 수협체크카드',
45-
etcNote: '- 1인 1계좌 \n- 월 가입한도 : 20만원',
46-
maxLimit: '200,000',
47-
maturityInterestInfo:
48-
'* 만기후 1년 이내\n - 만기당시 상호부금 \n계약기간별 기본금리 1/2\n* 만기후 1년 초과\n - 만기당시 보통예금 기본금리',
49-
options: [
50-
{
51-
interestType: '단리',
52-
reserveType: '자유적립식',
53-
saveTerm: 12,
54-
baseRate: 3.65,
55-
maxRate: 4.15,
56-
},
57-
],
58-
};
59-
60-
// TODO: API 연결 후 주석 삭제
61-
//const [detail, setDetail] = useState<ProductDetail | null>(null);
62-
const [detail, setDetail] = useState<ProductDetail | null>(mockDetail);
42+
const [detail, setDetail] = useState<ProductDetail | null>(null);
6343

6444
useEffect(() => {
6545
if (!productId || !optionId) return;
@@ -69,9 +49,9 @@ const SavingsDetailPage = () => {
6949
});
7050
}, [productId, optionId]);
7151

72-
if (!detail) return <div>Loading...</div>;
73-
74-
const option = detail.options[0];
52+
if (!detail) {
53+
return <div className={styles.notFound}>찾으시는 상품이 존재하지 않습니다.</div>;
54+
}
7555

7656
return (
7757
<>
@@ -110,31 +90,29 @@ const SavingsDetailPage = () => {
11090
</div>
11191
</div>
11292

113-
{option && (
114-
<div className={styles.optionContainer}>
115-
<h3 className={styles.optionText}>상품 옵션 ⭐</h3>
116-
<div className={styles.optionTextContainer}>
117-
<h4 className={styles.optionTitle}>이자 유형:</h4>
118-
<p className={styles.optionValue}>{option.interestType}</p>
119-
</div>
120-
<div className={styles.optionTextContainer}>
121-
<h4 className={styles.optionTitle}>적립 방식:</h4>
122-
<p className={styles.optionValue}>{option.reserveType}</p>
123-
</div>
124-
<div className={styles.optionTextContainer}>
125-
<h4 className={styles.optionTitle}>저축 기간:</h4>
126-
<p className={styles.optionValue}>{option.saveTerm}개월</p>
127-
</div>
128-
<div className={styles.optionTextContainer}>
129-
<h4 className={styles.optionTitle}>기본 금리:</h4>
130-
<p className={styles.optionValue}>{option.baseRate}%</p>
131-
</div>
132-
<div className={styles.optionTextContainer}>
133-
<h4 className={styles.optionTitle}>최대 금리:</h4>
134-
<p className={styles.optionValue}>{option.maxRate}%</p>
135-
</div>
93+
<div className={styles.optionContainer}>
94+
<h3 className={styles.optionText}>상품 옵션 ⭐</h3>
95+
<div className={styles.optionTextContainer}>
96+
<h4 className={styles.optionTitle}>이자 유형:</h4>
97+
<p className={styles.optionValue}>{detail.interestType}</p>
13698
</div>
137-
)}
99+
<div className={styles.optionTextContainer}>
100+
<h4 className={styles.optionTitle}>적립 방식:</h4>
101+
<p className={styles.optionValue}>{detail.reserveType}</p>
102+
</div>
103+
<div className={styles.optionTextContainer}>
104+
<h4 className={styles.optionTitle}>저축 기간:</h4>
105+
<p className={styles.optionValue}>{detail.saveTerm}개월</p>
106+
</div>
107+
<div className={styles.optionTextContainer}>
108+
<h4 className={styles.optionTitle}>기본 금리:</h4>
109+
<p className={styles.optionValue}>{detail.baseRate}%</p>
110+
</div>
111+
<div className={styles.optionTextContainer}>
112+
<h4 className={styles.optionTitle}>최대 금리:</h4>
113+
<p className={styles.optionValue}>{detail.maxRate}%</p>
114+
</div>
115+
</div>
138116
</div>
139117

140118
{/* TODO: 유사 상품 리스트 API 연결 후 구현 */}

src/shared/api/endpoints.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,14 @@ export const AUTH = {
77

88
export const PRODUCTS = {
99
SAVINGS_LIST: '/products/savings',
10-
SAVINGS_DETAIL: (productId: number, optionId: number) => `/savings/${productId}/${optionId}`,
10+
SAVINGS_DETAIL: (productId: number, optionId: number) =>
11+
`products/savings/${productId}/${optionId}`,
1112
DEPOSITS_LIST: '/products/deposits',
12-
DEPOSITS_DETAIL: (productId: number, optionId: number) => `/deposits/${productId}/${optionId}`,
13+
DEPOSITS_DETAIL: (productId: number, optionId: number) =>
14+
`products/deposits/${productId}/${optionId}`,
1315
};
1416

1517
export const POPULARITY = {
1618
SAVINGS_POPULAR: '/recommendations/savings',
17-
SAVINGS_COMPARE: (productId: number, optionId: number) =>
18-
`/recommendations/savings/compare/${productId}/${optionId}`,
1919
DEPOSITS_POPULAR: '/recommendations/deposits',
20-
DEPOSITS_COMPARE: (productId: number, optionId: number) =>
21-
`/recommendations/deposits/compare/${productId}/${optionId}`,
2220
};

src/shared/api/popularity.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,7 @@ export const getPopularSavings = async () => {
66
return res.data;
77
};
88

9-
export const compareSavings = async (productId: number, optionId: number) => {
10-
const res = await api.get(POPULARITY.SAVINGS_COMPARE(productId, optionId));
11-
return res.data;
12-
};
13-
149
export const getPopularDeposits = async () => {
1510
const res = await api.get(POPULARITY.DEPOSITS_POPULAR);
1611
return res.data;
1712
};
18-
19-
export const compareDeposits = async (productId: number, optionId: number) => {
20-
const res = await api.get(POPULARITY.DEPOSITS_COMPARE(productId, optionId));
21-
return res.data;
22-
};

0 commit comments

Comments
 (0)