[MobileSendPopUp]

- HistoryPhoneNumber 작업
- retCode에 따른 alert 처리
- appDataRecuer : SEND_SMS,CLERA_SMS 추가
- appDataActions: clearSMS 추가
- localSettingsReducer:
initialLocalSettings phoneNumbers 추가
This commit is contained in:
jiwon93.son
2024-05-09 17:56:19 +09:00
parent 6c4fd158b6
commit 0011f8a725
9 changed files with 313 additions and 61 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@@ -36,6 +36,7 @@ export const types = {
// appData actions // appData actions
ADD_MAIN_INDEX: "ADD_MAIN_INDEX", ADD_MAIN_INDEX: "ADD_MAIN_INDEX",
SEND_SMS: "SEND_SMS", SEND_SMS: "SEND_SMS",
CLEAR_SMS: "CLEAR_SMS",
// home actions // home actions
GET_HOME_TERMS: "GET_HOME_TERMS", GET_HOME_TERMS: "GET_HOME_TERMS",

View File

@@ -62,3 +62,7 @@ export const sendSms = (params) => (dispatch, getState) => {
onFail onFail
); );
}; };
export const clearSMS = () => ({
type: types.CLEAR_SMS,
});

View File

@@ -0,0 +1,48 @@
import React, { useEffect } from "react";
import { Spottable } from "@enact/spotlight/Spottable";
import TButton from "../../TButton/TButton";
import css from "./HistoryPhoneNumber.module.less";
const SpottableComponent = Spottable("div");
export default function HistoryPhoneNumber({
handleClickSelect,
recentSentNumber,
handleDelete,
}) {
const handleClickNumber = (number) => {
handleClickSelect(number);
};
return (
<>
{recentSentNumber &&
recentSentNumber.length > 0 &&
recentSentNumber.map((number, index) => {
return (
<div
className={css.container}
key={"history-phone-number-" + index}
>
<SpottableComponent
onClick={() => {
handleClickNumber(number);
}}
className={css.phoneNumberList}
>
{number}
</SpottableComponent>
<TButton
className={css.deleteButton}
onClick={() => {
handleDelete(index);
}}
/>
</div>
);
})}
</>
);
}

View File

