Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

충남대 FE_임세빈 3주차 STEP2 #79

Open
wants to merge 15 commits into
base: yimsebin
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# 카카오 테크 캠퍼스 - 프론트엔드 카카오 선물하기 편 Week3

[🔗 link](https://edu.nextstep.camp/s/hazAC9xa)

## ✏ 기능 목록

### STEP1

- [x] 메인페이지 API 연결
- [x] Theme 카테고리 섹션 API 연결 : /api/v1/themes API 사용.
- [x] 실시간 급상승 선물랭킹 섹션 API 연결 : /api/v1/ranking/products API 사용.
- [x] 필터 조건을 선택하면 해당 조건에 맞게 API를 요청해서 보여지게 함.
- [x] Theme 페이지 API 연결
- [x] Header API 연결 : url의 pathParams와 /api/v1/themes API 사용.
- [x] themeKey가 잘못된 경우 메인페이지로 연결.
- [x] 상품목록 섹션 API 연결 : /api/v1/themes/{themeKey}/products API 연결
- [x] API 요청 시 한 번에 20개 상품 보여지도록 함.

### STEP2

- [x] 메인페이지 ThemeCategorySection 에러처리
- [x] 메인페이지 실시간 급상승 Section 에러처리
- [ ] Theme페이지 헤더부분 에러처리
- [ ] Tehme페이지 상품부분 에러처리
4 changes: 4 additions & 0 deletions oas.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,10 @@ components:
type: string
description: 선물 테마 카테고리 배경색
example: '#F5F5F5'
imageUrl:
type: string
description: 선물 테마 이미지 URL
example: 'https://img1.daumcdn.net/thumb/S104x104/?fname=https%3A%2F%2Ft1.daumcdn.net%2Fgift%2Fhome%2Ftheme%2F292020231106_MXMUB.png'
required:
- id
- key
Expand Down
29 changes: 16 additions & 13 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"dependencies": {
"@emotion/react": "^11.11.3",
"@emotion/styled": "^11.11.0",
"axios": "^1.7.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.22.1"
Expand Down
49 changes: 44 additions & 5 deletions src/components/features/Home/GoodsRankingSection/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import styled from '@emotion/styled';
import { useState } from 'react';
import axios from 'axios';
import { useEffect, useState } from 'react';

import { Container } from '@/components/common/layouts/Container';
import { breakpoints } from '@/styles/variants';
import type { RankingFilterOption } from '@/types';
import { GoodsMockList } from '@/types/mock';
import { type GoodsData, type RankingFilterOption } from '@/types';

import { GoodsRankingFilter } from './Filter';
import { GoodsRankingList } from './List';
Expand All @@ -14,15 +14,54 @@ export const GoodsRankingSection = () => {
targetType: 'ALL',
rankType: 'MANY_WISH',
});
const [goods, setGoods] = useState<GoodsData[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>();

// GoodsMockData를 21번 반복 생성
const url = 'https://react-gift-mock-api-two.vercel.app/api/v1/ranking/products';
useEffect(() => {
axios({
method: 'get',
url: url,
params: filterOption,
})
.then((res) => {
setGoods(res.data.products);
})
.catch((err) => {
console.error('Error fetching themes:', err);
setError(err); // 에러 메시지 설정
})
.finally(() => {
setLoading(false); // 로딩 상태 해제
});
}, [filterOption]);

if (loading)
return (
<Container>
<div>데이터를 로딩중입니다.</div>
</Container>
);
if (error)
return (
<Container>
<div>Error: {error}</div>
</Container>
);
if (goods.length === 0)
return (
<Container>
<div>데이터가 존재하지 않습니다.</div>
</Container>
);

return (
<Wrapper>
<Container>
<Title>실시간 급상승 선물랭킹</Title>
<GoodsRankingFilter filterOption={filterOption} onFilterOptionChange={setFilterOption} />
<GoodsRankingList goodsList={GoodsMockList} />
<GoodsRankingList goodsList={goods} />
</Container>
</Wrapper>
);
Expand Down
121 changes: 49 additions & 72 deletions src/components/features/Home/ThemeCategorySection/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,57 @@
import styled from '@emotion/styled';
import axios from 'axios';
import { useEffect, useState } from 'react';
import { Link } from 'react-router-dom';

import { Container } from '@/components/common/layouts/Container';
import { Grid } from '@/components/common/layouts/Grid';
import { getDynamicPath } from '@/routes/path';
import { breakpoints } from '@/styles/variants';
import { type ThemeData } from '@/types';

import { ThemeCategoryItem } from './ThemeCategoryItem';

export const ThemeCategorySection = () => {
const [themes, setThemes] = useState<ThemeData[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>();

const url = 'https://react-gift-mock-api-two.vercel.app/api/v1/themes';
useEffect(() => {
axios
.get(url)
.then((res) => {
setThemes(res.data.themes);
setError(null);
})
.catch((err) => {
console.error('Error fetching themes:', err);
setError(err); // 에러 메시지 설정
})
.finally(() => {
setLoading(false); // 로딩 상태 해제
});
}, []);

if (loading)
return (
<Container>
<div>데이터를 로딩중입니다.</div>
</Container>
);
if (error)
return (
<Container>
<div>Error: {error}</div>
</Container>
);
if (themes.length === 0)
return (
<Container>
<div>데이터가 존재하지 않습니다.</div>
</Container>
);

return (
<Wrapper>
<Container>
Expand All @@ -18,78 +61,12 @@ export const ThemeCategorySection = () => {
md: 6,
}}
>
<Link to={getDynamicPath.theme('life_small_gift')}>
<ThemeCategoryItem
image="https://img1.daumcdn.net/thumb/S104x104/?fname=https%3A%2F%2Ft1.daumcdn.net%2Fgift%2Fhome%2Ftheme%2F292020231106_MXMUB.png"
label="생일"
/>
</Link>
<Link to={getDynamicPath.theme('life_small_gift')}>
<ThemeCategoryItem
image="https://img1.daumcdn.net/thumb/S104x104/?fname=https%3A%2F%2Ft1.daumcdn.net%2Fgift%2Fhome%2Ftheme%2F292020231106_MXMUB.png"
label="졸업선물"
/>
</Link>
<Link to={getDynamicPath.theme('life_small_gift')}>
<ThemeCategoryItem
image="https://img1.daumcdn.net/thumb/S104x104/?fname=https%3A%2F%2Ft1.daumcdn.net%2Fgift%2Fhome%2Ftheme%2F292020231106_MXMUB.png"
label="스몰럭셔리"
/>
</Link>
<Link to={getDynamicPath.theme('life_small_gift')}>
<ThemeCategoryItem
image="https://img1.daumcdn.net/thumb/S104x104/?fname=https%3A%2F%2Ft1.daumcdn.net%2Fgift%2Fhome%2Ftheme%2F292020231106_MXMUB.png"
label="명품선물"
/>
</Link>
<Link to={getDynamicPath.theme('life_small_gift')}>
<ThemeCategoryItem
image="https://img1.daumcdn.net/thumb/S104x104/?fname=https%3A%2F%2Ft1.daumcdn.net%2Fgift%2Fhome%2Ftheme%2F292020231106_MXMUB.png"
label="결혼/집들이"
/>
</Link>
<Link to={getDynamicPath.theme('life_small_gift')}>
<ThemeCategoryItem
image="https://img1.daumcdn.net/thumb/S104x104/?fname=https%3A%2F%2Ft1.daumcdn.net%2Fgift%2Fhome%2Ftheme%2F292020231106_MXMUB.png"
label="따뜻한선물"
/>
</Link>
<Link to={getDynamicPath.theme('life_small_gift')}>
<ThemeCategoryItem
image="https://img1.daumcdn.net/thumb/S104x104/?fname=https%3A%2F%2Ft1.daumcdn.net%2Fgift%2Fhome%2Ftheme%2F292020231106_MXMUB.png"
label="가벼운선물"
/>
</Link>
<Link to={getDynamicPath.theme('life_small_gift')}>
<ThemeCategoryItem
image="https://img1.daumcdn.net/thumb/S104x104/?fname=https%3A%2F%2Ft1.daumcdn.net%2Fgift%2Fhome%2Ftheme%2F292020231106_MXMUB.png"
label="팬심저격"
/>
</Link>
<Link to={getDynamicPath.theme('life_small_gift')}>
<ThemeCategoryItem
image="https://img1.daumcdn.net/thumb/S104x104/?fname=https%3A%2F%2Ft1.daumcdn.net%2Fgift%2Fhome%2Ftheme%2F292020231106_MXMUB.png"
label="교환권"
/>
</Link>
<Link to={getDynamicPath.theme('life_small_gift')}>
<ThemeCategoryItem
image="https://img1.daumcdn.net/thumb/S104x104/?fname=https%3A%2F%2Ft1.daumcdn.net%2Fgift%2Fhome%2Ftheme%2F292020231106_MXMUB.png"
label="건강/비타민"
/>
</Link>
<Link to={getDynamicPath.theme('life_small_gift')}>
<ThemeCategoryItem
image="https://img1.daumcdn.net/thumb/S104x104/?fname=https%3A%2F%2Ft1.daumcdn.net%2Fgift%2Fhome%2Ftheme%2F292020231106_MXMUB.png"
label="과일/한우"
/>
</Link>
<Link to={getDynamicPath.theme('life_small_gift')}>
<ThemeCategoryItem
image="https://img1.daumcdn.net/thumb/S104x104/?fname=https%3A%2F%2Ft1.daumcdn.net%2Fgift%2Fhome%2Ftheme%2F292020231106_MXMUB.png"
label="출산/키즈"
/>
</Link>
{themes &&
themes.map((theme) => (
<Link to={getDynamicPath.theme(theme.key)}>
<ThemeCategoryItem image={theme.imageURL} label={theme.label} />
</Link>
))}
</Grid>
</Container>
</Wrapper>
Expand Down
Loading