[myPagePanel] ListContents/ContactContents component 추가, Support 내용 수정

This commit is contained in:
jiwon93.son
2024-02-15 17:00:37 +09:00
parent 1c971bb578
commit 0bb117edfd
12 changed files with 434 additions and 166 deletions

View File

@@ -39,6 +39,8 @@ export const types = {
// myPage actions
GET_MY_RECOMMANDED_KEYWORD: "GET_MY_RECOMMANDED_KEYWORD",
GET_MY_FAQ_INFO: "GET_MY_FAQ_INFO",
GET_NOTICE: "GET_NOTICE",
GET_MY_CUSTOMERS: "GET_MY_CUSTOMERS",
// onSale actions
GET_ON_SALE_INFO: "GET_ON_SALE_INFO",

View File

@@ -54,3 +54,46 @@ export const getMyFaqInfo = () => (dispatch, getState) => {
onFail
);
};
// Notice 조회 (IF-LGSP-049)
export const getNotice = () => (dispatch, getState) => {
const onSuccess = (response) => {
console.log("getMyNotice onSuccess ", response.data);
dispatch({
type: types.GET_NOTICE,
payload: response.data.data,
});
};
const onFail = (error) => {
console.error("getMyNotice onFail ", error);
};
TAxios(dispatch, getState, "get", URLS.GET_NOTICE, {}, {}, onSuccess, onFail);
};
// MyPage 파트너사 Contact 정보 조회 (IF-LGSP-033)
export const getMyCustomers = () => (dispatch, getState) => {
const onSuccess = (response) => {
console.log("getMyCustomers onSuccess ", response.data);
dispatch({
type: types.GET_MY_CUSTOMERS,
payload: response.data.data,
});
};
const onFail = (error) => {
console.error("getMyCustomers onFail ", error);
};
TAxios(
dispatch,
getState,
"get",
URLS.GET_MY_CUSTOMERS,
{},
{},
onSuccess,
onFail
);
};

View File

