Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
2d6aba8
docs(readme): 요구사항을 정의했습니다.
DreamPaste May 19, 2025
c74d60a
docs(readme): 추가적인 구현사항 추가
DreamPaste May 21, 2025
4b25a67
chore: lint, 디렉터리 구조 등 초기 설정
DreamPaste May 21, 2025
708b777
chore(assets): 미션 4 assets 폴더를 불러왔습니다.
DreamPaste May 22, 2025
2ed076e
fix(vite.config): scss 재귀 주입되던 문제를 수정함
DreamPaste May 22, 2025
df35011
feat(mixins.scss): 미디어쿼리용 믹스인 정의
DreamPaste May 22, 2025
e564aec
feat(/routes): 라우터 경로 및 라우터 컴포넌트 제작, scss 모듈화 설정 추가
DreamPaste May 22, 2025
28af859
feat(constans/LogoImage): 로고 모듈화
DreamPaste May 22, 2025
0b599d7
feat(Header.tsx): 글로벌 네이게이션 헤더를 만들었습니다.
DreamPaste May 24, 2025
92062c6
feat(AuthContext): 로그인 인증 상태와 유저 정보를 context로 관리하는 Provider을 제작했습니다.
DreamPaste May 24, 2025
78975ea
refactor(AutContext): AuthProvider에서 최소한의 상태만 관리하도록 최적화했습니다.
DreamPaste May 24, 2025
406f102
feat(useAuthService): 로그인 로그아웃을 관리하고 context에 user을 입력하도록 변경하였습니다
DreamPaste May 25, 2025
0ae5df5
feat(MarketPage): 마켓 페이지 레이아웃 제작
DreamPaste May 26, 2025
70e7d21
design(variables.scss): 사이즈 변수들을 세밀하게 조정했습니다
DreamPaste May 26, 2025
bea0deb
feat(useMediaQuery, getMediaCount): 미디어 쿼리 변화에 따라 breakpoint를 반환하고,각 …
DreamPaste May 26, 2025
8050c9a
fix(getMediaCount): 함수 이름 오타 수정
DreamPaste May 26, 2025
5cc2e08
feat(products): 상품 목록 조회 api 제작
DreamPaste May 26, 2025
7d84d6f
feat(useApi): api를 받아올때 로딩여부와 오류를 관리하는 커스텀 훅 제작
DreamPaste May 26, 2025
12b27b0
fix: 에러 상황에 맞게 에러를 throw하도록 변경
DreamPaste May 26, 2025
10f51f3
fix(useApi): useCallback을 통해 불필요한 재호출 방지
DreamPaste May 26, 2025
6533b4f
feat(PrductCard): 상품을 보여주는 카드 제작
DreamPaste May 26, 2025
5aad591
feat(BestProduct): 베스트 상품을 반응형으로 불러오도록 제작함
DreamPaste May 26, 2025
3991663
feat(AllProduct): 전체 상품 목록을 보여주는 컴포넌트 제작
DreamPaste May 26, 2025
b7f02a1
feat(useDebounce): 디비운스 커스텀 훅을 통해 검색어의 사용자 경험을 최적화했습니다.
DreamPaste May 26, 2025
401bb21
docs(readme): 구현 사항 정리
DreamPaste May 26, 2025
1145f91
chore: 사소한 오류 수정
DreamPaste May 26, 2025
9f437a9
fix(package.json): dependencies에 husky 설치
DreamPaste May 27, 2025
c4f0afe
fix(vite.config.ts): 빌드 결과물의 기본 경로를 설정하였습니다.
DreamPaste May 27, 2025
b6fa445
fix(vite.config.ts): 빌드시 상대 경로로 불러오던 문제 수정
DreamPaste May 27, 2025
d089b5e
fix: add Netlify SPA redirects
DreamPaste May 27, 2025
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
39 changes: 39 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
module.exports = {
root: true,
env: {
browser: true,
es2021: true,
node: true,
},
parser: "@typescript-eslint/parser",
parserOptions: {
ecmaVersion: 12,
sourceType: "module",
ecmaFeatures: { jsx: true },
},
plugins: [
"react",
"react-hooks",
"@typescript-eslint",
"jsx-a11y",
"prettier",
],
extends: [
"eslint:recommended",
"plugin:react/recommended",
"plugin:react-hooks/recommended",
"plugin:jsx-a11y/recommended",
"plugin:@typescript-eslint/recommended",
"prettier",
],
settings: {
react: { version: "detect" },
},
rules: {
// Prettier 문제를 ESLint 에러로 표시
"prettier/prettier": "error",
// 필요에 따라 아래에 커스텀 룰 추가
// 'react/prop-types': 'off',
// '@typescript-eslint/explicit-module-boundary-types': 'off',
},
};
12 changes: 12 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"printWidth": 80,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": true,
"trailingComma": "es5",
"bracketSpacing": true,
"arrowParens": "always",
"htmlWhitespaceSensitivity": "css",
"endOfLine": "lf"
}
20 changes: 20 additions & 0 deletions .stylelintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module.exports = {
extends: ['stylelint-config-standard-scss', 'stylelint-prettier/recommended'],
plugins: ['stylelint-scss'],
rules: {
// Prettier 포맷팅 충돌 방지
'prettier/prettier': true,

// 미디어쿼리 표기법 (e.g. @media (max-width: 600px))
'media-feature-range-notation': 'prefix',

// BEM + kebab-case 강제
'selector-class-pattern': [
'^[a-z][a-z0-9-]*(?:__[a-z0-9-]+)*(?:--[a-z0-9-]+)*$',
{
message:
'클래스 패턴에는 BEM(block__element--modifier) 또는 kebab-case(user-profile)만을 사용해야 합니다.',
},
],
},
};
156 changes: 118 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,70 +1,150 @@
# Getting Started with Create React App
## Sprint Misson 5

