Skip to content

Commit 0fd357b

Browse files
dev-dino22pocojangJeLee-river
authored
[2단계 - 페이먼츠] 카멜(진나영) 미션 제출합니다. (#477)
* initial: 프로젝트 세팅 * feat: selectBox 컴포넌트 작성 * feat: 카드 입력 폼 브랜드 셀렉트 구현 * refactor: PaymentInputPage 컴포넌트의 각 상태를 하나의cardInfo 상태로 통합 * feat: 카드 브랜드 선택에 따라 카드 프리뷰의 색상 변경 기능 구현 * feat: 카드 번호 및 유효기간 입력 시 다음 필드로 포커스 이동 기능 추가 * feat: 카드 비밀번호 입력 컴포넌트 작성 * chore: PaymentInputPage 모듈 css 높이 설정 및 CardInfo 에 비밀번호 컴포넌트 상수 작성 * feat: 값이 유효하면 다음 입력 컴포넌트 렌더링 기능 구현 * refactor: react router 페이지기능 도입 전 디렉터리 구조 변경 - pages 폴더 분류 * refactor: pages 폴더명 케밥케이스로 변경 및 PAGE_URL 상수 작성 * feat: NotFoundPage 컴포넌트 작성 및 Route 연결 * feat: 페이먼츠 메인페이지 작성 * feat: 카드 등록 성공 페이지 작성 * refactor: 디렉터리 네이밍 페이지 폴더는 케밥케이스로 통일 * style: CSS 스타일 수정 및 컴포넌트 레이아웃 개선 * feat: 버튼 컴포넌트 추가 및 카드 입력 폼에서 사용, 성공 페이지에서 카드 정보 표시 수정 * refactor: setCardInfo 훅을 각 용도별 핸들러를 만들어 프롭 전달하는 구조로 개선 * refactor: 카드 입력 컴포넌트 리팩터링 - CardPasswordInput과 CardExpirationDateInput 컴포넌트를 제거 - CardNumberInput 컴포넌트를 개선된 검증 및 상태 관리 로직으로 새로 작성 - 관심사 분리를 위해 usePasswordInput, useCardNumberInput 훅을 추가 - 카드 브랜드 및 에러 메시지 상수를 정의 - 폼 검증 상태를 관리하는 useFormState 훅을 구현 - 카드 입력 검증을 위한 validator 함수를 수정 * refactor: 컴포넌트의 상태 관리 개선 및 타입 안전성 강화 * feat: 다음 인풋 활성화 시 자동 포커스 구현 * test: 카드 입력 및 성공 페이지, 카드 미리보기 및 입력 필드 컴포넌트 스토리북 작성 및 개선 * fix: gitpages 배포 위해 BrouserRouter에서 HashRouter로 변경 * fix: CVC 입력 및 유효기간 입력 조건 분기 수정 및 유효기간 연도 입력 시 달이 비어있으면 헤당 포커스 이동 기능 추가 * feat: SPA BrowserRouter 배포 설정 * refactor: 404.html 퍼블릭 폴더 * chore: 스토리북 css 임포트 경로 수정 * fix: storybook index.css 경로 수정 및 글로벌 css를 src 내부 글로벌 폴더로 이동 * test: storybook meta 설정 수정 * refactor: package.json 크로매틱 환경변수로 배포 * init project * feat: init react payments project * [1단계 - 페이먼츠] 카멜(진나영) 미션 제출합니다. (#435) * feat: 페어 프로그래밍 초기 세팅 Co-authored-by: dev-dino22 <[email protected]> * docs: 미션의 기능목록, 설계 구조 등 작성 Co-authored-by: dev-dino22 <[email protected]> * style: 전역 스타일링 적용 Co-authored-by: dev-dino22 <[email protected]> * feat: Input 컴포넌트 생성 Co-authored-by: dev-dino22 <[email protected]> * feat: InputForm 컴포넌트 생성 Co-authored-by: dev-dino22 <[email protected]> * feat: 카드 번호 입력 컴포넌트 작성 Co-authored-by: dev-dino22 <[email protected]> * feat: 카드 유효기간 입력 컴포넌트 작성 Co-authored-by: dev-dino22 <[email protected]> * feat: 카드 CVC 입력 컴포넌트 작성 Co-authored-by: dev-dino22 <[email protected]> * feat: 카드 입력 form 컴포넌트 작성 Co-authored-by: dev-dino22 <[email protected]> * refactor: InputForm이 Input을 children으로 받도록 리팩토링 Co-authored-by: dev-dino22 <[email protected]> * style: 전역 변수로 관리하는 색상 추가 Co-authored-by: dev-dino22 <[email protected]> * feat: 카드 브랜드 로고 이미지 생성 Co-authored-by: dev-dino22 <[email protected]> * style: 카드 입력 form 컴포넌트 스타일 적용 Co-authored-by: dev-dino22 <[email protected]> * style: 기본 스타일을 초기화하는 파일 수정 Co-authored-by: dev-dino22 <[email protected]> * style: 카드 입력 컴포넌트의 스타일 수정 Co-authored-by: dev-dino22 <[email protected]> * feat: 카드 정보를 입력하는 UI를 렌더링하는 함수 생성 Co-authored-by: dev-dino22 <[email protected]> * style: 카드 정보를 입력하는 UI에 스타일 추가 Co-authored-by: dev-dino22 <[email protected]> * style: 카드 입력 form의 스타일 조정 Co-authored-by: dev-dino22 <[email protected]> * feat: 사용자가 입력한 카드 정보를 프리뷰에 렌더링하는 기능 구현 Co-authored-by: dev-dino22 <[email protected]> * feat: 카드 번호와 유효기간 정보를 상태관리 하도록 코드 추가 Co-authored-by: dev-dino22 <[email protected]> * refactor: 사용자 카드 정보 등록 페이지가 렌더링되도록 app 수정 Co-authored-by: dev-dino22 <[email protected]> * feat: 사용자 입력값의 예외 처리 로직 생성 Co-authored-by: dev-dino22 <[email protected]> * feat: 사용자 입력값에 대한 피드백 메시지 렌더링 로직 추가 Co-authored-by: dev-dino22 <[email protected]> * refactor: 유효기간 검증 로직 수정 Co-authored-by: dev-dino22 <[email protected]> * feat: 카드 유효기간 검증 로직 추가 Co-authored-by: dev-dino22 <[email protected]> * feat: 카드 CVC 검증 로직 추가 Co-authored-by: dev-dino22 <[email protected]> * feat: 카드 번호 검증 로직 추가 Co-authored-by: dev-dino22 <[email protected]> * docs: 구현한 기능 목록 체크 * refactor: 상태 변경 함수의 타입 추가 * style: storybook에 css 적용 Co-authored-by: dev-dino22 <[email protected]> * refactor: 불필요한 props 제거 Co-authored-by: dev-dino22 <[email protected]> * test: storybook 비주얼 테스트 추가 Co-authored-by: dev-dino22 <[email protected]> * fix: 웹 배포 환경에 따라 이미지 경로 수정 * refactor: 불필요한 fragment 제거 * refactor: 카드 정보 상수 분리 * refactor: checkBrand 조건문 startsWith()로 가독성 개선 * refactor: 다시 유효한 값 입력 시 오류 스타일 삭제 * refactor: 유효기간 month, year로 나누고 전용 validator 분리 * refactor: 전역 상태 대신 ref로 유효기간 검증 관리 * refactor: 카드 유효기간입력 컴포넌트의 inputs를 map 함수 렌더링으로 변경 * refactor: CardExpirationDateInput 의 onChangeHandler 함수/상수 분리 및 추상화 * refactor: 카드프리뷰의 let 을 사용한 함수 내 상태관리에서 useMemo()훅 활용 * refactor: Input 컴포넌트에서 이제 불필요한 forwardRef 제거 및 props 전개 방식으로 변경 * chore: Input컴포넌트 폴명 파스칼케이스 수정을 위한 중간임시 폴더명 * feat: input 폴더명 카멜케이스 수정 * refactor: validateCardInput.ts 의 숫자문자열 검사 메서드명 수정 * refactor: validateCardInput.ts의 반환값 에러결과불리언객체로 통일 * refactor: Input 컴포넌트는 isValid 프롭을 전달받고 각 유효 상태를 사용처에서 제어하도록 변경 및 에러메세지 상수분리와 에러메세지 함수 작성 * chore: 불필요한 import 문 제거 --------- Co-authored-by: Jeongeun Lee <[email protected]> Co-authored-by: dev-dino22 <[email protected]> * refactor: react router 페이지기능 도입 전 디렉터리 구조 변경 - pages 폴더 분류 * feat: SPA BrowserRouter 배포 설정 * chore: 스토리북 css 임포트 경로 수정 * fix: rebase 충돌로 인해 포함된 불필요한 파일 제거 * chore: PAGE_URL 의 ADD_CARD.SUCCESS 오타 수정 * refactor: useFormState() 훅의 handle-* 추상화 * refactor: CardPreview의 style 삼항 연산자 가독성 개선 * refactor: AddCardSuccessPage의 이중 import문 수정 * refactor: isVisibleSubmitButton을 상태로 관리하지 않고 useMemo를 사용해 파생 상태로 관리하도록 개선 * refactor: PaymentInputPage.tsx의 handleInputChange 함수 추상화 * style: SelectBox 선택 시 글자와 ArrowSVG 컬러 검은색으로 변경 * refactor: useNumberInput의 onChangeHandler 내부 로직 함수 분리 시도 --------- Co-authored-by: devJang <[email protected]> Co-authored-by: Jeongeun Lee <[email protected]> Co-authored-by: dev-dino22 <[email protected]>
1 parent c4e7d81 commit 0fd357b

File tree

77 files changed

+2425
-374
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+2425
-374
lines changed

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# Vite
22
.vite
33

4+
.env
5+
.env.production
6+
47
# Logs
58
logs
69
*.log
@@ -26,4 +29,5 @@ dist-ssr
2629
*.sln
2730
*.sw?
2831

29-
*storybook.log
32+
*storybook.log
33+
*storybook-static

.storybook/preview-head.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<meta charset="UTF-8" />
55
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
66

7-
<link href="../src/index.css" rel="stylesheet" />
7+
<link href="./index.css" rel="stylesheet" />
88

99
<title>Document</title>
1010
</head>

.storybook/preview.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { Preview } from "@storybook/react";
2+
import "../src/global/index.css";
23

34
const preview: Preview = {
45
parameters: {

404.html

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8" />
5+
<title>Single Page Apps for GitHub Pages</title>
6+
<script type="text/javascript">
7+
// Single Page Apps for GitHub Pages
8+
// MIT License
9+
// https://github.com/rafgraph/spa-github-pages
10+
// This script takes the current url and converts the path and query
11+
// string into just a query string, and then redirects the browser
12+
// to the new url with only a query string and hash fragment,
13+
// e.g. https://www.foo.tld/one/two?a=b&c=d#qwe, becomes
14+
// https://www.foo.tld/?/one/two&a=b~and~c=d#qwe
15+
// Note: this 404.html file must be at least 512 bytes for it to work
16+
// with Internet Explorer (it is currently > 512 bytes)
17+
18+
// If you're creating a Project Pages site and NOT using a custom domain,
19+
// then set pathSegmentsToKeep to 1 (enterprise users may need to set it to > 1).
20+
// This way the code will only replace the route part of the path, and not
21+
// the real directory in which the app resides, for example:
22+
// https://username.github.io/repo-name/one/two?a=b&c=d#qwe becomes
23+
// https://username.github.io/repo-name/?/one/two&a=b~and~c=d#qwe
24+
// Otherwise, leave pathSegmentsToKeep as 0.
25+
var pathSegmentsToKeep = 1;
26+
27+
var l = window.location;
28+
l.replace(
29+
l.protocol +
30+
"//" +
31+
l.hostname +
32+
(l.port ? ":" + l.port : "") +
33+
l.pathname
34+
.split("/")
35+
.slice(0, 1 + pathSegmentsToKeep)
36+
.join("/") +
37+
"/?/" +
38+
l.pathname
39+
.slice(1)
40+
.split("/")
41+
.slice(pathSegmentsToKeep)
42+
.join("/")
43+
.replace(/&/g, "~and~") +
44+
(l.search ? "&" + l.search.slice(1).replace(/&/g, "~and~") : "") +
45+
l.hash
46+
);
47+
</script>
48+
</head>
49+
<body></body>
50+
</html>
51+
52+
53+
54+
55+

index.html

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,31 @@
11
<!DOCTYPE html>
2-
<html lang="en">
2+
<html lang="ko">
33
<head>
44
<meta charset="UTF-8" />
55
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
66
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
77
<title>React Payments</title>
8+
<script type="text/javascript">
9+
(function (l) {
10+
if (l.search[1] === "/") {
11+
var decoded = l.search
12+
.slice(1)
13+
.split("&")
14+
.map(function (s) {
15+
return s.replace(/~and~/g, "&");
16+
})
17+
.join("?");
18+
window.history.replaceState(
19+
null,
20+
null,
21+
l.pathname.slice(0, -1) + decoded + l.hash
22+
);
23+
}
24+
})(window.location);
25+
</script>
826
</head>
927
<body>
1028
<div id="root"></div>
1129
<script type="module" src="/src/main.tsx"></script>
1230
</body>
13-
</html>
31+
</html>

package-lock.json

Lines changed: 135 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,18 @@
99
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
1010
"preview": "vite preview",
1111
"storybook": "storybook dev -p 6006",
12-
"build-storybook": "storybook build"
12+
"build-storybook": "storybook build",
13+
"deploy": "vite build --base=/react-payments/ --minify=false && npx gh-pages -d dist",
14+
"chromatic": "dotenv -e .env -- npx chromatic --project-token=$CHROMATIC_PROJECT_TOKEN"
1315
},
1416
"dependencies": {
1517
"react": "^19.1.0",
16-
"react-dom": "^19.1.0"
18+
"react-dom": "^19.1.0",
19+
"react-router": "^7.5.1"
1720
},
1821
"devDependencies": {
19-
"@eslint/js": "^9.24.0",
2022
"@chromatic-com/storybook": "^3.2.6",
23+
"@eslint/js": "^9.24.0",
2124
"@storybook/addon-essentials": "^8.6.12",
2225
"@storybook/addon-interactions": "^8.6.12",
2326
"@storybook/addon-links": "^8.6.12",
@@ -29,6 +32,7 @@
2932
"@types/react": "^19.1.1",
3033
"@types/react-dom": "^19.1.2",
3134
"@vitejs/plugin-react-swc": "^3.8.1",
35+
"dotenv-cli": "^8.0.0",
3236
"eslint": "^9.24.0",
3337
"eslint-plugin-react-hooks": "^5.2.0",
3438
"eslint-plugin-react-refresh": "^0.4.19",

0 commit comments

Comments
 (0)