@@ -39,7 +39,7 @@ export const URLS = {
//my-page controller
GET_MY_RECOMMANDED_KEYWORD: "/lgsp/v1/mypage/reckeyword.lge",
GET_MY_FAQ_INFO: "/lgsp/v1/mypage/support/faq.lge",
GET_MY_NOTICE_INFO: "/lgsp/v1/mypage/support/notice.lge",
GET_NOTICE: "/lgsp/v1/mypage/support/notice.lge",
GET_MY_CUSTOMERS: "/lgsp/v1/mypage/customers.lge",
//search controller

View File

@@ -19,6 +19,16 @@ export const myPageReducer = (state = initialState, action) => {
...state,
faqData: action.payload,
};
case types.GET_NOTICE:
return {
...state,
noticeData: action.payload,
};
case types.GET_MY_CUSTOMERS:
return {
...state,
contactData: action.payload,
};
default:
return state;

View File

@@ -1,32 +1,16 @@
import React, { useCallback, useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { getMyFaqInfo } from "../../actions/myPageActions";
import TBody from "../../components/TBody/TBody";
import TPanel from "../../components/TPanel/TPanel";
import css from "./MyPagePanel.module.less";
import Support from "./MyPageSub/Support/Support";
export default function MyPagePanel() {
const dispatch = useDispatch();
const [faqs, setFaqs] = useState();
const faqInfos = useSelector((state) => state.myPage.faqData.faqInfos);
const contactInfos = useSelector((state) => state.myPage.faqData);
useEffect(() => {
dispatch(getMyFaqInfo({}));
}, [dispatch]);
useEffect(() => {
if (faqInfos) {
setFaqs(faqInfos);
}
}, [faqInfos]);
return (
<TPanel>
<Support faqs={faqs} />
<TBody className={css.tBody}>
<Support />
</TBody>
</TPanel>
);
}

View File

@@ -0,0 +1,3 @@
.tBody {
height: 100%;
}

View File

@@ -0,0 +1,73 @@
import React, { useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import Spottable from "@enact/spotlight/Spottable";
import { getMyCustomers } from "../../../../../actions/myPageActions";
import TScroller from "../../../../../components/TScroller/TScroller";
import { $L } from "../../../../../utils/helperMethods";
import css from "./ContactContents.module.less";
const SpottableComponent = Spottable("div");
const STR_FOOTER = `For any other LG TV Shopping app related inquires, please contact us below\nSupport email address shoptime.support@lge.com`;
export default function ContactContents() {
const dispatch = useDispatch();
useEffect(() => {
dispatch(getMyCustomers({}));
}, [dispatch]);
const contactInfos = useSelector(
(state) => state.myPage.contactData.partners
);
return (
<div>
<TScroller className={css.contactContainer}>
{contactInfos && contactInfos.length > 0 && (
<div className={css.container}>
{contactInfos &&
contactInfos.length > 0 &&
contactInfos.map((contact, idx) => {
return (
<SpottableComponent
key={`contact: ${idx}`}
className={css.contactList}
>
<div className={css.partners}>
{contact.patncLogoPath && (
<img src={contact.patncLogoPath} alt="partnerImg" />
)}
{contact.patncNm && contact.patncNm}
</div>
<div className={css.contents}>
{contact.csInfos &&
contact.csInfos.length > 0 &&
contact.csInfos.map((cs, idx) => {
return (
<div key={`csInfos: ${idx}`}>
{cs.csPhnNo && (
<span>{$L(`Phone: ${cs.csPhnNo}`)}</span>
)}
{cs.csMail && (
<span>{$L(`Email: ${cs.csMail}`)}</span>
)}
{cs.csSiteUrl && (
<span>{$L(`Website: ${cs.csSiteUrl}`)}</span>
)}
</div>
);
})}
</div>
</SpottableComponent>
);
})}
</div>
)}
</TScroller>
<div className={css.notiBottom}>{$L(STR_FOOTER)}</div>
</div>
);
}

View File

@@ -0,0 +1,79 @@
@import "../../../../../style/CommonStyle.module.less";
@import "../../../../../style/utils.module.less";
.contactContainer {
width: 1680px;
height: 540px;
.container {
height: 635px;
width: 100%;
.contactList {
width: 1650px;
height: 120px;
.flex(@justifyCenter: flex-start);
color: @COLOR_GRAY06;
.font(@fontFamily: @arialFontBold,@fontSize:30px);
background: @COLOR_WHITE;
text-align: left;
letter-spacing: -0.75px;
box-shadow: 0px 3px 5.6px 0.4px rgba(0, 0, 0, 0.11);
margin: 0 0 10px;
.border-solid(@size:1px,@color:#cccccc);
border-radius: 8px;
.partners {
display: flex;
padding: 25px 27px;
align-items: center;
width: 237px;
height: 100%;
background: @COLOR_LIGHT_SKYBLUE;
.font(@fontFamily: @arialFont,@fontSize:28px);
img {
width: 60px;
height: 60px;
margin-right: 10px;
}
}
.contents {
padding: 29px 31px;
.font(@fontFamily: @arialFont,@fontSize:28px);
color: @COLOR_GRAY06;
span:not(:last-child) {
&::after {
content: "|";
font-size: 26px;
color: @COLOR_GRAY06;
padding: 0 8px;
position: relative;
top: -3px;
}
}
}
&:focus-within,
&:focus {
box-shadow: 0 3px 5.64px 0.36px #0000007d,
0 0 0 4px @PRIMARY_COLOR_RED inset;
box-sizing: border-box;
}
}
}
}
.notiBottom {
text-align: center;
.font(@fontFamily: @baseFont,@fontSize:24px);
color: @COLOR_GRAY06;
margin-top: 71px;
white-space: pre-line;
line-height: 1.25;
letter-spacing: normal;
height: 53px;
}

View File

@@ -0,0 +1,96 @@
import React, { useCallback, useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import Spottable from "@enact/spotlight/Spottable";
import Marquee from "@enact/ui/Marquee";
import { getMyFaqInfo, getNotice } from "../../../../../actions/myPageActions";
import TPopUp from "../../../../../components/TPopUp/TPopUp";
import TScroller from "../../../../../components/TScroller/TScroller";
import css from "./ListContents.module.less";
const SpottableComponent = Spottable("li");
export default function ListContents({ selectedTab }) {
const dispatch = useDispatch();
const faqInfos = useSelector((state) => state.myPage.faqData.faqInfos);
const noticeInfos = useSelector(
(state) => state.myPage.noticeData.noticeInfos
);
const [faqPopUpOpen, setFaqPopUpOpen] = useState(false);
const [currentInfos, setCurrentInfos] = useState(null);
const [listInfos, setListInfos] = useState([]);
useEffect(() => {
dispatch(getMyFaqInfo({}));
dispatch(getNotice({}));
}, [dispatch]);
useEffect(() => {
selectedTab === 0 ? setListInfos(faqInfos) : setListInfos(noticeInfos);
}, [selectedTab, faqInfos, noticeInfos]);
const handleListClick = useCallback(
(notiNo) => {
if (listInfos) {
const selectedData = listInfos.find((list) => list.notiNo === notiNo);
setCurrentInfos(selectedData);
setFaqPopUpOpen(true);
}
},
[listInfos, currentInfos, faqInfos, noticeInfos]
);
return (
<>
<TScroller className={css.scrollContainer} verticalScrollbar="visible">
<ul className={css.liContainer}>
{listInfos &&
listInfos.map((list, idx) => {
return (
<SpottableComponent
className={css.supportList}
key={`list:${idx}`}
onClick={() => {
handleListClick(list.notiNo);
}}
>
<Marquee className={css.marquee} marqueeOn="focus">
{list.notiTitl}
</Marquee>
</SpottableComponent>
);
})}
</ul>
</TScroller>
<TPopUp
kind="supportPopup"
open={faqPopUpOpen}
onClose={() => {
setFaqPopUpOpen(false);
}}
hasButton
button1Text="OK"
>
{currentInfos && (
<div className={css.faqConts}>
<div className={css.faqTitle}>
{currentInfos.notiTitl}
<div className={css.expDate}>
{currentInfos.expsDt.substring(0, 10)}
</div>
</div>
<TScroller className={css.faqDesc} verticalScrollbar="visible">
{currentInfos.notiCntt}
</TScroller>
</div>
)}
</TPopUp>
</>
);
}
0;

View File

@@ -0,0 +1,82 @@
@import "../../../../../style/CommonStyle.module.less";
@import "../../../../../style/utils.module.less";
.scrollContainer {
height: 635px;
width: 1680px;
> div:nth-child(2) {
padding: 0;
> div {
background-color: #cccccc;
height: 100%;
width: 4px;
> div {
background-color: @COLOR_GRAY05;
}
}
}
}
.liContainer {
height: 635px;
width: 100%;
li {
width: 1650px;
height: 70px;
color: @COLOR_GRAY06;
.font(@fontFamily: @arialFontBold,@fontSize:30px);
background: @COLOR_WHITE;
text-align: left;
line-height: 70px;
letter-spacing: -0.75px;
padding: 0 61px;
box-shadow: 0px 3px 5.6px 0.4px rgba(0, 0, 0, 0.11);
margin: 0 0 10px;
.border-solid(@size:1px,@color:#cccccc);
border-radius: 8px;
&:hover,
&:focus {
box-shadow: 0 3px 5.64px 0.36px #0000007d,
0 0 0 4px @PRIMARY_COLOR_RED inset;
color: @PRIMARY_COLOR_RED;
box-sizing: border-box;
}
.marquee {
width: 100%;
}
}
}
.faqConts {
background-color: @COLOR_WHITE;
font-size: 30px;
border: 1px solid @COLOR_GRAY02;
color: @COLOR_BLACK;
border-radius: 4px;
white-space: pre-wrap;
.faqTitle {
.font(@fontFamily: @baseFontBold,@fontSize:30px);
border-bottom: 1px solid @COLOR_GRAY02;
padding: 20px 30px;
display: flex;
flex-direction: column;
.expDate {
text-align: right;
.font(@fontFamily: @baseFont,@fontSize:24px);
}
}
.faqDesc {
padding: 30px;
line-height: 50px;
height: 460px;
}
}

View File

@@ -1,29 +1,22 @@
import React, { useCallback, useState } from "react";
import { Marquee, MarqueeController } from "@enact/sandstone/Marquee";
import Spottable from "@enact/spotlight/Spottable";
import TBody from "../../../../components/TBody/TBody";
import TPopUp from "../../../../components/TPopUp/TPopUp";
import TScroller from "../../../../components/TScroller/TScroller";
import TButtonTab from "../../../../components/TButtonTab/TButtonTab";
import { $L } from "../../../../utils/helperMethods";
import ContactContents from "./ContactContents/ContactContents";
import ListContents from "./ListContents/ListContents";
import css from "./Support.module.less";
const SpottableComponent = Spottable("li");
export default function Support() {
const [selectedTab, setSelectedTab] = useState(0);
export default function Support({ faqs }) {
const [faqPopUpOpen, setFaqPopUpOpen] = useState(false);
const [currentFaqs, setCurrentFaqs] = useState(null);
const tabList = [$L("FAQ"), $L("Contact"), $L("Notice")];
const handleListClick = useCallback(
(notiNo) => {
if (faqs) {
const selectedFaq = faqs.find((faq) => faq.notiNo === notiNo);
setCurrentFaqs(selectedFaq);
setFaqPopUpOpen(true);
}
const handleItemClick = useCallback(
({ index, ...rest }) => {
console.log("#TButtonTab onItemClick", index, rest);
setSelectedTab(index);
},
[faqs, currentFaqs]
[selectedTab]
);
const confirmClick = useCallback(() => {
@@ -32,62 +25,20 @@ export default function Support({ faqs }) {
return (
<div className={css.supportContainer}>
<div className={css.title}>{$L("Support")}</div>
<TBody>
{/* FAQ */}
<ul className={css.liContainer}>
{faqs &&
faqs.map((faq, idx) => {
return (
<SpottableComponent
className={css.supportList}
key={`faq:${idx}`}
onClick={() => {
handleListClick(faq.notiNo);
}}
>
{faq.notiTitl}
</SpottableComponent>
);
})}
</ul>
</TBody>
<TPopUp
kind="supportPopup"
open={faqPopUpOpen}
onClose={() => {
setFaqPopUpOpen(false);
}}
hasButton
button1Text="OK"
>
{currentFaqs && (
<div className={css.faqConts}>
<div className={css.faqTitle}>
{/* <Marquee className={css.marquee} marqueeOn="render"> */}
{/* <div className={css.notTitle}> */}
{currentFaqs.notiTitl}
{/* </div> */}
{/* </Marquee> */}
<div className={css.expDate}>
{currentFaqs.expsDt.substring(0, 10)}
</div>
</div>
{/* <TBody */}
<TScroller
className={css.faqDesc}
verticalScrollbar="visible"
// focusableScrollbar={true}
// dangerouslySetInnerHTML={{
// __html: currentFaqs && currentFaqs.notiCntt,
// }}
>
{currentFaqs.notiCntt}
{/* </TBody> */}
</TScroller>
</div>
)}
</TPopUp>
<div className={css.header}>
<div className={css.title}>{$L("Support")}</div>
<TButtonTab
contents={tabList}
className={css.tTab}
onItemClick={handleItemClick}
selectedIndex={selectedTab && selectedTab}
/>
</div>
{selectedTab && selectedTab === 1 ? (
<ContactContents />
) : (
<ListContents selectedTab={selectedTab} />
)}
</div>
);
}

View File

@@ -6,81 +6,26 @@
height: 100%;
padding-left: 60px;
padding-top: 120px;
.title {
color: #9ba5b5;
.font(@fontFamily: @arialFont,@fontSize:60px);
line-height: normal;
letter-spacing: -0.6px;
}
.tBody {
height: 1080px;
}
.liContainer {
height: 640px;
margin-top: 50px;
width: 100%;
}
li {
width: 1660px;
height: 70px;
color: @COLOR_GRAY06;
.font(@fontFamily: @arialFontBold,@fontSize:30px);
background: @COLOR_WHITE;
text-align: left;
.header {
margin-bottom: 50px;
line-height: 70px;
// padding: 25px 0 25px 61px;
letter-spacing: -0.75px;
padding-left: 61px;
box-shadow: 0px 3px 5.6px 0.4px rgba(0, 0, 0, 0.11);
margin: 0 0 10px;
.title {
color: #9ba5b5;
.font(@fontFamily: @baseFont,@fontSize:60px);
line-height: normal;
letter-spacing: -0.6px;
margin-bottom: 35px;
}
.border-solid(@size:1px,@color:#cccccc);
border-radius: 8px;
.tTab {
> div {
min-width: 260px;
&:hover,
&:focus {
// .border-solid(@size:1px,@color:@PRIMARY_COLOR_RED);
// box-shadow: 0 3px 5.64px 0.36px #0000007d;
box-shadow: 0 3px 5.64px 0.36px #0000007d,
0 0 0 4px @PRIMARY_COLOR_RED inset;
color: @PRIMARY_COLOR_RED;
box-sizing: border-box;
> div {
.font(@fontFamily: @baseFontBold, @fontSize: 30px);
}
}
}
}
}
.faqConts {
background-color: @COLOR_WHITE;
font-size: 30px;
border: 1px solid @COLOR_GRAY02;
color: @COLOR_BLACK;
border-radius: 4px;
white-space: pre-wrap;
.faqTitle {
.font(@fontFamily: @baseFontBold,@fontSize:30px);
border-bottom: 1px solid @COLOR_GRAY02;
padding: 20px 30px;
display: flex;
flex-direction: column;
// .marquee {
// width: calc(100% - 150px);
// }
// .notiTitle {
// width: calc(100% - 150px);
// }
.expDate {
// width: 150px;
text-align: right;
.font(@fontFamily: @baseFont,@fontSize:24px);
}
}
.faqDesc {
padding: 30px;
line-height: 50px;
height: 460px;
}
}