This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
### 요구사항

## Available Scripts
- [x] 중고마켓 페이지 주소는 “/items” 입니다.
- [x] 페이지 주소가 “/items” 일때 상단네비게이션바의 “중고마켓" 버튼의 색상은 “3692FF”입니다.
- [x] 상단 네비게이션 바는 이전 미션에서 구현한 랜딩 페이지와 동일한 스타일로 만들어 주세요.
- [x] 전체 상품에서 드롭 다운으로 “최신 순” 또는 “좋아요 순”을 선택해서 정렬을 할 수 있습니다.
- [x] 베스트 상품의 정렬 기준은 `favorit`, **favorit이 가장 높은 상품 4가지**를 표시합니다.
- [x] ‘상품 등록하기’ 버튼을 누르면 “/additem” 로 이동합니다. ( 빈 페이지 )
- [x] 카드 데이터는 제공된 백엔드 API 페이지의 GET 메소드인 “/products”를 사용해주세요.
- [x] 미디어 쿼리를 사용하여 반응형 view 마다 물품 개수를 다르게 보여줍니다 (서버로 요청하는 값은 동일)
- [x] 페이지 네이션 기능을 구현합니다.
- [x] 반응형으로 보여지는 물품들의 개수를 다르게 설정할때 서버에 보내는 pageSize값을 적절하게 설정합니다.

In the project directory, you can run:
> > #### 베스트 상품
>
> - Desktop : 4개 보이기
> - Tablet : 2개 보이기
> - Mobile : 1개 보이기
>
> > #### 전체 상품
>
> - Desktop : 10개 보이기
> - Tablet : 6개 보이기
> - Mobile : 4개 보이기

### `npm start`
### 추가 구현사항

Runs the app in the development mode.\
Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
- [x] ESLint, Stylelint, Prettier, Husky 사용
- [x] Vite 번들러 기반으로 변경
- [x] ts 기반으로 제작
- [ ] 테스트 코드 제작
- [x] 재사용 가능한 부분들을 커스텀 훅 사용
- [x] 스켈레톤 디자인 로딩 화면 제작

The page will reload when you make changes.\
You may also see any lint errors in the console.
## 구현

### `npm test`
### 1. 프로젝트 환경 세팅

Launches the test runner in the interactive watch mode.\
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
- Vite + TypeScript로 초기화

### `npm run build`
- ESLint, Stylelint, Prettier, Husky 연동

Builds the app for production to the `build` folder.\
It correctly bundles React in production mode and optimizes the build for the best performance.
### 2. 라우팅 구조 잡기

The build is minified and the filenames include the hashes.\
Your app is ready to be deployed!
- / (랜딩 페이지)

See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
- /board (자유게시판)

### `npm run eject`
- /items (중고마켓)

**Note: this is a one-way operation. Once you `eject`, you can't go back!**
- /additem (상품등록 빈 페이지)

