[checkoutPanel] confirmPanel UI 작업 및 checkoutPanel 예외 처리
This commit is contained in:
@@ -8,23 +8,26 @@ import Spotlight from "@enact/spotlight";
|
||||
import {
|
||||
getCheckoutTotalAmtDummy,
|
||||
getMyInfoCheckoutInfo,
|
||||
getTaxInfos,
|
||||
resetCheckoutData,
|
||||
} from "../../actions/checkoutActions";
|
||||
import { changeAppStatus } from "../../actions/commonActions";
|
||||
import {
|
||||
changeAppStatus,
|
||||
setHidePopup,
|
||||
setShowPopup,
|
||||
} from "../../actions/commonActions";
|
||||
import { getShoptimeTerms } from "../../actions/empActions";
|
||||
import { popPanel } from "../../actions/panelActions";
|
||||
import TBody from "../../components/TBody/TBody";
|
||||
import TButtonScroller from "../../components/TButtonScroller/TButtonScroller";
|
||||
import TButtonTab from "../../components/TButtonTab/TButtonTab";
|
||||
import TFullPopup from "../../components/TFullPopup/TFullPopup";
|
||||
import THeader from "../../components/THeader/THeader";
|
||||
import TPanel from "../../components/TPanel/TPanel";
|
||||
import TScroller from "../../components/TScroller/TScroller";
|
||||
import TPopUp from "../../components/TPopUp/TPopUp";
|
||||
import useScrollTo from "../../hooks/useScrollTo";
|
||||
import { $L } from "../../utils/helperMethods";
|
||||
import * as Config from "../../utils/Config";
|
||||
import { $L, scaleH, scaleW } from "../../utils/helperMethods";
|
||||
import css from "./CheckOutPanel.module.less";
|
||||
import CheckoutQRCode from "./components/CheckoutQRCode";
|
||||
import CheckOutTerms from "./components/CheckOutTerms";
|
||||
import PinCode from "./components/PinCode";
|
||||
import PinCodeInput from "./components/PinCodeInput";
|
||||
import FixedSideBar from "./container/FixedSideBar";
|
||||
import InformationContainer from "./container/InformationContainer";
|
||||
@@ -49,11 +52,19 @@ export default function CheckOutPanel() {
|
||||
const selectedCoupons = useSelector(
|
||||
(state) => state.checkout.selectedCoupons
|
||||
);
|
||||
const empTermsData = useSelector((state) => state.emp.empTermsData.terms);
|
||||
const { popupVisible, activePopup } = useSelector(
|
||||
(state) => state.common.popup
|
||||
);
|
||||
|
||||
const [orderSideBarOpen, setOrderSideBarOpen] = useState(false);
|
||||
const [offerSideBarOpen, setOfferSideBarOpen] = useState(false);
|
||||
const [placeOrderPopup, setPlaceOrderPopup] = useState(false);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [currentTerms, setCurrentTerms] = useState(null);
|
||||
const [tabList, setTabList] = useState([]);
|
||||
const [selectedTabIndex, setSelectedTabIndex] = useState(0);
|
||||
const [resetScroll, setResetScroll] = useState(false);
|
||||
|
||||
const isMounted = useRef(true);
|
||||
|
||||
@@ -149,6 +160,18 @@ export default function CheckOutPanel() {
|
||||
}
|
||||
}, [dispatch, infoForCheckoutData, productData, userNumber, selectedCoupons]);
|
||||
|
||||
useEffect(() => {
|
||||
const newTabList = [];
|
||||
|
||||
if (empTermsData) {
|
||||
empTermsData.forEach((term) => {
|
||||
newTabList.push(term.termsTypeName);
|
||||
});
|
||||
|
||||
setTabList(newTabList);
|
||||
}
|
||||
}, [empTermsData]);
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
dispatch(resetCheckoutData());
|
||||
@@ -180,6 +203,53 @@ export default function CheckOutPanel() {
|
||||
setPlaceOrderPopup(false);
|
||||
}, []);
|
||||
|
||||
const onCloseTermsPopup = useCallback(() => {
|
||||
dispatch(setHidePopup());
|
||||
}, [dispatch]);
|
||||
|
||||
const handleTermsClick = useCallback(
|
||||
(termsID) => {
|
||||
if (empTermsData) {
|
||||
const selectedTerms = empTermsData.find(
|
||||
(term) => term.termsID === termsID
|
||||
);
|
||||
|
||||
setCurrentTerms(selectedTerms);
|
||||
dispatch(setShowPopup(Config.ACTIVE_POPUP.termsPopup));
|
||||
|
||||
const selectedIndex = empTermsData.findIndex(
|
||||
(term) => term.termsID === termsID
|
||||
);
|
||||
|
||||
setSelectedTabIndex(selectedIndex);
|
||||
setResetScroll(true);
|
||||
}
|
||||
},
|
||||
[empTermsData, dispatch]
|
||||
);
|
||||
|
||||
const handleTabClick = useCallback(({ index }) => {
|
||||
setSelectedTabIndex(index);
|
||||
setResetScroll(true);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (empTermsData && empTermsData[selectedTabIndex]) {
|
||||
setCurrentTerms(empTermsData[selectedTabIndex]);
|
||||
setResetScroll(true);
|
||||
}
|
||||
}, [selectedTabIndex, empTermsData]);
|
||||
|
||||
useEffect(() => {
|
||||
if (resetScroll) {
|
||||
setResetScroll(false);
|
||||
}
|
||||
}, [resetScroll]);
|
||||
|
||||
useEffect(() => {
|
||||
Spotlight.focus();
|
||||
}, [popupVisible]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<TPanel
|
||||
@@ -194,14 +264,17 @@ export default function CheckOutPanel() {
|
||||
onClick={onBackClick}
|
||||
/>
|
||||
<div className={css.Wrap}>
|
||||
<SummaryContainer setPlaceOrderPopup={setPlaceOrderPopup} />
|
||||
<SummaryContainer
|
||||
setPlaceOrderPopup={setPlaceOrderPopup}
|
||||
empTermsData={empTermsData}
|
||||
handleTermsClick={handleTermsClick}
|
||||
/>
|
||||
<InformationContainer
|
||||
toggleOrderSideBar={toggleOrderSideBar}
|
||||
toggleOfferSideBar={toggleOfferSideBar}
|
||||
scrollTopBody={scrollTopBody}
|
||||
/>
|
||||
</div>
|
||||
{/* <CheckoutQRCode open={false} /> */}
|
||||
</TBody>
|
||||
</TPanel>
|
||||
|
||||
@@ -210,6 +283,42 @@ export default function CheckOutPanel() {
|
||||
)}
|
||||
{offerSideBarOpen && <FixedSideBar closeSideBar={toggleOfferSideBar} />}
|
||||
|
||||
{activePopup === Config.ACTIVE_POPUP.termsPopup && (
|
||||
<TPopUp
|
||||
kind="introTermsPopup"
|
||||
open={popupVisible}
|
||||
onClose={onCloseTermsPopup}
|
||||
hasButton
|
||||
button1Text={$L("OK")}
|
||||
>
|
||||
{currentTerms && (
|
||||
<div className={css.termsConts}>
|
||||
<TButtonTab
|
||||
className={css.tab}
|
||||
selectedIndex={selectedTabIndex}
|
||||
onItemClick={handleTabClick}
|
||||
contents={tabList}
|
||||
role="button"
|
||||
/>
|
||||
<TButtonScroller
|
||||
boxHeight={scaleH(300)}
|
||||
width={scaleW(980)}
|
||||
className={css.termsDescription}
|
||||
resetScrollPosition={resetScroll}
|
||||
forcedFocus={false}
|
||||
>
|
||||
<div
|
||||
className={css.termsDesc}
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: currentTerms && currentTerms.termContent,
|
||||
}}
|
||||
></div>
|
||||
</TButtonScroller>
|
||||
</div>
|
||||
)}
|
||||
</TPopUp>
|
||||
)}
|
||||
|
||||
<TFullPopup
|
||||
open={placeOrderPopup}
|
||||
className={css.pinCodePopup}
|
||||
|
||||
@@ -22,3 +22,29 @@
|
||||
position: fixed;
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.termsConts {
|
||||
background-color: #f8f8f8;
|
||||
|
||||
> div:nth-child(2) {
|
||||
background-color: @COLOR_WHITE;
|
||||
.border-solid(1px,@COLOR_GRAY02);
|
||||
width: 980px;
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.termsDesc {
|
||||
padding: 30px;
|
||||
min-height: 300px;
|
||||
color: @COLOR_GRAY03;
|
||||
font-size: 24px;
|
||||
line-height: 1.27;
|
||||
letter-spacing: normal;
|
||||
text-align: left;
|
||||
.flex( @direction:column, @justifyCenter:flex-start,@alignCenter:flex-start);
|
||||
}
|
||||
|
||||
.tab {
|
||||
width: 980px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ export default function PinCodeInput({ setPlaceOrderPopup }) {
|
||||
const userNumber = useSelector(
|
||||
(state) => state.common.appStatus.loginUserData.userNumber
|
||||
);
|
||||
|
||||
const addrInfo = useSelector((state) => state.checkout?.infoForCheckoutData);
|
||||
const selectedCoupons = useSelector(
|
||||
(state) => state.checkout?.selectedCoupons
|
||||
@@ -45,6 +46,9 @@ export default function PinCodeInput({ setPlaceOrderPopup }) {
|
||||
const productList = useSelector(
|
||||
(state) => state.checkout?.checkoutData?.productList?.[0]
|
||||
);
|
||||
const auctProdYn = useSelector(
|
||||
(state) => state.checkout?.checkoutData?.productList?.[0].auctProdYn
|
||||
);
|
||||
|
||||
const [pin, setPin] = useState(["", "", "", ""]);
|
||||
const [errorMsg, setErrorMsg] = useState("");
|
||||
@@ -173,12 +177,14 @@ export default function PinCodeInput({ setPlaceOrderPopup }) {
|
||||
if (!isMounted.current) return;
|
||||
|
||||
if (response.data.retCode === 0) {
|
||||
dispatch(resetPanels());
|
||||
setPlaceOrderPopup(false);
|
||||
dispatch(
|
||||
pushPanel({
|
||||
name: Config.panel_names.CONFIRM_PANEL,
|
||||
panelInfos: response.data.data,
|
||||
panelInfo: {
|
||||
orderInfo: response.data.data,
|
||||
auctProdYn: auctProdYn,
|
||||
},
|
||||
})
|
||||
);
|
||||
} else {
|
||||
@@ -209,6 +215,7 @@ export default function PinCodeInput({ setPlaceOrderPopup }) {
|
||||
selectedCoupons,
|
||||
productList,
|
||||
isMounted,
|
||||
auctProdYn,
|
||||
dispatch,
|
||||
]);
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 31px 59px 0 61px;
|
||||
margin-bottom: 147px;
|
||||
margin-bottom: 120px;
|
||||
> div {
|
||||
font-weight: bold;
|
||||
font-size: 30px;
|
||||
@@ -69,19 +69,31 @@
|
||||
.bottom {
|
||||
padding: 0 60px;
|
||||
|
||||
.checkboxWrap {
|
||||
.termsWrap {
|
||||
.termsList {
|
||||
margin-bottom: 30px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.checkbox {
|
||||
}
|
||||
|
||||
.contents {
|
||||
font-weight: normal;
|
||||
font-size: 24px;
|
||||
.termsTypeName {
|
||||
display: inline-block;
|
||||
.font(@fontFamily: @baseFont, @fontSize: 24px);
|
||||
color: #009cff;
|
||||
text-decoration: underline;
|
||||
transform: translateY(-3px);
|
||||
.elip(@clamp: 1);
|
||||
width: 332px;
|
||||
}
|
||||
|
||||
.viewAllButton {
|
||||
margin-left: 25px;
|
||||
min-width: unset;
|
||||
max-width: unset;
|
||||
width: 124px;
|
||||
height: 40px;
|
||||
font-size: 24px;
|
||||
line-height: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,10 @@ import { useDispatch, useSelector } from "react-redux";
|
||||
|
||||
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
|
||||
|
||||
import { setShowPopup } from "../../../actions/commonActions";
|
||||
import TButton from "../../../components/TButton/TButton";
|
||||
import * as Config from "../../../utils/Config";
|
||||
import { $L } from "../../../utils/helperMethods";
|
||||
import css from "./SummaryContainer.module.less";
|
||||
|
||||
const Container = SpotlightContainerDecorator(
|
||||
@@ -12,7 +15,11 @@ const Container = SpotlightContainerDecorator(
|
||||
"div"
|
||||
);
|
||||
|
||||
export default function SummaryContainer({ setPlaceOrderPopup }) {
|
||||
export default function SummaryContainer({
|
||||
setPlaceOrderPopup,
|
||||
empTermsData,
|
||||
handleTermsClick,
|
||||
}) {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const priceTotalData = useSelector(
|
||||
@@ -54,12 +61,31 @@ export default function SummaryContainer({ setPlaceOrderPopup }) {
|
||||
<div className={css.price}>{priceTotalData?.ordPmtReqAmt || "-"}</div>
|
||||
</div>
|
||||
<div className={css.bottom}>
|
||||
<ul className={css.termsWrap}>
|
||||
{empTermsData &&
|
||||
empTermsData.length > 0 &&
|
||||
empTermsData.map((term) => {
|
||||
const { termsID, termsTypeName } = term;
|
||||
|
||||
return (
|
||||
<li key={termsID} className={css.termsList}>
|
||||
<span className={css.termsTypeName}>{termsTypeName}</span>
|
||||
<TButton
|
||||
className={css.viewAllButton}
|
||||
onClick={() => handleTermsClick(termsID)}
|
||||
>
|
||||
{$L("View All")}
|
||||
</TButton>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
<TButton
|
||||
className={css.tButton}
|
||||
onClick={handleClickOrder}
|
||||
spotlightId="spotlightId_placeOrderBtn"
|
||||
>
|
||||
{"PLACE ORDER"}
|
||||
{$L("PLACE ORDER")}
|
||||
</TButton>
|
||||
</div>
|
||||
</Container>
|
||||
|
||||
@@ -1,12 +1,141 @@
|
||||
import React from "react";
|
||||
import React, { useCallback } from "react";
|
||||
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
|
||||
import { popPanel, pushPanel, resetPanels } from "../../actions/panelActions";
|
||||
import TButton from "../../components/TButton/TButton";
|
||||
import TPanel from "../../components/TPanel/TPanel";
|
||||
import * as Config from "../../utils/Config";
|
||||
import { $L } from "../../utils/helperMethods";
|
||||
import css from "./ConfirmPanel.module.less";
|
||||
|
||||
export default function ConfirmPanel({ spotlightId }) {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const panels = useSelector((state) => state.panels.panels);
|
||||
const panelInfo = panels.find(
|
||||
(panel) => panel.name === "confirmpanel"
|
||||
)?.panelInfo;
|
||||
const {
|
||||
bilCityNm,
|
||||
bilCtpt,
|
||||
bilDtlAddr,
|
||||
bilEmalAddr,
|
||||
bilOdrFnm,
|
||||
bilOdrLnm,
|
||||
bilStatNm,
|
||||
bilZpcd,
|
||||
cardKnd,
|
||||
dlvrCityNm,
|
||||
dlvrCtpt,
|
||||
dlvrDate,
|
||||
dlvrDtlAddr,
|
||||
dlvrEmalAddr,
|
||||
dlvrOdrFnm,
|
||||
dlvrOdrLnm,
|
||||
dlvrZpcd,
|
||||
ordNo,
|
||||
realTotAmt,
|
||||
totDlvrAmt,
|
||||
} = panelInfo?.orderInfo || {};
|
||||
const auctProdYn = panelInfo?.auctProdYn || {};
|
||||
|
||||
const handleCancel = useCallback((e) => {
|
||||
if (e && typeof e.preventDefault === "function") {
|
||||
e.preventDefault();
|
||||
}
|
||||
if (e && typeof e.stopPropagation === "function") {
|
||||
e.stopPropagation();
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handleReviewClick = useCallback(() => {
|
||||
dispatch(resetPanels());
|
||||
dispatch(
|
||||
pushPanel({
|
||||
name: Config.panel_names.MY_PAGE_PANEL,
|
||||
panelInfo: {
|
||||
menuNm: "My Orders",
|
||||
menuOrd: 4,
|
||||
},
|
||||
})
|
||||
);
|
||||
}, [dispatch]);
|
||||
|
||||
const handleContinueClick = useCallback(() => {
|
||||
dispatch(resetPanels());
|
||||
dispatch(popPanel());
|
||||
}, [dispatch]);
|
||||
|
||||
return (
|
||||
<TPanel className={css.confirmPanel} isTabActivated={false} spotlightId={spotlightId}>
|
||||
OK!
|
||||
<TPanel
|
||||
className={css.confirmPanel}
|
||||
isTabActivated={false}
|
||||
spotlightId={spotlightId}
|
||||
handleCancel={(e) => handleCancel(e)}
|
||||
>
|
||||
<div className={css.title}>
|
||||
<h2>{$L("THANK YOU.")}</h2>
|
||||
<h2>{$L("Your Order Has Been Placed")}</h2>
|
||||
</div>
|
||||
{panelInfo && (
|
||||
<div className={css.contentsBox}>
|
||||
<div className={css.topContents}>
|
||||
<p className={css.topContentsTitle}>{$L("ESTIMATED DELEVERY")}</p>
|
||||
<span className={css.topContentsDesc}>{dlvrDate}</span>
|
||||
</div>
|
||||
<ul className={css.midContents}>
|
||||
<li>
|
||||
<p>{$L("ORDER NUMBER")}</p>
|
||||
<span>{ordNo}</span>
|
||||
</li>
|
||||
<li>
|
||||
<p className={css.shippingAddressTitle}>
|
||||
{$L("SHIPPING ADDRESS")}
|
||||
</p>
|
||||
<span>
|
||||
{dlvrCityNm}
|
||||
<br />
|
||||
{dlvrDtlAddr}
|
||||
<br />
|
||||
{dlvrZpcd}
|
||||
</span>
|
||||
</li>
|
||||
<li>
|
||||
<p>{$L("FULL NAME")}</p>
|
||||
<span>
|
||||
{dlvrOdrFnm} {dlvrOdrLnm}
|
||||
</span>
|
||||
</li>
|
||||
<li>
|
||||
<p>{$L("PHONE NUMBER")}</p>
|
||||
<span>{dlvrCtpt}</span>
|
||||
</li>
|
||||
<li>
|
||||
<p>{$L("EMAIL")}</p>
|
||||
<span>{dlvrEmalAddr}</span>
|
||||
</li>
|
||||
</ul>
|
||||
<div className={css.bottomContents}>
|
||||
<p className={css.bottomContentsTitle}>{$L("ESTIMATED TOTAL")}</p>
|
||||
{auctProdYn && auctProdYn === "Y" ? (
|
||||
<span>
|
||||
{$L("Purchased products will be paid at the final price.")}
|
||||
</span>
|
||||
) : (
|
||||
<span className={css.bottomContentsDesc}>
|
||||
{realTotAmt} ({cardKnd})
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className={css.buttonWrap}>
|
||||
<TButton onClick={handleReviewClick}>{$L("REVIEW ORDER")}</TButton>
|
||||
<TButton onClick={handleContinueClick}>
|
||||
{$L("CONTINUE SHOPPING")}
|
||||
</TButton>
|
||||
</div>
|
||||
</TPanel>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
@import "../../style/CommonStyle.module.less";
|
||||
@import "../../style/utils.module.less";
|
||||
|
||||
.confirmPanel {
|
||||
background-color: @BG_COLOR_01;
|
||||
padding-top: 100px;
|
||||
|
||||
.title {
|
||||
.font(@fontSize: 48px, @fontFamily: @baseFont);
|
||||
font-weight: bold;
|
||||
line-height: 1.17;
|
||||
color: @COLOR_GRAY07;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.contentsBox {
|
||||
background: @COLOR_WHITE;
|
||||
.size(@w: 1080px, @h: auto);
|
||||
margin: 30px auto;
|
||||
padding: 40px 0 90px 60px;
|
||||
border: 1px solid #dadada;
|
||||
border-radius: 12px;
|
||||
|
||||
.topContents {
|
||||
margin-bottom: 27px;
|
||||
|
||||
.topContentsTitle {
|
||||
.font(@fontSize: 30px, @fontFamily: @baseFont);
|
||||
font-weight: bold;
|
||||
color: @COLOR_GRAY07;
|
||||
width: 330px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.topContentsDesc {
|
||||
.font(@fontSize: 30px, @fontFamily: @baseFont);
|
||||
font-weight: bold;
|
||||
color: @PRIMARY_COLOR_RED;
|
||||
width: 600px;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.midContents {
|
||||
li {
|
||||
p {
|
||||
display: inline-block;
|
||||
width: 330px;
|
||||
font-size: 24px;
|
||||
color: @COLOR_GRAY03;
|
||||
line-height: 1.33;
|
||||
margin-bottom: 27px;
|
||||
|
||||
.shippingAddressTitle {
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
display: inline-block;
|
||||
width: 600px;
|
||||
font-size: 24px;
|
||||
color: @COLOR_GRAY03;
|
||||
line-height: 1.33;
|
||||
margin-bottom: 27px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottomContents {
|
||||
margin-top: 27px;
|
||||
|
||||
.bottomContentsTitle {
|
||||
.font(@fontSize: 30px, @fontFamily: @baseFont);
|
||||
font-weight: bold;
|
||||
color: @COLOR_GRAY07;
|
||||
width: 330px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.bottomContentsDesc {
|
||||
.font(@fontSize: 30px, @fontFamily: @baseFont);
|
||||
font-weight: bold;
|
||||
color: @PRIMARY_COLOR_RED;
|
||||
width: 600px;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.buttonWrap {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user