Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
c06f451
과제 제출을 위한 빈 커밋 날리기
kju1018 Dec 1, 2025
b4d6394
refactor: Header 분리
Dec 2, 2025
6bf5ad3
refactor: Notification 분리작업
kju1018 Dec 2, 2025
11c98a5
refactor: Header props명 수정
Dec 3, 2025
c02df27
refactor: useProducts, product 관련 함수 추가
Dec 4, 2025
27a96ff
refactor: type추가
Dec 4, 2025
f2fd89d
refactor: useCart 추가
Dec 4, 2025
4347c57
reafactor: cart 함수파일 추가
Dec 4, 2025
8f366d7
refactor: 초기값, fomatters 추가
Dec 4, 2025
d360210
refactor: AdminPage 수정
Dec 4, 2025
948b623
refactor: useCoupons 추가, useCart 수정
kju1018 Dec 4, 2025
48cacda
refactor: useNotification 추가
kju1018 Dec 4, 2025
e4fbfd8
feat: useLocalStorage 훅 구현
kju1018 Dec 4, 2025
357e446
refactor: useLocalStorage 적용
kju1018 Dec 4, 2025
5880a6f
fix: useLocalStorage setValue 클로저 문제 해결
kju1018 Dec 4, 2025
9149786
fix: useCart removeFromCart stale closure 문제 해결
kju1018 Dec 4, 2025
4f61067
feat: useDebounce 추가
kju1018 Dec 4, 2025
7dcac95
refactor: useProducts filteredProducts수정
kju1018 Dec 4, 2025
b342cc8
refactor: adminPage 컴포넌트 분리
kju1018 Dec 4, 2025
4b5d617
reafactor: ProductForm 로직 분리
kju1018 Dec 5, 2025
efe77da
refactor: productTable, ProductList 추가
kju1018 Dec 5, 2025
cfabdb4
refactor: CouponManagement페이지 분리 및 컴포넌트분리작업
kju1018 Dec 5, 2025
552e5f0
refactor: ShopPage 컴포넌트 분리
kju1018 Dec 5, 2025
23024f1
refactor: ProductList 컴포넌트 분리
kju1018 Dec 5, 2025
4395c68
refactor: CartSection 추가
kju1018 Dec 5, 2025
bada5c8
refactor: ProductCard 컴포넌트 추가
kju1018 Dec 5, 2025
b779a2b
refactor: CartSection 분리작업
kju1018 Dec 5, 2025
6d1c007
refactor: coupon관련 함수 분리작업
kju1018 Dec 5, 2025
581f049
refactor: discount 로직 분리
kju1018 Dec 5, 2025
53a0073
refactor: icon 분리작업
kju1018 Dec 5, 2025
c8ed8d0
refactor: button, input, select 컴포넡트 분리
kju1018 Dec 5, 2025
08491bb
chore: basic 폴더를 advanced로 복사
kju1018 Dec 5, 2025
fe575a5
chore: Jotai 상태관리 라이브러리 추가
kju1018 Dec 5, 2025
0102d3d
refactor: ShopPage, App.tsx함수 선언 위치 수정
kju1018 Dec 5, 2025
cb04b36
refactor: ShopPage, App.tsx함수 선언 위치 수정
kju1018 Dec 5, 2025
42462db
feat: cartAtoms 추가
kju1018 Dec 5, 2025
3529920
feat: productAtoms 추가
kju1018 Dec 5, 2025
ef9b940
refactor: useProducts에 pruductAtoms적용
kju1018 Dec 5, 2025
541b839
feat: couponAtoms 추가
kju1018 Dec 5, 2025
7915254
refactor: useCoupons에 couponsAtom 적용
kju1018 Dec 5, 2025
6736515
refactor: cart관련 props 일부 제거
kju1018 Dec 5, 2025
ece0470
refactor: 전역상태관리, props 제거
Dec 5, 2025
64b8c9a
refactor: props수정
Dec 5, 2025
cd74704
chore: 배포파일 추가
Dec 5, 2025
24cc73d
fix: 배포오류 수정
Dec 5, 2025
ef899f4
fix: 배포 오류 수정
Dec 5, 2025
aea81ae
fix: 배포 에러 수정
Dec 5, 2025
04c420d
refactor: useNotification jotai 적용
kju1018 Dec 7, 2025
fca1004
refactor: 불필요한 함수 제거
kju1018 Dec 7, 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
55 changes: 55 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Deploy to GitHub Pages

on:
push:
branches:
- main

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: "pages"
cancel-in-progress: true

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install pnpm
uses: pnpm/action-setup@v2
with:
version: latest

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: "22"
cache: "pnpm"

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Build Advanced App
run: pnpm run build

- name: Prepare deployment
run: |
mv dist/index.advanced.html dist/index.html
cp dist/index.html dist/404.html

