[checkoutpanel] pinCode 포커스 처리 및 에러코드 별 분기처리 / qr팝업 추가 / SHA256 암호화
This commit is contained in:
25
com.twin.app.shoptime/package-lock.json
generated
25
com.twin.app.shoptime/package-lock.json
generated
@@ -16,6 +16,8 @@
|
||||
"@enact/ui": "^3.3.0",
|
||||
"@enact/webos": "^3.3.0",
|
||||
"axios": "^0.21.1",
|
||||
"crypto-js": "^4.2.0",
|
||||
"google-libphonenumber": "^3.2.34",
|
||||
"ilib": "^14.3.0",
|
||||
"prop-types": "^15.6.2",
|
||||
"qrcode": "^1.5.3",
|
||||
@@ -675,6 +677,11 @@
|
||||
"integrity": "sha512-ZiPp9pZlgxpWRu0M+YWbm6+aQ84XEfH1JRXvfOc/fILWI0VKhLC2LX13X1NYq4fULzLMq7Hfh43CSo2/aIaUPA==",
|
||||
"deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js."
|
||||
},
|
||||
"node_modules/crypto-js": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz",
|
||||
"integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q=="
|
||||
},
|
||||
"node_modules/csstype": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||
@@ -908,6 +915,14 @@
|
||||
"process": "^0.11.10"
|
||||
}
|
||||
},
|
||||
"node_modules/google-libphonenumber": {
|
||||
"version": "3.2.34",
|
||||
"resolved": "https://registry.npmjs.org/google-libphonenumber/-/google-libphonenumber-3.2.34.tgz",
|
||||
"integrity": "sha512-CLwkp0lZvMywh6dCh0T3Fm8XsfJhLAupc8AECwYkJNQBPW8wQPrv/tV0oFKCs8FMw+pTQyNPZoycgBzYjqtTZQ==",
|
||||
"engines": {
|
||||
"node": ">=0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/graceful-fs": {
|
||||
"version": "4.2.11",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
|
||||
@@ -2409,6 +2424,11 @@
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
|
||||
"integrity": "sha512-ZiPp9pZlgxpWRu0M+YWbm6+aQ84XEfH1JRXvfOc/fILWI0VKhLC2LX13X1NYq4fULzLMq7Hfh43CSo2/aIaUPA=="
|
||||
},
|
||||
"crypto-js": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz",
|
||||
"integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q=="
|
||||
},
|
||||
"csstype": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||
@@ -2587,6 +2607,11 @@
|
||||
"process": "^0.11.10"
|
||||
}
|
||||
},
|
||||
"google-libphonenumber": {
|
||||
"version": "3.2.34",
|
||||
"resolved": "https://registry.npmjs.org/google-libphonenumber/-/google-libphonenumber-3.2.34.tgz",
|
||||
"integrity": "sha512-CLwkp0lZvMywh6dCh0T3Fm8XsfJhLAupc8AECwYkJNQBPW8wQPrv/tV0oFKCs8FMw+pTQyNPZoycgBzYjqtTZQ=="
|
||||
},
|
||||
"graceful-fs": {
|
||||
"version": "4.2.11",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
"@enact/ui": "^3.3.0",
|
||||
"@enact/webos": "^3.3.0",
|
||||
"axios": "^0.21.1",
|
||||
"crypto-js": "^4.2.0",
|
||||
"google-libphonenumber": "^3.2.34",
|
||||
"ilib": "^14.3.0",
|
||||
"prop-types": "^15.6.2",
|
||||
|
||||
@@ -135,6 +135,7 @@ export const types = {
|
||||
GET_TAX_INFOS: "GET_TAX_INFOS",
|
||||
UPDATE_SELECTED_SHIPPING_ADDR: "UPDATE_SELECTED_SHIPPING_ADDR",
|
||||
UPDATE_SELECTED_BILLING_ADDR: "UPDATE_SELECTED_BILLING_ADDR",
|
||||
CHECKOUT_DATA_RESET: "CHECKOUT_DATA_RESET",
|
||||
|
||||
// order actions
|
||||
SET_PURCHASE_TERMS_AGREE: "SET_PURCHASE_TERMS_AGREE",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { URLS } from '../api/apiConfig';
|
||||
import { TAxios } from '../api/TAxios';
|
||||
import { types } from './actionTypes';
|
||||
import { changeAppStatus } from './commonActions';
|
||||
import { URLS } from "../api/apiConfig";
|
||||
import { TAxios } from "../api/TAxios";
|
||||
import { types } from "./actionTypes";
|
||||
import { changeAppStatus } from "./commonActions";
|
||||
|
||||
// 회원 체크아웃 정보 조회 IF-LGSP-345
|
||||
export const getMyInfoCheckoutInfo = (props) => (dispatch, getState) => {
|
||||
@@ -86,16 +86,12 @@ export const getTaxInfos = (props) => (dispatch, getState) => {
|
||||
type: types.GET_TAX_INFOS,
|
||||
payload: response.data.data,
|
||||
});
|
||||
|
||||
dispatch(changeAppStatus({ showLoadingPanel: { show: false } }));
|
||||
};
|
||||
|
||||
const onFail = (error) => {
|
||||
console.error("getTaxInfos onFail: ", error);
|
||||
};
|
||||
|
||||
dispatch(changeAppStatus({ showLoadingPanel: { show: true, type: "wait" } }));
|
||||
|
||||
TAxios(
|
||||
dispatch,
|
||||
getState,
|
||||
@@ -130,3 +126,7 @@ export const updateSelectedBillingAddr = (bilAddrSno) => ({
|
||||
type: types.UPDATE_SELECTED_BILLING_ADDR,
|
||||
payload: bilAddrSno,
|
||||
});
|
||||
|
||||
export const resetCheckoutData = () => ({
|
||||
type: types.CHECKOUT_DATA_RESET,
|
||||
});
|
||||
|
||||
@@ -1,22 +1,28 @@
|
||||
import { URLS } from '../api/apiConfig';
|
||||
import { TAxios } from '../api/TAxios';
|
||||
import { types } from './actionTypes';
|
||||
import { URLS } from "../api/apiConfig";
|
||||
import { TAxios } from "../api/TAxios";
|
||||
import { types } from "./actionTypes";
|
||||
import { changeAppStatus } from "./commonActions";
|
||||
|
||||
// 회원 등록카드 PIN CODE 입력 체크 IF-LGSP-336
|
||||
export const getMyInfoCardPincodeCheck = (params) => (dispatch, getState) => {
|
||||
const { mbrNo, pinCd } = params;
|
||||
|
||||
dispatch(changeAppStatus({ showLoadingPanel: { show: true, type: "wait" } }));
|
||||
|
||||
const onSuccess = (response) => {
|
||||
console.log("getMyInfoCardPincodeCheck onSuccess ", response.data);
|
||||
console.log("getMyInfoCardPincodeCheck onSuccess ", response);
|
||||
|
||||
dispatch({
|
||||
type: types.GET_MY_INFO_CARD_PINCODE_CHECK,
|
||||
payload: response.data.data,
|
||||
payload: response.data,
|
||||
});
|
||||
|
||||
dispatch(changeAppStatus({ showLoadingPanel: { show: false } }));
|
||||
};
|
||||
|
||||
const onFail = (error) => {
|
||||
console.error("getMyInfoCardPincodeCheck onFail ", error);
|
||||
dispatch(changeAppStatus({ showLoadingPanel: { show: false } }));
|
||||
};
|
||||
|
||||
TAxios(
|
||||
|
||||
@@ -40,6 +40,7 @@ const KINDS = [
|
||||
"checkoutTermsPopup",
|
||||
"scrollPopup",
|
||||
"watchPopup",
|
||||
"setPinCodePopup",
|
||||
];
|
||||
|
||||
export default function TPopUp({
|
||||
|
||||
@@ -504,3 +504,25 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.setPinCodePopup {
|
||||
.default-style();
|
||||
|
||||
.info {
|
||||
.text {
|
||||
padding: 0 60px;
|
||||
min-height: 180px;
|
||||
margin: 30px 0;
|
||||
}
|
||||
.buttonContainer {
|
||||
margin: 0 0 30px 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
> div {
|
||||
min-width: 240px;
|
||||
height: 78px;
|
||||
margin: 0 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { types } from '../actions/actionTypes';
|
||||
import { types } from "../actions/actionTypes";
|
||||
|
||||
const initialState = {
|
||||
checkoutData: {},
|
||||
@@ -39,6 +39,9 @@ export const checkoutReducer = (state = initialState, action) => {
|
||||
},
|
||||
};
|
||||
|
||||
case types.CHECKOUT_DATA_RESET:
|
||||
return initialState;
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -60,6 +60,7 @@ export const ACTIVE_POPUP = {
|
||||
eventPopup: "eventPopup",
|
||||
smsPopup: "smsPopup",
|
||||
alertPopup: "alertPopup",
|
||||
setPinCodePopup: "setPinCodePopup",
|
||||
};
|
||||
export const DEBUG_VIDEO_SUBTITLE_TEST = false;
|
||||
export const AUTO_SCROLL_DELAY = 600;
|
||||
|
||||
@@ -17,4 +17,7 @@ export const SpotlightIds = {
|
||||
PLAYER_SLIDER: "playerslider",
|
||||
LIST_PLAYER: "list_player",
|
||||
LIST_PLAYER2: "list_player2",
|
||||
|
||||
//pin Code Popup
|
||||
PINCODE_CONTAINER: "pincodeContainer",
|
||||
};
|
||||
|
||||
@@ -8,6 +8,7 @@ import Spotlight from "@enact/spotlight";
|
||||
import {
|
||||
getMyInfoCheckoutInfo,
|
||||
getTaxInfos,
|
||||
resetCheckoutData,
|
||||
} from "../../actions/checkoutActions";
|
||||
import { changeAppStatus } from "../../actions/commonActions";
|
||||
import { getShoptimeTerms } from "../../actions/empActions";
|
||||
@@ -47,6 +48,7 @@ export default function CheckOutPanel() {
|
||||
const cardInfo = useSelector(
|
||||
(state) => state.checkout?.checkoutData.cardInfo
|
||||
);
|
||||
const taxInfosData = useSelector((state) => state.checkout?.taxInfosData);
|
||||
|
||||
const [orderSideBarOpen, setOrderSideBarOpen] = useState(false);
|
||||
const [offerSideBarOpen, setOfferSideBarOpen] = useState(false);
|
||||
@@ -73,33 +75,41 @@ export default function CheckOutPanel() {
|
||||
],
|
||||
})
|
||||
);
|
||||
}, [dispatch, userNumber, checkoutPanelInfo]);
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
dispatch(resetCheckoutData());
|
||||
};
|
||||
}, [dispatch]);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(
|
||||
getTaxInfos({
|
||||
mbrNo: userNumber,
|
||||
bilAddrSno: infoForCheckoutData?.bilAddrSno,
|
||||
dlvrAddrSno: infoForCheckoutData?.dlvrAddrSno,
|
||||
reqCheckoutTaxInfoItemList: [
|
||||
{
|
||||
cpnSno: null,
|
||||
dcAmt: null,
|
||||
frgtTaxCd: productData?.[0].frgtTaxCd,
|
||||
patnrId: productData?.[0].patnrId,
|
||||
prdtId: productData?.[0].prdtId,
|
||||
prodPrc: productData?.[0].price3,
|
||||
prodQty: productData?.[0].prodQty,
|
||||
taxCd: productData?.[0].taxCd,
|
||||
},
|
||||
],
|
||||
})
|
||||
);
|
||||
}, [dispatch, infoForCheckoutData, productData]);
|
||||
if (infoForCheckoutData && productData) {
|
||||
dispatch(
|
||||
getTaxInfos({
|
||||
mbrNo: userNumber,
|
||||
bilAddrSno: infoForCheckoutData?.bilAddrSno,
|
||||
dlvrAddrSno: infoForCheckoutData?.dlvrAddrSno,
|
||||
reqCheckoutTaxInfoItemList: [
|
||||
{
|
||||
cpnSno: null,
|
||||
dcAmt: null,
|
||||
frgtTaxCd: productData?.[0].frgtTaxCd,
|
||||
patnrId: productData?.[0].patnrId,
|
||||
prdtId: productData?.[0].prdtId,
|
||||
prodPrc: productData?.[0].price3,
|
||||
prodQty: productData?.[0].prodQty,
|
||||
taxCd: productData?.[0].taxCd,
|
||||
},
|
||||
],
|
||||
})
|
||||
);
|
||||
}
|
||||
}, [dispatch, infoForCheckoutData, productData, userNumber]);
|
||||
|
||||
useEffect(() => {
|
||||
spotJob.current.start(() => {
|
||||
Spotlight.focus("spotlightId_backBtn");
|
||||
Spotlight.focus("spotlightId_placeOrderBtn");
|
||||
});
|
||||
return () => {
|
||||
spotJob.current.stop();
|
||||
@@ -112,11 +122,15 @@ export default function CheckOutPanel() {
|
||||
|
||||
const toggleOrderSideBar = useCallback(() => {
|
||||
setOrderSideBarOpen((prev) => !prev);
|
||||
}, [orderSideBarOpen]);
|
||||
}, []);
|
||||
|
||||
const toggleOfferSideBar = useCallback(() => {
|
||||
setOfferSideBarOpen((prev) => !prev);
|
||||
}, [offerSideBarOpen]);
|
||||
}, []);
|
||||
|
||||
const onClosePopup = useCallback(() => {
|
||||
setPlaceOrderPopup(false);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -151,6 +165,7 @@ export default function CheckOutPanel() {
|
||||
<TFullPopup
|
||||
open={placeOrderPopup}
|
||||
className={css.pinCodePopup}
|
||||
onClose={onClosePopup}
|
||||
noAnimation={true}
|
||||
>
|
||||
<PinCodeInput setPlaceOrderPopup={setPlaceOrderPopup} />
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
import React, {
|
||||
useCallback,
|
||||
useState,
|
||||
} from 'react';
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
|
||||
import classNames from 'classnames';
|
||||
import {
|
||||
useDispatch,
|
||||
useSelector,
|
||||
} from 'react-redux';
|
||||
import classNames from "classnames";
|
||||
import CryptoJS from "crypto-js";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
|
||||
import SpotlightContainerDecorator
|
||||
from '@enact/spotlight/SpotlightContainerDecorator';
|
||||
import Spottable from '@enact/spotlight/Spottable';
|
||||
import Spotlight from "@enact/spotlight";
|
||||
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
|
||||
import Spottable from "@enact/spotlight/Spottable";
|
||||
|
||||
import { getMyInfoCardPincodeCheck } from '../../../actions/pinCodeActions';
|
||||
import TButton from '../../../components/TButton/TButton';
|
||||
import { $L } from '../../../utils/helperMethods';
|
||||
import css from './PinCodeInput.module.less';
|
||||
import { setHidePopup, setShowPopup } from "../../../actions/commonActions";
|
||||
import { getMyInfoCardPincodeCheck } from "../../../actions/pinCodeActions";
|
||||
import TButton from "../../../components/TButton/TButton";
|
||||
import TPopUp from "../../../components/TPopUp/TPopUp";
|
||||
import TQRCode from "../../../components/TQRCode/TQRCode";
|
||||
import * as Config from "../../../utils/Config";
|
||||
import { $L } from "../../../utils/helperMethods";
|
||||
import { SpotlightIds } from "../../../utils/SpotlightIds";
|
||||
import css from "./PinCodeInput.module.less";
|
||||
|
||||
const PinCodeContainer = SpotlightContainerDecorator("div");
|
||||
|
||||
@@ -25,12 +25,39 @@ const SpottableButton = Spottable("div");
|
||||
export default function PinCodeInput({ setPlaceOrderPopup }) {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const { activePopup, popupVisible } = useSelector(
|
||||
(state) => state.common.popup
|
||||
);
|
||||
const pinCodeDatas = useSelector((state) => state.pinCode.pinCodeData);
|
||||
const userNumber = useSelector(
|
||||
(state) => state.common.appStatus.loginUserData.userNumber
|
||||
);
|
||||
|
||||
const [pin, setPin] = useState(["", "", "", ""]);
|
||||
const [errorMsg, setErrorMsg] = useState("");
|
||||
const [okClicked, setOkClicked] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (pinCodeDatas && pinCodeDatas.retCode !== 0 && okClicked) {
|
||||
if (pinCodeDatas.data.pwdErrorCnt >= 3) {
|
||||
dispatch(setShowPopup(Config.ACTIVE_POPUP.setPinCodePopup));
|
||||
} else {
|
||||
setErrorMsg($L("Your entries did not match. Please try again."));
|
||||
}
|
||||
}
|
||||
}, [pinCodeDatas, dispatch, okClicked]);
|
||||
|
||||
useEffect(() => {
|
||||
setOkClicked(false);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (popupVisible && activePopup) {
|
||||
setTimeout(() => {
|
||||
Spotlight.focus("tPopupBtn1");
|
||||
}, 0);
|
||||
}
|
||||
}, [popupVisible, activePopup]);
|
||||
|
||||
const handleDigitClick = useCallback(
|
||||
(digit) => {
|
||||
@@ -40,10 +67,6 @@ export default function PinCodeInput({ setPlaceOrderPopup }) {
|
||||
if (nextIndex !== -1) {
|
||||
newPin[nextIndex] = digit;
|
||||
setPin(newPin);
|
||||
|
||||
if (nextIndex === 3) {
|
||||
console.log("chw", newPin.join(""));
|
||||
}
|
||||
}
|
||||
},
|
||||
[pin]
|
||||
@@ -66,49 +89,113 @@ export default function PinCodeInput({ setPlaceOrderPopup }) {
|
||||
}, [setPlaceOrderPopup]);
|
||||
|
||||
const onClickConfirm = useCallback(() => {
|
||||
if (pin.includes("")) {
|
||||
setErrorMsg($L("Please enter a PIN CODE."));
|
||||
return;
|
||||
}
|
||||
|
||||
setOkClicked(true);
|
||||
|
||||
const pinString = pin.join("");
|
||||
const encryptedPin = CryptoJS.SHA256(pinString).toString();
|
||||
|
||||
dispatch(
|
||||
getMyInfoCardPincodeCheck({
|
||||
mbrNo: userNumber,
|
||||
pinCd: pin,
|
||||
pinCd: encryptedPin,
|
||||
})
|
||||
);
|
||||
}, [pin, userNumber, dispatch]);
|
||||
|
||||
const handleClickSetPinCode = useCallback(() => {
|
||||
dispatch(setShowPopup(Config.ACTIVE_POPUP.qrPopup));
|
||||
}, [dispatch]);
|
||||
|
||||
const handleCancelPopup = useCallback(() => {
|
||||
dispatch(setHidePopup());
|
||||
Spotlight.focus(SpotlightIds.PINCODE_CONTAINER);
|
||||
}, [dispatch]);
|
||||
|
||||
return (
|
||||
<PinCodeContainer className={css.pinCodeContainer}>
|
||||
<h1 className={css.pinCodeTitle}>{$L("Enter PIN CODE")}</h1>
|
||||
<div className={css.pinCodeBoxes}>
|
||||
{pin.map((digit, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className={classNames(css.pinCodeBox, {
|
||||
[css.focused]: pin.findIndex((p) => p === "") === index,
|
||||
})}
|
||||
>
|
||||
{digit ? "•" : ""}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className={css.errMsg}>ERROR</div>
|
||||
<div className={css.pinCodeDigits}>
|
||||
{[...Array(10).keys()].map((digit) => (
|
||||
<>
|
||||
<PinCodeContainer
|
||||
spotlightId={SpotlightIds.PINCODE_CONTAINER}
|
||||
className={css.pinCodeContainer}
|
||||
>
|
||||
<h1 className={css.pinCodeTitle}>{$L("Enter PIN CODE")}</h1>
|
||||
<div className={css.pinCodeBoxes}>
|
||||
{pin.map((digit, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className={classNames(css.pinCodeBox, {
|
||||
[css.focused]: pin.findIndex((p) => p === "") === index,
|
||||
})}
|
||||
>
|
||||
{digit ? "•" : ""}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className={css.errMsg}>{errorMsg}</div>
|
||||
<div className={css.pinCodeDigits}>
|
||||
{[...Array(10).keys()].map((digit) => (
|
||||
<SpottableButton
|
||||
key={digit}
|
||||
className={css.pinCodeDigit}
|
||||
onClick={() => handleDigitClick(digit.toString())}
|
||||
>
|
||||
{digit}
|
||||
</SpottableButton>
|
||||
))}
|
||||
<SpottableButton
|
||||
key={digit}
|
||||
className={css.pinCodeDigit}
|
||||
onClick={() => handleDigitClick(digit.toString())}
|
||||
>
|
||||
{digit}
|
||||
</SpottableButton>
|
||||
))}
|
||||
<SpottableButton
|
||||
className={classNames(css.pinCodeDigit, css.deleteKey)}
|
||||
onClick={handleBackspace}
|
||||
className={classNames(css.pinCodeDigit, css.deleteKey)}
|
||||
onClick={handleBackspace}
|
||||
/>
|
||||
</div>
|
||||
<div className={css.buttonContainer}>
|
||||
<TButton onClick={onClickCancel}>{$L("Cancel")}</TButton>
|
||||
<TButton onClick={onClickConfirm}>{$L("OK")}</TButton>
|
||||
</div>
|
||||
</PinCodeContainer>
|
||||
|
||||
{activePopup === Config.ACTIVE_POPUP.setPinCodePopup && (
|
||||
<TPopUp
|
||||
kind="setPinCodePopup"
|
||||
open={popupVisible}
|
||||
hasButton
|
||||
button1Text={$L("OK")}
|
||||
button2Text={$L("Cancel")}
|
||||
onClick={handleClickSetPinCode}
|
||||
onClose={handleCancelPopup}
|
||||
hasText
|
||||
text={$L(
|
||||
"The number of PIN CODE errors has been exceeded and the PIN CODE cannot be used. Would you like to set a new PIN CODE?"
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div className={css.buttonContainer}>
|
||||
<TButton onClick={onClickCancel}>{$L("Cancel")}</TButton>
|
||||
<TButton onClick={onClickConfirm}>{$L("OK")}</TButton>
|
||||
</div>
|
||||
</PinCodeContainer>
|
||||
)}
|
||||
|
||||
{activePopup === Config.ACTIVE_POPUP.qrPopup && (
|
||||
<TPopUp kind="qrPopup" open={popupVisible} onClose={handleCancelPopup}>
|
||||
<div className={css.popupContainer}>
|
||||
<div className={css.header}>
|
||||
<h3>{$L("QR CODE")}</h3>
|
||||
</div>
|
||||
|
||||
<div className={css.qrcodeContainer}>
|
||||
<div className={css.qrcode}>
|
||||
<TQRCode text={"http://google.com"} width="360" height="360" />
|
||||
</div>
|
||||
<h3>
|
||||
{$L(
|
||||
"If you want to add or edit your address and payment information, please scan the QR CODE."
|
||||
)}
|
||||
</h3>
|
||||
<TButton className={css.popupBtn} onClick={handleCancelPopup}>
|
||||
{$L("CLOSE")}
|
||||
</TButton>
|
||||
</div>
|
||||
</div>
|
||||
</TPopUp>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -112,3 +112,44 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.popupContainer {
|
||||
.header {
|
||||
.size(@w: 780px , @h: 102px);
|
||||
.flex(@display: flex, @justifyCenter: center, @alignCenter: center, @direction: row);
|
||||
background-color: #e7ebef;
|
||||
|
||||
> h3 {
|
||||
font-size: 36px;
|
||||
color: #222222;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.qrcodeContainer {
|
||||
padding: 30px 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
.qrcode {
|
||||
.size(@w: 360px , @h: 360px);
|
||||
background-color: #ffffff;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 0 0 1px #dadada inset;
|
||||
margin-bottom: 41px;
|
||||
}
|
||||
|
||||
> h3 {
|
||||
display: flex;
|
||||
text-align: center;
|
||||
word-break: break-word;
|
||||
line-height: 1.27;
|
||||
}
|
||||
|
||||
.popupBtn {
|
||||
.size(@w: 300px , @h: 78px);
|
||||
margin-top: 38px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,25 +1,12 @@
|
||||
import React, {
|
||||
useCallback,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useState,
|
||||
} from 'react';
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
|
||||
import {
|
||||
useDispatch,
|
||||
useSelector,
|
||||
} from 'react-redux';
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
|
||||
import SpotlightContainerDecorator
|
||||
from '@enact/spotlight/SpotlightContainerDecorator';
|
||||
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
|
||||
|
||||
import { registerDevice } from '../../../actions/deviceActions';
|
||||
import { getHomeTerms } from '../../../actions/homeActions';
|
||||
import { setPurchaseTermsAgree } from '../../../actions/orderActions';
|
||||
import TButton from '../../../components/TButton/TButton';
|
||||
import TCheckBox from '../../../components/TCheckBox/TCheckBox';
|
||||
import { $L } from '../../../utils/helperMethods';
|
||||
import css from './SummaryContainer.module.less';
|
||||
import { changeAppStatus } from "../../../actions/commonActions";
|
||||
import TButton from "../../../components/TButton/TButton";
|
||||
import css from "./SummaryContainer.module.less";
|
||||
|
||||
const Container = SpotlightContainerDecorator(
|
||||
{ enterTo: "last-focused" },
|
||||
@@ -27,12 +14,13 @@ const Container = SpotlightContainerDecorator(
|
||||
);
|
||||
|
||||
const DEFAULT_SUMMARY = {
|
||||
itemPrice: "0",
|
||||
shPrice: "0",
|
||||
couponPrice: "0",
|
||||
itemsTotal: "0",
|
||||
taxTotal: "0",
|
||||
itemsTaxTotal: "0",
|
||||
itemPrice: "-",
|
||||
shPrice: "-",
|
||||
couponPrice: "-",
|
||||
itemsTotal: "-",
|
||||
taxTotal: "-",
|
||||
itemsTaxTotal: "-",
|
||||
estimatedTotal: "-",
|
||||
currSign: "",
|
||||
currSignLoc: "",
|
||||
};
|
||||
@@ -41,7 +29,6 @@ export default function SummaryContainer({ setPlaceOrderPopup }) {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const { productList } = useSelector((state) => state.checkout.checkoutData);
|
||||
const termsData = useSelector((state) => state.home.termsData);
|
||||
const taxInfosData = useSelector((state) => state.checkout?.taxInfosData);
|
||||
|
||||
const [summary, setSummary] = useState(DEFAULT_SUMMARY);
|
||||
@@ -51,7 +38,7 @@ export default function SummaryContainer({ setPlaceOrderPopup }) {
|
||||
(productList) => {
|
||||
if (!productList?.length) return;
|
||||
|
||||
let itemCnt = 0; // 상품 함계
|
||||
let itemCnt = 0; // 상품 합계
|
||||
let shCnt = 0; // 배송비 합계
|
||||
let couponCnt = 0; // 쿠폰 할인 합계
|
||||
let itemsTotal = 0; // 상품 + 배송비
|
||||
@@ -96,7 +83,7 @@ export default function SummaryContainer({ setPlaceOrderPopup }) {
|
||||
currSignLoc: productList[0]?.currSignLoc || "",
|
||||
}));
|
||||
},
|
||||
[taxInfosData, auctProdYn]
|
||||
[taxInfosData, auctProdYn, dispatch]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -116,7 +103,7 @@ export default function SummaryContainer({ setPlaceOrderPopup }) {
|
||||
|
||||
const handleClickOrder = useCallback(() => {
|
||||
setPlaceOrderPopup(true);
|
||||
}, []);
|
||||
}, [setPlaceOrderPopup]);
|
||||
|
||||
return (
|
||||
<Container className={css.container}>
|
||||
@@ -144,7 +131,7 @@ export default function SummaryContainer({ setPlaceOrderPopup }) {
|
||||
) : (
|
||||
<div className={css.noticeBox}>
|
||||
<span className={css.noticeBoxText}>
|
||||
{$L("Purchased products will be paid at the final price.")}
|
||||
{"Purchased products will be paid at the final price."}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
@@ -165,7 +152,11 @@ export default function SummaryContainer({ setPlaceOrderPopup }) {
|
||||
</div>
|
||||
</div>
|
||||
<div className={css.bottom}>
|
||||
<TButton className={css.tButton} onClick={handleClickOrder}>
|
||||
<TButton
|
||||
className={css.tButton}
|
||||
onClick={handleClickOrder}
|
||||
spotlightId="spotlightId_placeOrderBtn"
|
||||
>
|
||||
{"PLACE ORDER"}
|
||||
</TButton>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user