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

[11팀 장원정] [Chapter 2-2] 디자인 패턴과 함수형 프로그래밍 #41

Open
wants to merge 28 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
81e6f0e
chore: eslint, pretiier 설정
Jan 12, 2025
396e89c
refacotr: FSD 아키텍처 기존 컴포넌트 구조로 1차 분류
Jan 13, 2025
2f765a0
fix: hooks import 오류 수정
Jan 13, 2025
939bf27
refactor: FSD eslint 규칙 추가 및 main.tsx, App.tsx app 레이어 폴더로 이동
Jan 13, 2025
28504d8
refactor: shared -> ui -> typography 폴더 생성 및 PageTitle, SectionTitle …
Jan 13, 2025
bf1aa46
refactor: 훅들 및 cart.ts 작성 완료, 기본 과제 테스트 완료
Jan 13, 2025
fbc6933
refacotr: CartPage -> CartList, ProductList로 분할
Jan 14, 2025
d494504
refactor: 기존 features에 있는 파일들 widgets로 옮김.
Jan 15, 2025
a83a0f9
refactor: shared에 공통 유틸 함수 및 컴포넌트 작성
Jan 15, 2025
dfa46f4
refactor: widgets에 있는 UI 컴포넌트 분할하여 features에 생성, shared에 전역 타입 생성, 전역…
Jan 15, 2025
04c0298
refactor: 기존 UI 컴포넌트들 features 레이어까지 분할
Jan 15, 2025
91552fb
refactor: Layout 컴포넌트 수정 및 app 레이어로 이동
Jan 15, 2025
cfcd45a
refactor: 전역 타입 app -> shared로 이동
Jan 15, 2025
a254412
refacotr: useCart, useCoupons, useProduct -> ContextAPI로 컴포넌트에서 전달 받을…
Jan 16, 2025
e51d8e3
refactor: 기존 useCart에서 쿠폰 선택 및 총액 계산 로직 useCartTotal로 분리
Jan 16, 2025
e63d6ec
refactor: useCart, useCartTotal -> entities로 이동
Jan 16, 2025
0f4d4c5
refacotr: shared에 Select 컴포넌트 생성 및 적용
Jan 16, 2025
243337a
refactor: features 레이어 컴포넌트 내부 함수 lib로 이동
Jan 16, 2025
4584499
refactor: Product 컴포넌트 생성, test 코드 수정
Jan 16, 2025
dd83841
refactor: ProductManagement 컴포넌트 분리, useDiscounts 훅 생성, useProduct에 f…
Jan 16, 2025
feea5d0
refacotr: 기존 ContextProvider들 수정
Jan 16, 2025
48f289f
refactor: EditingProductContextProvider 생성
Jan 16, 2025
d10f28b
refactor: DiscountView 컴포넌트 분리
Jan 16, 2025
8f73e12
refacotr: DiscountView key 추가
Jan 16, 2025
5e5eef3
fix: advanced.test.tsx 오류 수정
Jan 16, 2025
78b1de6
fix: 의존성 충돌 해결
Jan 17, 2025
b477a81
fix: lint 의존성 문제 해결
Jan 17, 2025
7579172
fix: lint airbnb fsd 관련 플러그인 삭제
Jan 17, 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
Prev Previous commit
Next Next commit
refactor: 기존 useCart에서 쿠폰 선택 및 총액 계산 로직 useCartTotal로 분리
  • Loading branch information
장원정 committed Jan 16, 2025
commit e51d8e3df0a0ed6786bc20a9e68a71523c9368bf
4 changes: 2 additions & 2 deletions src/refactoring/app/providers/CouponContextProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ const initialCoupons: ICoupon[] = [
},
];