- name: Setup Pages
uses: actions/configure-pages@v4

- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: "./dist"

- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0"
},
"dependencies": {
"class-variance-authority": "^0.7.1",
"jotai": "^2.15.2",
"react": "^19.1.1",
"react-dom": "^19.1.1"
},
Expand Down
42 changes: 42 additions & 0 deletions pnpm-lock.yaml

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

132 changes: 132 additions & 0 deletions refactoring-guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# Frontend Refactoring Guide
(Design Pattern + Functional Programming 기준)

이 문서는 본 프로젝트의 대규모 리팩토링(App.tsx 1000+ lines)을 수행할 때
**모든 컴포넌트를 일관된 기준으로 분리하기 위해 작성된 가이드라인입니다.**

---

# 1. 리팩토링 전체 목표

### ✔ 엔티티 중심 계층 분리
README 명시 기준
- 엔티티를 다루는 것과 아닌 것을 명확히 구분한다
- 엔티티 상태 예: cart, product, coupon
- 비엔티티 상태 예: isShowPopup, 검색창 value
- 엔티티 컴포넌트 vs UI 컴포넌트 분리
- 엔티티 훅(useCart, useProduct, useCoupon) 분리
- 엔티티 계산 함수(calculate*, getMaxApplicableDiscount 등) 분리

### ✔ UI는 순수하게 만들기 (FP 원칙)
- UI 컴포넌트는 "표현"만 담당한다
- 상태/도메인/비즈니스 로직/데이터 구조 몰라야 함
- props = 값 + 이벤트 핸들러만 받는다
- side-effect 없음

### ✔ Container - Presenter(Presentational) 패턴 적용
- Container: 상태/비즈니스 로직/도메인 판단 담당
- Presenter(UI): 렌더링만 담당

### ✔ 테스트 통과 구조 만들기
- 계산 로직, 상태 로직, UI 분리하면 테스트 가능해짐

### ✔ Props Drilling 제거(심화)
- 전역 상태(Zustand, Jotai, Context 중 택 1)
- 불필요한 props 제거

---

# 2. 컴포넌트 분류 기준

## ✅ (1) UI Component (순수 UI)
- 도메인 모름
- 엔티티 모름
- 상태 없음
- props로 받은 값만 렌더링
- props로 받은 핸들러만 호출
- 재사용 가능
- 스타일/구조 중심

**예)** Button, Input, Badge, Modal, Layout, Grid, Table…

---

## ✅ (2) Entity Component (도메인 컴포넌트)
- 특정 엔티티(cart, product, coupon)를 직접 다룸
- useCart, useProduct 등 엔티티 훅을 사용
- 비즈니스 판단을 내부에서 수행
- 로직이 들어있지만 UI도 포함될 수 있음
- 다만 UI는 최대한 presenter로 분리하는 것이 이상적

**예)**
CartItemView, ProductCard, CouponSection…

---

## ✅ (3) Function / Util (순수 함수)
- 데이터만 입력 → 새로운 데이터만 반환 (순수함수)
- 외부 상태 접근 X
- 계산/가공 책임만 있음

README 요구 예:
- calculateItemTotal
- calculateCartTotal
- getMaxApplicableDiscount
- updateCartItemQuantity

---

## ✅ (4) Custom Hook (상태/비즈니스 로직)
- 비즈니스 로직 + 상태 관리
- API 연동 or 로컬 저장 등 side-effect 포함 가능
- 도메인 단위로 묶기 (useCart, useProduct, useCoupon 등)

---

# 3. 리팩토링 절차 (단계별)

## 🔥 Step 1) 구조적 분리
> “실제로 로직을 UI에서 제거하는 단계”

- App.tsx에서
- 상태
- 로직
- 엔티티 접근
- API 호출
- 조건 분기
모두 분리한다
- Presenter(UI)에는 **로직 없는 코드만 남긴다**

---

## 🔥 Step 2) 의미적 책임 분리 (네이밍 관점)
> “UI가 도메인을 모르게 만드는 단계”

예:
- searchTerm → value
- setSearchTerm → onChange
- isAdmin → isActive
- onAdminToggle → onToggle

이름이 UI 레이어의 책임과 일관되도록 변경

---

## 🔥 Step 3) 엔티티 및 훅 분리
README 기준:
- useCart, useProduct, useCoupon 등 로직을 훅으로 이동
- 계산 로직을 util로 이동
- 엔티티 컴포넌트(ProductCard, Cart 등)를 별도 폴더 구조로 이동

---

## 🔥 Step 4) Props Drilling 제거(심화)
README 기준:
- Jotai / Zustand / Context 중 하나 선택
- 전역 상태로 공유
- Presenter는 props를 최소화

---

# 4. 폴더 구조 제안

Loading