From a6d159ab1236eb42661fda772c3749eb0efc4ae6 Mon Sep 17 00:00:00 2001 From: hanseungyuun <166717941+hanseungyuun@users.noreply.github.com> Date: Mon, 16 Jun 2025 22:48:03 +0900 Subject: [PATCH 1/9] Update page.tsx --- src/app/mypage/page.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/app/mypage/page.tsx b/src/app/mypage/page.tsx index 93b3ba9..33d4a6a 100644 --- a/src/app/mypage/page.tsx +++ b/src/app/mypage/page.tsx @@ -1,7 +1,13 @@ +import React, { useContext } from 'react'; +import { Link } from 'react-router-dom'; +import { UserContext } from '../contexts/UserContext'; // UserContext의 경로 +import Header from '../components/layout/Header.tsx'; // Header 컴포넌트의 경로 + // 과제 1: 마이페이지 구현 export default function MyPage() { // 1.1. UserContext를 활용한 Mypage 구현 (UserContext에 아이디(userId: string), 나이(age: number), 핸드폰번호(phoneNumber: string) 추가) - + const { user } = userContext; + return (
{/* 1.2. Header Component를 재활용하여 Mypage Header 표기 (title: 마이페이지) */} From a3a8311868f8813856e0cb368c43226a075d0a5b Mon Sep 17 00:00:00 2001 From: hanseungyuun <166717941+hanseungyuun@users.noreply.github.com> Date: Mon, 16 Jun 2025 22:53:30 +0900 Subject: [PATCH 2/9] complete 1.1 --- src/app/mypage/page.tsx | 53 +++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/src/app/mypage/page.tsx b/src/app/mypage/page.tsx index 33d4a6a..12c7b95 100644 --- a/src/app/mypage/page.tsx +++ b/src/app/mypage/page.tsx @@ -1,20 +1,49 @@ import React, { useContext } from 'react'; import { Link } from 'react-router-dom'; -import { UserContext } from '../contexts/UserContext'; // UserContext의 경로 -import Header from '../components/layout/Header.tsx'; // Header 컴포넌트의 경로 +import { UserContext } from '../contexts/UserContext'; +import Header from '../components/layout/Header.tsx'; // 과제 1: 마이페이지 구현 export default function MyPage() { - // 1.1. UserContext를 활용한 Mypage 구현 (UserContext에 아이디(userId: string), 나이(age: number), 핸드폰번호(phoneNumber: string) 추가) - const { user } = userContext; - - return ( -
- {/* 1.2. Header Component를 재활용하여 Mypage Header 표기 (title: 마이페이지) */} -

마이페이지