export interface ICouponContextType {
export interface ICouponContext {
coupons: ICoupon[];
addCoupon: (coupon: ICoupon) => void;
}

export const CouponContext = createContext<ICouponContextType | undefined>(
export const CouponContext = createContext<ICouponContext | undefined>(
undefined,
);

Expand Down
4 changes: 2 additions & 2 deletions src/refactoring/app/providers/ProductContextProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ const initialProducts: IProduct[] = [
},
];

export interface IProductContextType {
export interface IProductContext {
products: IProduct[];
updateProduct: (product: IProduct) => void;
addProduct: (product: IProduct) => void;
}

export const ProductContext = createContext<IProductContextType | undefined>(
export const ProductContext = createContext<IProductContext | undefined>(
undefined,
);

Expand Down
4 changes: 2 additions & 2 deletions src/refactoring/features/coupon/ui/CouponSelector.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { SectionTitle } from '../../../shared/ui/typography';
import { useCouponContext } from '../../../entities/coupon/model';
import { useCartContext } from '../../../pages/cart/model';
import { useCartTotalContext } from '../../../pages/cart/ui/CartTotalContextProvider.tsx';

export function CouponSelector() {
const { coupons } = useCouponContext();
const { selectedCoupon, applyCoupon } = useCartContext();
const { selectedCoupon, applyCoupon } = useCartTotalContext();

return (
<>
Expand Down
6 changes: 4 additions & 2 deletions src/refactoring/features/order/ui/OrderSummary.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { SectionTitle } from '../../../shared/ui/typography';
import { useCartTotalContext } from '../../../pages/cart/ui/CartTotalContextProvider.tsx';
import { useCartContext } from '../../../pages/cart/model';

export function OrderSummary() {
const { calculateTotal } = useCartContext();
const { cart } = useCartContext();
const { calculateTotal } = useCartTotalContext();
const { totalBeforeDiscount, totalAfterDiscount, totalDiscount } =
calculateTotal();
calculateTotal(cart);

return (
<div className="mt-6 bg-white p-4 rounded shadow">
Expand Down
22 changes: 5 additions & 17 deletions src/refactoring/pages/cart/model/useCart.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
// useCart.ts
import { useState } from 'react';
import { CartItem, Coupon, Product } from '../../../../types.ts';
import { calculateCartTotal, updateCartItemQuantity } from '../lib/cart.ts';
import { updateCartItemQuantity } from '../lib/cart.ts';
import { ICartItem, IProduct } from '../../../shared/types';

export const useCart = () => {
const [cart, setCart] = useState<CartItem[]>([]);
const [selectedCoupon, setSelectedCoupon] = useState<Coupon | null>(null);
const [cart, setCart] = useState<ICartItem[]>([]);

const getRemainingStock = (product: Product) => {
const getRemainingStock = (product: IProduct) => {
const cartItem = cart.find((item) => item.product.id === product.id);
return product.stock - (cartItem?.quantity || 0);
};

const addToCart = (product: Product) => {
const addToCart = (product: IProduct) => {
const remainingStock = getRemainingStock(product);
if (remainingStock <= 0) return;

Expand Down Expand Up @@ -43,21 +42,10 @@ export const useCart = () => {
);
};

const applyCoupon = (coupon: Coupon) => {
setSelectedCoupon(coupon);
};

const calculateTotal = () => {
return calculateCartTotal(cart, selectedCoupon);
};

return {
cart,
addToCart,
removeFromCart,
updateQuantity,
applyCoupon,
calculateTotal,
selectedCoupon,
};
};
2 changes: 1 addition & 1 deletion src/refactoring/pages/cart/model/useCartContext.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useContext } from 'react';
import { CartContext } from '../../providers/CartContextProvider.tsx';
import { CartContext } from '../ui/CartContextProvider.tsx';

export const useCartContext = () => {
const context = useContext(CartContext);
Expand Down
18 changes: 18 additions & 0 deletions src/refactoring/pages/cart/model/useCartTotal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { useState } from 'react';
import { Coupon } from '../../../../types.ts';
import { calculateCartTotal } from '../lib/cart.ts';
import { ICartItem } from '../../../shared/types';

export const useCartTotal = () => {
const [selectedCoupon, setSelectedCoupon] = useState<Coupon | null>(null);

const applyCoupon = (coupon: Coupon) => {
setSelectedCoupon(coupon);
};

const calculateTotal = (cart: ICartItem[]) => {
return calculateCartTotal(cart, selectedCoupon);
};

return { selectedCoupon, applyCoupon, calculateTotal };
};
22 changes: 22 additions & 0 deletions src/refactoring/pages/cart/ui/CartContextProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { ICartItem, IProduct } from '../../../shared/types';
import React, { createContext } from 'react';
import { useCart } from '../model';

export interface ICartContext {
cart: ICartItem[];
addToCart: (item: IProduct) => void;
removeFromCart: (productId: string) => void;
updateQuantity: (productId: string, newQuantity: number) => void;
}

export const CartContext = createContext<ICartContext | undefined>(undefined);

export function CartContextProvider({
children,
}: {
children: React.ReactNode;
}) {
return (
<CartContext.Provider value={useCart()}>{children}</CartContext.Provider>
);
}
9 changes: 6 additions & 3 deletions src/refactoring/pages/cart/ui/CartPage.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { ProductList } from '../../../widgets/product/ui/ProductList.tsx';
import { CartView } from '../../../widgets/cart/ui/CartView.tsx';
import { CartContextProvider } from '../../providers/CartContextProvider.tsx';
import { CartContextProvider } from './CartContextProvider.tsx';
import { CartTotalContextProvider } from './CartTotalContextProvider.tsx';

export const CartPage = () => {
return (
<CartContextProvider>
<ProductList />
<CartView />
<CartTotalContextProvider>
<ProductList />
<CartView />
</CartTotalContextProvider>
</CartContextProvider>
);
};
39 changes: 39 additions & 0 deletions src/refactoring/pages/cart/ui/CartTotalContextProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { ICartItem, ICoupon } from '../../../shared/types';
import { createContext, useContext } from 'react';
import { useCartTotal } from '../model/useCartTotal.ts';

export interface ICartTotalContext {
applyCoupon: (coupon: ICoupon) => void;
calculateTotal: (cart: ICartItem[]) => {
totalBeforeDiscount: number;
totalAfterDiscount: number;
totalDiscount: number;
};
selectedCoupon: ICoupon | null;
}

export const CartTotalContext = createContext<ICartTotalContext | undefined>(
undefined,
);

export const useCartTotalContext = () => {
const context = useContext(CartTotalContext);
if (!context) {
throw new Error(
'useCartTotalContext must be used within CartTotalContextProvider',
);
}
return context;
};

export function CartTotalContextProvider({
children,
}: {
children: React.ReactNode;
}) {
return (
<CartTotalContext.Provider value={useCartTotal()}>
{children}
</CartTotalContext.Provider>
);
}
31 changes: 0 additions & 31 deletions src/refactoring/pages/providers/CartContextProvider.tsx

This file was deleted.