If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
### 3. 글로벌 인증 컨텍스트

Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
- AuthProvider 생성: user, isLoggedIn 상태 관리

You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
- useAuth 훅으로 상태 접근 및 setUser 제공

## Learn More
- useAuthService 훅으로 로그인·로그아웃 비즈니스 로직 분리

You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
### 4. 헤더 컴포넌트 구현

To learn React, check out the [React documentation](https://reactjs.org/).
- 로고 / 내비게이션 버튼

### Code Splitting
- 로그인 상태에 따라 UserProfile ↔️ 로그인 | 회원가입 버튼 표시

This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
- useAuthService.login으로 모의 로그인 처리

### Analyzing the Bundle Size
- useAuthService.logout 수행

This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
- [todo]: 기존 회원가입 로그인 페이지 마이그레이션 및 인증 수행

### Making a Progressive Web App
### 5. 미디어 쿼리용 훅 제작

This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
- useMediaQuery 로 현재 브레이크포인트(mobile/tablet/desktop) 반환

### Advanced Configuration
- getMediaCount 로 각 뷰포트별 bestProductsCount·allProductsCount 제공

This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
### 6. API 연동

### Deployment
- fetchProducts(page, pageSize, sort, keyword) 함수 작성

This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
- axios 기반 에러 핸들링 로직 구현

### `npm run build` fails to minify
### 7. API 호출 / 로딩 / 에러 훅

This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
- useApi(apiFn, deps) 훅: loading·data·error 상태 자동 관리

- useCallback 으로 apiFn 메모이제이션

### 8. 베스트 상품 컴포넌트

- bestProductsCount 따라 1/2/4개 요청

- useApi(() => fetchProducts(1, count, 'favorite', ''), [count])

- ProductCard + 로딩 스켈레톤 SkeletonCard 렌더링

### 9. 전체 상품 컴포넌트

- page, sort, keyword 상태 선언

- 헤더(AllProductsHeader) 분리: 검색·정렬·등록

- useDebounce 커스텀 훅으로 검색어 300ms 디바운스

- useApi(() => fetchProducts(page, pageSize, sort, debouncedKeyword), [...])

- ProductCard + 로딩 스켈레톤 그리드 표시

### 10. 페이지네이션 컴포넌트

- totalPages = ceil(totalCount / pageSize) 계산

- 최대 5개 버튼: 현재 페이지 중심으로 앞뒤 2개씩

- “‹”, “›” 이전·다음 버튼

- 클릭 시 setPage 호출 → useApi 자동 재호출

### 11. 반응형 스타일링

- Mobile / Tablet / Desktop 에 따라

- 베스트 상품: 1/2/4 컬럼

- 전체 상품: 4/6/10 개 요청, 그리드 컬럼 수 조절

- 검색·정렬 UI 배치 변경

- select 아이콘을 모바일에서는 원형 버튼, 태블릿 이상에서 텍스트+화살표로

### todo

- 상태 관리 최적화 필요
- 가독성 향상 및 관심사 분리 재확인
- 페이지네이션에서 현재 페이지를 볼 수 있도록 유저 경험 향상
- 컴포넌트 메모이제이션
- 기존 페이지들 마이그레이션
- 테스트 코드 작성(API 유틸, 훅, 주요 컴포넌트 단위 테스트)
- notFound페이지 제작
- 오류 상황시 UI로 보여줄 수 있도록 함

### issue

- 아직 `srcset` 적용이 잘 안된다.
- `AllProductHeader`에서 반응형 css가 미흡한거같다.
- 타입 선언에서 혼동이 온다.
3 changes: 3 additions & 0 deletions dist/_redirects
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# public/_redirects

/* /index.html 200
Binary file added dist/assets/Pretendard-Light-knQmDAda.woff2
Binary file not shown.
Binary file added dist/assets/Pretendard-Medium-Dw2vNklR.woff2
Binary file not shown.
Binary file added dist/assets/Pretendard-Regular-BhrLQoBv.woff2
Binary file not shown.
Binary file added dist/assets/Pretendard-SemiBold-ClEDdoZU.woff2
Binary file not shown.
Binary file added dist/assets/Pretendard-Thin-DWJVAZ2K.woff2
Binary file not shown.
Binary file added dist/assets/heart-fill-BP4_qiU3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added dist/assets/heart-orwlBO01.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading