[TFullPopup] 풀팝업 제작 /

[CheckoutPanel] 체크아웃 작업 진행 중 - 핀코드 /
[CustomImage] 이미지 보이지 않던 현상 수정 (확인 필요)
This commit is contained in:
hyunwoo93.cha
2024-05-22 16:32:08 +09:00
parent d351c4c2ee
commit 193acdde79
13 changed files with 343 additions and 15 deletions

View File

@@ -158,4 +158,7 @@ export const types = {
// emp actions
GET_SHOPTIME_TERMS: "GET_SHOPTIME_TERMS",
// pinCode actions
GET_MY_INFO_CARD_PINCODE_CHECK: "GET_MY_INFO_CARD_PINCODE_CHECK",
};

View File

@@ -0,0 +1,32 @@
import { URLS } from '../api/apiConfig';
import { TAxios } from '../api/TAxios';
import { types } from './actionTypes';
// 회원 등록카드 PIN CODE 입력 체크 IF-LGSP-336
export const getMyInfoCardPincodeCheck = (params) => (dispatch, getState) => {
const { mbrNo, pinCd } = params;
const onSuccess = (response) => {
console.log("getMyInfoCardPincodeCheck onSuccess ", response.data);
dispatch({
type: types.GET_MY_INFO_CARD_PINCODE_CHECK,
payload: response.data.data,
});
};
const onFail = (error) => {
console.error("getMyInfoCardPincodeCheck onFail ", error);
};
TAxios(
dispatch,
getState,
"get",
URLS.GET_MY_INFO_CARD_PINCODE_CHECK,
{ mbrNo, pinCd },
{},
onSuccess,
onFail
);
};

View File

