1. myOrder cancel / focus

2. checkOut QRCode
This commit is contained in:
hyunwoo93.cha
2024-07-04 18:04:18 +09:00
parent 264ffa77e5
commit b34cb7a08e
10 changed files with 251 additions and 144 deletions

View File

@@ -1,6 +1,7 @@
import { URLS } from "../api/apiConfig";
import { TAxios } from "../api/TAxios";
import { types } from "./actionTypes";
import { changeAppStatus } from "./commonActions";
// 회원 주문 취소/반품/교환 사유 조회 (IF-LGSP-347)
export const getMyinfoOrderCancelColumnsSearch =
@@ -104,30 +105,40 @@ export const updateOrderPartialCancel = (params) => (dispatch, getState) => {
};
// 결제전체취소 (IF-LGSP-367)
export const paymentTotalCancel = (params) => (dispatch, getState) => {
const { mbrNo, ordNo, reqChngRsn, reqChngRsnCd } = params;
export const paymentTotalCancel =
(params, callback) => (dispatch, getState) => {
const { mbrNo, ordNo, reqChngRsn, reqChngRsnCd } = params;
const onSuccess = (response) => {
console.log("paymentTotalCancel onSuccess ", response.data);
dispatch(
changeAppStatus({ showLoadingPanel: { show: true, type: "wait" } })
);
dispatch({
type: types.PAYMENT_TOTAL_CANCEL,
payload: response.data.data,
});
const onSuccess = (response) => {
console.log("paymentTotalCancel onSuccess ", response.data);
dispatch({
type: types.PAYMENT_TOTAL_CANCEL,
payload: response.data.data,
});
dispatch(changeAppStatus({ showLoadingPanel: { show: false } }));
if (callback) callback(response.data);
};
const onFail = (error) => {
console.error("paymentTotalCancel onFail ", error);
dispatch(changeAppStatus({ showLoadingPanel: { show: false } }));
};
TAxios(
dispatch,
getState,
"post",
URLS.PAYMENT_TOTAL_CANCEL,
{},
{ mbrNo, ordNo, reqChngRsn, reqChngRsnCd },
onSuccess,
onFail
);
};
const onFail = (error) => {
console.error("paymentTotalCancel onFail ", error);
};
TAxios(
dispatch,
getState,
"post",
URLS.PAYMENT_TOTAL_CANCEL,
{ mbrNo, ordNo, reqChngRsn, reqChngRsnCd },
{},
onSuccess,
onFail
);
};

View File

@@ -10,20 +10,23 @@ import { changeAppStatus, getTermsAgreeYn } from "./commonActions";
let getMyinfoOrderSearchKey = null;
let lastMyinfoOrderSearchParams = {};
export const getMyinfoOrderSearch =
(params, orderInfoDataIdx = 1, key, loading = true) =>
(params, forceUpdate = false, orderInfoDataIdx = 1, key, loading = true) =>
(dispatch, getState) => {
const { mbrNo, srchMonth, cancelOrderYn } = params;
let limitNum = params.limitNum || GET_MY_INFO_ORDER_SEARCH_LIMIT;
if (orderInfoDataIdx === 1) {
if (
JSON.stringify(lastMyinfoOrderSearchParams) === JSON.stringify(params)
) {
console.log("getMyinfoOrderSearch ignore patch");
return;
}
// if (
// JSON.stringify(lastMyinfoOrderSearchParams) ===
// JSON.stringify(params) &&
// !forceUpdate
// ) {
// console.log("getMyinfoOrderSearch ignore patch");
// return;
// }
lastMyinfoOrderSearchParams = params;
dispatch(clearMyinfoOrderSearch());
}
if (loading) {
@@ -96,7 +99,17 @@ export const getMyinfoOrderSearch =
export const continueGetMyinfoOrderSearch =
(orderInfoDataIdx = 2) =>
(dispatch, getState) => {
const orderInfoData = getState().order.orderInfoData || {};
const state = getState();
const orderSearchParams = state.order.orderSearchParams;
const isCancelOrder = orderSearchParams.cancelOrderYn === "Y";
const orderInfoData = isCancelOrder
? state.order.cancelOrderInfoData
: state.order.orderInfoData;
if (!orderInfoData || !orderInfoData.orderInfo) {
return;
}
const totalCount = orderInfoData.orderInfoCount ?? 0;
const startIndex = GET_MY_INFO_ORDER_SEARCH_LIMIT * (orderInfoDataIdx - 1);
@@ -107,6 +120,7 @@ export const continueGetMyinfoOrderSearch =
dispatch(
getMyinfoOrderSearch(
{ ...lastMyinfoOrderSearchParams },
false,
orderInfoDataIdx,
getMyinfoOrderSearchKey,
false
@@ -114,7 +128,7 @@ export const continueGetMyinfoOrderSearch =
);
};
export const clearMyinfoOrderSearch = () => ({
const clearMyinfoOrderSearch = () => ({
type: types.CLEAR_MY_INFO_ORDER_SEARCH,
});

View File

@@ -123,8 +123,8 @@ export const commonReducer = (state = initialState, action) => {
popupVisible: true,
activePopup: action.payload.activePopup,
secondaryPopup: action.payload.secondaryPopup,
text: action.payload.text || "",
data: action.payload.data || {},
text: action.payload.text,
data: action.payload.data,
},
};
case types.SET_SHOW_SECONDARY_POPUP:
@@ -134,8 +134,11 @@ export const commonReducer = (state = initialState, action) => {
...state.popup,
secondaryPopupVisible: true,
secondaryPopup: action.payload.activePopup,
secondaryText: action.payload.text || "",
secondaryData: action.payload.data || {},
secondaryText: action.payload.secondaryText,
secondaryData: {
...state.popup.secondaryData,
...action.payload.secondaryData,
},
},
};
case types.SET_HIDE_POPUP:

View File

@@ -28,8 +28,6 @@ export const orderReducer = (state = initialState, action) => {
const { cancelOrderYn } =
action.orderSearchParams || state.orderSearchParams;
console.log("chw", newResults, cancelOrderYn, action.payload);
if (cancelOrderYn === "Y") {
if (action.append) {
const existingData = state.cancelOrderInfoData.orderInfo || [];

View File

@@ -17,6 +17,7 @@ export const SpotlightIds = {
MY_PAGE_FAVORITES_BOX: "myPageFavoritesBox",
MY_PAGE_REMINDRES_BOX: "myPageRemindresBox",
MY_PAGE_MY_ORDER_BOX: "myPageMyOrderBox",
MY_PAGE_MY_ORDER_TAB_CONTAINER: "myPageMyOrderTabContainer",
// categoryPanel
CATEGORY_CONTENTS_BOX: "categoryContentsBox",

View File

@@ -1,4 +1,4 @@
import React, { useCallback, useMemo, useState } from "react";
import React, { useCallback, useEffect, useMemo, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
@@ -6,7 +6,6 @@ import Spotlight from "@enact/spotlight";
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
import Spottable from "@enact/spotlight/Spottable";
import { getMyInfoCheckoutInfo } from "../../../actions/checkoutActions";
import { setHidePopup, setShowPopup } from "../../../actions/commonActions";
import { popPanel } from "../../../actions/panelActions";
import TButton from "../../../components/TButton/TButton";
@@ -41,12 +40,7 @@ export default function InformationContainer({
const { popupVisible, activePopup } = useSelector(
(state) => state.common.popup
);
const cardInfo = useSelector(
(state) => state.checkout?.checkoutData?.cardInfo?.easyPmtSeq
);
const bilAddrSno = useSelector(
(state) => state.checkout?.infoForCheckoutData?.bilAddrSno
);
const auctProdYn = useSelector(
(state) => state.checkout?.checkoutData?.productList?.[0].auctProdYn
);
@@ -56,18 +50,32 @@ export default function InformationContainer({
const serverType = useSelector((state) => state.localSettings.serverType);
const countryCode = useSelector((state) => state.common.httpHeader.cntry_cd);
const [tab, setTab] = useState(0);
const [_, setTab] = useState(0);
const [prdtData, setPrdtData] = useState({});
const { getScrollTo } = useScrollTo();
const { scrollTopByDistance } = useScrollTopByDistance();
const { shippingAddressListUrl, billingAddressListUrl, cardListUrl } =
getQRCodeUrl({ serverType, countryCode });
useEffect(() => {
if (checkoutData) {
const { patnrId, prdtId, prodQty } = checkoutData.productList[0];
const prodOptCdCval =
checkoutData.productList[0].prdtOpt.length > 0
? checkoutData.productList[0].prdtOpt[0].prodOptCdCval
: "";
const qrCodeUrls = useMemo(
() => [shippingAddressListUrl, billingAddressListUrl, cardListUrl],
[shippingAddressListUrl, billingAddressListUrl, cardListUrl]
);
const params = {
patnrId: patnrId,
prdtId: prdtId,
prodOptCdCval: prodOptCdCval || "",
prodQty: prodQty,
};
setPrdtData(params);
}
}, [checkoutData]);
const { checkoutUrl } = getQRCodeUrl({ serverType, countryCode, prdtData });
const handleFocus = useCallback(() => {
const c = Spotlight.getCurrent();
@@ -99,25 +107,8 @@ export default function InformationContainer({
const handleDone = useCallback(() => {
dispatch(setHidePopup());
dispatch(
getMyInfoCheckoutInfo({
mbrNo: checkoutData.mbrNo,
dirPurcSelYn: "Y",
cartList: [
{
patnrId: checkoutData.productList?.[0].patnrId,
prdtId: checkoutData.productList?.[0].prdtId,
prodOptCdCval:
checkoutData.productList?.[0].prdtOpt.length > 0
? checkoutData.productList?.[0].prdtOpt?.[0].prodOptCdCval
: null,
prodQty: checkoutData.productList?.[0].prodQty,
},
],
})
),
[dispatch, checkoutData];
});
dispatch(popPanel());
}, [dispatch, checkoutData]);
return (
<>
@@ -200,9 +191,9 @@ export default function InformationContainer({
</div>
<div className={css.qrcodeContainer}>
{qrCodeUrls[tab] && (
{checkoutUrl && (
<div className={css.qrcode}>
<TQRCode text={qrCodeUrls[tab]} width="360" height="360" />
<TQRCode text={checkoutUrl} width="360" height="360" />
</div>
)}
<h3>

View File

@@ -72,6 +72,7 @@ export default function ConfirmPanel({ spotlightId }) {
menuId: myOrder.menuId,
menuNm: myOrder.menuNm,
menuOrd: myOrder.menuOrd,
forceUpdate: true,
},
})
);

View File

@@ -91,6 +91,9 @@ export default function MyOrders({ title, panelInfo, isOnTop }) {
const orderDetailData =
useSelector((state) => state.order?.orderDetailData?.orderInfo?.[0]) || {};
const orderInfoData = useSelector((state) => state.order?.orderInfoData);
const cancelOrderInfoData = useSelector(
(state) => state.order?.cancelOrderInfoData
);
const isLoading = useSelector(
(state) => state.common.appStatus?.showLoadingPanel?.show
);
@@ -105,42 +108,59 @@ export default function MyOrders({ title, panelInfo, isOnTop }) {
const { popupVisible, activePopup, data } = popup || {};
const orderInfo = orderInfoData?.orderInfo || {};
const cancelOrderInfo = cancelOrderInfoData?.orderInfo || {};
const cbChangePageRef = useRef(null);
const focusedContainerIdRef = useRef(null);
const [selectedTab, setSelectedTab] = useState(0);
const [dropDownTab, setDropDownTab] = useState(0);
const [selectedTab, setSelectedTab] = useState(
panelInfo.selectedTab ? panelInfo.selectedTab : 0
);
const [dropDownTab, setDropDownTab] = useState(
panelInfo.dropDownTab ? panelInfo.dropDownTab : 0
);
const [styleChange, setStyleChange] = useState(false);
const listContainerRef = useRef(null);
const tabRef = usePrevious(selectedTab);
const dropDownTabRef = usePrevious(dropDownTab);
const orderInfoDataRef = usePrevious(orderInfoData);
const cancelOrderInfoDataRef = usePrevious(cancelOrderInfoData);
const filterMethods = useMemo(
() => [$L("Last 3 Month"), $L("Last 6 Month")],
[]
);
const reload = useCallback(() => {
const cancelOrderYn = tabRef.current === 0 ? "N" : "Y";
const srchMonth = dropDownTabRef.current === 0 ? 3 : 6;
const reload = useCallback(
(forceUpdate = false) => {
const cancelOrderYn = tabRef.current === 0 ? "N" : "Y";
const srchMonth = dropDownTabRef.current === 0 ? 3 : 6;
if (
orderSearchParams.srchMonth !== srchMonth ||
orderSearchParams.cancelOrderYn !== cancelOrderYn
) {
dispatch(clearMyinfoOrderSearch());
dispatch(
getMyinfoOrderSearch({
mbrNo: userNumber,
srchMonth: srchMonth,
cancelOrderYn: cancelOrderYn,
})
);
if (
forceUpdate ||
orderSearchParams.srchMonth !== srchMonth ||
orderSearchParams.cancelOrderYn !== cancelOrderYn
) {
dispatch(
getMyinfoOrderSearch({
mbrNo: userNumber,
srchMonth: srchMonth,
cancelOrderYn: cancelOrderYn,
})
);
}
},
[userNumber, orderSearchParams, selectedTab, dropDownTab]
);
useEffect(() => {
if (!panelInfo.skipReload) {
reload(true);
} else {
dispatch(updatePanel({ skipReload: false }));
}
}, [userNumber, orderSearchParams, selectedTab, dropDownTab, dispatch]);
}, []);
useEffect(() => {
if (isOnTop) {
@@ -171,6 +191,20 @@ export default function MyOrders({ title, panelInfo, isOnTop }) {
}
}, [isOnTop, panelInfo]);
useEffect(() => {
if (orderInfoData || cancelOrderInfoData) {
const tabNode = document.querySelector(
`[data-spotlight-id="${"tab-" + selectedTab}"]`
);
if (tabNode) {
setContainerLastFocusedElement(tabNode, [
SpotlightIds.MY_PAGE_MY_ORDER_TAB_CONTAINER,
]);
}
}
}, [orderInfoData, cancelOrderInfoData, selectedTab]);
useEffect(() => {
setContainerLastFocusedElement(null, [SpotlightIds.MY_PAGE_MY_ORDER_BOX]);
reload();
@@ -219,7 +253,7 @@ export default function MyOrders({ title, panelInfo, isOnTop }) {
}, []);
const showGotoTopButton = useMemo(() => {
const targetData = orderInfoData;
const targetData = selectedTab === 0 ? orderInfoData : cancelOrderInfoData;
if (!targetData && !targetData.orderInfo) {
if (!targetData.orderInfo.length === 0) {
@@ -232,7 +266,7 @@ export default function MyOrders({ title, panelInfo, isOnTop }) {
}
return false;
}, [orderInfoData]);
}, [orderInfoData, cancelOrderInfoData, selectedTab]);
const handleTopButtonClick = useCallback(() => {
if (cbChangePageRef.current) {
@@ -243,44 +277,47 @@ export default function MyOrders({ title, panelInfo, isOnTop }) {
Spotlight.focus("tab-" + selectedTab);
}, [selectedTab]);
const onScrollStop = useCallback(
(event) => {
const childrenItems = document.querySelector(
`[data-spotlight-id="${SpotlightIds.MY_PAGE_MY_ORDER_BOX}"]`
).childNodes;
const targetData = orderInfoDataRef.current;
const onScrollStop = useCallback((event) => {
const childrenItems = document.querySelector(
`[data-spotlight-id="${SpotlightIds.MY_PAGE_MY_ORDER_BOX}"]`
).childNodes;
const targetData =
tabRef.current === 0
? orderInfoDataRef.current
: cancelOrderInfoDataRef.current;
let visibleIndexes = [];
let visibleIndexes = [];
childrenItems.forEach((child, index) => {
if (isElementInContainer(child, null, false)) {
visibleIndexes.push(index);
}
});
childrenItems.forEach((child, index) => {
if (isElementInContainer(child, null, false)) {
visibleIndexes.push(index);
}
});
if (visibleIndexes.length > 0) {
const lastVisibleIndex = visibleIndexes[visibleIndexes.length - 1];
if (visibleIndexes.length > 0) {
const lastVisibleIndex = visibleIndexes[visibleIndexes.length - 1];
if (lastVisibleIndex === childrenItems.length - 1) {
const nextQueryIndex =
Math.floor(lastVisibleIndex / GET_MY_INFO_ORDER_SEARCH_LIMIT + 1) *
GET_MY_INFO_ORDER_SEARCH_LIMIT;
if (lastVisibleIndex === childrenItems.length - 1) {
const nextQueryIndex =
Math.floor(lastVisibleIndex / GET_MY_INFO_ORDER_SEARCH_LIMIT + 1) *
GET_MY_INFO_ORDER_SEARCH_LIMIT;
if (targetData && !targetData.orderInfo[nextQueryIndex]) {
dataAppendJob.current.throttle(() => {
dispatch(
continueGetMyinfoOrderSearch(
Math.floor(nextQueryIndex / GET_MY_INFO_ORDER_SEARCH_LIMIT) +
1
)
);
});
}
if (
targetData &&
targetData.orderInfo &&
!targetData.orderInfo[nextQueryIndex]
) {
dataAppendJob.current.throttle(() => {
dispatch(
continueGetMyinfoOrderSearch(
Math.floor(nextQueryIndex / GET_MY_INFO_ORDER_SEARCH_LIMIT) + 1
)
);
});
}
}
},
[dispatch, orderInfoDataRef]
);
}
}, []);
const handleClosePopupBtn = useCallback(() => {
dispatch(setHidePopup());
@@ -302,6 +339,7 @@ export default function MyOrders({ title, panelInfo, isOnTop }) {
selectedTab: tabRef.current,
dropDownTab: dropDownTabRef.current,
focusedContainerId: focusedContainerIdRef.current,
skipReload: true,
},
})
);
@@ -325,18 +363,24 @@ export default function MyOrders({ title, panelInfo, isOnTop }) {
}, []);
const onClickCancelReasonItem = useCallback(
(detailCd) => {
console.log("chw", detailCd);
(detailCd, detailCdNm) => {
dispatch(
setShowSecondaryPopup(Config.ACTIVE_POPUP.cancelConfirmPopup, {
data: detailCd,
secondaryText: "zz",
secondaryData: {
mbrNo: userNumber,
ordNo: popup.data,
reqChngRsnCd: detailCd,
reqChngRsn: detailCdNm,
},
})
);
setTimeout(() => {
Spotlight.focus("tPopupBtn2");
}, 0);
},
[dispatch]
[dispatch, userNumber, popup.data]
);
const onClickSecondaryPopupCancelButton = useCallback(() => {
@@ -346,9 +390,25 @@ export default function MyOrders({ title, panelInfo, isOnTop }) {
}, 0);
}, [dispatch]);
function moveToCancelTab(response) {
if (response) {
console.log("chw rersponse", response);
if (response.retCode === 0) {
console.log("chw im here");
dispatch(setHidePopup());
reload(true);
} else {
console.error("order cancel failed");
}
}
}
const onClickSecondaryPopupOkButton = useCallback(() => {
const params = popup.secondaryData;
dispatch(setHidePopup());
}, [dispatch]);
dispatch(paymentTotalCancel(params, moveToCancelTab));
}, [dispatch, popup, moveToCancelTab]);
useEffect(() => {
Spotlight.focus();
@@ -406,6 +466,7 @@ export default function MyOrders({ title, panelInfo, isOnTop }) {
onItemClick={handleButtonTabClick}
selectedIndex={selectedTab && selectedTab}
listType={LIST_TYPE.medium}
spotlightId={SpotlightIds.MY_PAGE_MY_ORDER_TAB_CONTAINER}
/>
<TDropDown
className={classNames(
@@ -428,16 +489,27 @@ export default function MyOrders({ title, panelInfo, isOnTop }) {
ref={listContainerRef}
>
{!isLoading &&
(orderInfo && orderInfo.length > 0 ? (
orderInfo.map((item, index) => {
return (
(selectedTab === 0 ? (
orderInfo && orderInfo.length > 0 ? (
orderInfo.map((item, index) => (
<OrderListCard
item={item}
key={index}
key={"order" + index}
onClickBuyAgain={onClickBuyAgain}
/>
);
})
))
) : (
<NoOrderList />
)
) : cancelOrderInfo && cancelOrderInfo.length > 0 ? (
cancelOrderInfo.map((item, index) => (
<OrderListCard
item={item}
key={"cancelOrder" + index}
onClickBuyAgain={onClickBuyAgain}
cancelItem={true}
/>
))
) : (
<NoOrderList />
))}
@@ -479,7 +551,11 @@ export default function MyOrders({ title, panelInfo, isOnTop }) {
>
<div className={css.orderDetailPopupContainer}>
<div className={css.header}>
<h3 className={css.headerTitle}>{$L("ORDER DETAILS")}</h3>
<h3 className={css.headerTitle}>
{selectedTab === 0
? $L("ORDER DETAILS")
: $L("CANCELLATION DETAILS")}
</h3>
</div>
<div className={css.contentsBody}>
@@ -494,7 +570,7 @@ export default function MyOrders({ title, panelInfo, isOnTop }) {
{orderDetailData.orderProductInfo[0]?.shptmOrdStNm}
</p>
<span className={css.arrivingDate}>
Arriving January 10 - January 15
{/* Arriving January 10 - January 15 */}
</span>
</div>
<div className={css.productWrap}>
@@ -660,7 +736,9 @@ export default function MyOrders({ title, panelInfo, isOnTop }) {
<SpottableListItem
key={dispOrd}
className={css.cancelReasonItem}
onClick={() => onClickCancelReasonItem(detailCd)}
onClick={() =>
onClickCancelReasonItem(detailCd, detailCdNm)
}
>
{detailCdNm}
</SpottableListItem>

View File

@@ -20,7 +20,11 @@ const OrderListCardContainer = SpotlightContainerDecorator(
"div"
);
export default memo(function OrderListCard({ item, onClickBuyAgain }) {
export default memo(function OrderListCard({
item,
onClickBuyAgain,
cancelItem = false,
}) {
const dispatch = useDispatch();
const {
@@ -75,6 +79,7 @@ export default memo(function OrderListCard({ item, onClickBuyAgain }) {
<OrderListCardStatus
orderProductInfo={orderProductInfo?.[0]}
onClickBuyAgain={onClickBuyAgain}
cancelItem={cancelItem}
/>
</OrderListCardContainer>
);

View File

@@ -30,6 +30,7 @@ const ITEM_STATUS_TYPE = {
export default function OrderListCardStatus({
orderProductInfo,
onClickBuyAgain,
cancelItem,
}) {
const {
prdtId,
@@ -81,7 +82,9 @@ export default function OrderListCardStatus({
getMyinfoOrderCancelColumnsSearch(
{ reasonTpCd: ITEM_STATUS_TYPE.cancel },
() => {
dispatch(setShowPopup(Config.ACTIVE_POPUP.orderCancelPopup));
dispatch(
setShowPopup(Config.ACTIVE_POPUP.orderCancelPopup, { data: ordNo })
);
}
)
);
@@ -134,7 +137,7 @@ export default function OrderListCardStatus({
<div className={css.wrap}>
<span className={className}>{message}</span>
<span className={css.arrivingDate}>
Arriving January 10 - January 15
{/* Arriving January 10 - January 15 */}
</span>
</div>
<TButton
@@ -142,7 +145,9 @@ export default function OrderListCardStatus({
className={css.viewOrderDetailsBtn}
onClick={onClickViewOrderDetailsButton}
>
{$L("VIEW ORDER DETAILS")}
{cancelItem
? $L("VIEW CANCELLATION ITEM")
: $L("VIEW ORDER DETAILS")}
</TButton>
</div>
<div className={css.statusCardBody}>