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_임지환 6주차 과제 제출합니다. #118

Open
wants to merge 19 commits into
base: dlawlghks
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
72e283d
chore: 이전 과제 코드 가져오기
dlawlghks Aug 6, 2024
1cc9fac
docs: README 업데이트
dlawlghks Aug 6, 2024
1254aff
feat: BackendContext 및 BackendProvider로 백엔드 URL 관리 기능 추가
dlawlghks Aug 6, 2024
659fc93
feat: 백엔드 URL을 이용한 회원가입 및 로그인 API 연동 기능 추가
dlawlghks Aug 6, 2024
e879236
feat: 백엔드 URL을 이용한 카테고리 API 연동 및 데이터 형식 변환 기능 추가
dlawlghks Aug 6, 2024
b126149
feat: 백엔드 URL을 이용한 상품 상세 API 연동 및 에러 처리 기능 추가
dlawlghks Aug 6, 2024
8bd49b7
feat: 백엔드 URL을 이용한 상품 옵션 API 연동 기능 추가
dlawlghks Aug 6, 2024
1b5cf89
feat: 백엔드 URL을 이용한 상품 목록 무한 스크롤 API 연동 기능 추가
dlawlghks Aug 6, 2024
be1ac3a
feat: 인증 토큰 포함된 Axios 인스턴스 생성 및 React Query 클라이언트 설정
dlawlghks Aug 6, 2024
63c2653
feat: Header 컴포넌트에 백엔드 URL 선택 기능 추가
dlawlghks Aug 6, 2024
5140333
feat: 상품 옵션 섹션 및 관심 상품 API 연동 기능 구현
dlawlghks Aug 6, 2024
c3fad84
feat: 로그인 페이지 인증 기능 구현
dlawlghks Aug 6, 2024
9324821
feat: 회원가입 페이지 사용자 등록 기능 구현
dlawlghks Aug 6, 2024
53c0948
feat: OrderFormData 및 WishlistResponse 타입 추가
dlawlghks Aug 6, 2024
cfaca57
feat: 사용자 인증 정보 관리 위한 AuthContext 및 AuthProvider 구현
dlawlghks Aug 6, 2024
396a147
feat: 마이페이지에 관심 상품 목록 및 삭제 기능 추가
dlawlghks Aug 6, 2024
af7a1f2
feat: 주문서 컴포넌트에 포인트 사용 및 유효성 검사 기능 추가
dlawlghks Aug 6, 2024
942ae40
feat: 주문 정보 컴포넌트(OrderFormOrderInfo) 포인트 사용 기능 구현
dlawlghks Aug 6, 2024
849e1bb
chore: npm run build로 생성된 docs 파일 추가
dlawlghks Aug 6, 2024
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
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
BUILD_PATH=docs
59 changes: 59 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
module.exports = {
env: {
browser: true,
es2021: true,
node: true,
},
extends: [
'plugin:@typescript-eslint/recommended',
'airbnb/hooks',
'airbnb-typescript',
'prettier',
'plugin:storybook/recommended',
],
parser: '@typescript-eslint/parser',
parserOptions: {
project: './tsconfig.json',
ecmaFeatures: {
jsx: true,
},
ecmaVersion: 'latest',
sourceType: 'module',
},
plugins: [
'react',
'@typescript-eslint',
'react-hooks',
'json-format',
'simple-import-sort',
'@emotion',
'prettier',
],
rules: {
'react/react-in-jsx-scope': 'off',
'simple-import-sort/imports': 'error',
'simple-import-sort/exports': 'error',
'@typescript-eslint/consistent-type-imports': 'warn',
'@typescript-eslint/no-unused-vars': [
'error',
{
argsIgnorePattern: '^_',
},
],
'import/extensions': ['off'],
'import/no-extraneous-dependencies': ['off'],
'react/jsx-filename-extension': [
'warn',
{
extensions: ['.tsx', '.js', '.jsx'],
},
],
'@typescript-eslint/no-use-before-define': ['off'],
},
ignorePatterns: ['**/build/**/*', '.eslintrc.js', 'craco.config.js'],
settings: {
'import/resolver': {
typescript: {},
},
},
};
26 changes: 26 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# 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*

.yaml
node_modules/.cache/
3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/.vscode
/node_modules

8 changes: 8 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"singleQuote": true,
"semi": true,
"tabWidth": 2,
"trailingComma": "all",
"printWidth": 100,
"arrowParens": "always"
}
36 changes: 36 additions & 0 deletions .storybook/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import type { StorybookConfig } from '@storybook/react-webpack5';
import TsconfigPathsPlugin from 'tsconfig-paths-webpack-plugin';
import path from 'path';

