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

[장바구니 미션 Step 1] 코난(윤정민) 미션 제출합니다. #170

Merged
merged 38 commits into from
May 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
b1f1ed7
chore: 개발 환경 설정
cruelladevil May 9, 2023
d1eaa67
docs: 기능 요구사항 작성
cruelladevil May 9, 2023
49b6809
chore: styled-component, ts-jest 환경 설치
cruelladevil May 10, 2023
3022c91
chore: 목데이터 추가
cruelladevil May 10, 2023
d5f1a41
feat: Global Style 추가
cruelladevil May 10, 2023
b0a9129
chore: 타입스크립트 module 선언
cruelladevil May 10, 2023
052148a
feat: Router, RecoilRoot 적용
cruelladevil May 10, 2023
3318bb9
feat: GlobalStyle 적용
cruelladevil May 10, 2023
bf1fab3
chore: 카트 이미지 추가
cruelladevil May 10, 2023
515adc7
feat: cart, product 타입 선언
cruelladevil May 10, 2023
ccb3efd
feat: cartState, totalAmountState 선언
cruelladevil May 10, 2023
20d7f4f
feat: Header 컴포넌트 구현
cruelladevil May 10, 2023
82e6904
feat: array 유틸함수, useCart 커스텀 훅 구현
cruelladevil May 10, 2023
7f0247e
test: useCart 훅 테스트
cruelladevil May 10, 2023
67ef7e8
feat: ProductItem 컴포넌트 구현
cruelladevil May 10, 2023
289ea98
feat: ProductList 컴포넌트 구현
cruelladevil May 10, 2023
183342d
feat: ProductPage 구현
cruelladevil May 10, 2023
e2d60ed
refactor: console.log 삭제
cruelladevil May 10, 2023
f7691f5
feat: NotFoundPage 구현
cruelladevil May 11, 2023
cec0b07
feat: product fetch 구현
cruelladevil May 11, 2023
0c2231c
feat: LoadingPage 구현
cruelladevil May 11, 2023
56bef5f
feat: ErrorBoundary 구현
cruelladevil May 11, 2023
c1820cb
feat: Suspense, Errorboundary 적용
cruelladevil May 11, 2023
8bef552
test: cypress e2e 테스트 작성
cruelladevil May 11, 2023
e4d6c5a
feat: LocalStorage 기능 추가
cruelladevil May 11, 2023
f41ec9e
chore: 배포 환경 설정
cruelladevil May 11, 2023
98adcd7
refactor: 불필요한 기본값 및 localStorage 유틸 삭제
cruelladevil May 15, 2023
329bb3c
feat: Header에 카트 이미지 및 링크 추가
cruelladevil May 16, 2023
6820579
feat: 장바구니에 들어간 상품 종류로 수정
cruelladevil May 16, 2023
72a008a
style: Pretendard 폰트 추가
cruelladevil May 16, 2023
f9ec764
refactor: products를 목데이터로 교체
cruelladevil May 16, 2023
754ca15
feat: cart에서 quantity를 가져오는 selectorFamily 구현
cruelladevil May 16, 2023
cad964f
refactor: toSpliced 활용
cruelladevil May 16, 2023
31af335
style: Header및 ProductList 스타일 수정
cruelladevil May 16, 2023
24bae4f
refactor: LocalStorageKey 상수 추출
cruelladevil May 16, 2023
91dd10f
feat: Counter 컴포넌트 구현
cruelladevil May 16, 2023
853591b
chore: mock data 수정
cruelladevil May 16, 2023
8714c4a
style: Header, ProductList, ProductItem 스타일 수정
cruelladevil May 16, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
23 changes: 23 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*
40 changes: 40 additions & 0 deletions REQUIREMENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
## 기능 목록

- Header 구현

- 장바구니에 담긴 상품 전체의 갯수 구현

- 상품 목록 구현

- 상품 목록 레이아웃 구현 (grid)
- mock 데이터를 기반으로 정렬하기

- 상품 아이템 구현

- img 파일 import 하기

- 장바구니 버튼
- 장바구니 버튼을 클릭하면 상품이 1개가 담긴다.
- 장바구니 버튼이 숫자 인풋으로 바뀐다.
- 장바구니에 담을 상품의 갯수를 조절할 수 있다.

## mock 데이터

- Products