@@ -128,6 +128,9 @@ export const URLS = {
// emp controller
GET_SHOPTIME_TERMS: "/lgsp/m/v1/emp/shoptime/terms.lge",
// pinCode controller
GET_MY_INFO_CARD_PINCODE_CHECK: "/lgsp/v1/myinfo/card/pincode/check.lge",
// IF-LGSP-LOG-001 log live controller
LOG_LIVE: "/lgsp/v1/log/live.lge",

View File

@@ -3,13 +3,19 @@
*
* @module CustomImage
*/
import React, { memo, useCallback, useEffect, useRef, useState } from "react";
import React, {
memo,
useCallback,
useEffect,
useRef,
useState,
} from 'react';
import classNames from "classnames";
import classNames from 'classnames';
import { Job } from "@enact/core/util";
import { Job } from '@enact/core/util';
import css from "./CustomImage.module.less";
import css from './CustomImage.module.less';
//animationSpeed : "slow", "normal", "fast", ==> 500ms, 250ms, 10ms
export default memo(function CustomImage({
@@ -34,14 +40,17 @@ export default memo(function CustomImage({
useEffect(() => {
setImageLoaded(false);
setImgSrc(src);
setError(false);
showImageJob.current.stop();
}, [src]);
useEffect(() => {
return () => {
showImageJob.current.stop();
};
}, [src]);
}, []);
const _onLoad = useCallback(() => {
showImageJob.current.start(setImageLoaded);

View File

@@ -0,0 +1,48 @@
import React, { useCallback } from 'react';
import classNames from 'classnames';
import Popup from '@enact/sandstone/Popup';
import css from './TFullPopup.module.less';
export default function TFullPopup({
noAnimation = false,
noAutoDismiss = false,
onClose,
onHide,
open,
position = "fullscreen",
scrimType = "translucent",
spotlightRestrict,
className,
children,
}) {
const _onClose = useCallback(() => {
if (onClose) {
onClose();
}
}, [onClose]);
const _onHide = useCallback(() => {
if (onHide) {
onHide();
}
}, [onHide]);
return (
<Popup
noAnimation={noAnimation}
noAutoDismiss={noAutoDismiss}
onClose={_onClose}
onHide={_onHide}
open={open}
position={position}
scrimType={scrimType}
spotlightRestrict={spotlightRestrict}
className={classNames(css.tFullPopup, className && className)}
>
{children}
</Popup>
);
}

View File

@@ -0,0 +1,10 @@
@import "../../style/CommonStyle.module.less";
@import "../../style/utils.module.less";
.tFullPopup {
> div {
font-family: @baseFont !important;
font-size: unset !important;
padding: 0 !important;
}
}

View File

@@ -64,7 +64,7 @@ export const getLoginUserData = (
} else {
return new LS2Request().send({
service: "luna://com.webos.service.accountmanager",
method: "getLoginUserData",
method: "getLoginID",
subscribe: false,
parameters: parameters,
onSuccess,

View File

@@ -17,13 +17,16 @@ import { changeAppStatus } from '../../actions/commonActions';
import { getShoptimeTerms } from '../../actions/empActions';
import { popPanel } from '../../actions/panelActions';
import TBody from '../../components/TBody/TBody';
import TFullPopup from '../../components/TFullPopup/TFullPopup';
import THeader from '../../components/THeader/THeader';
import TPanel from '../../components/TPanel/TPanel';
import TScroller from '../../components/TScroller/TScroller';
import { $L } from '../../utils/helperMethods';
import css from './CheckOutPanel.module.less';
import CheckoutQRCode from './components/CheckoutQRCode';
import CheckOutTerms from './components/CheckOutTerms';
import PinCode from './components/PinCode';
import PinCodeInput from './components/PinCodeInput';
import FixedSideBar from './container/FixedSideBar';
import InformationContainer from './container/InformationContainer';
import OrderItemsSideBar from './container/OrderItemsSideBar';
@@ -44,8 +47,13 @@ export default function CheckOutPanel() {
const infoForCheckoutData = useSelector(
(state) => state.checkout?.infoForCheckoutData
);
const cardInfo = useSelector(
(state) => state.checkout?.checkoutData.cardInfo
);
const [orderSideBarOpen, setOrderSideBarOpen] = useState(false);
const [offerSideBarOpen, setOfferSideBarOpen] = useState(false);
const [placeOrderPopup, setPlaceOrderPopup] = useState(false);
useEffect(() => {
dispatch(getShoptimeTerms());
@@ -114,7 +122,7 @@ export default function CheckOutPanel() {
onClick={onBackClick}
/>
<div className={css.Wrap}>
<SummaryContainer userInfo={userNumber} />
<SummaryContainer setPlaceOrderPopup={setPlaceOrderPopup} />
<InformationContainer
toggleOrderSideBar={toggleOrderSideBar}
toggleOfferSideBar={toggleOfferSideBar}
@@ -128,6 +136,14 @@ export default function CheckOutPanel() {
<OrderItemsSideBar closeSideBar={toggleOrderSideBar} />
)}
{offerSideBarOpen && <FixedSideBar closeSideBar={toggleOfferSideBar} />}
<TFullPopup
open={placeOrderPopup}
className={css.pinCodePopup}
noAnimation={true}
>
<PinCodeInput setPlaceOrderPopup={setPlaceOrderPopup} />
</TFullPopup>
</>
);
}

View File

@@ -16,6 +16,10 @@
}
}
.pinCodePopup {
background-color: #000 !important;
}
.fixedSideBar {
position: fixed;
background-color: rgba(0, 0, 0, 0.3);

View File

@@ -1,11 +1,12 @@
import React, { useState } from "react";
import React, { useState } from 'react';
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
import Spottable from "@enact/spotlight/Spottable";
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";
import TButton from '../../../components/TButton/TButton';
import { $L } from '../../../utils/helperMethods';
import css from './PinCode.module.less';
const Container = SpotlightContainerDecorator(
{ enterTo: "last-focused" },

View File

@@ -0,0 +1,93 @@
import React, {
useCallback,
useState,
} from 'react';
import classNames from 'classnames';
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 './PinCodeInput.module.less';
const PinCodeContainer = SpotlightContainerDecorator("div");
const SpottableButton = Spottable("div");
export default function PinCodeInput({ setPlaceOrderPopup }) {
const [pin, setPin] = useState(["", "", "", ""]);
const handleDigitClick = useCallback(
(digit) => {
const newPin = [...pin];
const nextIndex = pin.findIndex((p) => p === "");
if (nextIndex !== -1) {
newPin[nextIndex] = digit;
setPin(newPin);
if (nextIndex === 3) {
console.log("chw", newPin.join(""));
}
}
},
[pin]
);
const handleBackspace = useCallback(() => {
const newPin = [...pin];
const lastIndex = pin.lastIndexOf("");
const index = lastIndex === -1 ? 3 : lastIndex - 1;
if (index >= 0) {
newPin[index] = "";
setPin(newPin);
}
}, [pin]);
const onClickCancel = useCallback(() => {
setPin(["", "", "", ""]);
setPlaceOrderPopup(false);
}, [setPlaceOrderPopup]);
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.filled]: digit !== "",
[css.focused]: pin.findIndex((p) => p === "") === index,
})}
>
{digit ? "*" : ""}
</div>
))}
</div>
<div className={css.pinCodeDigits}>
{[...Array(10).keys()].map((digit) => (
<SpottableButton
key={digit}
className={css.pinCodeDigit}
onClick={() => handleDigitClick(digit.toString())}
>
{digit}
</SpottableButton>
))}
<SpottableButton
className={classNames(css.pinCodeDigit, css.deleteKey)}
onClick={handleBackspace}
/>
</div>
<div className={css.buttonContainer}>
<TButton onClick={onClickCancel}>{$L("Cancel")}</TButton>
<TButton>{$L("OK")}</TButton>
</div>
</PinCodeContainer>
);
}

View File

@@ -0,0 +1,109 @@
@import "../../../style/CommonStyle.module.less";
@import "../../../style/utils.module.less";
.pinCodeContainer {
width: 100%;
height: 100%;
padding: 120px 0;
.pinCodeTitle {
text-align: center;
font-size: 72px;
color: #e6e6e6;
}
.pinCodeBoxes {
margin-top: 162px;
display: flex;
justify-content: center;
.pinCodeBox {
width: 120px;
height: 144px;
border-radius: 6px;
background-color: #e6e6e6;
margin-right: 18px;
opacity: 0.15;
color: #000; // 검은색 * 표시
display: flex;
justify-content: center;
align-items: center;
font-size: 48px;
&.focused {
background-color: #fff;
opacity: 1;
}
&.filled {
opacity: 1;
}
&:last-child {
margin-right: 0;
}
}
}
.pinCodeDigits {
margin: 150px auto 0;
display: flex;
justify-content: center;
.pinCodeDigit {
width: 84px;
height: 84px;
line-height: 84px;
text-align: center;
color: #e6e6e6;
font-size: 42px;
font-weight: bold;
&:focus {
background-color: #fff;
color: #4c5059;
border-radius: 6px;
font-weight: bold;
}
}
.deleteKey {
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

@@ -37,7 +37,7 @@ const DEFAULT_SUMMARY = {
currSignLoc: "",
};
export default function SummaryContainer({ userInfo }) {
export default function SummaryContainer({ setPlaceOrderPopup }) {
const dispatch = useDispatch();
const { productList } = useSelector((state) => state.checkout.checkoutData);
@@ -126,7 +126,7 @@ export default function SummaryContainer({ userInfo }) {
];
const handleClickOrder = useCallback(() => {
console.log("success");
setPlaceOrderPopup(true);
}, []);
return (