const config: StorybookConfig = {
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
'@storybook/preset-create-react-app',
'@storybook/addon-onboarding',
'@storybook/addon-interactions',
],
webpackFinal: async (config) => {
config.resolve?.plugins?.push(
new TsconfigPathsPlugin({
configFile: path.resolve(__dirname, '../tsconfig.json'),
}),
);

return config;
},
framework: {
name: '@storybook/react-webpack5',
options: {
builder: {
useSWC: true,
},
},
},
docs: {
autodocs: 'tag',
},
staticDirs: ['../public'],
};
export default config;
16 changes: 16 additions & 0 deletions .storybook/preview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { Preview } from '@storybook/react';
import '@/styles';

const preview: Preview = {
parameters: {
actions: { argTypesRegex: '^on[A-Z].*' },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/i,
},
},
},
};

export default preview;
97 changes: 96 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,96 @@
# react-deploy
# 🚀 1단계 - API 명세 협의 & 반영

## 기능 요구 사항

### 작성한 API 문서를 기반으로 팀 내에서 지금까지 만든 API를 검토하고 통일하여 변경 사항을 반영한다.

- [] 팀 내에서 일관된 기준을 정하여 API 명세를 결정한다.
- [] 때로는 클라이언트의 편의를 위해 API 명세를 결정하는 것이 좋다.
- [] 팀 내에 배포 될 API가 여러개 일 경우 상단 네비게이션 바에서 선택 가능하게 한다.
- [] 프론트엔드의 경우 배포와 사용자가 팀 내 여러 서버 중 하나를 선택하여 서비스를 이용
- [] 팀내 백엔드 엔지니어의 이름을 넣고, 이름을 선택하면 해당 엔지니어의 API로 API통신을 하게 한다.
- [] 기본 선택은 제일 첫번째 이름으로 한다.

# 🚀 2단계 - 배포하기

## 기능 요구 사항

### 세가지 방법 중 본인이 원하는 방식으로 배포한다.

### (단, 가능하면 최대한 방법 1, 3번으로 진행하고 CI/CD를 구축하는 것을 권장해요)

#### 방법1.

- github action을 사용하여 ci/cd를 구성한다.
- cloudflare의 pages에 배포한다.

#### 방법2.

- vercel을 사용하여 배포한다.

#### 방법3.

- github pages를 사용하여 배포한다.
- 서버 API가 의도대로 잘 동작하는지 확인하고, 문제가 있다면 해결한다.

# 🚀 3단계 - 포인트

## 기능 요구 사항

### 상품 구매에 사용할 수 있는 포인트 기능을 구현한다.

- [] 포인트는 사용자별로 보유한다.
- [] 포인트 차감 방법 등 나머지 기능에 대해서는 팀과 논의하여 정책을 결정하고 구현한다.
- e.g.
- 5만 원 이상 주문 시 총 금액의 10%가 할인된다.
- 현금 영수증을 받으려면 휴대전화 번호를 입력해야 한다.
- [] API 명세는 팀과 협의하여 결정하고 구현한다.

# 🚀 4단계 - 질문의 답변을 README에 작성

## 아래 질문에 대한 답변을 README에 추가하여 과제 제출을 해요.

## 📝 Requirements

### 6주차 질문

### 질문 1. SPA 페이지를 정적 배포를 하려고 할 때 Vercel을 사용하지 않고 한다면 어떻게 할 수 있을까요?

1. GitHub Pages:
◦ GitHub Pages를 사용하여 정적 사이트를 배포할 수 있다. 프로젝트의 리포지토리를 GitHub에 올리고, 해당 리포지토리의 설정에서 GitHub Pages를 활성화하면 된다.
2. Netlify:
◦ Netlify는 정적 사이트 배포를 쉽게 할 수 있는 플랫폼이다. Git 리포지토리와 연동하여 자동 배포를 설정할 수 있으며, 다양한 빌드 옵션을 제공한다.
3. AWS S3:
◦ AWS S3를 사용하여 정적 웹사이트 호스팅을 할 수 있다. S3 버킷을 생성하고, 정적 파일을 업로드한 후, 버킷의 퍼블릭 접근 권한을 설정하면 된다. CloudFront를 이용하여 CDN 설정도 가능하다.
4. Firebase Hosting:
◦ Firebase Hosting은 빠르고 안전한 정적 호스팅을 제공한다. Firebase CLI를 사용하여 배포할 수 있으며, SSL 인증서와 CDN도 자동으로 설정된다.
5. Surge:
◦ Surge는 간단한 CLI 명령어를 통해 정적 사이트를 쉽게 배포할 수 있는 서비스이다. 프로젝트 디렉토리에서 surge 명령어를 실행하면 된다.
6. DigitalOcean:
◦ DigitalOcean의 Droplet을 사용하여 웹 서버를 설정하고, Nginx나 Apache와 같은 웹 서버를 통해 정적 파일을 배포할 수 있다. 서버 설정과 관리를 직접 해야 한다는 점에서 다소 복잡할 수 있다.