- {/* Mypage 정보를 UserContext 활용하여 표시 (이름, 아이디, 나이, 핸드폰번호 모두 포함) */} + // 1.1. UserContext를 활용한 Mypage 구현 (UserContext에 아이디(userId: string), 나이(age: number), 핸드폰번호(phoneNumber: string) 추가) + const { user } = userContext; - {/* 1.3. 홈으로 가기 버튼 구현(Link or Router 활용) */} -
+ return ( +
+ {/* 1.2. Header Component를 재활용하여 Mypage Header 표기 (title: 마이페이지) */} +
+ {/* Mypage 정보를 UserContext 활용하여 표시 (이름, 아이디, 나이, 핸드폰번호 모두 포함) */} +
+

내 정보

+ +
+

+ 이름: + {user.name} +

+

+ 아이디: + {user.userId} +

+

+ 나이: + {user.age}세 +

+

+ 핸드폰번호: + {user.phoneNumber} +

+
+ + {/* 1.3. 홈으로 가기 버튼 구현(Link or Router 활용) */} +
+ + + +
+
+
); } From e3ab6fa006fa7ab611ce9022d8484c8fc3e3d79b Mon Sep 17 00:00:00 2001 From: hanseungyuun <166717941+hanseungyuun@users.noreply.github.com> Date: Mon, 16 Jun 2025 22:57:25 +0900 Subject: [PATCH 3/9] complete 1.1 --- src/context/UserContext.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/context/UserContext.tsx b/src/context/UserContext.tsx index e5d3f14..067e63a 100644 --- a/src/context/UserContext.tsx +++ b/src/context/UserContext.tsx @@ -8,6 +8,9 @@ interface User { name: string; // age: number // 추가하고 싶은 속성들 ... + userId: string; + age: number; + phoneNumber: string; } // UserContextType interface UserContextType { From 8cfab4de8dd510773a2c8e15e0d9a5315b5cb772 Mon Sep 17 00:00:00 2001 From: hanseungyuun <166717941+hanseungyuun@users.noreply.github.com> Date: Mon, 16 Jun 2025 23:02:39 +0900 Subject: [PATCH 4/9] Update ProductCart.tsx --- src/component/shopping/ProductCart.tsx | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/component/shopping/ProductCart.tsx b/src/component/shopping/ProductCart.tsx index a66c2b3..1feac34 100644 --- a/src/component/shopping/ProductCart.tsx +++ b/src/component/shopping/ProductCart.tsx @@ -1,4 +1,5 @@ // ProductCartPage.tsx +"use client"; import { useEffect, useState } from "react"; import ProductList from "./ProductList"; import { ProductItem } from "@/types/Product"; @@ -8,6 +9,11 @@ export default function ProductCart({ items }: { items: ProductItem[] }) { const [cart, setCart] = useState<{ [id: string]: number }>({}); // {"88159814281" : 1} const [showCart, setShowCart] = useState(false); // 과제 2.1 + useEffect(() => { + const hasItems = Object.keys(cart).length > 0; + setShowCart(hasItems); + }, [cart]); + // 카트에 담기 const handleAddToCart = (item: ProductItem, quantity: number) => { setCart((prev) => ({ @@ -15,12 +21,18 @@ export default function ProductCart({ items }: { items: ProductItem[] }) { [item.productId]: quantity, })); - localStorage.setItem(item.productId, quantity + ""); - localStorage.getItem(item.productId); + //localStorage.setItem(item.productId, quantity + ""); + //localStorage.getItem(item.productId); }; /* 과제 2-3: Cart 아이템 지우기 */ - const handleRemoveFromCart = () => {}; + const handleRemoveFromCart = (productIdToRemove: string) => { + setCart((prevCart) => { + const cartEntries = Object.entries(prevCart); + const filteredEntries = cartEntries.filter(([key, value]) => key !== productIdToRemove); + const newCart = Object.fromEntries(filteredEntries); + return newCart; + }; return (
From b6c2c574e563b311bf0bb0d71f5f9a72703cbf70 Mon Sep 17 00:00:00 2001 From: hanseungyuun <166717941+hanseungyuun@users.noreply.github.com> Date: Mon, 16 Jun 2025 23:05:11 +0900 Subject: [PATCH 5/9] Update SearchInput.tsx --- src/component/search/SearchInput.tsx | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/component/search/SearchInput.tsx b/src/component/search/SearchInput.tsx index aea7294..6ee3f10 100644 --- a/src/component/search/SearchInput.tsx +++ b/src/component/search/SearchInput.tsx @@ -1,8 +1,16 @@ "use client"; import { useSearch } from "@/context/SearchContext"; +import { useRef, useEffect } from "react"; export default function SearchInput() { const { query, setQuery, setResult } = useSearch(); + const inputRef = useRef(null); + + useEffect(() => { + if (inputRef.current) { + inputRef.current.focus(); + } + }, []); // 검색 기능 const search = async () => { @@ -19,13 +27,16 @@ export default function SearchInput() { }; // 2.2. SearchInput 컴포넌트가 최초 렌더링 될 때, input tag에 포커스 되는 기능 - const handleInputChange = () => {}; + const handleInputChange = (e: React.ChangeEvent) => { + setQuery(e.target.value); + }; // 과제 1-2-3: 페이지 최초 렌더링 시, input에 포커스 되는 기능 (useRef) return (
Date: Mon, 16 Jun 2025 23:06:52 +0900 Subject: [PATCH 6/9] Update CartList.tsx --- src/component/shopping/CartList.tsx | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/component/shopping/CartList.tsx b/src/component/shopping/CartList.tsx index adc8745..5a2360d 100644 --- a/src/component/shopping/CartList.tsx +++ b/src/component/shopping/CartList.tsx @@ -1,5 +1,6 @@ "use client"; import { ProductItem } from "@/types/Product"; +import { useRouter } from 'next/navigation'; interface Props { cart: { [productId: string]: number }; @@ -8,6 +9,8 @@ interface Props { } export default function CartList({ cart, products, onRemove }: Props) { + const router = useRouter(); + const cartItems = Object.entries(cart) .map(([id, quantity]) => { const product = products.find((p) => p.productId === id); @@ -21,7 +24,14 @@ export default function CartList({ cart, products, onRemove }: Props) { ); // 2.4 결제하기: "결제하기" 버튼을 클릭하면, 현재 장바구니에 담긴 상품을 확인해 **localStorage**에 저장 후, 결제완료(/checkout) 페이지로 이동한다. - const handleCheckout = () => {}; + const handleCheckout = () => { + if (cartItems.length === 0) { + alert("장바구니에 상품이 없습니다."); + return; + } + localStorage.setItem('checkoutItems', JSON.stringify(cartItems)); + router.push('/checkout'); + }; return (
@@ -62,6 +72,7 @@ export default function CartList({ cart, products, onRemove }: Props) { From 2230009f6809ccca146c5627f0625eb46e47a68c Mon Sep 17 00:00:00 2001 From: hanseungyuun <166717941+hanseungyuun@users.noreply.github.com> Date: Mon, 16 Jun 2025 23:11:36 +0900 Subject: [PATCH 7/9] Update page.tsx --- src/app/checkout/page.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/app/checkout/page.tsx b/src/app/checkout/page.tsx index 0d40153..90deb5c 100644 --- a/src/app/checkout/page.tsx +++ b/src/app/checkout/page.tsx @@ -1,5 +1,6 @@ // CheckoutPage -import { useState } from "react"; +import { useState, useEffect } from "react"; +import Link from 'next/link'; import { ProductItem } from "@/types/Product"; interface CheckoutItem { From 59b98b2d6f50ce86d8f6bb47a28277719cfea6d0 Mon Sep 17 00:00:00 2001 From: hanseungyuun <166717941+hanseungyuun@users.noreply.github.com> Date: Mon, 16 Jun 2025 23:12:53 +0900 Subject: [PATCH 8/9] Update CartList.tsx --- src/component/shopping/CartList.tsx | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/component/shopping/CartList.tsx b/src/component/shopping/CartList.tsx index 5a2360d..65baca9 100644 --- a/src/component/shopping/CartList.tsx +++ b/src/component/shopping/CartList.tsx @@ -29,7 +29,16 @@ export default function CartList({ cart, products, onRemove }: Props) { alert("장바구니에 상품이 없습니다."); return; } - localStorage.setItem('checkoutItems', JSON.stringify(cartItems)); + + const itemsToCheckout = cartItems.map(item => { + const { quantity, ...productDetails } = item; + return { + product: productDetails, + quantity: quantity + }; + }); + + localStorage.setItem('checkoutItems', JSON.stringify(itemsToChechout)); router.push('/checkout'); }; From f61d834143b962e7768382d4f836eb08e60c357e Mon Sep 17 00:00:00 2001 From: hanseungyuun <166717941+hanseungyuun@users.noreply.github.com> Date: Mon, 16 Jun 2025 23:15:44 +0900 Subject: [PATCH 9/9] Update page.tsx --- src/app/checkout/page.tsx | 52 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/src/app/checkout/page.tsx b/src/app/checkout/page.tsx index 90deb5c..cf97e36 100644 --- a/src/app/checkout/page.tsx +++ b/src/app/checkout/page.tsx @@ -10,13 +10,63 @@ interface CheckoutItem { // 과제 3 export default function CheckoutPage() { const [items, setItems] = useState([]); + const [totalPrice, setTotalPrice] = useState(0); // 3.1. 결제하기 구현 + + useEffect(() => { + const storedItemsJSON = localStorage.getItem('checkoutItems'); + + if (storedItemsJSON) { + const parsedItems: CheckoutItem[] = JSON.parse(storedItemsJSON); + setItems(parsedItems); + + const total = parsedItems.reduce((sum, item) => { + return sum + (Number(item.product.lprice) * item.quantity); + }, 0); + setTotalPrice(total); + + localStorage.removeItem('checkoutItems'); + } + }, []); + return (

✅ 결제가 완료되었습니다!

{/* 3.1. 결제하기 구현 */} -
+ {items.length === 0 ? ( +

결제된 아이템이 없습니다.

+ ) : ( +
+

결제 내역

+
    + {items.map((item) => ( +
  • +
    +

    +

    + {Number(item.product.lprice).toLocaleString()}원 x {item.quantity}개 +

    +
    +

    + {(Number(item.product.lprice) * item.quantity).toLocaleString()}원 +

    +
  • + ))} +
+
+ 총 결제 금액: + {totalPrice.toLocaleString()}원 +
+
+ )} {/* 3.2. 홈으로 가기 버튼 구현 */} +
+ + + +
); }