[checkout] 금일까지 작업되어있는 부분 업로드

This commit is contained in:
junghoon86.park
2024-04-14 17:22:09 +09:00
parent 3945a3a1f4
commit 9f6e2ab51d
14 changed files with 659 additions and 68 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -33,6 +33,8 @@ const KINDS = [
"exitPopup",
"couponPopup",
"mobileSendPopup",
"qrPopup",
"checkoutTermsPopup",
];
export default function TPopUp({

View File

@@ -305,4 +305,84 @@
.info {
.size(@w: 780px , @h: 750px);
}
.buttonContainer {
display: flex;
justify-content: center;
padding: 30px 0;
> div {
margin-top: 2;
min-width: 340px;
height: 80px;
margin: 0 10px;
background: @COLOR_GRAY09;
}
}
}
.checkoutTermsPopup {
.info {
.size(@w: 1100px , @h: 750px);
padding: 60px 60px 30px 60px;
background-color: @BG_COLOR_01;
color: @COLOR_GRAY03;
display: flex;
flex-direction: column;
font-weight: normal;
box-sizing: border-box;
border-radius: 4px;
.textLayer {
width: 100%;
padding-bottom: 35px;
border-bottom: 1px solid #dadada;
.text {
min-height: 126px;
color: #1a1a1a;
font-size: 36px;
line-height: 42px;
text-align: left;
font-weight: bold;
.flex();
}
}
> div:nth-child(2) {
margin-top: 30px;
.size(@w: 980px, @h: 67px);
}
> div:nth-child(3) {
.size(@w:980px,@h:300px);
overflow-y: scroll;
font-size: 24px;
line-height: 32px;
padding: 30px 30px 0 30px;
&::-webkit-scrollbar {
width: 8px;
height: 300px;
}
&::-webkit-scrollbar-track-piece {
background-color: #fff;
}
&::-webkit-scrollbar-thumb {
background-color: #7a808d;
}
}
}
.buttonContainer {
display: flex;
justify-content: center;
padding: 30px 0;
> div {
min-width: 300px;
height: 78px;
margin: 0 10px;
background: @COLOR_GRAY09;
font-size: 30px;
&:focus {
box-shadow: 0px 18px 28.2px 1.8px rgba(62, 59, 59, 0.4);
background-color: @PRIMARY_COLOR_RED;
color: @COLOR_WHITE;
}
}
}
}

View File

@@ -9,6 +9,9 @@ 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";
@@ -18,7 +21,7 @@ export default function CheckOutPanel() {
(state) => state.common.appStatus.loginUserData
);
const checkoutData = useSelector((state) => state.checkout?.checkoutData);
console.log("###shippingAddressList", checkoutData);
const testData = useSelector((state) => state);
useEffect(() => {
dispatch(
getMyInfoCheckoutInfo({
@@ -50,13 +53,15 @@ export default function CheckOutPanel() {
onBackButton
onClick={onBackClick}
/>
<div className={css.Wrap}>
<SummaryContainer userInfo={userInfo} />
<InformationContainer checkoutData={checkoutData} />
</div>
<CheckoutQRCode open={false} />
</TBody>
</TPanel>
{/* <CheckOutTerms /> 약관부분 */}
{/* <PinCode /> */}
</>
);
}

View File

@@ -15,62 +15,46 @@ export const ITEM_SIZE = {
export default function BillingAddressCard({ list }) {
const { getScrollTo, scrollLeft } = useScrollTo();
const renderItem = useCallback(
({ index, ...rest }) => {
const {
bilAddrSno,
bilCityNm,
bilCtpt,
bilDtlAddr,
bilEmalAddr,
bilOdrFnm,
bilOdrLnm,
bilStatNm,
bilStatPvc,
bilZpcd,
chgDt,
cntryCd,
cntryNm,
mbrNo,
regDt,
useFlag,
} = list[index];
return (
<BillingAddressItem
key={index}
bilOdrFnm={bilOdrFnm}
bilOdrLnm={bilOdrLnm}
bilZpcd={bilZpcd}
bilStatNm={bilStatNm}
bilCityNm={bilCityNm}
bilDtlAddr={bilDtlAddr}
bilCtpt={bilCtpt}
bilEmalAddr={bilEmalAddr}
/>
);
},
[list]
);
return (
<CheckOutContainer>
<div className={css.billingBox}>
{list && list.length > 0 ? (
<TVirtualGridList
cbScrollTo={getScrollTo}
className={css.grid}
dataSize={list.length}
renderItem={renderItem}
direction="horizontal"
itemWidth={ITEM_SIZE.itemWidth}
itemHeight={ITEM_SIZE.itemHeight}
spacing={ITEM_SIZE.spacing}
/>
) : (
<MyInfoNoResults type="BILLING ADDRESS" />
)}
{list &&
list.map(
(
{
bilAddrSno,
bilCityNm,
bilCtpt,
bilDtlAddr,
bilEmalAddr,
bilOdrFnm,
bilOdrLnm,
bilStatNm,
bilStatPvc,
bilZpcd,
chgDt,
cntryCd,
cntryNm,
mbrNo,
regDt,
useFlag,
},
index
) => {
<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>
);

View File

@@ -0,0 +1,68 @@
import React, { useCallback, useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import Spotlight from "@enact/spotlight";
import TButtonTab from "../../../components/TButtonTab/TButtonTab";
import TPopUp from "../../../components/TPopUp/TPopUp";
import { $L } from "../../../utils/helperMethods";
import css from "./CheckOutTerms.module.less";
export default function CheckOutTerms() {
const dispatch = useDispatch();
const termsData = useSelector((state) => state.home.termsData);
const introTermsData = termsData?.data?.terms.filter(
(item) => item.trmsTpCd === "MST00401" || item.trmsTpCd === "MST00402"
);
const [selectedTab, setSelectedTab] = useState(0);
const [currentTerms, setCurrentTerms] = useState(null);
const handleTermsClick = useCallback(({ index }) => {
setSelectedTab(index);
if (index === 0) {
setCurrentTerms(
introTermsData.filter((item) => item.trmsTpCd === "MST00401")[0]
);
} else {
setCurrentTerms(
introTermsData.filter((item) => item.trmsTpCd === "MST00402")[0]
);
}
}, []);
useEffect(() => {
handleTermsClick(0);
Spotlight.focus("tab-0");
}, [introTermsData, dispatch]);
const description =
$L(`Check out more LIVE SHOWS and enjoy Shopping via your TV \n at Shop Times special prices by agreeing to the LG TV
Shopping Terms and Conditions`);
const checkOut = [$L("Terms of Purchase"), $L("Privacy Policy")];
return (
<TPopUp
kind="checkoutTermsPopup"
open={true}
hasButton
hasText
text={description}
button1Text={$L("AGREE")}
button2Text={$L("DO NOT AGREE")}
>
<TButtonTab
className={css.tTab}
contents={checkOut}
onItemClick={handleTermsClick}
selectedIndex={selectedTab && selectedTab}
/>
<div
className={css.termsInfo}
dangerouslySetInnerHTML={{
__html: currentTerms && currentTerms.trmsCntt,
}}
/>
</TPopUp>
);
}

View File

@@ -0,0 +1,106 @@
@import "../../../style/CommonStyle.module.less";
@import "../../../style/utils.module.less";
.panel {
> section {
color: @COLOR_GRAY06;
}
}
.introLayout {
.flex(@direction: column);
background-color: @BG_COLOR_03;
text-align: center;
width: 100%;
height: 100vh;
.title {
font-size: 60px;
padding: 44px 201px;
white-space: pre-wrap;
line-height: normal;
}
.txtPoint {
font-weight: bold;
font-size: 74px;
color: #57585a;
}
.pointColor {
color: #c91d53;
}
.description {
white-space: pre-wrap;
line-height: normal;
font-size: 36px;
padding: 0 10px;
padding-top: 14px;
}
.termsItemsLayer {
display: flex;
margin: 113px 0 120px 0;
}
.bottomBtnLayer {
margin-top: 50px;
.flex();
}
}
.checkoutTermsPopup {
.info {
.size(@w: 1100px , @h: 750px);
padding: 60px 60px 30px 60px;
background-color: @BG_COLOR_01;
color: @COLOR_GRAY03;
display: flex;
flex-direction: column;
font-weight: normal;
box-sizing: border-box;
border-radius: 4px;
.textLayer {
width: 100%;
.title {
text-align: left;
font-size: 36px;
font-weight: bold;
line-height: normal;
color: @COLOR_BLACK;
background-color: @COLOR_SKYBLUE;
padding: 30px 60px;
}
.text {
min-height: 126px;
padding-bottom: 30px;
color: #1a1a1a;
font-size: 36px;
line-height: 42px;
text-align: left;
font-weight: bold;
.flex();
border-bottom: 1px solid #dadada;
}
}
.tTab {
width: 100%;
}
.buttonContainer {
display: flex;
justify-content: center;
padding: 30px 0;
> div {
min-width: 300px;
height: 80px;
margin: 0 10px;
background: @COLOR_GRAY09;
}
}
}
}

View File

@@ -0,0 +1,28 @@
import React, { useState } from "react";
import TPopUp from "../../../components/TPopUp/TPopUp";
import { $L } from "../../../utils/helperMethods";
import css from "./CheckoutQRCode.module.less";
export default function CheckoutQRCode(open) {
const handleCancel = () => {
setOpen(false);
};
const [_open, setOpen] = useState(open);
return (
<>
<TPopUp
open={_open}
kind="qrPopup"
hasButton
button1Text={$L("CLOSE")}
hasText
title={$L("QR CODE")}
text={$L(
"If you want to add or edit your address and payment information, please scan the QR CODE."
)}
onClose={handleCancel}
></TPopUp>
</>
);
}

View File

@@ -0,0 +1,79 @@
import React, { useState } from "react";
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
import Spottable from "@enact/spotlight/Spottable";
import TButton from "../../../components/TButton/TButton";
import { $L } from "../../../utils/helperMethods";
import css from "./PinCode.module.less";
const Container = SpotlightContainerDecorator(
{ enterTo: "last-focused" },
"div"
);
const ContainerCode = SpotlightContainerDecorator(
{ enterTo: "last-focused" },
"div"
);
const ContainerNum = SpotlightContainerDecorator(
{ enterTo: "default-element" },
"div"
);
const SpottableDiv = Spottable("div");
const SpottableBtn = Spottable("button");
export default function PinCode() {
const [numOne, setNumOne] = useState(null);
const [numTwo, setNumTwo] = useState(null);
const [numThree, setNumThree] = useState(null);
const [numFour, setNumFour] = useState(null);
const _onClick = () => {};
const _onClose = () => {};
return (
<Container className={css.container}>
<div className={css.title}>Enter PIN CODE</div>
<ContainerCode className={css.pinCodeBox}>
<SpottableDiv className={css.pinCode} spotlightId={"code_One"}>
{numOne}
</SpottableDiv>
<SpottableDiv className={css.pinCode} spotlightId={"code_Two"}>
{numTwo}
</SpottableDiv>
<SpottableDiv className={css.pinCode} spotlightId={"code_Three"}>
{numThree}
</SpottableDiv>
<SpottableDiv className={css.pinCode} spotlightId={"code_Four"}>
{numFour}
</SpottableDiv>
<input type="hidden" name={"pinCode"} value />
</ContainerCode>
<div className={css.errorText}>
{/* The purchase cannot be processed with the registered payment
information. Please check your payment information again. */}
</div>
<ContainerNum className={css.pinCodeSelector}>
<SpottableBtn spotlightId={"PinCode_1"}>1</SpottableBtn>
<SpottableBtn spotlightId={"PinCode_2"}>2</SpottableBtn>
<SpottableBtn spotlightId={"PinCode_3"}>3</SpottableBtn>
<SpottableBtn spotlightId={"PinCode_4"}>4</SpottableBtn>
<SpottableBtn spotlightId={"PinCode_5"}>5</SpottableBtn>
<SpottableBtn spotlightId={"PinCode_6"}>6</SpottableBtn>
<SpottableBtn spotlightId={"PinCode_7"}>7</SpottableBtn>
<SpottableBtn spotlightId={"PinCode_8"}>8</SpottableBtn>
<SpottableBtn spotlightId={"PinCode_9"}>9</SpottableBtn>
<SpottableBtn spotlightId={"PinCode_0"}>0</SpottableBtn>
<SpottableBtn spotlightId={"PinCode_DelBtn"}></SpottableBtn>
</ContainerNum>
<div className={css.buttonContainer}>
<TButton spotlightId="tPopupBtn1" onClick={_onClick}>
{$L("Cancel")}
</TButton>
<TButton spotlightId="tPopupBtn2" onClick={_onClose}>
{$L("OK")}
</TButton>
</div>
</Container>
);
}

View File

@@ -0,0 +1,106 @@
@import "../../../style/CommonStyle.module.less";
@import "../../../style/utils.module.less";
.container {
width: 1920px;
height: 1080px;
background-color: #000;
.title {
margin: 120px auto 0;
text-align: center;
font-size: 72px;
font-weight: 200;
color: #e6e6e6;
width: 1320px;
height: 84px;
line-height: 84px;
}
.pinCodeBox {
margin: 162px auto 0;
width: 534px;
height: 144px;
display: flex;
.pinCode {
width: 120px;
height: 144px;
border-radius: 6px;
background-color: #e6e6e6;
margin-right: 18px;
opacity: 0.15;
&:focus {
background-color: #fff;
opacity: 1;
}
&:last-child {
margin-right: 0;
}
}
}
.errorText {
margin: 24px auto 60px;
height: 66px;
width: 1070px;
text-align: center;
display: flex;
font-size: 30px;
color: #fb5656;
align-items: center;
}
.pinCodeSelector {
width: 924px;
height: 84px;
margin: 0 auto;
display: flex;
> button {
width: 84px;
height: 84px;
line-height: 84px;
text-align: center;
color: #e6e6e6;
font-size: 42px;
font-weight: bold;
&:focus {
background: #fff;
color: #4c5059;
border-radius: 6px;
font-weight: bold;
}
&:last-child {
background: url("../../../../assets/images/icons/ic-delete-nor@3x.png");
background-size: contain;
&:focus {
background: url("../../../../assets/images/icons/ic-delete-foc@3x.png");
background-size: contain;
}
}
}
}
.buttonContainer {
display: flex;
justify-content: center;
margin-top: 168px;
> div {
width: 270px;
height: 72px;
line-height: 72px;
font-weight: 200;
margin: 0 10px;
background: @COLOR_GRAY09;
&:focus {
box-shadow: 0px 18px 28.2px 1.8px rgba(62, 59, 59, 0.4);
background-color: @PRIMARY_COLOR_RED;
color: @COLOR_WHITE;
transform: translateY(3%) translateX(-3%) scale(1.1);
}
&:last-child {
&:focus {
box-shadow: 0px 18px 28.2px 1.8px rgba(62, 59, 59, 0.4);
background-color: @PRIMARY_COLOR_RED;
color: @COLOR_WHITE;
transform: translateY(3%) translateX(3%) scale(1.1);
}
}
}
}
}

View File

@@ -2,8 +2,15 @@ import React, { useEffect, useState } from "react";
import classNames from "classnames";
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";
const SpottableComponent = Spottable("div");
const SpottableSmall = Spottable("div");
export default function FixedSideBar({ list, open }) {
const [display, setDisplay] = useState(open);
useEffect(() => {
@@ -44,45 +51,72 @@ export default function FixedSideBar({ list, open }) {
OFFERS & PROMOTION
</div>
<div className={css.sideLine} />
<div className={css.sideCoupon}></div>
<div className={css.sideCoupon}>
<div className={css.right}>COUPON</div>
<div className={css.left}>
Maximum Benefit
<TCheckBox onToggle={true} />
</div>
</div>
<div className={css.sideLine} />
<div className={css.sideItemList}>
<div className={classNames(css.sideItemList, css.hasCoupon)}>
<div className={css.sideItemTitle}>ITEM COUPON</div>
<div className={css.noRegiCoupon}>
<div className={css.noRegiCouponBg}></div>
<div className={css.noRegiCouponInfo}>
<img src={noCouponImg} />
<p>There are no registered coupons.</p>
</div>
</div>
{/*
{list &&
list.length > 0 &&
list.map((item, index) => {
return (
<div className={css.sideItem} key={index}>
<SpottableComponent
className={classNames(css.sideItem, css.hasCoupon)}
key={index}
>
{/* 하단부분 드랍다운 없을시에 hasCoupon 없어야 함
<div className={css.sideTitle}>
<img src={item.patncLogPath} className={css.sideLogoImg} />
ID: {item.prdtId}
</div>
<div className={css.sideLine} />
<div className={css.productInfo}>
<div className={classNames(css.productInfo, css.hasCoupon)}>
<div className={css.productImg}>
<img src={item.imgUrls[0].imgUrl} />
</div>
<div className={css.pdInfo}>
<div className={css.pdName}>{item.prdtNm}</div>
<div className={css.pdOpt}>
{/* 일반가격 정확하게 몰라서 우선 최종가격있을때는 최종가격 노출되도록 변경.
{/* <div className={css.pdOpt}>
{item.prdtOpt[0].prodOptCval}
</div>
<div className={css.pdEa}>QTY : {item.prodQty}</div>
{/* 일반가격 정확하게 몰라서 우선 최종가격있을때는 최종가격 노출되도록 변경. */}
{/* <div className={css.pdPriceInfo}>
<div className={css.pdEa}>
QTY : {item.prodQty}
</div>
<div className={css.pdPriceInfo}>
$ {item.price3 !== 0 ? item.price3 : item.price2}
<span> | S&H{item.shippingCharge}</span>
</div> */}
{/* 노출 경로부분 확인필요 */}
<div className={css.paidInfo}>
</div>
노출 경로부분 확인필요
<div className={classNames(css.paidInfo, css.hasCoupon)}>
<span /> Purchased products will be paid at the final
price.
</div>
</div>
</div>
</div>
<div className={css.dropDown}>5%($2.09) discount applied</div>
<div className={css.dropDown}>No discount applied</div>
</SpottableComponent>
);
})}
*/}
</div>
</div>
</>

View File

@@ -50,14 +50,81 @@
.sideLine {
border-bottom: 1px solid #d9d9d9;
}
.sideCoupon {
padding: 30px;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
.right {
height: 42px;
font-size: 30px;
font-weight: bold;
color: #fff;
line-height: 42px;
}
.left {
height: 42px;
display: flex;
font-size: 24px;
font-weight: normal;
color: #ccc;
line-height: 42px;
align-items: center;
}
}
.sideItemList {
padding: 30px;
.sideItemTitle {
font-size: 30px;
color: #fff;
font-weight: bold;
width: 660px;
height: 42px;
margin-bottom: 12px;
}
.noRegiCoupon {
width: 660px;
height: 312px;
text-align: center;
position: relative;
.noRegiCouponBg {
position: absolute;
left: 0;
top: 0;
width: 660px;
height: 312px;
background-color: #000;
opacity: 0.2;
}
.noRegiCouponInfo {
width: 660px;
height: 312px;
padding: 42px 150px 52px 150px;
position: absolute;
left: 0;
top: 0;
z-index: 1;
> img {
width: 360px;
height: 180px;
}
> p {
color: #8290a0;
font-size: 24px;
font-weight: normal;
}
}
}
.sideItem {
width: 660px;
height: 333px;
min-height: 333px;
background: #fff;
border-radius: 12px;
margin-bottom: 12px;
padding-bottom: 10px;
&.hasCoupon {
height: auto;
}
.sideTitle {
padding: 20px 30px;
color: #767676;
@@ -73,6 +140,9 @@
padding: 20px 30px 30px;
display: flex;
flex-wrap: wrap;
&.hasCoupon {
padding: 30px 30px 10px 30px;
}
.productImg {
border: 1px solid #f0f0f0;
width: 200px;
@@ -139,6 +209,9 @@
background-color: #dadada;
line-height: 1.56;
border-radius: 5px;
&.hasCoupon {
margin-top: 66px;
}
> span {
width: 18px;
height: 18px;
@@ -149,6 +222,32 @@
}
}
}
.dropDown {
margin: 0 30px 10px 30px;
width: 600px;
height: 90px;
border: 1px solid #dadada;
position: relative;
font-size: 24px;
border-radius: 12px;
text-align: center;
line-height: 90px;
background-image: url("../../../../assets/images/btn/btn-dropdown-nor@3x.png");
background-position: 528px center;
background-repeat: no-repeat;
background-size: 42px 43px;
&:focus {
font-weight: bold;
color: @PRIMARY_COLOR_RED;
background-image: url("../../../../assets/images/btn/btn-dropdown-foc@3x.png");
background-position: 528px center;
background-repeat: no-repeat;
background-size: 42px 43px;
&::after {
.focused(@boxShadow: 0, @borderRadius: 12px);
}
}
}
}
}
}