앞서 말했듯 작성한 글은 로컬에서 돌린걸 기준으로 작성했다
프로그래머스에선 제한 시간이 있어서 로컬에서 돌릴 방법을 찾다 발견한 레포다
https://github.com/ChangHyun2/programmers-vanillaJS-SPA
로컬에서 돌려보고 싶다면 참조하자
localStorage에 장바구니 데이터가 비어있으면 alert 출력 후 상품 목록 페이지로 라우팅 처리를 해야한다
CartPage의 코드를 변경해보자
import { routeChange } from "../router.js";
import { getItem } from "../storage.js";
function CartPage({ $app }) {
const $page = document.createElement("div");
$page.className = "CartPage";
$page.innerHTML = `<h1>장바구니</h1>`;
const cartData = getItem("products_cart", []);
this.state = {
products: null,
};
this.render = () => {
if (cartData.length === 0) {
// 카트가 비었을 때
alert("장바구니가 비었습니다.");
routeChange("/coffee/index.html");
} else {
// 카트에 상품이 담겼을 때
$app.appendChild($page);
}
};
}
export default CartPage;
import { getIdProduct } from "../apis/api.js";
import Cart from "../components/Cart.js";
import { routeChange } from "../router.js";
import { getItem } from "../storage.js";
function CartPage({ $app }) {
const $page = document.createElement("div");
$page.className = "CartPage";
$page.innerHTML = `<h1>장바구니</h1>`;
const cartData = getItem("products_cart", []);
// 새로 추가한 부분
let cartComponent = null;
this.render = () => {
if (cartData.length === 0) {
alert("장바구니가 비었습니다.");
routeChange("/coffee/index.html");
} else {
$app.appendChild($page);
// this.state.products와 cartComponent가 null이 아닐 때 Cart 컴포넌트 생성
if (this.state.products && !cartComponent) {
cartComponent = new Cart({
$target: $page,
initialState: this.state.products,
});
}
}
};
this.state = {
products: null,
};
// 새로 추가한 부분
this.setState = (nextState) => {
this.state = nextState;
this.render();
};
this.fetchProducts = async () => {
const products = await Promise.all(
cartData.map(async (item) => {
const product = await getIdProduct(item.productId);
const selectedOption = product.productOptions.find((option) => option.id === item.optionId);
return {
imageUrl: product.imageUrl,
productName: product.name,
quantity: item.quantity,
productPrice: product.price,
optionName: selectedOption.name,
optionPrice: selectedOption.price,
};
})
);
this.setState({ products });
};
this.fetchProducts();
}
export default CartPage;
실제 장바구니를 그릴 부분
<div class="Cart"> <ul> <li class="Cart__item"> <img src="https://grepp-cloudfront.s3.ap-northeast-2.amazonaws.com/programmers_imgs/assignment_image/cafe_coffee_cup.png" /> <div class="Cart__itemDesription"> <div>커피잔 100개 번들 10,000원 10개</div> <div>100,000원</div> </div> </li> </ul> <div class="Cart__totalPrice">총 상품가격 175,000원</div> <button class="OrderButton">주문하기</button> </div>
function Cart({ $target, initialState }) {
const $component = document.createElement("div");
$component.className = "Cart";
this.state = initialState;
$target.appendChild($component);
this.setState = (nextState) => {
this.state = nextState;
this.render();
};
// 총 가격
this.getTotalPrice = () => {
return this.state.reduce((acc, option) => acc + (option.productPrice + option.optionPrice) * option.quantity, 0);
};
this.render = () => {
$component.innerHTML = `<ul>
${this.state
.map(
(item) => `
<li class="Cart__item">
<img
src="${item.imageUrl}"
/>
<div class="Cart__itemDesription">
<div>${item.productName} ${item.productName} ${item.quantity}</div>
<div>${item.productPrice + item.optionPrice}</div>
</div>
</li>`
)
.join("")}
</ul>
<div class="Cart__totalPrice">총 상품가격 ${this.getTotalPrice()}</div>
<button class="OrderButton">주문하기</button>`;
return $component;
};
$component.addEventListener("click", (event) => {
if (event.target.className === "OrderButton") {
alert("주문 되었습니다!");
removeItem("products_cart");
routeChange("/coffee/index.html");
}
});
this.render();
}
export default Cart;
그럼 그림과 같이 잘 그려지고 주문이 완료되면 목록으로 리다이렉팅되는 것을 확인할 수 있다
다음에 시간이 되면 다른 문제도 풀어보고 오답노트를 작성해봐야겠다!