@@ -0,0 +1,43 @@
@import "../../../style/CommonStyle.module.less";
@import "../../../style/utils.module.less";
.container {
width: 492px;
height: 68px;
display: flex;
align-items: center;
.phoneNumberList {
width: 437px;
height: 68px;
background-color: #434040;
.border-solid(@size:1px,@color:#cccccc);
color: @COLOR_WHITE;
padding: 18px 5px 18px 20px;
position: relative;
&:focus {
&::after {
.focused();
}
}
p {
color: @COLOR_WHITE;
}
}
.deleteButton {
background-image: url("../../../../assets/images/icons/ico-del-keyword.png");
min-width: 40px;
height: 40px;
background-color: transparent;
background-position: -4px -4px;
transition: none;
border-radius: 50%;
margin-left: 10px;
&:focus {
background-position: -4px -100px;
}
}
}

View File

@@ -5,9 +5,10 @@ import { PhoneNumberFormat, PhoneNumberUtil } from "google-libphonenumber";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import { off, on } from "@enact/core/dispatcher"; import { off, on } from "@enact/core/dispatcher";
import { Spottable } from "@enact/spotlight/Spottable";
import { sendSms } from "../../actions/appDataActions"; import { clearSMS, sendSms } from "../../actions/appDataActions";
import { setHidePopup } from "../../actions/commonActions"; import { changeLocalSettings, setHidePopup } from "../../actions/commonActions";
import { import {
getDeviceAdditionInfo, getDeviceAdditionInfo,
registerDeviceInfo, registerDeviceInfo,
@@ -16,6 +17,7 @@ import { setEventIssueReq } from "../../actions/eventActions";
import { $L } from "../../utils/helperMethods"; import { $L } from "../../utils/helperMethods";
import TButton from "../TButton/TButton"; import TButton from "../TButton/TButton";
import TPopUp from "../TPopUp/TPopUp"; import TPopUp from "../TPopUp/TPopUp";
import HistoryPhoneNumber from "./HistoryPhoneNumber/HistoryPhoneNumber";
import css from "./MobileSendPopUp.module.less"; import css from "./MobileSendPopUp.module.less";
import SMSNumKeyPad from "./SMSNumKeyPad"; import SMSNumKeyPad from "./SMSNumKeyPad";
@@ -26,6 +28,8 @@ const instruction = $L(`
By entering my mobile number, I agree to receive messages from LGE with information on how to purchase the product I selected. Message and data rates may apply. </span> By entering my mobile number, I agree to receive messages from LGE with information on how to purchase the product I selected. Message and data rates may apply. </span>
`); `);
const SpottableComponent = Spottable("div");
export default function MobileSendPopUp({ export default function MobileSendPopUp({
open, open,
onClose, onClose,
@@ -48,10 +52,14 @@ export default function MobileSendPopUp({
const deviceInfo = useSelector((state) => state.device.deviceInfo); const deviceInfo = useSelector((state) => state.device.deviceInfo);
const [mobileNumber, setMobileNumber] = useState(""); const [mobileNumber, setMobileNumber] = useState("");
const [recentSentNumber, setRecentSentNumber] = useState([]); const [recentSentNumber, setRecentSentNumber] = useState([]);
const [keyPadOff, setKeyPadOff] = useState(true); const [keyPadOff, setKeyPadOff] = useState(false);
const [SMSRetCode, setSMSRetCode] = useState();
const { httpHeader } = useSelector((state) => state.common); const { httpHeader } = useSelector((state) => state.common);
const info = useSelector((state) => state.common.appStatus);
const sendSmsSuccess = useSelector((state) => state.appData.sendSms); const sendSmsSuccess = useSelector((state) => state.appData.sendSms);
const smsRetCode = useSelector((state) => state.appData.sendSms?.retCode);
const { phoneNumberList } = useSelector(
(state) => state.localSettings.phoneNumbers
);
const deviceCountryCode = httpHeader["X-Device-Country"]; const deviceCountryCode = httpHeader["X-Device-Country"];
const dispatch = useDispatch(); const dispatch = useDispatch();
@@ -63,6 +71,16 @@ export default function MobileSendPopUp({
} else return 10; } else return 10;
}; };
const handleClickSelect = (_phoneNumber) => {
setKeyPadOff((state) => !state);
setMobileNumber(_phoneNumber);
};
const handleInputClick = () => {
setKeyPadOff(false);
if (recentSentNumber) setMobileNumber(recentSentNumber[0]);
};
const getRawPhoneNumber = useCallback( const getRawPhoneNumber = useCallback(
(key) => { (key) => {
let rawPhoneNumber = `${mobileNumber}${key}`.replace(/\D/g, ""); let rawPhoneNumber = `${mobileNumber}${key}`.replace(/\D/g, "");
@@ -135,11 +153,16 @@ export default function MobileSendPopUp({
dispatch(getDeviceAdditionInfo()); dispatch(getDeviceAdditionInfo());
}, [dispatch]); }, [dispatch]);
// useEffect(() => { useEffect(() => {
// if (sendSmsSuccess?.retCode === 0) { if (phoneNumberList) setRecentSentNumber(phoneNumberList);
// console.log("#### 성공"); }, []);
// }
// }, [sendSmsSuccess]); useEffect(() => {
if (recentSentNumber && recentSentNumber.length > 0) {
setKeyPadOff(true);
setMobileNumber(recentSentNumber[0]);
} else setKeyPadOff(false);
}, [recentSentNumber]);
const numKeypadClicked = useCallback( const numKeypadClicked = useCallback(
(key) => { (key) => {
@@ -154,14 +177,66 @@ export default function MobileSendPopUp({
[deviceCountryCode, mobileNumber] [deviceCountryCode, mobileNumber]
); );
const handleDelete = (selectedIndex) => {
if (recentSentNumber) {
const updateItems = recentSentNumber.filter(
(_, index) => index !== selectedIndex
);
setRecentSentNumber(updateItems);
dispatch(
changeLocalSettings({
phoneNumbers: {
phoneNumberList: updateItems,
},
})
);
}
};
const handleAgreeSendClick = useCallback(() => { const handleAgreeSendClick = useCallback(() => {
if (!mobileNumber) return; if (!mobileNumber) return;
let naturalNumber = mobileNumber.replace(/\D/g, ""); let naturalNumber = mobileNumber.replace(/\D/g, "");
// TODO(jw) : RUSIA Check if (deviceCountryCode === "KR") {
// if (deviceCountryCode === "RU") { naturalNumber = "82" + naturalNumber;
// naturalNumber = "7" + naturalNumber; }
// }
if (recentSentNumber && recentSentNumber.length > 0) {
const updatedNumbers = [...recentSentNumber];
const existingNumberIndex = updatedNumbers.findIndex(
(existingNum) => existingNum === mobileNumber
);
if (existingNumberIndex !== -1) {
updatedNumbers.splice(existingNumberIndex, 1);
}
if (updatedNumbers.length >= 5) {
updatedNumbers.pop();
}
updatedNumbers.unshift(mobileNumber);
setRecentSentNumber(updatedNumbers);
dispatch(
changeLocalSettings({
phoneNumbers: {
phoneNumberList: updatedNumbers,
},
})
);
} else {
setRecentSentNumber([mobileNumber]);
dispatch(
changeLocalSettings({
phoneNumbers: {
phoneNumberList: [mobileNumber],
},
})
);
}
if (isCurationEvnt) { if (isCurationEvnt) {
// EVT00102 CURATION EVENT : 원하는 페이지로 이동(앱 내 모든 페이지) 미완 // EVT00102 CURATION EVENT : 원하는 페이지로 이동(앱 내 모든 페이지) 미완
@@ -205,57 +280,126 @@ export default function MobileSendPopUp({
mbphNo: naturalNumber, mbphNo: naturalNumber,
}) })
); );
// dispatch(setHidePopup());
} }
}, [dispatch, mobileNumber, smsTpCd, evntTpCd]); }, [dispatch, mobileNumber, smsTpCd, evntTpCd, sendSmsSuccess]);
const _onClose = (e) => {
if (e.target) {
setSMSRetCode(undefined);
}
onClose();
};
useEffect(() => {
setSMSRetCode(smsRetCode);
if (smsRetCode === 0) {
setTimeout(() => {
dispatch(setHidePopup());
}, 3000);
}
}, [smsRetCode]);
useEffect(() => {
// smsRetCode initialize
return () => {
dispatch(clearSMS());
};
}, [dispatch]);
return ( return (
<TPopUp <>
kind={"mobileSendPopup"} {SMSRetCode === undefined && open && (
className={css.container} <TPopUp
open={open} kind={"mobileSendPopup"}
onClose={onClose} className={css.container}
hasText open={open}
> onClose={onClose}
<div className={css.header}> hasText
{productImg && (
<p className={css.productImg}>
<img className={css.img} src={productImg} alt="alt" />
</p>
)}
<div
className={classNames(css.textBox, !productImg && css.textBoxOnly)}
> >
{title && <div className={css.smsTitle}>{title}</div>} <div className={css.header}>
{subTitle && ( {productImg && (
<p className={css.productImg}>
<img className={css.img} src={productImg} alt="alt" />
</p>
)}
<div <div
className={classNames( className={classNames(
css.subTitle, css.textBox,
!productImg && css.subTitleOnly !productImg && css.textBoxOnly
)} )}
> >
{subTitle} {title && <div className={css.smsTitle}>{title}</div>}
{subTitle && (
<div
className={classNames(
css.subTitle,
!productImg && css.subTitleOnly
)}
>
{subTitle}
</div>
)}
{productPrice && <div className={css.price}>{productPrice}</div>}
</div> </div>
)}
{productPrice && <div className={css.price}>{productPrice}</div>}
</div>
</div>
<div className={css.smsArea}>
<div className={css.smsContainer}>
<div className={css.smsNumLayer}>
<div className={css.inputNum}>{mobileNumber}</div>
<SMSNumKeyPad onKeyDown={numKeypadClicked} />
</div> </div>
</div> <div className={css.smsArea}>
<div <div className={css.smsContainer}>
className={css.instruction} <div className={css.smsNumLayer}>
dangerouslySetInnerHTML={{ __html: instruction }} <SpottableComponent
></div> className={css.inputNum}
</div> onClick={handleInputClick}
<div className={css.btnContainer}> >
<TButton onClick={handleAgreeSendClick}>{$L("Agree and Send")}</TButton> {mobileNumber}
<TButton onClick={onClose}>{$L("Cancel")}</TButton> </SpottableComponent>
</div> {keyPadOff ? (
</TPopUp> <HistoryPhoneNumber
handleClickSelect={handleClickSelect}
handleDelete={handleDelete}
recentSentNumber={recentSentNumber}
/>
) : (
<SMSNumKeyPad onKeyDown={numKeypadClicked} />
)}
</div>
</div>
<div
className={css.instruction}
dangerouslySetInnerHTML={{ __html: instruction }}
></div>
</div>
<div className={css.btnContainer}>
<TButton onClick={handleAgreeSendClick}>
{$L("Agree and Send")}
</TButton>
<TButton onClick={onClose}>{$L("Cancel")}</TButton>
</div>
</TPopUp>
)}
{SMSRetCode === 907 ||
(SMSRetCode === 900 && (
<TPopUp
kind="exitPopup"
open={true}
hasText
text={$L(
`Only ${getMaxNum(
deviceCountryCode
)} digits is permitted. Please check again`
)}
onClick={_onClose}
hasButton
button1Text={$L("OK")}
/>
))}
{SMSRetCode === 0 && (
<TPopUp
kind="exitPopup"
open={true}
hasText
text={$L(`Text Send ${mobileNumber}`)}
/>
)}
</>
); );
} }

View File

@@ -79,6 +79,7 @@
.flex(@justifyCenter: space-between, @alignCenter: flex-start); .flex(@justifyCenter: space-between, @alignCenter: flex-start);
.smsNumLayer { .smsNumLayer {
.inputNum { .inputNum {
position: relative;
padding: 18px 5px 18px 20px; padding: 18px 5px 18px 20px;
width: 437px; width: 437px;
.border-solid(@size:1px,#cccccc); .border-solid(@size:1px,#cccccc);
@@ -86,10 +87,11 @@
cursor: text; cursor: text;
font-weight: normal; font-weight: normal;
font-size: 28px; font-size: 28px;
&::after {
content: ""; &:focus {
width: 2px; &::after {
height: 100%; .focused();
}
} }
} }
min-width: 437px; min-width: 437px;

View File

@@ -2,6 +2,7 @@ import { types } from "../actions/actionTypes";
const initialState = { const initialState = {
mainIndex: null, mainIndex: null,
sendSms: {},
}; };
export const appDataReducer = (state = initialState, action) => { export const appDataReducer = (state = initialState, action) => {
@@ -10,9 +11,17 @@ export const appDataReducer = (state = initialState, action) => {
return { return {
...state, ...state,
mainIndex: action.payload, mainIndex: action.payload,
retCode: action.retCode,
}; };
case types.SEND_SMS:
return {
...state,
sendSms: { retCode: action.retCode },
};
case types.CLEAR_SMS:
return {
...state,
sendSms: { retCode: undefined },
};
default: default:
return state; return state;
} }

View File

@@ -6,6 +6,7 @@ const initialLocalSettings = {
serverType: Config.DEFAULT_SERVERTYPE, serverType: Config.DEFAULT_SERVERTYPE,
ricCodeSetting: Config.DEFAULT_RIC_CODE, ricCodeSetting: Config.DEFAULT_RIC_CODE,
accessToken: null, accessToken: null,
phoneNumbers: {},
}; };
const updateInitialLocalSettings = () => { const updateInitialLocalSettings = () => {