-
Notifications
You must be signed in to change notification settings - Fork 50
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_김시현_5주차 과제 #251
전남대FE_김시현_5주차 과제 #251
Changes from all commits
1a2312f
33e2dda
4fbb895
4a3ae56
3fac059
fa56abd
0cf6cb8
1a02be3
036921b
70eeed1
80d48f6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export default { | ||
testEnvironment: "node", | ||
testMatch: ["**/*.test.js"], | ||
extensionsToTreatAsEsm: [".js", ".jsx", ".mjs"], | ||
}; |
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -284,3 +284,11 @@ | |
.cartpage { | ||
margin-top: 80px; | ||
} | ||
|
||
.orderpage { | ||
margin-top: 80px; | ||
} | ||
|
||
.orderCompletepage { | ||
margin-top: 80px; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { render, screen, fireEvent } from "@testing-library/react"; | ||
import OrderTemplate from "./templates/OrderTemplate"; | ||
|
||
describe("OrderTemplate 컴포넌트 테스트", () => { | ||
it("주문하기 버튼 클릭 시 handleClickOrder 함수가 호출되는지 확인", () => { | ||
const data = { | ||
data: { | ||
response: { | ||
products: [ | ||
{ | ||
productName: "상품 1", | ||
carts: [ | ||
{ | ||
id: 1, | ||
option: { | ||
optionName: "옵션 1", | ||
}, | ||
quantity: 2, | ||
price: 1000, | ||
}, | ||
], | ||
}, | ||
], | ||
totalPrice: 2000, | ||
}, | ||
}, | ||
}; | ||
|
||
render(<OrderTemplate data={data} />); | ||
const orderButton = screen.getByText("결제하기"); | ||
|
||
fireEvent.click(orderButton); | ||
|
||
console.log("handleClickOrder 함수가 호출되었습니다."); | ||
}); | ||
|
||
// 여기에 추가적인 테스트를 작성할 수 있습니다. | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import React from "react"; | ||
|
||
const Footer = () => { | ||
return ( | ||
<div> | ||
<span | ||
style={{ | ||
display: "block", | ||
color: "#a6a6a6", | ||
fontSize: "12px", | ||
padding: "20px 100px", | ||
}} | ||
> | ||
(주)카카오대표이사 : 홍은택주소 : 제주특별자치도 제주시 첨단로 242{" "} | ||
<br /> | ||
사업자등록번호 : 120-81-47521통신판매업신고 : 제2015 - 제주아라 - | ||
0032호호스팅 사업자 : <br /> | ||
(주)카카오 이메일 : cs.shopping@kakaocorp.com <br /> | ||
고객센터 : 1544-5664 (통화료 발생 / 평일 09:00~18:00) 톡상담하기 (평일 | ||
09:00~18:00) Copyright © Kakao Corp. All rights reserved | ||
<br /> | ||
(주)카카오에서 판매하는 상품 중에는 개별판매자가 판매하는 상품이 | ||
포함되어 있습니다. 개별판매자가 판매하는 상품에 대해 (주)카카오는 | ||
통신중개판매업자로서 통신판매의 당사자가 아니며 상품의 주문, 배송 및 | ||
환불 등과 관련한 의무와 책임은 각 판매자에게 있습니다. | ||
</span> | ||
</div> | ||
); | ||
}; | ||
|
||
export default Footer; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import React from "react"; | ||
|
||
const OrderCompleteTemplate = () => { | ||
return ( | ||
<div className="orderComplete-container"> | ||
<div className="complete-innerwrap"> | ||
<div className="complete-messagebox"> | ||
<div className="complete-messages"> | ||
<span className="complete-num">주문번호 : 12345678abc</span> | ||
<span className="message1">구매완료!</span> | ||
<span className="message2">구매가 정상적으로 완료되었습니다.</span> | ||
</div> | ||
<div className="complete-next-buttons"> | ||
<button className="next-button1">전체 주문 내역</button> | ||
<button className="next-button2">쇼핑 계속하기</button> | ||
</div> | ||
</div> | ||
|
||
<div className="complete-info" id="complete-deliveryinfo"> | ||
<div className="complete-info-tit"> | ||
<span>배송지 정보</span> | ||
</div> | ||
<div className="complete-info-content"></div> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default OrderCompleteTemplate; |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,205 @@ | ||||||
import { useMutation } from "react-query"; | ||||||
import { comma } from "../../utils/convert"; | ||||||
import { order } from "../../services/order"; | ||||||
import { useNavigate } from "react-router-dom"; | ||||||
import { useRef, useState } from "react"; | ||||||
import "../../styles/template/OrderTemplate.css"; | ||||||
|
||||||
const OrderTemplate = ({ data }) => { | ||||||
console.log("넘어옴"); | ||||||
|
||||||
const { products, totalPrice } = data?.data?.response; | ||||||
const navigate = useNavigate(); | ||||||
|
||||||
const [agreePayment, setAgreePayment] = useState(false); | ||||||
const [agreePolicy, setAgreePolicy] = useState(false); | ||||||
|
||||||
//useRef에 null을 넣어줘야 작동 이상 없음! | ||||||
const agreeAllRef = useRef(null); | ||||||
const agreePaymentRef = useRef(null); | ||||||
const agreePolicyRef = useRef(null); | ||||||
|
||||||
const { mutate } = useMutation({ | ||||||
mutationKey: "order", | ||||||
mutationFn: order, | ||||||
onError: (error) => { | ||||||
// 404 에러 발생 시 error 페이지로 이동 | ||||||
if (error?.response?.status === 404) { | ||||||
navigate("/error"); | ||||||
} else if (error?.response?.status === 401) { | ||||||
// 사용자 정보 유실 에러 (예: 토큰 만료 등) | ||||||
// 로그인 페이지로 이동 | ||||||
navigate("/login"); | ||||||
} else { | ||||||
// 기타 에러 처리 | ||||||
alert("주문에 실패했습니다🥲"); | ||||||
} | ||||||
}, | ||||||
onSuccess: (res) => { | ||||||
const id = res.data.response.id; | ||||||
alert("주문이 완료되었습니다!😉"); | ||||||
navigate(`/orders/complete/${id}`); | ||||||
}, | ||||||
}); | ||||||
|
||||||
const handleClickOrder = () => { | ||||||
// 동의 하나라도 안이루어진 경우 | ||||||
if (agreePayment === false || agreePolicy === false) { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
이렇게 바꿔줄 수 있겠습니다. |
||||||
alert("모든 항목에 동의가 필요합니다!🙏🏻"); | ||||||
return; | ||||||
} | ||||||
// 주문 로직을 실행하고 결과를 처리하기 위해 mutate 호출 | ||||||
mutate(); | ||||||
}; | ||||||
|
||||||
const handleAgreeAll = (e) => { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 여기도 변수명에서 click 이벤트에 대한 핸들러 인지 알 수 있게 해주면 좋을 것 같아요. |
||||||
const value = e.target.checked; | ||||||
// 전체 동의가 선택되면 나머지도 한번에 체크 | ||||||
setAgreePayment(value); | ||||||
setAgreePolicy(value); | ||||||
}; | ||||||
|
||||||
const handleAgreement = (e) => { | ||||||
console.log(e.target.checked); | ||||||
const { name, checked } = e.target; | ||||||
if (name === "agree-payment") { | ||||||
setAgreePayment(checked); | ||||||
} else if (name === "agree-policy") { | ||||||
setAgreePolicy(checked); | ||||||
} | ||||||
}; | ||||||
|
||||||
// OrderItems | ||||||
const OrderItems = () => { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 부분은 다른분들이랑 같은 의견 드리겠습니다. 이 컴포넌트는 별도로 분리해주시면 가독성 측면에서 더 좋겠습니다. 현업에서는 소나큐브 같은 도구를 활용해서 코드의 복잡도를 분석하고, let renderComponent = []; |
||||||
let renderComponent = []; | ||||||
//각각 상품들 | ||||||
products.forEach((item) => { | ||||||
// item: 각각의 상품. carts: 옵션들의 모임 | ||||||
// 상품하나에 대한 각각의 옵션들 | ||||||
renderComponent.push( | ||||||
item.carts.map((cart) => { | ||||||
return ( | ||||||
<div key={cart.id} className="order-option"> | ||||||
<div className="namegroup"> | ||||||
<span className="material-symbols-outlined">storefront</span> | ||||||
<span className="prodcut-name">{`${item.productName}`}</span> | ||||||
</div> | ||||||
<div className="optionNamegroup"> | ||||||
<span className="option-name">{`[옵션]${cart.option.optionName}`}</span> | ||||||
<span className="product-quantity"> | ||||||
{comma(cart.quantity)}개 | ||||||
</span> | ||||||
</div> | ||||||
|
||||||
<div className="option-price"> | ||||||
<span>{comma(cart.price * cart.quantity)}원</span> | ||||||
</div> | ||||||
</div> | ||||||
); | ||||||
}) | ||||||
); | ||||||
}); | ||||||
|
||||||
return renderComponent; | ||||||
}; | ||||||
|
||||||
return ( | ||||||
<div className="order-container"> | ||||||
<div className="order-innerwrap"> | ||||||
<div className="order-top"> | ||||||
<span>주문하기</span> | ||||||
</div> | ||||||
|
||||||
<div className="order-delivery-info"> | ||||||
<span className="info-title">배송지 정보</span> | ||||||
<span>(kakao계정정보)</span> | ||||||
|
||||||
<div className="delivery-customer-info"> | ||||||
<span className="name">춘식이</span> | ||||||
<span className="destination">기본배송지</span> | ||||||
<p className="number">010-1234-5678</p> | ||||||
<p className="address"> | ||||||
(12345)판교 카카오로 가는길 1 <br /> (쿠키즈동, 춘식팰리스) | ||||||
101-111 | ||||||
</p> | ||||||
</div> | ||||||
</div> | ||||||
|
||||||
<div className="order-info"> | ||||||
<div className="order-product-info"> | ||||||
<span className="info-title">주문상품정보</span> | ||||||
{/* 각 주문 정보 */} | ||||||
<OrderItems /> | ||||||
<div className="order-total-price"> | ||||||
<span>총 주문 금액</span> | ||||||
<span className="won">{comma(totalPrice)}원</span> | ||||||
</div> | ||||||
</div> | ||||||
</div> | ||||||
|
||||||
<div className="order-info"> | ||||||
<div className="order-agree"> | ||||||
<div className="agree-title"> | ||||||
<input | ||||||
type="checkbox" | ||||||
id="agree-all" | ||||||
className="check" | ||||||
ref={agreeAllRef} | ||||||
checked={agreePayment && agreePolicy} | ||||||
onChange={handleAgreeAll} | ||||||
/> | ||||||
<label htmlFor="agree-all"> | ||||||
<span>전체 동의</span> | ||||||
</label> | ||||||
</div> | ||||||
<div className="agree-group"> | ||||||
<div className="check"> | ||||||
<input | ||||||
type="checkbox" | ||||||
id="agree-1" | ||||||
name="agree-payment" | ||||||
ref={agreePaymentRef} | ||||||
checked={agreePayment} | ||||||
onChange={handleAgreement} | ||||||
/> | ||||||
<label htmlFor="agree-1"> | ||||||
<span> 구매조건 확인 및 결제 진행 동의</span> | ||||||
</label> | ||||||
</div> | ||||||
<div className="check"> | ||||||
<input | ||||||
type="checkbox" | ||||||
id="agree-2" | ||||||
name="agree-policy" | ||||||
ref={agreePolicyRef} | ||||||
checked={agreePolicy} | ||||||
onChange={handleAgreement} | ||||||
/> | ||||||
<label htmlFor="agree-2"> | ||||||
<span> 개인정보 제3자 제공 동의</span> | ||||||
</label> | ||||||
</div> | ||||||
</div> | ||||||
</div> | ||||||
</div> | ||||||
|
||||||
<div className="order-bottom"> | ||||||
<div className="legal-notice"> | ||||||
<span>법적고지</span> | ||||||
<br /> | ||||||
<span> | ||||||
(주)카카오에서 판매하는 상품 중에는 개별 판매자가 판매하는 상품이 | ||||||
포함되어 있습니다. 개별 판매자가 판매하는 상품에 대해 (주)카카오는 | ||||||
통신중개 판매업자로서 통신판매의 당사자가 아니며 상품의 주문, 배송 | ||||||
및 환불 등과 관련한 의무와 책임은 각 판매자에게 있습니다. | ||||||
</span> | ||||||
</div> | ||||||
<button className="checkout-btn" onClick={handleClickOrder}> | ||||||
결제하기 | ||||||
</button> | ||||||
</div> | ||||||
</div> | ||||||
</div> | ||||||
); | ||||||
}; | ||||||
export default OrderTemplate; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 ref 변수는 현재 존재하는 이유가 없는 것 같은데 지워주는게 어떨까요?