[checkoutpanel] 결제 관련 api 추가 및 action, reducer 추가 / UI 작업
This commit is contained in:
@@ -124,6 +124,10 @@ export const types = {
|
||||
|
||||
// checkout actions
|
||||
GET_CHECKOUT_INFO: "GET_CHECKOUT_INFO",
|
||||
INSERT_MY_INFO_CHECKOUT_ORDER: "INSERT_MY_INFO_CHECKOUT_ORDER",
|
||||
GET_TAX_INFOS: "GET_TAX_INFOS",
|
||||
UPDATE_SELECTED_SHIPPING_ADDR: "UPDATE_SELECTED_SHIPPING_ADDR",
|
||||
UPDATE_SELECTED_BILLING_ADDR: "UPDATE_SELECTED_BILLING_ADDR",
|
||||
|
||||
// order actions
|
||||
SET_PURCHASE_TERMS_AGREE: "SET_PURCHASE_TERMS_AGREE",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
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';
|
||||
|
||||
// 회원 체크아웃 정보 조회 IF-LGSP-345
|
||||
export const getMyInfoCheckoutInfo = (props) => (dispatch, getState) => {
|
||||
@@ -30,3 +30,98 @@ export const getMyInfoCheckoutInfo = (props) => (dispatch, getState) => {
|
||||
onFail
|
||||
);
|
||||
};
|
||||
|
||||
// 회원 CheckOut 상품 주문 IF-LGSP-346
|
||||
export const insertMyInfoCheckoutOrder = (props) => (dispatch, getState) => {
|
||||
const { mbrNo, bilAddrSno, dlvrAddrSno, pinCd, orderProductCoup, ontUse } =
|
||||
props;
|
||||
|
||||
const onSuccess = (response) => {
|
||||
console.log("insertMyInfoCheckoutOrder onSuccess: ", response.data);
|
||||
|
||||
dispatch({
|
||||
type: types.INSERT_MY_INFO_CHECKOUT_ORDER,
|
||||
payload: response.data.data,
|
||||
});
|
||||
};
|
||||
|
||||
const onFail = (error) => {
|
||||
console.error("insertMyInfoCheckoutOrder onFail: ", error);
|
||||
};
|
||||
|
||||
TAxios(
|
||||
dispatch,
|
||||
getState,
|
||||
"post",
|
||||
URLS.INSERT_MY_INFO_CHECKOUT_ORDER,
|
||||
{},
|
||||
{ mbrNo, bilAddrSno, dlvrAddrSno, pinCd, orderProductCoup, ontUse },
|
||||
onSuccess,
|
||||
onFail
|
||||
);
|
||||
};
|
||||
|
||||
// 파트너사 배송비 및 LBP 관련 세금 정보 IF-LGSP-362
|
||||
export const getTaxInfos = (props) => (dispatch, getState) => {
|
||||
const {
|
||||
mbrNo,
|
||||
bilAddrSno,
|
||||
dlvrAddrSno,
|
||||
reqCheckoutTaxInfoItemList,
|
||||
patnrId,
|
||||
prdtId,
|
||||
prodQty,
|
||||
prodPrc,
|
||||
taxCd,
|
||||
frgTaxCd,
|
||||
dcAmt,
|
||||
cpnSno,
|
||||
} = props;
|
||||
|
||||
const onSuccess = (response) => {
|
||||
console.log("getTaxInfos onSuccess: ", response.data);
|
||||
|
||||
dispatch({
|
||||
type: types.GET_TAX_INFOS,
|
||||
payload: response.data.data,
|
||||
});
|
||||
};
|
||||
|
||||
const onFail = (error) => {
|
||||
console.error("getTaxInfos onFail: ", error);
|
||||
};
|
||||
|
||||
TAxios(
|
||||
dispatch,
|
||||
getState,
|
||||
"post",
|
||||
URLS.GET_TAX_INFOS,
|
||||
{},
|
||||
{
|
||||
mbrNo,
|
||||
bilAddrSno,
|
||||
dlvrAddrSno,
|
||||
reqCheckoutTaxInfoItemList,
|
||||
patnrId,
|
||||
prdtId,
|
||||
prodQty,
|
||||
prodPrc,
|
||||
taxCd,
|
||||
frgTaxCd,
|
||||
dcAmt,
|
||||
cpnSno,
|
||||
},
|
||||
onSuccess,
|
||||
onFail
|
||||
);
|
||||
};
|
||||
|
||||
export const updateSelectedShippingAddr = (dlvrAddrSno) => ({
|
||||
type: types.UPDATE_SELECTED_SHIPPING_ADDR,
|
||||
payload: dlvrAddrSno,
|
||||
});
|
||||
|
||||
export const updateSelectedBillingAddr = (bilAddrSno) => ({
|
||||
type: types.UPDATE_SELECTED_BILLING_ADDR,
|
||||
payload: bilAddrSno,
|
||||
});
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { types } from "../actions/actionTypes";
|
||||
import { types } from '../actions/actionTypes';
|
||||
|
||||
const initialState = {
|
||||
checkoutData: {},
|
||||
taxInfosData: {},
|
||||
infoForCheckoutData: {},
|
||||
};
|
||||
|
||||
export const checkoutReducer = (state = initialState, action) => {
|
||||
@@ -12,6 +14,30 @@ export const checkoutReducer = (state = initialState, action) => {
|
||||
checkoutData: action.payload,
|
||||
};
|
||||
|
||||
case types.GET_TAX_INFOS:
|
||||
return {
|
||||
...state,
|
||||
taxInfosData: action.payload,
|
||||
};
|
||||
|
||||
case types.UPDATE_SELECTED_SHIPPING_ADDR:
|
||||
return {
|
||||
...state,
|
||||
infoForCheckoutData: {
|
||||
...state.infoForCheckoutData,
|
||||
dlvrAddrSno: action.payload,
|
||||
},
|
||||
};
|
||||
|
||||
case types.UPDATE_SELECTED_BILLING_ADDR:
|
||||
return {
|
||||
...state,
|
||||
infoForCheckoutData: {
|
||||
...state.infoForCheckoutData,
|
||||
bilAddrSno: action.payload,
|
||||
},
|
||||
};
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -1,30 +1,53 @@
|
||||
import React, { useCallback, useEffect } from "react";
|
||||
import React, {
|
||||
useCallback,
|
||||
useEffect,
|
||||
useState,
|
||||
} from 'react';
|
||||
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import {
|
||||
useDispatch,
|
||||
useSelector,
|
||||
} from 'react-redux';
|
||||
|
||||
import { getMyInfoCheckoutInfo } from "../../actions/checkoutActions";
|
||||
import { popPanel } from "../../actions/panelActions";
|
||||
import TBody from "../../components/TBody/TBody";
|
||||
import THeader from "../../components/THeader/THeader";
|
||||
import TPanel from "../../components/TPanel/TPanel";
|
||||
import TScroller from "../../components/TScroller/TScroller";
|
||||
import css from "./CheckOutPanel.module.less";
|
||||
import CheckoutQRCode from "./components/CheckoutQRCode";
|
||||
import CheckOutTerms from "./components/CheckOutTerms";
|
||||
import PinCode from "./components/PinCode";
|
||||
import InformationContainer from "./container/InformationContainer";
|
||||
import SummaryContainer from "./container/SummaryCotainer";
|
||||
import {
|
||||
getMyInfoCheckoutInfo,
|
||||
getTaxInfos,
|
||||
} from '../../actions/checkoutActions';
|
||||
import { popPanel } from '../../actions/panelActions';
|
||||
import TBody from '../../components/TBody/TBody';
|
||||
import THeader from '../../components/THeader/THeader';
|
||||
import TPanel from '../../components/TPanel/TPanel';
|
||||
import TScroller from '../../components/TScroller/TScroller';
|
||||
import css from './CheckOutPanel.module.less';
|
||||
import CheckoutQRCode from './components/CheckoutQRCode';
|
||||
import CheckOutTerms from './components/CheckOutTerms';
|
||||
import PinCode from './components/PinCode';
|
||||
import FixedSideBar from './container/FixedSideBar';
|
||||
import InformationContainer from './container/InformationContainer';
|
||||
import OrderItemsSideBar from './container/OrderItemsSideBar';
|
||||
import SummaryContainer from './container/SummaryCotainer';
|
||||
|
||||
export default function CheckOutPanel() {
|
||||
const dispatch = useDispatch();
|
||||
const panels = useSelector((state) => state.panels.panels);
|
||||
const { userInfo } = useSelector(
|
||||
(state) => state.common.appStatus.loginUserData
|
||||
);
|
||||
const panels = useSelector((state) => state.panels.panels);
|
||||
const checkoutData = useSelector((state) => state.checkout?.checkoutData);
|
||||
const testData = useSelector((state) => state);
|
||||
const checkoutPanelInfo = panels.find(
|
||||
(panel) => panel.name === "checkoutpanel"
|
||||
)?.panelInfo;
|
||||
const productData = useSelector(
|
||||
(state) => state.checkout?.checkoutData.productList
|
||||
);
|
||||
const infoForCheckoutData = useSelector(
|
||||
(state) => state.checkout?.infoForCheckoutData
|
||||
);
|
||||
|
||||
console.log("#panels", panels);
|
||||
const [orderSideBarOpen, setOrderSideBarOpen] = useState(false);
|
||||
const [offerSideBarOpen, setOfferSideBarOpen] = useState(false);
|
||||
|
||||
console.log("chw", infoForCheckoutData);
|
||||
console.log("chw", productData);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(
|
||||
@@ -33,10 +56,32 @@ export default function CheckOutPanel() {
|
||||
dirPurcSelYn: "Y",
|
||||
cartList: [
|
||||
{
|
||||
patnrId: "11",
|
||||
prdtId: "7280567",
|
||||
prodOptCdCval: "7326490",
|
||||
prodQty: 1,
|
||||
patnrId: checkoutPanelInfo.cartList.patnrId,
|
||||
prdtId: checkoutPanelInfo.cartList.prdtId,
|
||||
prodOptCdCval: checkoutPanelInfo.cartList.prodOptCdCval,
|
||||
prodQty: checkoutPanelInfo.cartList.prodQty,
|
||||
},
|
||||
],
|
||||
})
|
||||
);
|
||||
}, [dispatch]);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(
|
||||
getTaxInfos({
|
||||
mbrNo: userInfo,
|
||||
bilAddrSno: infoForCheckoutData?.bilAddrSno || 206,
|
||||
dlvrAddrSno: infoForCheckoutData?.dlvrAddrSno || 3003,
|
||||
reqCheckoutTaxInfoItemList: [
|
||||
{
|
||||
cpnSno: null,
|
||||
dcAmt: null,
|
||||
frgtTaxCd: productData?.[0].frgtTaxCd || "FR020900",
|
||||
patnrId: productData?.[0].patnrId || "11",
|
||||
prdtId: productData?.[0].prdtId || "7127927",
|
||||
prodPrc: productData?.[0].price3 || 9.99,
|
||||
prodQty: productData?.[0].prodQty || 1,
|
||||
taxCd: productData?.[0].taxCd || "P0000000",
|
||||
},
|
||||
],
|
||||
})
|
||||
@@ -46,10 +91,21 @@ export default function CheckOutPanel() {
|
||||
const onBackClick = useCallback(() => {
|
||||
dispatch(popPanel());
|
||||
}, [dispatch]);
|
||||
//{ name: panel_names.ON_SALE_PANEL }
|
||||
|
||||
const toggleOrderSideBar = useCallback(() => {
|
||||
setOrderSideBarOpen((prev) => !prev);
|
||||
}, [orderSideBarOpen]);
|
||||
|
||||
const toggleOfferSideBar = useCallback(() => {
|
||||
setOfferSideBarOpen((prev) => !prev);
|
||||
}, [offerSideBarOpen]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<TPanel isTabActivated={false}>
|
||||
<TPanel
|
||||
isTabActivated={false}
|
||||
spotlightDisabled={orderSideBarOpen || offerSideBarOpen}
|
||||
>
|
||||
<TBody className={css.tbody}>
|
||||
<THeader
|
||||
className={css.theader}
|
||||
@@ -59,13 +115,19 @@ export default function CheckOutPanel() {
|
||||
/>
|
||||
<div className={css.Wrap}>
|
||||
<SummaryContainer userInfo={userInfo} />
|
||||
<InformationContainer checkoutData={checkoutData} />
|
||||
<InformationContainer
|
||||
toggleOrderSideBar={toggleOrderSideBar}
|
||||
toggleOfferSideBar={toggleOfferSideBar}
|
||||
/>
|
||||
</div>
|
||||
<CheckoutQRCode open={false} />
|
||||
{/* <CheckoutQRCode open={false} /> */}
|
||||
</TBody>
|
||||
</TPanel>
|
||||
{/* <CheckOutTerms /> 약관부분 */}
|
||||
{/* <PinCode /> */}
|
||||
|
||||
{orderSideBarOpen && (
|
||||
<OrderItemsSideBar closeSideBar={toggleOrderSideBar} />
|
||||
)}
|
||||
{offerSideBarOpen && <FixedSideBar closeSideBar={toggleOfferSideBar} />}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,64 +1,116 @@
|
||||
import React, { useCallback } from "react";
|
||||
import React, {
|
||||
memo,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useState,
|
||||
} from 'react';
|
||||
|
||||
import TVirtualGridList from "../../../components/TVirtualGridList/TVirtualGridList";
|
||||
import useScrollTo from "../../../hooks/useScrollTo";
|
||||
import BillingAddressItem from "../../MyPagePanel/MyPageSub/MyInfo/MyInfoTabContents/BillingAddressTab/BillingAddressItem";
|
||||
import MyInfoNoResults from "../../MyPagePanel/MyPageSub/MyInfo/MyInfoTabContents/MyInfoNoResults/MyInfoNoResults";
|
||||
import css from "./BillingAddressCard.module.less";
|
||||
import CheckOutContainer from "./CheckOutContainer";
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
export const ITEM_SIZE = {
|
||||
itemWidth: 444,
|
||||
itemHeight: 348,
|
||||
spacing: 18,
|
||||
};
|
||||
import SpotlightContainerDecorator
|
||||
from '@enact/spotlight/SpotlightContainerDecorator';
|
||||
|
||||
import { updateSelectedBillingAddr } from '../../../actions/checkoutActions';
|
||||
import TCheckBox from '../../../components/TCheckBox/TCheckBox';
|
||||
import TScroller from '../../../components/TScroller/TScroller';
|
||||
import css from './BillingAddressCard.module.less';
|
||||
import CheckOutContainer from './CheckOutContainer';
|
||||
|
||||
const ItemContainer = SpotlightContainerDecorator("li");
|
||||
|
||||
export default memo(function BillingAddressCard({ list, ...rest }) {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const [selected, setSelected] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (list) {
|
||||
setSelected(list[0].bilAddrSno);
|
||||
dispatch(updateSelectedBillingAddr(list[0]?.bilAddrSno));
|
||||
}
|
||||
}, [dispatch, list]);
|
||||
|
||||
const handleSelectAddress = useCallback(
|
||||
(bilAddrSno) => {
|
||||
if (bilAddrSno !== selected) {
|
||||
setSelected(bilAddrSno);
|
||||
dispatch(updateSelectedBillingAddr(bilAddrSno));
|
||||
}
|
||||
},
|
||||
[dispatch, selected]
|
||||
);
|
||||
|
||||
export default function BillingAddressCard({ list }) {
|
||||
const { getScrollTo, scrollLeft } = useScrollTo();
|
||||
console.log("###list", list);
|
||||
return (
|
||||
<CheckOutContainer>
|
||||
<div className={css.billingBox}>
|
||||
{list &&
|
||||
list.map(
|
||||
(
|
||||
{
|
||||
bilAddrSno,
|
||||
bilCityNm,
|
||||
bilCtpt,
|
||||
bilDtlAddr,
|
||||
bilEmalAddr,
|
||||
bilOdrFnm,
|
||||
bilOdrLnm,
|
||||
bilStatNm,
|
||||
bilStatPvc,
|
||||
bilZpcd,
|
||||
chgDt,
|
||||
cntryCd,
|
||||
cntryNm,
|
||||
mbrNo,
|
||||
regDt,
|
||||
useFlag,
|
||||
},
|
||||
index
|
||||
) => {
|
||||
return (
|
||||
<BillingAddressItem
|
||||
key={index}
|
||||
bilOdrFnm={bilOdrFnm}
|
||||
bilOdrLnm={bilOdrLnm}
|
||||
bilZpcd={bilZpcd}
|
||||
bilStatNm={bilStatNm}
|
||||
bilCityNm={bilCityNm}
|
||||
bilDtlAddr={bilDtlAddr}
|
||||
bilCtpt={bilCtpt}
|
||||
bilEmalAddr={bilEmalAddr}
|
||||
/>
|
||||
);
|
||||
}
|
||||
)}
|
||||
{/* <MyInfoNoResults type="BILLING ADDRESS" /> */}
|
||||
</div>
|
||||
<CheckOutContainer className={css.shippingBox}>
|
||||
<TScroller
|
||||
className={css.shipping}
|
||||
direction="horizontal"
|
||||
noScrollByWheel
|
||||
>
|
||||
<ul>
|
||||
{list &&
|
||||
list.map(
|
||||
(
|
||||
{
|
||||
bilAddrSno,
|
||||
bilCityNm,
|
||||
bilCtpt,
|
||||
bilDtlAddr,
|
||||
bilEmalAddr,
|
||||
bilOdrFnm,
|
||||
bilOdrLnm,
|
||||
bilStatNm,
|
||||
bilStatPvc,
|
||||
bilZpcd,
|
||||
chgDt,
|
||||
cntryCd,
|
||||
cntryNm,
|
||||
mbrNo,
|
||||
regDt,
|
||||
useFlag,
|
||||
},
|
||||
index
|
||||
) => {
|
||||
return (
|
||||
<ItemContainer
|
||||
className={css.itemContainer}
|
||||
key={index}
|
||||
{...rest}
|
||||
>
|
||||
<TCheckBox
|
||||
className={css.checkBox}
|
||||
selected={selected === bilAddrSno}
|
||||
onToggle={() => handleSelectAddress(bilAddrSno)}
|
||||
/>
|
||||
<h2 className={css.title}>
|
||||
{bilOdrFnm} {bilOdrLnm}
|
||||
</h2>
|
||||
<div className={css.addressWrap}>
|
||||
<p>
|
||||
{bilZpcd} {bilStatNm}, <br />
|
||||
{bilCityNm} <br />
|
||||
{bilDtlAddr}
|
||||
</p>
|
||||
</div>
|
||||
<div className={css.cardFooter}>
|
||||
<p className={css.callNumber}>
|
||||
<span />
|
||||
{bilCtpt.replace(
|
||||
/^(\d{2,3})(\d{3,4})(\d{4})$/,
|
||||
`$1-$2-$3`
|
||||
)}
|
||||
</p>
|
||||
<p className={css.email}>
|
||||
<span />
|
||||
{bilEmalAddr}
|
||||
</p>
|
||||
</div>
|
||||
</ItemContainer>
|
||||
);
|
||||
}
|
||||
)}
|
||||
</ul>
|
||||
</TScroller>
|
||||
</CheckOutContainer>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,6 +1,88 @@
|
||||
@import "../../../style/CommonStyle.module.less";
|
||||
@import "../../../style/utils.module.less";
|
||||
|
||||
.billingBox {
|
||||
.shippingBox {
|
||||
position: relative;
|
||||
.size(@w: 100%, @h:100%);
|
||||
min-height: 383px;
|
||||
|
||||
> div:nth-child(1) {
|
||||
.size(@w: inherit, @h: inherit);
|
||||
}
|
||||
|
||||
ul {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: inherit;
|
||||
|
||||
.itemContainer {
|
||||
.size(@w: 444px, @h: 348px);
|
||||
background-color: @BG_COLOR_05;
|
||||
border-radius: 12px;
|
||||
padding: 32px 30px;
|
||||
position: relative;
|
||||
margin-right: 12px;
|
||||
|
||||
.checkBox {
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
top: 20px;
|
||||
}
|
||||
|
||||
.title {
|
||||
color: @COLOR_GRAY06;
|
||||
font-weight: bold;
|
||||
font-size: 36px;
|
||||
margin-bottom: 19px;
|
||||
}
|
||||
|
||||
.addressWrap {
|
||||
color: @COLOR_GRAY03;
|
||||
line-height: 1.33;
|
||||
margin-bottom: 37px;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.cardFooter {
|
||||
font-weight: bold;
|
||||
font-size: 24px;
|
||||
color: @COLOR_GRAY03;
|
||||
|
||||
.callNumber {
|
||||
padding-left: 42px;
|
||||
margin-bottom: 6px;
|
||||
|
||||
> span {
|
||||
background-image: url("../../../../assets/images/icons/ic-gr-call.svg");
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
.size(@w: 36px, @h: 36px);
|
||||
position: absolute;
|
||||
left: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
.email {
|
||||
padding-left: 42px;
|
||||
|
||||
> span {
|
||||
background-image: url("../../../../assets/images/icons/ic-gr-mail-36.svg");
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
.size(@w: 36px, @h: 36px);
|
||||
position: absolute;
|
||||
left: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:focus {
|
||||
&::after {
|
||||
.focused(@boxShadow: 22px, @borderRadius: 12px);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,21 @@
|
||||
import React from "react";
|
||||
import React from 'react';
|
||||
|
||||
import classNames from "classnames";
|
||||
import classNames from 'classnames';
|
||||
|
||||
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
|
||||
import SpotlightContainerDecorator
|
||||
from '@enact/spotlight/SpotlightContainerDecorator';
|
||||
|
||||
import css from "./CheckOutContainer.module.less";
|
||||
import css from './CheckOutContainer.module.less';
|
||||
|
||||
const Container = SpotlightContainerDecorator(
|
||||
{ enterTo: "last-focused" },
|
||||
"div"
|
||||
);
|
||||
|
||||
export default function CheckOutContainer({ children }) {
|
||||
export default function CheckOutContainer({ children, className }) {
|
||||
return (
|
||||
<Container className={classNames(css.chekcoutBox)}>{children}</Container>
|
||||
<Container className={classNames(css.chekcoutBox, className)}>
|
||||
{children}
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
import React, { memo } from 'react';
|
||||
|
||||
import Spottable from '@enact/spotlight/Spottable';
|
||||
|
||||
import CustomImage from '../../../components/CustomImage/CustomImage';
|
||||
import { $L } from '../../../utils/helperMethods';
|
||||
import css from './OrderItemCard.module.less';
|
||||
|
||||
const OrderItemContainer = Spottable("div");
|
||||
|
||||
export const SIZES = {
|
||||
itemWidth: 660,
|
||||
itemHeight: 333,
|
||||
spacing: 12,
|
||||
};
|
||||
|
||||
export default memo(function OrderItemCard({
|
||||
imgUrls,
|
||||
prdtNm,
|
||||
prodQty,
|
||||
price2,
|
||||
price3,
|
||||
prodtOpt,
|
||||
patncLogPath,
|
||||
prdtId,
|
||||
currSign,
|
||||
currSignLoc,
|
||||
shippingCharge,
|
||||
}) {
|
||||
return (
|
||||
<OrderItemContainer className={css.itemContainer}>
|
||||
<div className={css.itemHeader}>
|
||||
<CustomImage src={patncLogPath} alt="" className={css.patnrLogo} />
|
||||
<h2 className={css.prdtId}>ID: {prdtId}</h2>
|
||||
</div>
|
||||
<div className={css.itemContents}>
|
||||
<div className={css.leftContents}>
|
||||
<CustomImage
|
||||
src={imgUrls[0].imgUrl}
|
||||
alt=""
|
||||
className={css.itemImage}
|
||||
/>
|
||||
</div>
|
||||
<div className={css.rightContents}>
|
||||
<p className={css.prdtNm}>{prdtNm}</p>
|
||||
<p className={css.options}>Silver Metal / XL</p>
|
||||
<p className={css.prodQty}>Qty: {prodQty}</p>
|
||||
<p className={css.priceWrap}>
|
||||
<span className={css.itemPrice}>
|
||||
{currSignLoc === "L"
|
||||
? `${currSign} ${price3}`
|
||||
: `${price2 || price3} ${currSign}`}
|
||||
</span>
|
||||
{`${$L("S&H")}: `}
|
||||
{currSignLoc === "L"
|
||||
? `${currSign} ${shippingCharge || 0.0}`
|
||||
: `${shippingCharge || 0.0} ${currSign}`}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</OrderItemContainer>
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,110 @@
|
||||
@import "../../../style/CommonStyle.module.less";
|
||||
@import "../../../style/utils.module.less";
|
||||
|
||||
.itemContainer {
|
||||
.size(@w: 660px, @h: 333px);
|
||||
position: relative;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
background-color: @COLOR_WHITE;
|
||||
padding: 20px 0;
|
||||
|
||||
.itemHeader {
|
||||
padding: 0 30px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-bottom: 20px;
|
||||
border-bottom: 1px solid #dadada;
|
||||
|
||||
.patnrLogo {
|
||||
.size(@w: 42px, @h: 42px);
|
||||
border: 1px solid #dadada;
|
||||
border-radius: 50%;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.prdtId {
|
||||
.font(@fontFamily: @baseFont, @fontSize: 30px);
|
||||
color: #767676;
|
||||
}
|
||||
}
|
||||
|
||||
.itemContents {
|
||||
display: flex;
|
||||
padding-top: 20px;
|
||||
padding-left: 30px;
|
||||
padding-right: 30px;
|
||||
|
||||
.leftContents {
|
||||
.size(@w: 200px, @h: 200px);
|
||||
border: 1px solid #f0f0f0;
|
||||
margin-right: 20px;
|
||||
|
||||
.itemImage {
|
||||
.size(@w: 100%, @h: 100%);
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
.rightContents {
|
||||
.size(@w: calc(100% - 200px), @h: 200px);
|
||||
|
||||
.prdtNm {
|
||||
.font(@fontFamily: @baseFont, @fontSize: 24px);
|
||||
.elip(@clamp: 2);
|
||||
line-height: 1.33;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.options {
|
||||
font-size: 24px;
|
||||
line-height: 1.33;
|
||||
color: #808080;
|
||||
}
|
||||
|
||||
.prodQty {
|
||||
font-size: 24px;
|
||||
line-height: 1.33;
|
||||
color: #808080;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.priceWrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.font(@fontFamily: @baseFont, @fontSize: 24px);
|
||||
color: @COLOR_GRAY03;
|
||||
line-height: 1.33;
|
||||
|
||||
.itemPrice {
|
||||
.font(@fontFamily: @baseFont, @fontSize: 30px);
|
||||
font-weight: bold;
|
||||
color: @PRIMARY_COLOR_RED;
|
||||
line-height: 1.27;
|
||||
padding-right: 16px;
|
||||
margin-right: 16px;
|
||||
position: relative;
|
||||
|
||||
&:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 2px;
|
||||
height: 18px;
|
||||
background-color: @COLOR_GRAY03;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:focus {
|
||||
&::after {
|
||||
.focused(@boxShadow:22px, @borderRadius: 12px);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,61 +1,108 @@
|
||||
import React, { memo } from "react";
|
||||
import React, {
|
||||
memo,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useState,
|
||||
} from 'react';
|
||||
|
||||
import Spottable from "@enact/spotlight/Spottable";
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import TScroller from "../../../components/TScroller/TScroller";
|
||||
import CheckOutContainer from "./CheckOutContainer";
|
||||
import css from "./ShippingAddressCard.module.less";
|
||||
import SpotlightContainerDecorator
|
||||
from '@enact/spotlight/SpotlightContainerDecorator';
|
||||
|
||||
const ItemContainer = Spottable("div");
|
||||
import { updateSelectedShippingAddr } from '../../../actions/checkoutActions';
|
||||
import TCheckBox from '../../../components/TCheckBox/TCheckBox';
|
||||
import TScroller from '../../../components/TScroller/TScroller';
|
||||
import CheckOutContainer from './CheckOutContainer';
|
||||
import css from './ShippingAddressCard.module.less';
|
||||
|
||||
const ItemContainer = SpotlightContainerDecorator("li");
|
||||
|
||||
export default memo(function ShippingAddressCard({ list, ...rest }) {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const [selected, setSelected] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (list) {
|
||||
setSelected(list[0].dlvrAddrSno);
|
||||
dispatch(updateSelectedShippingAddr(list[0]?.dlvrAddrSno));
|
||||
}
|
||||
}, [dispatch, list]);
|
||||
|
||||
const handleSelectAddress = useCallback(
|
||||
(dlvrAddrSno) => {
|
||||
if (dlvrAddrSno !== selected) {
|
||||
setSelected(dlvrAddrSno);
|
||||
dispatch(updateSelectedShippingAddr(dlvrAddrSno));
|
||||
}
|
||||
},
|
||||
[dispatch, selected]
|
||||
);
|
||||
|
||||
export default memo(function ShippingAddressCard({ list }) {
|
||||
return (
|
||||
<CheckOutContainer className={css.shippingBox}>
|
||||
<TScroller className={css.shipping}>
|
||||
{list &&
|
||||
list.map(
|
||||
(
|
||||
{
|
||||
dlvrOdrFnm,
|
||||
dlvrOdrLnm,
|
||||
dlvrZpcd,
|
||||
dlvrStatNm,
|
||||
dlvrCityNm,
|
||||
dlvrDtlAddr,
|
||||
dlvrCtpt,
|
||||
dlvrEmalAddr,
|
||||
},
|
||||
index
|
||||
) => {
|
||||
return (
|
||||
<ItemContainer className={css.itemContainer} key={index}>
|
||||
<h2 className={css.title}>
|
||||
{dlvrOdrFnm} {dlvrOdrLnm}
|
||||
</h2>
|
||||
<div className={css.addressWrap}>
|
||||
<p>
|
||||
{dlvrZpcd} {dlvrStatNm}, <br />
|
||||
{dlvrCityNm} <br />
|
||||
{dlvrDtlAddr}
|
||||
</p>
|
||||
</div>
|
||||
<div className={css.cardFooter}>
|
||||
<p className={css.callNumber}>
|
||||
<span />
|
||||
{dlvrCtpt?.replace(
|
||||
/^(\d{2,3})(\d{3,4})(\d{4})$/,
|
||||
`$1-$2-$3`
|
||||
)}
|
||||
</p>
|
||||
<p className={css.email}>
|
||||
<span />
|
||||
{dlvrEmalAddr}
|
||||
</p>
|
||||
</div>
|
||||
</ItemContainer>
|
||||
);
|
||||
}
|
||||
)}
|
||||
<TScroller
|
||||
className={css.shipping}
|
||||
direction="horizontal"
|
||||
noScrollByWheel
|
||||
>
|
||||
<ul>
|
||||
{list &&
|
||||
list.map(
|
||||
(
|
||||
{
|
||||
dlvrOdrFnm,
|
||||
dlvrOdrLnm,
|
||||
dlvrZpcd,
|
||||
dlvrStatNm,
|
||||
dlvrCityNm,
|
||||
dlvrDtlAddr,
|
||||
dlvrCtpt,
|
||||
dlvrEmalAddr,
|
||||
dlvrAddrSno,
|
||||
},
|
||||
index
|
||||
) => {
|
||||
return (
|
||||
<ItemContainer
|
||||
className={css.itemContainer}
|
||||
key={index}
|
||||
{...rest}
|
||||
>
|
||||
<TCheckBox
|
||||
className={css.checkBox}
|
||||
selected={selected === dlvrAddrSno}
|
||||
onToggle={() => handleSelectAddress(dlvrAddrSno)}
|
||||
/>
|
||||
<h2 className={css.title}>
|
||||
{dlvrOdrFnm} {dlvrOdrLnm}
|
||||
</h2>
|
||||
<div className={css.addressWrap}>
|
||||
<p>
|
||||
{dlvrZpcd} {dlvrStatNm}, <br />
|
||||
{dlvrCityNm} <br />
|
||||
{dlvrDtlAddr}
|
||||
</p>
|
||||
</div>
|
||||
<div className={css.cardFooter}>
|
||||
<p className={css.callNumber}>
|
||||
<span />
|
||||
{dlvrCtpt?.replace(
|
||||
/^(\d{2,3})(\d{3,4})(\d{4})$/,
|
||||
`$1-$2-$3`
|
||||
)}
|
||||
</p>
|
||||
<p className={css.email}>
|
||||
<span />
|
||||
{dlvrEmalAddr}
|
||||
</p>
|
||||
</div>
|
||||
</ItemContainer>
|
||||
);
|
||||
}
|
||||
)}
|
||||
</ul>
|
||||
</TScroller>
|
||||
</CheckOutContainer>
|
||||
);
|
||||
|
||||
@@ -2,68 +2,94 @@
|
||||
@import "../../../style/utils.module.less";
|
||||
|
||||
.shippingBox {
|
||||
min-height: 383px;
|
||||
}
|
||||
|
||||
.itemContainer {
|
||||
.size(@w: 444px, @h: 348px);
|
||||
background-color: @BG_COLOR_05;
|
||||
border-radius: 12px;
|
||||
padding: 32px 30px;
|
||||
position: relative;
|
||||
.size(@w: 100%, @h:100%);
|
||||
min-height: 383px;
|
||||
|
||||
.title {
|
||||
color: @COLOR_GRAY06;
|
||||
font-weight: bold;
|
||||
font-size: 36px;
|
||||
margin-bottom: 19px;
|
||||
> div:nth-child(1) {
|
||||
.size(@w: inherit, @h: inherit);
|
||||
}
|
||||
|
||||
.addressWrap {
|
||||
color: @COLOR_GRAY03;
|
||||
line-height: 1.33;
|
||||
margin-bottom: 37px;
|
||||
font-size: 24px;
|
||||
}
|
||||
ul {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: inherit;
|
||||
|
||||
.cardFooter {
|
||||
font-weight: bold;
|
||||
font-size: 24px;
|
||||
color: @COLOR_GRAY03;
|
||||
.itemContainer {
|
||||
.size(@w: 444px, @h: 348px);
|
||||
background-color: @BG_COLOR_05;
|
||||
border-radius: 12px;
|
||||
padding: 32px 30px;
|
||||
position: relative;
|
||||
flex: none;
|
||||
margin-right: 12px;
|
||||
|
||||
.callNumber {
|
||||
padding-left: 42px;
|
||||
margin-bottom: 6px;
|
||||
|
||||
> span {
|
||||
background-image: url("../../../../assets/images/icons/ic-gr-call.svg");
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
.size(@w: 36px, @h: 36px);
|
||||
.checkBox {
|
||||
position: absolute;
|
||||
left: 30px;
|
||||
right: 20px;
|
||||
top: 20px;
|
||||
|
||||
&.focus {
|
||||
&::after {
|
||||
.focused(@boxShadow:22px, @borderRadius: 12px);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.email {
|
||||
padding-left: 42px;
|
||||
|
||||
> span {
|
||||
background-image: url("../../../../assets/images/icons/ic-gr-mail-36.svg");
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
.size(@w: 36px, @h: 36px);
|
||||
position: absolute;
|
||||
left: 30px;
|
||||
.title {
|
||||
color: @COLOR_GRAY06;
|
||||
font-weight: bold;
|
||||
font-size: 36px;
|
||||
margin-bottom: 19px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:focus {
|
||||
&::after {
|
||||
.focused(@boxShadow: 22px, @borderRadius: 12px);
|
||||
.addressWrap {
|
||||
color: @COLOR_GRAY03;
|
||||
line-height: 1.33;
|
||||
margin-bottom: 37px;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.cardFooter {
|
||||
font-weight: bold;
|
||||
font-size: 24px;
|
||||
color: @COLOR_GRAY03;
|
||||
|
||||
.callNumber {
|
||||
padding-left: 42px;
|
||||
margin-bottom: 6px;
|
||||
|
||||
> span {
|
||||
background-image: url("../../../../assets/images/icons/ic-gr-call.svg");
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
.size(@w: 36px, @h: 36px);
|
||||
position: absolute;
|
||||
left: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
.email {
|
||||
padding-left: 42px;
|
||||
|
||||
> span {
|
||||
background-image: url("../../../../assets/images/icons/ic-gr-mail-36.svg");
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
.size(@w: 36px, @h: 36px);
|
||||
position: absolute;
|
||||
left: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:focus {
|
||||
&::after {
|
||||
.focused(@boxShadow: 22px, @borderRadius: 12px);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,56 +1,31 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import React, {
|
||||
useEffect,
|
||||
useState,
|
||||
} from 'react';
|
||||
|
||||
import classNames from "classnames";
|
||||
import classNames from 'classnames';
|
||||
|
||||
import Spottable from "@enact/spotlight/Spottable";
|
||||
import SpotlightContainerDecorator
|
||||
from '@enact/spotlight/SpotlightContainerDecorator';
|
||||
import Spottable from '@enact/spotlight/Spottable';
|
||||
|
||||
import noCouponImg from "../../../../assets/images/img-checkout-coupon@3x.png";
|
||||
import TCheckBox from "../../../components/TCheckBox/TCheckBox";
|
||||
import css from "./FixedSideBar.module.less";
|
||||
import noCouponImg from '../../../../assets/images/img-checkout-coupon@3x.png';
|
||||
import TCheckBox from '../../../components/TCheckBox/TCheckBox';
|
||||
import TIconButton from '../../../components/TIconButton/TIconButton';
|
||||
import { $L } from '../../../utils/helperMethods';
|
||||
import css from './FixedSideBar.module.less';
|
||||
|
||||
const SpottableComponent = Spottable("div");
|
||||
const SpottableSmall = Spottable("div");
|
||||
const SideBarContainer = SpotlightContainerDecorator("div");
|
||||
|
||||
export default function FixedSideBar({ list, open }) {
|
||||
const [display, setDisplay] = useState(open);
|
||||
useEffect(() => {
|
||||
if (open) {
|
||||
setDisplay(true);
|
||||
} else {
|
||||
setDisplay(false);
|
||||
}
|
||||
}, [open]);
|
||||
const clickHandler = () => {
|
||||
setDisplay(false);
|
||||
};
|
||||
export default function FixedSideBar({ closeSideBar }) {
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className={classNames(
|
||||
css.fixedBg,
|
||||
display ? css.displayOn : css.displayOff
|
||||
)}
|
||||
></div>
|
||||
<div
|
||||
className={classNames(
|
||||
css.fixedSideBar,
|
||||
display ? css.displayOn : css.displayOff
|
||||
)}
|
||||
>
|
||||
{/* 기본 */}
|
||||
{/*
|
||||
<div className={classNames(css.bgLayer)} onClick={closeSideBar} />
|
||||
<SideBarContainer className={classNames(css.fixedSideBar)}>
|
||||
<div className={css.sideMainTitle}>
|
||||
<span />
|
||||
ORDER ITEM
|
||||
<TIconButton className={css.backButton} onClick={closeSideBar} />
|
||||
<h2 className={css.title}>{$L("OFFERS & PROMOTION")}</h2>
|
||||
</div>
|
||||
<div className={css.sideLine} />
|
||||
*/}
|
||||
{/* 추가 */}
|
||||
<div className={css.sideMainTitle} onClick={clickHandler}>
|
||||
<span />
|
||||
OFFERS & PROMOTION
|
||||
</div>
|
||||
<div className={css.sideLine} />
|
||||
<div className={css.sideCoupon}>
|
||||
<div className={css.right}>COUPON</div>
|
||||
<div className={css.left}>
|
||||
@@ -58,7 +33,6 @@ export default function FixedSideBar({ list, open }) {
|
||||
<TCheckBox onToggle={true} />
|
||||
</div>
|
||||
</div>
|
||||
<div className={css.sideLine} />
|
||||
|
||||
<div className={classNames(css.sideItemList, css.hasCoupon)}>
|
||||
<div className={css.sideItemTitle}>ITEM COUPON</div>
|
||||
@@ -118,7 +92,7 @@ export default function FixedSideBar({ list, open }) {
|
||||
})}
|
||||
*/}
|
||||
</div>
|
||||
</div>
|
||||
</SideBarContainer>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
@import "../../../style/CommonStyle.module.less";
|
||||
@import "../../../style/utils.module.less";
|
||||
.fixedBg {
|
||||
|
||||
.bgLayer {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
@@ -8,20 +9,9 @@
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
z-index: 11;
|
||||
&.displayOn {
|
||||
display: block;
|
||||
}
|
||||
&.displayOff {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.fixedSideBar {
|
||||
&.displayOn {
|
||||
display: block;
|
||||
}
|
||||
&.displayOff {
|
||||
display: none;
|
||||
}
|
||||
position: fixed;
|
||||
right: 0;
|
||||
top: 0;
|
||||
@@ -29,32 +19,38 @@
|
||||
height: 100%;
|
||||
background: #2c343f;
|
||||
z-index: 12;
|
||||
|
||||
.sideMainTitle {
|
||||
margin: 60px 13px 30px 19px;
|
||||
font-size: 42px;
|
||||
color: #f8f8f8;
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
> span {
|
||||
padding: 60px 30px 18px;
|
||||
border-bottom: 1px solid #d9d9d9;
|
||||
|
||||
.backButton {
|
||||
background-image: url("../../../../assets/images/btn/btn-wh-arrow-left-nor.svg");
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
background-size: contain;
|
||||
object-fit: cover;
|
||||
background-repeat: no-repeat;
|
||||
|
||||
&:focus {
|
||||
background-image: url("../../../../assets/images/btn/btn-wh-arrow-left-foc.svg");
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
.font(@fontFamily: @arialFontBold, @fontSize: 42px);
|
||||
line-height: 1.14;
|
||||
color: @BG_COLOR_01;
|
||||
}
|
||||
}
|
||||
.sideLine {
|
||||
border-bottom: 1px solid #d9d9d9;
|
||||
}
|
||||
|
||||
.sideCoupon {
|
||||
padding: 30px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
border-bottom: 1px solid #d9d9d9;
|
||||
|
||||
.right {
|
||||
height: 42px;
|
||||
font-size: 30px;
|
||||
|
||||
@@ -1,16 +1,27 @@
|
||||
import React, { useCallback, useState } from "react";
|
||||
import React, {
|
||||
useCallback,
|
||||
useState,
|
||||
} from 'react';
|
||||
|
||||
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
|
||||
import Spottable from "@enact/spotlight/Spottable";
|
||||
import {
|
||||
useDispatch,
|
||||
useSelector,
|
||||
} from 'react-redux';
|
||||
|
||||
import TButton from "../../../components/TButton/TButton";
|
||||
import { $L } from "../../../utils/helperMethods";
|
||||
import BillingAddressCard from "../components/BillingAddressCard";
|
||||
import PaymentCard from "../components/PaymentCard";
|
||||
import ShippingAddressCard from "../components/ShippingAddressCard";
|
||||
import Subject from "../components/Subject";
|
||||
import FixedSideBar from "./FixedSideBar.jsx";
|
||||
import css from "./InformationContainer.module.less";
|
||||
import SpotlightContainerDecorator
|
||||
from '@enact/spotlight/SpotlightContainerDecorator';
|
||||
import Spottable from '@enact/spotlight/Spottable';
|
||||
|
||||
import { updateSelectedShippingAddr } from '../../../actions/checkoutActions';
|
||||
import TButton from '../../../components/TButton/TButton';
|
||||
import { $L } from '../../../utils/helperMethods';
|
||||
import BillingAddressCard from '../components/BillingAddressCard';
|
||||
import PaymentCard from '../components/PaymentCard';
|
||||
import ShippingAddressCard from '../components/ShippingAddressCard';
|
||||
import Subject from '../components/Subject';
|
||||
import FixedSideBar from './FixedSideBar.jsx';
|
||||
import css from './InformationContainer.module.less';
|
||||
import OrderItemsSideBar from './OrderItemsSideBar';
|
||||
|
||||
const Container = SpotlightContainerDecorator(
|
||||
{ enterTo: "last-focused" },
|
||||
@@ -18,25 +29,23 @@ const Container = SpotlightContainerDecorator(
|
||||
);
|
||||
|
||||
const BtnSpot = Spottable("p");
|
||||
export default function InformationContainer({ checkoutData }) {
|
||||
console.log("###infomantion", checkoutData);
|
||||
const [open, setOpen] = useState(false);
|
||||
const handleClick = () => {
|
||||
if (open === false) {
|
||||
setOpen(true);
|
||||
} else {
|
||||
setOpen(false);
|
||||
}
|
||||
};
|
||||
|
||||
export default function InformationContainer({
|
||||
toggleOfferSideBar,
|
||||
toggleOrderSideBar,
|
||||
}) {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const checkoutData = useSelector((state) => state.checkout?.checkoutData);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Container className={css.container}>
|
||||
<Subject title="ORDER ITEMS" />
|
||||
<div className={css.markBtn}>
|
||||
<BtnSpot onClick={handleClick}>
|
||||
<BtnSpot onClick={toggleOrderSideBar}>
|
||||
{checkoutData.productList?.length} ITEMS
|
||||
</BtnSpot>
|
||||
<div className={css.markImg}></div>
|
||||
</div>
|
||||
<div className={css.listBox}>
|
||||
<Subject title="SHIPPING ADDRESS" />
|
||||
@@ -55,13 +64,11 @@ export default function InformationContainer({ checkoutData }) {
|
||||
</div>
|
||||
<div className={css.listBox}>
|
||||
<Subject title="OFFERS & PROMOTION" />
|
||||
<BtnSpot className={css.markBtn}>
|
||||
<p>$12.60</p>
|
||||
<div className={css.markImg}></div>
|
||||
</BtnSpot>
|
||||
<div className={css.markBtn}>
|
||||
<BtnSpot onClick={toggleOfferSideBar}>$12.60</BtnSpot>
|
||||
</div>
|
||||
</div>
|
||||
</Container>
|
||||
<FixedSideBar list={checkoutData?.productList} open={open} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -12,49 +12,81 @@
|
||||
right: 60px;
|
||||
height: 48px;
|
||||
display: flex;
|
||||
|
||||
> p {
|
||||
font-size: 30px;
|
||||
font-weight: bold;
|
||||
color: #c70850;
|
||||
line-height: 48px;
|
||||
}
|
||||
.markImg {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
background-image: url("../../../../assets/images/btn/btn-bk-arrow-right-nor.svg");
|
||||
background-size: contain;
|
||||
}
|
||||
&:focus {
|
||||
.markImg {
|
||||
background-image: url("../../../../assets/images/btn/btn-bk-arrow-right-foc.svg");
|
||||
position: relative;
|
||||
padding-right: 50px;
|
||||
|
||||
&:after {
|
||||
position: absolute;
|
||||
content: "";
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
background-image: url("../../../../assets/images/btn/btn-bk-arrow-right-nor.svg");
|
||||
background-size: contain;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
&:after {
|
||||
position: absolute;
|
||||
content: "";
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
background-image: url("../../../../assets/images/btn/btn-bk-arrow-right-foc.svg");
|
||||
background-size: contain;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.listBox {
|
||||
position: relative;
|
||||
|
||||
.markBtn {
|
||||
position: absolute;
|
||||
top: 24px;
|
||||
right: 60px;
|
||||
height: 48px;
|
||||
display: flex;
|
||||
|
||||
> p {
|
||||
font-size: 30px;
|
||||
font-weight: bold;
|
||||
color: #c70850;
|
||||
color: @PRIMARY_COLOR_RED;
|
||||
line-height: 48px;
|
||||
}
|
||||
.markImg {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
background-image: url("../../../../assets/images/btn/btn-bk-arrow-right-nor.svg");
|
||||
background-size: contain;
|
||||
}
|
||||
&:focus {
|
||||
.markImg {
|
||||
background-image: url("../../../../assets/images/btn/btn-bk-arrow-right-foc.svg");
|
||||
position: relative;
|
||||
padding-right: 50px;
|
||||
|
||||
&:after {
|
||||
position: absolute;
|
||||
content: "";
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
background-image: url("../../../../assets/images/btn/btn-bk-arrow-right-nor.svg");
|
||||
background-size: contain;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
&:after {
|
||||
position: absolute;
|
||||
content: "";
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
background-image: url("../../../../assets/images/btn/btn-bk-arrow-right-foc.svg");
|
||||
background-size: contain;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
import React, { useCallback } from 'react';
|
||||
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import SpotlightContainerDecorator
|
||||
from '@enact/spotlight/SpotlightContainerDecorator';
|
||||
|
||||
import TIConButton from '../../../components/TIconButton/TIconButton';
|
||||
import TVirtualGridList
|
||||
from '../../../components/TVirtualGridList/TVirtualGridList';
|
||||
import { $L } from '../../../utils/helperMethods';
|
||||
import OrderItemCard, { SIZES } from '../components/OrderItemCard';
|
||||
import css from './OrderItemsSideBar.module.less';
|
||||
|
||||
const SideBarContainer = SpotlightContainerDecorator("div");
|
||||
|
||||
export default function OrderItemsSideBar({ closeSideBar }) {
|
||||
const orderItemList = useSelector(
|
||||
(state) => state.checkout?.checkoutData?.productList
|
||||
);
|
||||
|
||||
console.log("chw", orderItemList);
|
||||
|
||||
const renderItem = useCallback(
|
||||
({ index, ...rest }) => {
|
||||
const item = orderItemList[index];
|
||||
|
||||
return (
|
||||
<OrderItemCard
|
||||
{...rest}
|
||||
key={index}
|
||||
imgUrls={item.imgUrls}
|
||||
prdtNm={item.prdtNm}
|
||||
prodQty={item.prodQty}
|
||||
price2={item.price2}
|
||||
price3={item.price3}
|
||||
prodOpt={item.prodOpt}
|
||||
patncLogPath={item.patncLogPath}
|
||||
prdtId={item.prdtId}
|
||||
currSign={item.currSign}
|
||||
currSignLoc={item.currSignLoc}
|
||||
shippingCharge={item.shippingCharge}
|
||||
/>
|
||||
);
|
||||
},
|
||||
[orderItemList]
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={css.bgLayer} onClick={closeSideBar} />
|
||||
<SideBarContainer className={css.container}>
|
||||
<div className={css.titleBox}>
|
||||
<TIConButton className={css.backButton} onClick={closeSideBar} />
|
||||
<h2 className={css.title}>{$L("ORDER ITEMS")}</h2>
|
||||
</div>
|
||||
<div className={css.orderItemListsWrap}>
|
||||
{orderItemList && orderItemList.length > 0 ? (
|
||||
<TVirtualGridList
|
||||
className={css.grid}
|
||||
itemRenderer={renderItem}
|
||||
dataSize={orderItemList.length}
|
||||
itemWidth={SIZES.itemWidth}
|
||||
itemHeight={SIZES.itemHeight}
|
||||
spacing={SIZES.spacing}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
</SideBarContainer>
|
||||
;
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
@import "../../../style/CommonStyle.module.less";
|
||||
@import "../../../style/utils.module.less";
|
||||
|
||||
.bgLayer {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
z-index: 11;
|
||||
}
|
||||
|
||||
.container {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 720px;
|
||||
height: 100%;
|
||||
background-color: #2c343f;
|
||||
z-index: 12;
|
||||
|
||||
.titleBox {
|
||||
display: flex;
|
||||
padding: 60px 30px 18px;
|
||||
border-bottom: 1px solid #d9d9d9;
|
||||
|
||||
.backButton {
|
||||
background-image: url("../../../../assets/images/btn/btn-wh-arrow-left-nor.svg");
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
object-fit: cover;
|
||||
background-repeat: no-repeat;
|
||||
|
||||
&:focus {
|
||||
background-image: url("../../../../assets/images/btn/btn-wh-arrow-left-foc.svg");
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
.font(@fontFamily: @arialFontBold, @fontSize: 42px);
|
||||
line-height: 1.14;
|
||||
color: @BG_COLOR_01;
|
||||
}
|
||||
}
|
||||
|
||||
.orderItemListsWrap {
|
||||
.size(@w: 100%, @h: 100%);
|
||||
margin-top: 30px;
|
||||
|
||||
.grid {
|
||||
padding: 0 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,6 @@
|
||||
.size(@w: 315px, @h: 265px);
|
||||
position: relative;
|
||||
border-radius: 12px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
.itemContainer {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import React, { memo } from "react";
|
||||
import React, { memo } from 'react';
|
||||
|
||||
import Spottable from "@enact/spotlight/Spottable";
|
||||
import Spottable from '@enact/spotlight/Spottable';
|
||||
|
||||
import css from "./BillingAddressItem.module.less";
|
||||
import css from './BillingAddressItem.module.less';
|
||||
|
||||
const ItemContainer = Spottable("div");
|
||||
|
||||
@@ -15,9 +15,10 @@ export default memo(function BillingAddressItem({
|
||||
bilDtlAddr,
|
||||
bilCtpt,
|
||||
bilEmalAddr,
|
||||
...rest
|
||||
}) {
|
||||
return (
|
||||
<ItemContainer className={css.itemContainer}>
|
||||
<ItemContainer className={css.itemContainer} {...rest}>
|
||||
<h2 className={css.title}>
|
||||
{bilOdrFnm} {bilOdrLnm}
|
||||
</h2>
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import React, { useCallback } from "react";
|
||||
import React, { useCallback } from 'react';
|
||||
|
||||
import { useSelector } from "react-redux";
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import TVirtualGridList from "../../../../../../components/TVirtualGridList/TVirtualGridList";
|
||||
import useScrollTo from "../../../../../../hooks/useScrollTo";
|
||||
import MyInfoNoResults from "../MyInfoNoResults/MyInfoNoResults";
|
||||
import MyInfoTabContentsContainer from "../MyInfoTabContentsContainer";
|
||||
import BillingAddressItem from "./BillingAddressItem";
|
||||
import css from "./BillingAddressTab.module.less";
|
||||
import TVirtualGridList
|
||||
from '../../../../../../components/TVirtualGridList/TVirtualGridList';
|
||||
import useScrollTo from '../../../../../../hooks/useScrollTo';
|
||||
import MyInfoNoResults from '../MyInfoNoResults/MyInfoNoResults';
|
||||
import MyInfoTabContentsContainer from '../MyInfoTabContentsContainer';
|
||||
import BillingAddressItem from './BillingAddressItem';
|
||||
import css from './BillingAddressTab.module.less';
|
||||
|
||||
export const ITEM_SIZE = {
|
||||
itemWidth: 444,
|
||||
@@ -44,6 +45,7 @@ export default function BillingAddressTab() {
|
||||
|
||||
return (
|
||||
<BillingAddressItem
|
||||
{...rest}
|
||||
key={index}
|
||||
bilOdrFnm={bilOdrFnm}
|
||||
bilOdrLnm={bilOdrLnm}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
.grid {
|
||||
overflow: hidden;
|
||||
|
||||
> div {
|
||||
height: 348px;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import React, { memo } from "react";
|
||||
import React, { memo } from 'react';
|
||||
|
||||
import Spottable from "@enact/spotlight/Spottable";
|
||||
import Spottable from '@enact/spotlight/Spottable';
|
||||
|
||||
import css from "./ShippingAddressItem.module.less";
|
||||
import css from './ShippingAddressItem.module.less';
|
||||
|
||||
const ItemContainer = Spottable("div");
|
||||
|
||||
@@ -15,9 +15,10 @@ export default memo(function ShippingAddressItem({
|
||||
dlvrDtlAddr,
|
||||
dlvrCtpt,
|
||||
dlvrEmalAddr,
|
||||
...rest
|
||||
}) {
|
||||
return (
|
||||
<ItemContainer className={css.itemContainer}>
|
||||
<ItemContainer className={css.itemContainer} {...rest}>
|
||||
<h2 className={css.title}>
|
||||
{dlvrOdrFnm} {dlvrOdrLnm}
|
||||
</h2>
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import React, { useCallback } from "react";
|
||||
import React, { useCallback } from 'react';
|
||||
|
||||
import { useSelector } from "react-redux";
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import TVirtualGridList from "../../../../../../components/TVirtualGridList/TVirtualGridList";
|
||||
import useScrollTo from "../../../../../../hooks/useScrollTo";
|
||||
import { ITEM_SIZE } from "../BillingAddressTab/BillingAddressTab";
|
||||
import MyInfoNoResults from "../MyInfoNoResults/MyInfoNoResults";
|
||||
import MyInfoTabContentsContainer from "../MyInfoTabContentsContainer";
|
||||
import ShippingAddressItem from "./ShippingAddressItem";
|
||||
import css from "./ShippingAddressTab.module.less";
|
||||
import TVirtualGridList
|
||||
from '../../../../../../components/TVirtualGridList/TVirtualGridList';
|
||||
import useScrollTo from '../../../../../../hooks/useScrollTo';
|
||||
import { ITEM_SIZE } from '../BillingAddressTab/BillingAddressTab';
|
||||
import MyInfoNoResults from '../MyInfoNoResults/MyInfoNoResults';
|
||||
import MyInfoTabContentsContainer from '../MyInfoTabContentsContainer';
|
||||
import ShippingAddressItem from './ShippingAddressItem';
|
||||
import css from './ShippingAddressTab.module.less';
|
||||
|
||||
export default function ShippingAddressTab() {
|
||||
const shippingDatas = useSelector((state) => state.shipping.shippingData);
|
||||
@@ -39,6 +40,7 @@ export default function ShippingAddressTab() {
|
||||
|
||||
return (
|
||||
<ShippingAddressItem
|
||||
{...rest}
|
||||
key={index}
|
||||
dlvrOdrFnm={dlvrOdrFnm}
|
||||
dlvrOdrLnm={dlvrOdrLnm}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
.grid {
|
||||
overflow: hidden;
|
||||
|
||||
> div {
|
||||
height: 348px;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user