From 0011f8a7254d9a9b68b21d287706f2ce51e698d6 Mon Sep 17 00:00:00 2001 From: "jiwon93.son" Date: Thu, 9 May 2024 17:56:19 +0900 Subject: [PATCH] =?UTF-8?q?[MobileSendPopUp]=20-=20HistoryPhoneNumber=20?= =?UTF-8?q?=EC=9E=91=EC=97=85=20-=20retCode=EC=97=90=20=EB=94=B0=EB=A5=B8?= =?UTF-8?q?=20alert=20=EC=B2=98=EB=A6=AC=20-=20appDataRecuer=20:=20SEND=5F?= =?UTF-8?q?SMS,CLERA=5FSMS=20=EC=B6=94=EA=B0=80=20-=20appDataActions:=20cl?= =?UTF-8?q?earSMS=20=EC=B6=94=EA=B0=80=20-=20localSettingsReducer:=20initi?= =?UTF-8?q?alLocalSettings=20phoneNumbers=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../assets/images/icons/ico-del-keyword.png | Bin 0 -> 4671 bytes .../src/actions/actionTypes.js | 1 + .../src/actions/appDataActions.js | 4 + .../HistoryPhoneNumber/HistoryPhoneNumber.jsx | 48 ++++ .../HistoryPhoneNumber.module.less | 43 +++ .../components/MobileSend/MobileSendPopUp.jsx | 254 ++++++++++++++---- .../MobileSend/MobileSendPopUp.module.less | 10 +- .../src/reducers/appDataReducer.js | 13 +- .../src/reducers/localSettingsReducer.js | 1 + 9 files changed, 313 insertions(+), 61 deletions(-) create mode 100644 com.twin.app.shoptime/assets/images/icons/ico-del-keyword.png create mode 100644 com.twin.app.shoptime/src/components/MobileSend/HistoryPhoneNumber/HistoryPhoneNumber.jsx create mode 100644 com.twin.app.shoptime/src/components/MobileSend/HistoryPhoneNumber/HistoryPhoneNumber.module.less diff --git a/com.twin.app.shoptime/assets/images/icons/ico-del-keyword.png b/com.twin.app.shoptime/assets/images/icons/ico-del-keyword.png new file mode 100644 index 0000000000000000000000000000000000000000..aef4e938b227824a79822185409104ccf618b2d4 GIT binary patch literal 4671 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 IGVqA|58NhbHvj+t literal 0 HcmV?d00001 diff --git a/com.twin.app.shoptime/src/actions/actionTypes.js b/com.twin.app.shoptime/src/actions/actionTypes.js index 1df8cfcd..73b45844 100644 --- a/com.twin.app.shoptime/src/actions/actionTypes.js +++ b/com.twin.app.shoptime/src/actions/actionTypes.js @@ -36,6 +36,7 @@ export const types = { // appData actions ADD_MAIN_INDEX: "ADD_MAIN_INDEX", SEND_SMS: "SEND_SMS", + CLEAR_SMS: "CLEAR_SMS", // home actions GET_HOME_TERMS: "GET_HOME_TERMS", diff --git a/com.twin.app.shoptime/src/actions/appDataActions.js b/com.twin.app.shoptime/src/actions/appDataActions.js index 5836d19e..b7e75fa9 100644 --- a/com.twin.app.shoptime/src/actions/appDataActions.js +++ b/com.twin.app.shoptime/src/actions/appDataActions.js @@ -62,3 +62,7 @@ export const sendSms = (params) => (dispatch, getState) => { onFail ); }; + +export const clearSMS = () => ({ + type: types.CLEAR_SMS, +}); diff --git a/com.twin.app.shoptime/src/components/MobileSend/HistoryPhoneNumber/HistoryPhoneNumber.jsx b/com.twin.app.shoptime/src/components/MobileSend/HistoryPhoneNumber/HistoryPhoneNumber.jsx new file mode 100644 index 00000000..3e9fe36c --- /dev/null +++ b/com.twin.app.shoptime/src/components/MobileSend/HistoryPhoneNumber/HistoryPhoneNumber.jsx @@ -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 ( +
+ { + handleClickNumber(number); + }} + className={css.phoneNumberList} + > + {number} + + { + handleDelete(index); + }} + /> +
+ ); + })} + + ); +} diff --git a/com.twin.app.shoptime/src/components/MobileSend/HistoryPhoneNumber/HistoryPhoneNumber.module.less b/com.twin.app.shoptime/src/components/MobileSend/HistoryPhoneNumber/HistoryPhoneNumber.module.less new file mode 100644 index 00000000..f7ef3f51 --- /dev/null +++ b/com.twin.app.shoptime/src/components/MobileSend/HistoryPhoneNumber/HistoryPhoneNumber.module.less @@ -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; + } + } +} diff --git a/com.twin.app.shoptime/src/components/MobileSend/MobileSendPopUp.jsx b/com.twin.app.shoptime/src/components/MobileSend/MobileSendPopUp.jsx index 07241476..2a34ad1a 100644 --- a/com.twin.app.shoptime/src/components/MobileSend/MobileSendPopUp.jsx +++ b/com.twin.app.shoptime/src/components/MobileSend/MobileSendPopUp.jsx @@ -5,9 +5,10 @@ import { PhoneNumberFormat, PhoneNumberUtil } from "google-libphonenumber"; import { useDispatch, useSelector } from "react-redux"; import { off, on } from "@enact/core/dispatcher"; +import { Spottable } from "@enact/spotlight/Spottable"; -import { sendSms } from "../../actions/appDataActions"; -import { setHidePopup } from "../../actions/commonActions"; +import { clearSMS, sendSms } from "../../actions/appDataActions"; +import { changeLocalSettings, setHidePopup } from "../../actions/commonActions"; import { getDeviceAdditionInfo, registerDeviceInfo, @@ -16,6 +17,7 @@ import { setEventIssueReq } from "../../actions/eventActions"; import { $L } from "../../utils/helperMethods"; import TButton from "../TButton/TButton"; import TPopUp from "../TPopUp/TPopUp"; +import HistoryPhoneNumber from "./HistoryPhoneNumber/HistoryPhoneNumber"; import css from "./MobileSendPopUp.module.less"; 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. `); +const SpottableComponent = Spottable("div"); + export default function MobileSendPopUp({ open, onClose, @@ -48,10 +52,14 @@ export default function MobileSendPopUp({ const deviceInfo = useSelector((state) => state.device.deviceInfo); const [mobileNumber, setMobileNumber] = 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 info = useSelector((state) => state.common.appStatus); 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 dispatch = useDispatch(); @@ -63,6 +71,16 @@ export default function MobileSendPopUp({ } else return 10; }; + const handleClickSelect = (_phoneNumber) => { + setKeyPadOff((state) => !state); + setMobileNumber(_phoneNumber); + }; + + const handleInputClick = () => { + setKeyPadOff(false); + if (recentSentNumber) setMobileNumber(recentSentNumber[0]); + }; + const getRawPhoneNumber = useCallback( (key) => { let rawPhoneNumber = `${mobileNumber}${key}`.replace(/\D/g, ""); @@ -135,11 +153,16 @@ export default function MobileSendPopUp({ dispatch(getDeviceAdditionInfo()); }, [dispatch]); - // useEffect(() => { - // if (sendSmsSuccess?.retCode === 0) { - // console.log("#### 성공"); - // } - // }, [sendSmsSuccess]); + useEffect(() => { + if (phoneNumberList) setRecentSentNumber(phoneNumberList); + }, []); + + useEffect(() => { + if (recentSentNumber && recentSentNumber.length > 0) { + setKeyPadOff(true); + setMobileNumber(recentSentNumber[0]); + } else setKeyPadOff(false); + }, [recentSentNumber]); const numKeypadClicked = useCallback( (key) => { @@ -154,14 +177,66 @@ export default function MobileSendPopUp({ [deviceCountryCode, mobileNumber] ); + const handleDelete = (selectedIndex) => { + if (recentSentNumber) { + const updateItems = recentSentNumber.filter( + (_, index) => index !== selectedIndex + ); + setRecentSentNumber(updateItems); + dispatch( + changeLocalSettings({ + phoneNumbers: { + phoneNumberList: updateItems, + }, + }) + ); + } + }; + const handleAgreeSendClick = useCallback(() => { if (!mobileNumber) return; + let naturalNumber = mobileNumber.replace(/\D/g, ""); - // TODO(jw) : RUSIA Check - // if (deviceCountryCode === "RU") { - // naturalNumber = "7" + naturalNumber; - // } + if (deviceCountryCode === "KR") { + naturalNumber = "82" + 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) { // EVT00102 CURATION EVENT : 원하는 페이지로 이동(앱 내 모든 페이지) 미완 @@ -205,57 +280,126 @@ export default function MobileSendPopUp({ 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 ( - -
- {productImg && ( -

- alt -

- )} -
+ {SMSRetCode === undefined && open && ( + - {title &&
{title}
} - {subTitle && ( +
+ {productImg && ( +

+ alt +

+ )}
- {subTitle} + {title &&
{title}
} + {subTitle && ( +
+ {subTitle} +
+ )} + {productPrice &&
{productPrice}
}
- )} - {productPrice &&
{productPrice}
} -
-
-
-
-
-
{mobileNumber}
-
-
-
-
-
- {$L("Agree and Send")} - {$L("Cancel")} -
- +
+
+
+ + {mobileNumber} + + {keyPadOff ? ( + + ) : ( + + )} +
+
+
+
+
+ + {$L("Agree and Send")} + + {$L("Cancel")} +
+ + )} + {SMSRetCode === 907 || + (SMSRetCode === 900 && ( + + ))} + {SMSRetCode === 0 && ( + + )} + ); } diff --git a/com.twin.app.shoptime/src/components/MobileSend/MobileSendPopUp.module.less b/com.twin.app.shoptime/src/components/MobileSend/MobileSendPopUp.module.less index e0d56855..4df4f316 100644 --- a/com.twin.app.shoptime/src/components/MobileSend/MobileSendPopUp.module.less +++ b/com.twin.app.shoptime/src/components/MobileSend/MobileSendPopUp.module.less @@ -79,6 +79,7 @@ .flex(@justifyCenter: space-between, @alignCenter: flex-start); .smsNumLayer { .inputNum { + position: relative; padding: 18px 5px 18px 20px; width: 437px; .border-solid(@size:1px,#cccccc); @@ -86,10 +87,11 @@ cursor: text; font-weight: normal; font-size: 28px; - &::after { - content: ""; - width: 2px; - height: 100%; + + &:focus { + &::after { + .focused(); + } } } min-width: 437px; diff --git a/com.twin.app.shoptime/src/reducers/appDataReducer.js b/com.twin.app.shoptime/src/reducers/appDataReducer.js index 63a8d04a..82bf1a85 100644 --- a/com.twin.app.shoptime/src/reducers/appDataReducer.js +++ b/com.twin.app.shoptime/src/reducers/appDataReducer.js @@ -2,6 +2,7 @@ import { types } from "../actions/actionTypes"; const initialState = { mainIndex: null, + sendSms: {}, }; export const appDataReducer = (state = initialState, action) => { @@ -10,9 +11,17 @@ export const appDataReducer = (state = initialState, action) => { return { ...state, 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: return state; } diff --git a/com.twin.app.shoptime/src/reducers/localSettingsReducer.js b/com.twin.app.shoptime/src/reducers/localSettingsReducer.js index ede96ed9..b83f6964 100644 --- a/com.twin.app.shoptime/src/reducers/localSettingsReducer.js +++ b/com.twin.app.shoptime/src/reducers/localSettingsReducer.js @@ -6,6 +6,7 @@ const initialLocalSettings = { serverType: Config.DEFAULT_SERVERTYPE, ricCodeSetting: Config.DEFAULT_RIC_CODE, accessToken: null, + phoneNumbers: {}, }; const updateInitialLocalSettings = () => {