[Log] Log, IF-LGSP-LOG-020 / 테마 상품 상세 이력 반영

This commit is contained in:
younghoon100.park
2024-05-30 15:40:39 +09:00
parent 4cd20afaad
commit 507bdf15c4
7 changed files with 140 additions and 63 deletions

View File

@@ -74,6 +74,10 @@ export const getUrlByLogTpNo = (logTpNo) => {
case LOG_TP_NO.ALARM_CLICK.NO:
return URLS.LOG_ALARM_CLICK;
// IF-LGSP-LOG-020 / 테마 상품 상세 이력 → 테마 상품 클릭 이력
case LOG_TP_NO.THEME_PRODUCT:
return URLS.LOG_THEME_PRODUCT;
// IF-LGSP-LOG-110 / Featured Brands View 이력
case LOG_TP_NO.BRANDS:
return URLS.LOG_BRANDS;

View File

@@ -746,6 +746,19 @@ export default function useLogService() {
*
* (M) tsvFlag TSV 여부
*/
const sendLogThemeProduct = useCallback(
(params) => {
const newParams = {
...params,
entryMenu: entryMenuRef.current,
logTpNo: LOG_TP_NO.THEME_PRODUCT,
nowMenu: nowMenuRef.current,
};
dispatch(postLog(newParams));
},
[dispatch, entryMenuRef, nowMenuRef]
);
/**
* IF-LGSP-LOG-102 / LG Account 로그인 이력
@@ -879,6 +892,7 @@ export default function useLogService() {
sendLogAlarmClick,
sendLogLgAccountLogin,
sendLogFeaturedBrands,
sendLogThemeProduct,
sendLogTerms,
};
}

View File

@@ -119,6 +119,8 @@ export const LOG_TP_NO = {
DETAIL: {},
THEME_PRODUCT: "411",
SHOP_BY_MOBILE: {
SHOP_BY_MOBILE: "450",
AGREE_AND_SEND: "452",

View File

@@ -1,4 +1,4 @@
import React from "react";
import React, { memo } from "react";
import { SpotlightContainerDecorator } from "@enact/spotlight/SpotlightContainerDecorator";
@@ -10,8 +10,8 @@ const Container = SpotlightContainerDecorator(
"div"
);
export default function ThemeCurationContents({
index,
export default memo(function ThemeCurationContents({
contentsIndex,
isTopButtonClicked,
shelfNm,
shelfProductInfos,
@@ -21,11 +21,11 @@ export default function ThemeCurationContents({
return (
<Container className={css.container}>
<h3
data-title-index={index}
data-title-index={contentsIndex}
className={css.title}
>{`${shelfNm} (${shelfProductInfos.length})`}</h3>
<ThemeCurationProductList
index={index}
contentsIndex={contentsIndex}
isTopButtonClicked={isTopButtonClicked}
shelfProductInfos={shelfProductInfos}
scrollTopBody={scrollTopBody}
@@ -33,4 +33,4 @@ export default function ThemeCurationContents({
/>
</Container>
);
}
});

View File

@@ -20,7 +20,7 @@ const Container = SpotlightContainerDecorator(
);
export default function ThemeCurationProductList({
index,
contentsIndex,
isTopButtonClicked,
shelfProductInfos,
scrollTopBody,
@@ -42,21 +42,21 @@ export default function ThemeCurationProductList({
return;
}
if (panelInfo?.exprOrd === index + 1) {
if (panelInfo?.exprOrd === contentsIndex + 1) {
const { x } = panelInfo;
scrollLeftJobValue.start(() => scrollLeft({ x }));
}
return () => {
if (panelInfo?.exprOrd === index + 1) {
if (panelInfo?.exprOrd === contentsIndex + 1) {
scrollLeftJobValue.stop();
}
};
}, [index, panelInfo, scrollLeft]);
}, [contentsIndex, panelInfo, scrollLeft]);
useEffect(() => {
const containerId = "theme-curation-product-list-id-" + index;
const containerId = "theme-curation-product-list-id-" + contentsIndex;
const container = document.getElementById(containerId);
if (container) {
@@ -71,19 +71,19 @@ export default function ThemeCurationProductList({
scrollLeft();
scrollTopBody();
}, [index, scrollLeft, scrollTopBody]);
}, [contentsIndex, scrollLeft, scrollTopBody]);
useEffect(() => {
if (index === 0 && isTopButtonClicked) {
if (contentsIndex === 0 && isTopButtonClicked) {
scrollLeft();
}
}, [index, isTopButtonClicked, scrollLeft]);
}, [contentsIndex, isTopButtonClicked, scrollLeft]);
return (
<Container
className={css.container}
id={"theme-curation-product-list-id-" + index}
spotlightId={"theme-curation-product-list-id-" + index}
id={"theme-curation-product-list-id-" + contentsIndex}
spotlightId={"theme-curation-product-list-id-" + contentsIndex}
>
<TScroller
cbScrollTo={getScrollTo}
@@ -96,7 +96,7 @@ export default function ThemeCurationProductList({
shelfProductInfos.map((themeProductInfosItem, itemIndex) => {
return (
<ThemeCurationProductListItem
index={index}
contentsIndex={contentsIndex}
itemIndex={itemIndex}
themeProductInfosItem={themeProductInfosItem}
key={"theme-product-infos-" + itemIndex}

View File

@@ -11,15 +11,19 @@ import useScrollTopByDistance from "../../../../../hooks/useScrollTopByDistance"
import { panel_names } from "../../../../../utils/Config";
import { SpotlightIds } from "../../../../../utils/SpotlightIds";
import css from "./ThemeCurationProductListItem.module.less";
import usePriceInfo from "../../../../../hooks/usePriceInfo";
import useLogService from "../../../../../hooks/useLogService";
export default function ThemeCurationProductListItem({
index,
contentsIndex,
itemIndex,
themeProductInfosItem,
scrollLeft,
scrollTopBody,
shelfProductInfosLength,
}) {
const { sendLogThemeProduct } = useLogService();
const { handleScrollReset, handleStopScrolling } = useScrollReset(
scrollLeft,
true
@@ -33,15 +37,20 @@ export default function ThemeCurationProductListItem({
(state) => state.panels.panels[panels?.length - 1]?.panelInfo
);
const { cursorVisible } = useSelector((state) => state.common.appStatus);
const { imgUrl, lgCatCd, patnrId, prdtNm, prdtId, priceInfo, offerInfo } =
themeProductInfosItem;
const cursorVisible = useSelector(
(state) => state.common.appStatus.cursorVisible
);
const themeMenuShelfInfo = useSelector(
(state) => state.home.themeMenuShelfInfoData
);
const { imgUrl, lgCatCd, offerInfo, prdtId, prdtNm, priceInfo } =
themeProductInfosItem;
const { originalPrice, discountedPrice, rewardFlag } =
usePriceInfo(priceInfo) || {};
const handleBlur = useCallback(() => {
if (itemIndex === 0) {
handleStopScrolling();
@@ -65,19 +74,55 @@ export default function ThemeCurationProductListItem({
dispatch(
updatePanel({
name: panel_names.THEME_CURATION_PANEL,
panelInfo: { ...panelInfo, x, y },
panelInfo: { x, y },
})
);
dispatch(
pushPanel({
name: panel_names.DETAIL_PANEL,
panelInfo: { patnrId, prdtId },
panelInfo: {
patnrId: themeProductInfosItem?.patnrId,
prdtId: themeProductInfosItem?.prdtId,
},
})
);
}
const params = {
befPrice: originalPrice,
curationId: themeMenuShelfInfo?.curationId,
curationNm: themeMenuShelfInfo?.curationNm,
lastPrice: discountedPrice,
lgCatCd: themeProductInfosItem?.lgCatCd ?? "",
lgCatNm: themeProductInfosItem?.lgCatNm ?? "",
linkTpCd: panelInfo?.linkTpCd ?? "",
patncNm: themeProductInfosItem?.patncNm,
patnrId: themeProductInfosItem?.patnrId,
prdtExpsOrd: themeProductInfosItem?.prdtExpsOrd,
prdtId: themeProductInfosItem?.prdtId,
prdtNm: themeProductInfosItem?.prdtNm,
rewdAplyFlag: rewardFlag,
shelfExpsOrd:
themeMenuShelfInfo?.shelfInfos[contentsIndex]?.shelfExpsOrd,
shelfId: themeMenuShelfInfo?.shelfInfos[contentsIndex]?.shelfId,
shelfNm: themeMenuShelfInfo?.shelfInfos[contentsIndex]?.shelfNm,
tsvFlag: themeProductInfosItem?.todaySpclFlag,
};
sendLogThemeProduct(params);
},
[dispatch, panelInfo, patnrId, prdtId]
[
contentsIndex,
discountedPrice,
dispatch,
originalPrice,
panelInfo?.linkTpCd,
rewardFlag,
sendLogThemeProduct,
themeMenuShelfInfo,
themeProductInfosItem,
]
);
const handleFocus = useCallback(() => {
@@ -92,7 +137,8 @@ export default function ThemeCurationProductListItem({
if (isLastItem) {
const targetId =
themeMenuShelfInfo?.shelfInfos[index + 1]?.shelfProductInfos[0]?.prdtId;
themeMenuShelfInfo?.shelfInfos[contentsIndex + 1]?.shelfProductInfos[0]
?.prdtId;
if (!targetId) return;
@@ -102,17 +148,18 @@ export default function ThemeCurationProductListItem({
}
scrollTopByDistance(
`[data-marker="scroll-marker"]`,
`[data-title-index="${isLastItem ? index + 1 : index}"]`,
`[data-title-index="${isLastItem ? contentsIndex + 1 : contentsIndex}"]`,
scrollTopBody,
-140
);
}, [
cursorVisible,
handleScrollReset,
index,
contentsIndex,
itemIndex,
scrollTopBody,
scrollTopByDistance,
shelfProductInfosLength,
themeMenuShelfInfo,
]);
@@ -120,7 +167,7 @@ export default function ThemeCurationProductListItem({
<li className={css.productItem}>
<TItemCard
data-lg-category-code={lgCatCd}
data-exposure-order={index + 1}
data-exposure-order={contentsIndex + 1}
imageAlt={prdtNm}
imageSource={imgUrl}
onBlur={handleBlur}

View File

@@ -55,11 +55,14 @@ export default function ThemeCurationPanel() {
sendLogGNB(LOG_MENU.THEME_PAGE);
}, [sendLogGNB]);
const handlePreviousButton = () => {
dispatch(popPanel());
};
const handlePreviousButton = useCallback(
() => () => {
dispatch(popPanel());
},
[dispatch]
);
const getPanelInfo = () => {
const getPanelInfo = useCallback(() => {
if (panels) {
for (let i = 0; i < panels.length; i++) {
if (panels[i].name === panel_names.THEME_CURATION_PANEL) {
@@ -69,37 +72,43 @@ export default function ThemeCurationPanel() {
}
}
}
if (panelInfos) {
setHasPanelInfo(Object.keys(panelInfos).length > 0);
setPreviousPanelIsDetail(Object.keys(panelInfos).length >= 5);
}
};
}, [panelInfos, panels]);
useEffect(() => {
getPanelInfo();
if (panelType === panel_names.THEME_CURATION_PANEL) {
dispatch(getThemeMenuShelfInfo({ curationId: selectedCurationId }));
}
}, [dispatch, panelType, selectedCurationId]);
}, [dispatch, getPanelInfo, panelType, selectedCurationId]);
useEffect(() => {
if (panelInfos) {
console.log("%c panelInfos", "background:pink; color:black", panelInfos);
console.log(
"%c panelInfos length",
"background:pink; color:black",
Object.keys(panelInfos)?.length
);
}
}, [panelInfos]);
// useEffect(() => {
// if (panelInfos) {
// console.log(
// "%c pyh panelInfos",
// "background:pink; color:black",
// panelInfos
// );
// console.log(
// "%c panelInfos length",
// "background:pink; color:black",
// Object.keys(panelInfos)?.length
// );
// }
// }, [panelInfos]);
useEffect(() => {
if (isInitialRendered) {
if (previousPanelIsDetail) {
console.log(
"%c initial Detail effect",
"background: blue; color: white"
);
// console.log(
// "%c initial Detail effect",
// "background: blue; color: white"
// );
return setIsInitialRendered(false);
}
}
@@ -107,17 +116,17 @@ export default function ThemeCurationPanel() {
useEffect(() => {
if (themeMenuShelfInfo) {
console.log(
"%c theme-menu-Infos effect, first focusable target is ready",
"background: red; color: white"
);
// console.log(
// "%c theme-menu-Infos effect, first focusable target is ready",
// "background: red; color: white"
// );
const prdtId = shelfInfos[0]?.shelfProductInfos[0]?.prdtId;
setFirstFocusableTarget("spotlightId-" + removeDotAndColon(prdtId));
setIsReadyForInitialFocusTarget(true);
}
}, [themeMenuShelfInfo]);
}, [themeMenuShelfInfo, shelfInfos]);
useEffect(() => {
if (isReadyForInitialFocusTarget && !isInitialFocusOccurred) {
@@ -144,12 +153,12 @@ export default function ThemeCurationPanel() {
`[data-spotlight-id="${targetId}"]`
);
console.log(
"%c *** initial focus *** effect",
"background: green; color: white"
);
// console.log(
// "%c *** initial focus *** effect",
// "background: green; color: white"
// );
console.log("initialFocusTarget?!?!\n\n", initialFocusTarget);
// console.log("initialFocusTarget?!?!\n\n", initialFocusTarget);
if (initialFocusTarget) {
Spotlight.focus(initialFocusTarget);
@@ -158,6 +167,7 @@ export default function ThemeCurationPanel() {
});
}
}, [
firstFocusableTarget,
hasPanelInfo,
isInitialFocusOccurred,
isReadyForInitialFocusTarget,
@@ -216,19 +226,19 @@ export default function ThemeCurationPanel() {
className={css.header}
title={$L("Theme Menu")}
onBackButton
onClick={handlePreviousButton}
onClick={handlePreviousButton()}
/>
<div data-marker="scroll-marker" />
<CustomImage src={banrImgUrl && banrImgUrl} className={css.banner} />
{shelfInfos && shelfInfos.length > 0 && (
<div className={css.contents}>
{shelfInfos.map(({ shelfNm, shelfProductInfos }, index) => {
{shelfInfos.map(({ shelfNm, shelfProductInfos }, contentsIndex) => {
return (
<ThemeCurationContents
index={index}
contentsIndex={contentsIndex}
isTopButtonClicked={isTopButtonClicked}
key={"theme-info-" + index}
key={"theme-info-" + contentsIndex}
shelfNm={shelfNm}
shelfProductInfos={shelfProductInfos}
scrollTopBody={scrollTopBody}