### 질문 2. CSRF나 XSS 공격을 막는 방법은 무엇일까요?

1. CSRF (Cross-Site Request Forgery) 방지 방법:
◦ CSRF 토큰 사용: 서버가 각 요청에 대해 고유한 CSRF 토큰을 발급하고, 이를 폼이나 AJAX 요청에 포함시킨다. 서버는 요청이 들어올 때 이 토큰을 검증한다.
◦ SameSite 쿠키 속성 설정: 쿠키의 SameSite 속성을 'Strict' 또는 'Lax'로 설정하여, 동일 사이트 내에서만 쿠키가 전송되도록 한다.
◦ CORS 설정: CORS(Cross-Origin Resource Sharing) 설정을 통해 신뢰할 수 있는 도메인에서만 요청을 받을 수 있도록 한다.
2. XSS (Cross-Site Scripting) 방지 방법:
◦ 입력값 검증 및 인코딩: 사용자로부터 입력받은 데이터는 반드시 검증하고, 출력 시에는 HTML 엔티티로 인코딩하여 스크립트가 실행되지 않도록 한다.
◦ CSP (Content Security Policy) 설정: CSP 헤더를 설정하여, 스크립트 소스를 제한함으로써 악성 스크립트가 실행되지 않도록 한다.
◦ 출력 시 안전한 메서드 사용: 데이터베이스나 서버에서 가져온 데이터를 HTML에 출력할 때는 안전한 메서드를 사용하여 XSS 공격을 방지한다.

### 질문 3. 브라우저 렌더링 원리에대해 설명해주세요.

1. DOM (Document Object Model) 생성:
◦ HTML 문서를 파싱하여 DOM 트리를 생성한다. DOM 트리는 문서의 구조를 계층적으로 표현한 트리 구조이다.
2. CSSOM (CSS Object Model) 생성:
◦ CSS 파일을 파싱하여 CSSOM 트리를 생성한다. CSSOM 트리는 스타일 정보를 계층적으로 표현한 트리 구조이다.
3. 렌더 트리 생성:
◦ DOM 트리와 CSSOM 트리를 결합하여 렌더 트리를 생성한다. 렌더 트리는 실제로 화면에 그려질 노드만 포함한다.
4. 레이아웃:
◦ 렌더 트리를 기반으로 각 노드의 크기와 위치를 계산한다. 이를 레이아웃 또는 리플로우라고 한다.
5. 페인팅:
◦ 계산된 레이아웃 정보를 바탕으로 각 노드를 화면에 픽셀 단위로 그린다. 이 과정을 페인팅 또는 래스터라이제이션이라고 한다.
6. 컴포지팅:
◦ 페인팅된 레이어들을 조합하여 최종적으로 화면에 출력한다. 이 과정에서는 GPU를 활용하여 성능을 최적화할 수 있다.
13 changes: 13 additions & 0 deletions craco.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const CracoAlias = require('craco-alias');

module.exports = {
plugins: [
{
plugin: CracoAlias,
options: {
source: 'tsconfig',
tsConfigPath: 'tsconfig.paths.json',
},
},
],
};
14 changes: 14 additions & 0 deletions docs/asset-manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"files": {
"main.css": "/react-deploy/static/css/main.689b7bff.css",
"main.js": "/react-deploy/static/js/main.bd5a99db.js",
"static/media/kakao_logo.svg": "/react-deploy/static/media/kakao_logo.976fd2de0dc47a40dc4cad638b9b69e1.svg",
"index.html": "/react-deploy/index.html",
"main.689b7bff.css.map": "/react-deploy/static/css/main.689b7bff.css.map",
"main.bd5a99db.js.map": "/react-deploy/static/js/main.bd5a99db.js.map"
},
"entrypoints": [
"static/css/main.689b7bff.css",
"static/js/main.bd5a99db.js"
]
}
1 change: 1 addition & 0 deletions docs/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<!doctype html><html lang="ko"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><title>Kakao Tech</title><script defer="defer" src="/react-deploy/static/js/main.bd5a99db.js"></script><link href="/react-deploy/static/css/main.689b7bff.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
Loading