```json
[
{
"id": 1,
"name": "치킨",
"price": 10000,
"imageUrl": "<http://example.com/chicken.jpg>"
},
{
"id": 2,
"name": "피자",
"price": 20000,
"imageUrl": "<http://example.com/pizza.jpg>"
}
]
```
16 changes: 16 additions & 0 deletions cypress.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { defineConfig } from "cypress";

export default defineConfig({
component: {
devServer: {
framework: "create-react-app",
bundler: "webpack",
},
},

e2e: {
setupNodeEvents(on, config) {
// implement node event listeners here
},
},
});
30 changes: 30 additions & 0 deletions cypress/e2e/fetchProduct.cy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
describe('장바구니 e2e 테스트', () => {
beforeEach(() => {
cy.intercept(
{
method: 'GET',
url: /^https:\/\/json-server-4140.onrender.com\/cart-itmes\/?.*/,
},
{
fixture: 'mockProducts.json',
},
).as('fetchProduct');

cy.visit('http://localhost:3000/');
});

it('페이지에 접속하면 상품 목록(목 데이터) 8개를 렌더링한다.', () => {
cy.get('[data-cy=product-item]').should('have.length', 8);
});

it('장바구니 버튼을 클릭하면 상품을 장바구니에 1개 추가한다.', () => {
cy.get('[data-cy=add-cart').first().click();
cy.get('[data-cy=cart-amount').should('contain', 1);
});

it('장바구니 버튼에 상품 개수를 12개로 수정 시 헤더의 장바구니에 개수가 반영된다.', () => {
cy.get('[data-cy=add-cart').first().click();
cy.get('input').type('2');
cy.get('[data-cy=cart-amount').should('contain', 12);
});
});
50 changes: 50 additions & 0 deletions cypress/fixtures/mockProducts.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
[
{
"id": 1,
"name": "정사각(420ml)",
"price": 43400,
"imageUrl": "https://item.kakaocdn.net/do/d0abc6fe74e616536cf07626699bbc707154249a3890514a43687a85e6b6cc82"
},
{
"id": 2,
"name": "밀크티(370ml)",
"price": 73400,
"imageUrl": "https://item.kakaocdn.net/do/d0abc6fe74e616536cf07626699bbc707154249a3890514a43687a85e6b6cc82"
},
{
"id": 3,
"name": "정사각(370ml)",
"price": 41000,
"imageUrl": "https://item.kakaocdn.net/do/d0abc6fe74e616536cf07626699bbc707154249a3890514a43687a85e6b6cc82"
},
{
"id": 4,
"name": "납작(450ml)",
"price": 39900,
"imageUrl": "https://item.kakaocdn.net/do/d0abc6fe74e616536cf07626699bbc707154249a3890514a43687a85e6b6cc82"
},
{
"id": 5,
"name": "단지(480ml)",
"price": 38000,
"imageUrl": "https://item.kakaocdn.net/do/d0abc6fe74e616536cf07626699bbc707154249a3890514a43687a85e6b6cc82"
},
{
"id": 6,
"name": "납작(260ml)",
"price": 40200,
"imageUrl": "https://item.kakaocdn.net/do/d0abc6fe74e616536cf07626699bbc707154249a3890514a43687a85e6b6cc82"
},
{
"id": 7,
"name": "원형(500ml)",
"price": 50200,
"imageUrl": "https://item.kakaocdn.net/do/d0abc6fe74e616536cf07626699bbc707154249a3890514a43687a85e6b6cc82"
},
{
"id": 8,
"name": "원형(600ml)",
"price": 62400,
"imageUrl": "https://item.kakaocdn.net/do/d0abc6fe74e616536cf07626699bbc707154249a3890514a43687a85e6b6cc82"
}
]
25 changes: 25 additions & 0 deletions cypress/support/commands.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add('login', (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
20 changes: 20 additions & 0 deletions cypress/support/e2e.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// ***********************************************************
// This example support/e2e.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************

// Import commands.js using ES2015 syntax:
import './commands'

// Alternatively you can use CommonJS syntax:
// require('./commands')
13 changes: 13 additions & 0 deletions cypress/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"extends": "../tsconfig.json",
"include": ["**/*.ts", "../cypress.d.ts", "e2e/fetchProduct.cy.tsx"],
"compilerOptions": {
"lib": ["es5", "dom"],
"types": ["cypress", "node"],
"target": "es5",
"jsx": "preserve",
"isolatedModules": false,
"allowJs": true,
"noEmit": true
}
}
5 changes: 5 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'jsdom',
};