redux-toolkit -> redux 마이그레이션 및 TAxios 로직 수정
This commit is contained in:
2
com.twin.app.shoptime/.env
Normal file
2
com.twin.app.shoptime/.env
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
ES5='true'
|
||||||
|
DISABLE_NEW_JSX_TRANSFORM='true'
|
||||||
1117
com.twin.app.shoptime/package-lock.json
generated
1117
com.twin.app.shoptime/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -6,8 +6,8 @@
|
|||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"serve": "enact serve",
|
"serve": "enact serve",
|
||||||
"pack": "enact pack",
|
"pack": "enact clean && enact pack",
|
||||||
"pack-p": "enact pack -p",
|
"build": "enact pack --production --locales=tv --verbose",
|
||||||
"watch": "enact pack --watch",
|
"watch": "enact pack --watch",
|
||||||
"clean": "enact clean",
|
"clean": "enact clean",
|
||||||
"lint": "enact lint .",
|
"lint": "enact lint .",
|
||||||
@@ -27,9 +27,6 @@
|
|||||||
"baseSize": 24
|
"baseSize": 24
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
|
||||||
"extends": "enact-proxy"
|
|
||||||
},
|
|
||||||
"eslintIgnore": [
|
"eslintIgnore": [
|
||||||
"node_modules/*",
|
"node_modules/*",
|
||||||
"build/*",
|
"build/*",
|
||||||
@@ -42,15 +39,16 @@
|
|||||||
"@enact/spotlight": "^3.3.0",
|
"@enact/spotlight": "^3.3.0",
|
||||||
"@enact/ui": "^3.3.0",
|
"@enact/ui": "^3.3.0",
|
||||||
"@enact/webos": "^3.3.0",
|
"@enact/webos": "^3.3.0",
|
||||||
"@reduxjs/toolkit": "^2.0.1",
|
"axios": "^0.21.1",
|
||||||
"axios": "^1.6.5",
|
|
||||||
"ilib": "^14.3.0",
|
"ilib": "^14.3.0",
|
||||||
"prop-types": "^15.8.1",
|
"prop-types": "^15.6.2",
|
||||||
"react": "^18.2.0",
|
"react": "^16.7.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^16.7.0",
|
||||||
"react-redux": "^9.1.0"
|
"react-redux": "^7.2.3",
|
||||||
|
"redux": "^3.7.2",
|
||||||
|
"redux-thunk": "^2.3.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"browserslist": [
|
||||||
"eslint-config-enact-proxy": "^1.0.7"
|
"chrome 38"
|
||||||
}
|
]
|
||||||
}
|
}
|
||||||
BIN
com.twin.app.shoptime/src/.DS_Store
vendored
BIN
com.twin.app.shoptime/src/.DS_Store
vendored
Binary file not shown.
@@ -4,18 +4,18 @@ import { useDispatch } from "react-redux";
|
|||||||
|
|
||||||
import ThemeDecorator from "@enact/sandstone/ThemeDecorator";
|
import ThemeDecorator from "@enact/sandstone/ThemeDecorator";
|
||||||
|
|
||||||
import { getBrandList } from "../features/brand/brandsSlice";
|
import { getBrandList } from "../actions/brandActions";
|
||||||
import { getAuthenticationCode } from "../features/device/deviceSlice";
|
import { getAuthenticationCode } from "../actions/deviceActions";
|
||||||
import {
|
import {
|
||||||
getHomeMenu,
|
|
||||||
getHomeLayout,
|
getHomeLayout,
|
||||||
getHomeMainContents,
|
getHomeMainContents,
|
||||||
|
getHomeMenu,
|
||||||
getThemeCurationInfo,
|
getThemeCurationInfo,
|
||||||
} from "../features/home/homeSlice";
|
} from "../actions/homeActions";
|
||||||
import { getMyRecommandedKeyword } from "../features/mypage/myPageSlice";
|
import { getSubCategory, getTop20Show } from "../actions/mainActions";
|
||||||
import { getOnSaleInfo } from "../features/onSale/onSaleSlice";
|
import { getMyRecommandedKeyword } from "../actions/myPageActions";
|
||||||
import { getSubCategory, getTop20Show } from "../features/main/mainSlice";
|
import { getOnSaleInfo } from "../actions/onSaleActions";
|
||||||
import { getBestSeller } from "../features/product/productSlice";
|
import { getBestSeller } from "../actions/productActions";
|
||||||
import MainView from "../views/MainView/MainView";
|
import MainView from "../views/MainView/MainView";
|
||||||
import css from "./App.module.less";
|
import css from "./App.module.less";
|
||||||
|
|
||||||
|
|||||||
49
com.twin.app.shoptime/src/actions/actionTypes.js
Normal file
49
com.twin.app.shoptime/src/actions/actionTypes.js
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
export const types = {
|
||||||
|
// panel actions
|
||||||
|
PUSH_PANEL: "PUSH_PANEL",
|
||||||
|
POP_PANEL: "POP_PANEL",
|
||||||
|
UPDATE_PANEL: "UPDATE_PANEL",
|
||||||
|
UPDATE_MODAL_STATUS: "UPDATE_MODAL_STATUS",
|
||||||
|
RESET_PANELS: "RESET_PANELS",
|
||||||
|
|
||||||
|
// device actions
|
||||||
|
GET_AUTHENTICATION_CODE: "GET_AUTHENTICATION_CODE",
|
||||||
|
|
||||||
|
// common actions
|
||||||
|
CHANGE_APP_STATUS: "CHANGE_APP_STATUS",
|
||||||
|
|
||||||
|
// appData actions
|
||||||
|
ADD_MAIN_INDEX: "ADD_MAIN_INDEX",
|
||||||
|
|
||||||
|
// home actions
|
||||||
|
GET_HOME_TERMS: "GET_HOME_TERMS",
|
||||||
|
GET_HOME_MENU: "GET_HOME_MENU",
|
||||||
|
GET_HOME_LAYOUT: "GET_HOME_LAYOUT",
|
||||||
|
GET_HOME_MAIN_CONTENTS: "GET_HOME_MAIN_CONTENTS",
|
||||||
|
GET_THEME_CURATION_INFO: "GET_THEME_CURATION_INFO",
|
||||||
|
|
||||||
|
// brand actions
|
||||||
|
GET_BRAND_LIST: "GET_BRAND_LIST",
|
||||||
|
GET_BRAND_LAYOUT_INFO: "GET_BRAND_LAYOUT_INFO",
|
||||||
|
GET_BRAND_LIVE_CHANNEL_INFO: "GET_BRAND_LIVE_CHANNEL_INFO",
|
||||||
|
|
||||||
|
// main actions
|
||||||
|
GET_SUB_CATEGORY: "GET_SUB_CATEGORY",
|
||||||
|
GET_TOP_20_SHOW: "GET_TOP_20_SHOW",
|
||||||
|
|
||||||
|
// myPage actions
|
||||||
|
GET_MY_RECOMMANDED_KEYWORD: "GET_MY_RECOMMANDED_KEYWORD",
|
||||||
|
|
||||||
|
// onSale actions
|
||||||
|
GET_ON_SALE_INFO: "GET_ON_SALE_INFO",
|
||||||
|
|
||||||
|
// product actions
|
||||||
|
GET_BEST_SELLER: "GET_BEST_SELLER",
|
||||||
|
|
||||||
|
// search actions
|
||||||
|
GET_SEARCH: "GET_SEARCH",
|
||||||
|
RESET_SEARCH: "RESET_SEARCH",
|
||||||
|
|
||||||
|
// event actions
|
||||||
|
GET_WELCOME_EVENT_INFO: "GET_WELCOME_EVENT_INFO",
|
||||||
|
};
|
||||||
6
com.twin.app.shoptime/src/actions/appDataActions.js
Normal file
6
com.twin.app.shoptime/src/actions/appDataActions.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { types } from "./actionTypes";
|
||||||
|
|
||||||
|
export const addMainIndex = (index) => ({
|
||||||
|
type: types.ADD_MAIN_INDEX,
|
||||||
|
payload: index,
|
||||||
|
});
|
||||||
89
com.twin.app.shoptime/src/actions/brandActions.js
Normal file
89
com.twin.app.shoptime/src/actions/brandActions.js
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
import { URLS } from "../api/apiConfig";
|
||||||
|
import { TAxios } from "../api/TAxios";
|
||||||
|
import { types } from "./actionTypes";
|
||||||
|
|
||||||
|
// Featured Brands 정보 조회 IF-LGSP-304
|
||||||
|
// @@pyh Todo, 기존의 key가 brandList에서 brandInfo로 변경 됨에 따라 함수명 또한 바뀔 수 있음 (문서 확인 후 변경 처리)
|
||||||
|
export const getBrandList = () => (dispatch, getState) => {
|
||||||
|
const onSuccess = (response) => {
|
||||||
|
console.log("@@ getBrandList onSuccess ", response.data);
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: types.GET_BRAND_LIST,
|
||||||
|
payload: response.data.data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onFail = (error) => {
|
||||||
|
console.error("@@ getBrandList onFail", error);
|
||||||
|
};
|
||||||
|
|
||||||
|
TAxios(
|
||||||
|
dispatch,
|
||||||
|
getState,
|
||||||
|
"get",
|
||||||
|
URLS.GET_BRAND_LIST,
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
onSuccess,
|
||||||
|
onFail
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Featured Brands LAYOUT (shelf) 정보 조회 IF-LGSP-305
|
||||||
|
export const getBrandLayoutInfo = (props) => (dispatch, getState) => {
|
||||||
|
const { patnrId } = props;
|
||||||
|
|
||||||
|
const onSuccess = (response) => {
|
||||||
|
console.log("@@ getBrandLayoutInfo onSuccess ", response.data);
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: types.GET_BRAND_LAYOUT_INFO,
|
||||||
|
payload: response.data.data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onFail = (error) => {
|
||||||
|
console.error("@@ getBrandLayoutInfo onFail ", error);
|
||||||
|
};
|
||||||
|
|
||||||
|
TAxios(
|
||||||
|
dispatch,
|
||||||
|
getState,
|
||||||
|
"get",
|
||||||
|
URLS.GET_BRAND_LAYOUT_INFO,
|
||||||
|
{ patnrId },
|
||||||
|
{},
|
||||||
|
onSuccess,
|
||||||
|
onFail
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Featured Brands Live 채널 정보 조회 IF-LGSP-306
|
||||||
|
export const getBrandLiveChannelInfo = (props) => (dispatch, getState) => {
|
||||||
|
const { patnrId } = props;
|
||||||
|
|
||||||
|
const onSuccess = (response) => {
|
||||||
|
console.log("@@ getBrandLiveChannelInfo onSuccess ", response.data);
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: types.GET_BRAND_LIVE_CHANNEL_INFO,
|
||||||
|
payload: response.data.data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onFail = (error) => {
|
||||||
|
console.error("@@ getBrandLiveChannelInfo onFail ", error);
|
||||||
|
};
|
||||||
|
|
||||||
|
TAxios(
|
||||||
|
dispatch,
|
||||||
|
getState,
|
||||||
|
"get",
|
||||||
|
URLS.GET_BRAND_LIVE_CHANNEL_INFO,
|
||||||
|
{ patnrId },
|
||||||
|
{},
|
||||||
|
onSuccess,
|
||||||
|
onFail
|
||||||
|
);
|
||||||
|
};
|
||||||
6
com.twin.app.shoptime/src/actions/commonActions.js
Normal file
6
com.twin.app.shoptime/src/actions/commonActions.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { types } from "./actionTypes";
|
||||||
|
|
||||||
|
export const changeAppStatus = (status) => ({
|
||||||
|
type: types.CHANGE_APP_STATUS,
|
||||||
|
payload: status,
|
||||||
|
});
|
||||||
29
com.twin.app.shoptime/src/actions/deviceActions.js
Normal file
29
com.twin.app.shoptime/src/actions/deviceActions.js
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import { URLS } from "../api/apiConfig";
|
||||||
|
import { TAxios } from "../api/TAxios";
|
||||||
|
import { types } from "./actionTypes";
|
||||||
|
|
||||||
|
export const getAuthenticationCode = () => (dispatch, getState) => {
|
||||||
|
const onSuccess = (response) => {
|
||||||
|
console.log("getAuthenticationCode onSuccess: ", response.data);
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: types.GET_AUTHENTICATION_CODE,
|
||||||
|
payload: response.data.data.accessToken,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onFail = (error) => {
|
||||||
|
console.error("getAuthenticationCode onFail: ", error);
|
||||||
|
};
|
||||||
|
|
||||||
|
TAxios(
|
||||||
|
dispatch,
|
||||||
|
getState,
|
||||||
|
"get",
|
||||||
|
URLS.GET_AUTHENTICATION_CODE,
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
onSuccess,
|
||||||
|
onFail
|
||||||
|
);
|
||||||
|
};
|
||||||
29
com.twin.app.shoptime/src/actions/eventActions.js
Normal file
29
com.twin.app.shoptime/src/actions/eventActions.js
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import { URLS } from "../api/apiConfig";
|
||||||
|
import { TAxios } from "../api/TAxios";
|
||||||
|
import { types } from "./actionTypes";
|
||||||
|
|
||||||
|
// 이벤트 정보 조회 IF-LGSP-070
|
||||||
|
export const getWelcomeEventInfo = () => (dispatch, getState) => {
|
||||||
|
const onSuccess = (response) => {
|
||||||
|
console.log("getWelcomeEventInfo onSuccess ", response.data);
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: types.GET_WELCOME_EVENT_INFO,
|
||||||
|
payload: response.data.data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onFail = (error) => {
|
||||||
|
console.error("getWelcomeEventInfo onFail ", error);
|
||||||
|
};
|
||||||
|
|
||||||
|
TAxios(
|
||||||
|
dispatch,
|
||||||
|
getState,
|
||||||
|
URLS.GET_WELCOME_EVENT_INFO,
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
onSuccess,
|
||||||
|
onFail
|
||||||
|
);
|
||||||
|
};
|
||||||
140
com.twin.app.shoptime/src/actions/homeActions.js
Normal file
140
com.twin.app.shoptime/src/actions/homeActions.js
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
import { URLS } from "../api/apiConfig";
|
||||||
|
import { TAxios } from "../api/TAxios";
|
||||||
|
import { types } from "./actionTypes";
|
||||||
|
|
||||||
|
// 약관 정보 조회 IF-LGSP-005
|
||||||
|
export const getHomeTerms = (props) => (dispatch, getState) => {
|
||||||
|
const { trmsTpCdList, mbrNo } = props;
|
||||||
|
|
||||||
|
const onSuccess = (response) => {
|
||||||
|
console.log("getHomeTerms onSuccess ", response.data);
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: types.GET_HOME_TERMS,
|
||||||
|
payload: response.data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onFail = (error) => {
|
||||||
|
console.error("getHomeTerms onFail ", error);
|
||||||
|
};
|
||||||
|
|
||||||
|
TAxios(
|
||||||
|
dispatch,
|
||||||
|
getState,
|
||||||
|
"get",
|
||||||
|
URLS.GET_HOME_TERMS,
|
||||||
|
{ trmsTpCdList, mbrNo },
|
||||||
|
{},
|
||||||
|
onSuccess,
|
||||||
|
onFail
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 메뉴 목록 조회 IF-LGSP-044
|
||||||
|
export const getHomeMenu = () => (dispatch, getState) => {
|
||||||
|
const onSuccess = (response) => {
|
||||||
|
console.log("getHomeMenu onSuccess ", response.data);
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: types.GET_HOME_MENU,
|
||||||
|
payload: response.data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onFail = (error) => {
|
||||||
|
console.error("getHomeMenu onFail ", error);
|
||||||
|
};
|
||||||
|
|
||||||
|
TAxios(
|
||||||
|
dispatch,
|
||||||
|
getState,
|
||||||
|
"get",
|
||||||
|
URLS.GET_HOME_MENU,
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
onSuccess,
|
||||||
|
onFail
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// HOME LAYOUT 정보 조회 IF-LGSP-300
|
||||||
|
export const getHomeLayout = () => (dispatch, getState) => {
|
||||||
|
const onSuccess = (response) => {
|
||||||
|
console.log("getHomeLayout onSuccess", response.data);
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: types.GET_HOME_LAYOUT,
|
||||||
|
payload: response.data.data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onFail = (error) => {
|
||||||
|
console.error("getHomeLayout onFail", error);
|
||||||
|
};
|
||||||
|
|
||||||
|
TAxios(
|
||||||
|
dispatch,
|
||||||
|
getState,
|
||||||
|
"get",
|
||||||
|
URLS.GET_HOME_LAYOUT,
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
onSuccess,
|
||||||
|
onFail
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// HOME Main Contents Banner 정보 조회 IF-LGSP-301
|
||||||
|
export const getHomeMainContents = () => (dispatch, getState) => {
|
||||||
|
const onSuccess = (response) => {
|
||||||
|
console.log("getHomeMainContents onSuccess", response.data);
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: types.GET_HOME_MAIN_CONTENTS,
|
||||||
|
payload: response.data.data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onFail = (error) => {
|
||||||
|
console.error("getHomeMainContents onFail", error);
|
||||||
|
};
|
||||||
|
|
||||||
|
TAxios(
|
||||||
|
dispatch,
|
||||||
|
getState,
|
||||||
|
"get",
|
||||||
|
URLS.GET_HOME_MAIN_CONTENTS,
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
onSuccess,
|
||||||
|
onFail
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Theme 전시 정보 조회 : IF-LGSP-045
|
||||||
|
export const getThemeCurationInfo = () => (dispatch, getState) => {
|
||||||
|
const onSuccess = (response) => {
|
||||||
|
console.log("getThemeCurationInfo onSuccess", response.data);
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: types.GET_THEME_CURATION_INFO,
|
||||||
|
payload: response.data.data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onFail = (error) => {
|
||||||
|
console.error("getThemeCurationInfo onFail", error);
|
||||||
|
};
|
||||||
|
|
||||||
|
TAxios(
|
||||||
|
dispatch,
|
||||||
|
getState,
|
||||||
|
"get",
|
||||||
|
URLS.GET_THEME_CURATION_INFO,
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
onSuccess,
|
||||||
|
onFail
|
||||||
|
);
|
||||||
|
};
|
||||||
59
com.twin.app.shoptime/src/actions/mainActions.js
Normal file
59
com.twin.app.shoptime/src/actions/mainActions.js
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import { URLS } from "../api/apiConfig";
|
||||||
|
import { TAxios } from "../api/TAxios";
|
||||||
|
import { types } from "./actionTypes";
|
||||||
|
|
||||||
|
// 서브카테고리 조회 IF-LGSP-051
|
||||||
|
export const getSubCategory = (props) => (dispatch, getState) => {
|
||||||
|
const { lgCatCd, patnrIdList, pageSize, tabType, filterType } = props;
|
||||||
|
|
||||||
|
const onSuccess = (response) => {
|
||||||
|
console.log("getSubCategory onSuccess ", response.data);
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: types.GET_SUB_CATEGORY,
|
||||||
|
payload: response.data.data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onFail = (error) => {
|
||||||
|
console.error("getSubCategory onFail", error);
|
||||||
|
};
|
||||||
|
|
||||||
|
TAxios(
|
||||||
|
dispatch,
|
||||||
|
getState,
|
||||||
|
"get",
|
||||||
|
URLS.GET_SUB_CATEGORY,
|
||||||
|
{ lgCatCd, patnrIdList, pageSize, tabType, filterType },
|
||||||
|
{},
|
||||||
|
onSuccess,
|
||||||
|
onFail
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// TOP20 영상 목록 조회 IF-LGSP-069
|
||||||
|
export const getTop20Show = () => (dispatch, getState) => {
|
||||||
|
const onSuccess = (response) => {
|
||||||
|
console.log("getTop20Show onSuccess ", response.data);
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: types.GET_TOP_20_SHOW,
|
||||||
|
payload: response.data.data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onFail = (error) => {
|
||||||
|
console.error("getTop20Show onFail", error);
|
||||||
|
};
|
||||||
|
|
||||||
|
TAxios(
|
||||||
|
dispatch,
|
||||||
|
getState,
|
||||||
|
"get",
|
||||||
|
URLS.GET_TOP20_SHOW,
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
onSuccess,
|
||||||
|
onFail
|
||||||
|
);
|
||||||
|
};
|
||||||
30
com.twin.app.shoptime/src/actions/myPageActions.js
Normal file
30
com.twin.app.shoptime/src/actions/myPageActions.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import { URLS } from "../api/apiConfig";
|
||||||
|
import { TAxios } from "../api/TAxios";
|
||||||
|
import { types } from "./actionTypes";
|
||||||
|
|
||||||
|
// 추천 Keyword 목록 조회 IF-LGSP-055
|
||||||
|
export const getMyRecommandedKeyword = () => (dispatch, getState) => {
|
||||||
|
const onSuccess = (response) => {
|
||||||
|
console.log("getMyRecommandedKeyword onSuccess ", response.data);
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: types.GET_MY_RECOMMANDED_KEYWORD,
|
||||||
|
payload: response.data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onFail = (error) => {
|
||||||
|
console.error("getMyRecommandedKeyword onFail ", error);
|
||||||
|
};
|
||||||
|
|
||||||
|
TAxios(
|
||||||
|
dispatch,
|
||||||
|
getState,
|
||||||
|
"get",
|
||||||
|
URLS.GET_MY_RECOMMANDED_KEYWORD,
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
onSuccess,
|
||||||
|
onFail
|
||||||
|
);
|
||||||
|
};
|
||||||
32
com.twin.app.shoptime/src/actions/onSaleActions.js
Normal file
32
com.twin.app.shoptime/src/actions/onSaleActions.js
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import { URLS } from "../api/apiConfig";
|
||||||
|
import { TAxios } from "../api/TAxios";
|
||||||
|
import { types } from "./actionTypes";
|
||||||
|
|
||||||
|
// On Sale 조회 IF-LGSP-086
|
||||||
|
export const getOnSaleInfo = (props) => (dispatch, getState) => {
|
||||||
|
const { categoryIncFlag, lgCatCd } = props;
|
||||||
|
|
||||||
|
const onSuccess = (response) => {
|
||||||
|
console.log("getOnSaleInfo onSuccess ", response.data);
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: types.GET_ON_SALE_INFO,
|
||||||
|
payload: response.data.data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onFail = (error) => {
|
||||||
|
console.error("getOnSaleInfo onFail", error);
|
||||||
|
};
|
||||||
|
|
||||||
|
TAxios(
|
||||||
|
dispatch,
|
||||||
|
getState,
|
||||||
|
"get",
|
||||||
|
URLS.GET_ON_SALE_INFO,
|
||||||
|
{ categoryIncFlag, lgCatCd },
|
||||||
|
{},
|
||||||
|
onSuccess,
|
||||||
|
onFail
|
||||||
|
);
|
||||||
|
};
|
||||||
26
com.twin.app.shoptime/src/actions/panelActions.js
Normal file
26
com.twin.app.shoptime/src/actions/panelActions.js
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import { types } from "./actionTypes";
|
||||||
|
|
||||||
|
export const pushPanel = (panel) => ({
|
||||||
|
type: types.PUSH_PANEL,
|
||||||
|
payload: panel,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const popPanel = (panelName) => ({
|
||||||
|
type: types.POP_PANEL,
|
||||||
|
payload: panelName,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const updatePanel = (panelInfo) => ({
|
||||||
|
type: types.UPDATE_PANEL,
|
||||||
|
payload: panelInfo,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const updateModalStatus = (status) => ({
|
||||||
|
type: types.UPDATE_MODAL_STATUS,
|
||||||
|
payload: status,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const resetPanels = (panels) => ({
|
||||||
|
type: types.RESET_PANELS,
|
||||||
|
payload: panels,
|
||||||
|
});
|
||||||
30
com.twin.app.shoptime/src/actions/productActions.js
Normal file
30
com.twin.app.shoptime/src/actions/productActions.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import { URLS } from "../api/apiConfig";
|
||||||
|
import { TAxios } from "../api/TAxios";
|
||||||
|
import { types } from "./actionTypes";
|
||||||
|
|
||||||
|
// Best Seller 상품 목록 조회 IF-LGSP-303
|
||||||
|
export const getBestSeller = () => (dispatch, getState) => {
|
||||||
|
const onSuccess = (response) => {
|
||||||
|
console.log("getBestSeller onSuccess", response.data);
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: types.GET_BEST_SELLER,
|
||||||
|
payload: response.data.data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onFail = (error) => {
|
||||||
|
console.error("getBestSeller onFail", error);
|
||||||
|
};
|
||||||
|
|
||||||
|
TAxios(
|
||||||
|
dispatch,
|
||||||
|
getState,
|
||||||
|
"get",
|
||||||
|
URLS.GET_PRODUCT_BESTSELLER,
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
onSuccess,
|
||||||
|
onFail
|
||||||
|
);
|
||||||
|
};
|
||||||
37
com.twin.app.shoptime/src/actions/searchActions.js
Normal file
37
com.twin.app.shoptime/src/actions/searchActions.js
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import { URLS } from "../api/apiConfig";
|
||||||
|
import { TAxios } from "../api/TAxios";
|
||||||
|
import { types } from "./actionTypes";
|
||||||
|
|
||||||
|
// Search 통합검색 (IBS) 데이터 조회 IF-LGSP-090
|
||||||
|
export const getSearch = (params) => (dispatch, getState) => {
|
||||||
|
const { service, query, startIndex, maxResults, domain } = params;
|
||||||
|
|
||||||
|
const onSuccess = (response) => {
|
||||||
|
console.log("getSearch onSuccess: ", response.data);
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: types.GET_SEARCH,
|
||||||
|
payload: response.data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onFail = (error) => {
|
||||||
|
console.error("getSearch onFail: ", error);
|
||||||
|
};
|
||||||
|
|
||||||
|
TAxios(
|
||||||
|
dispatch,
|
||||||
|
getState,
|
||||||
|
"post",
|
||||||
|
URLS.GET_SEARCH,
|
||||||
|
{},
|
||||||
|
{ service, query, startIndex, maxResults, domain },
|
||||||
|
onSuccess,
|
||||||
|
onFail
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const resetSearch = (status) => ({
|
||||||
|
type: types.RESET_SEARCH,
|
||||||
|
payload: status,
|
||||||
|
});
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
import { getUrl, URLS } from "./apiConfig";
|
|
||||||
import { addPanels, resetPanels } from "../features/panels/panelsSlice";
|
|
||||||
import * as HelperMethods from "../utils/helperMethods";
|
|
||||||
import * as Config from "../utils/Config";
|
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
|
||||||
|
import * as HelperMethods from "../utils/helperMethods";
|
||||||
|
import { getUrl, URLS } from "./apiConfig";
|
||||||
|
|
||||||
// refresh-token 구현 필요
|
// refresh-token 구현 필요
|
||||||
let tokenRefreshing = false;
|
let tokenRefreshing = false;
|
||||||
export const tokenRefresh = async (dispatch, getState, autoLogin, callback) => {
|
export const tokenRefresh = (dispatch, getState, autoLogin, callback) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
// console.log('getState ', getState());
|
// console.log('getState ', getState());
|
||||||
// const {serverType} = getState().common.localSettings;
|
// const {serverType} = getState().common.localSettings;
|
||||||
// const url = getUrl(URLS.TOKEN_REFRESH, serverType);
|
// const url = getUrl(URLS.TOKEN_REFRESH, serverType);
|
||||||
@@ -71,9 +71,11 @@ export const tokenRefresh = async (dispatch, getState, autoLogin, callback) => {
|
|||||||
// }
|
// }
|
||||||
// };
|
// };
|
||||||
tokenRefreshing = false;
|
tokenRefreshing = false;
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const TAxios = async (
|
export const TAxios = (
|
||||||
dispatch,
|
dispatch,
|
||||||
getState,
|
getState,
|
||||||
type,
|
type,
|
||||||
@@ -84,8 +86,24 @@ export const TAxios = async (
|
|||||||
onFail,
|
onFail,
|
||||||
noTokenRefresh = false
|
noTokenRefresh = false
|
||||||
) => {
|
) => {
|
||||||
let accessToken = getState().device.accessToken;
|
const checkAccessToken = () => {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const accessToken = getState().device.accessToken;
|
||||||
|
if (
|
||||||
|
accessToken ||
|
||||||
|
baseUrl === URLS.GET_AUTHENTICATION_CODE ||
|
||||||
|
noTokenRefresh
|
||||||
|
) {
|
||||||
|
resolve(accessToken);
|
||||||
|
} else {
|
||||||
|
HelperMethods.wait(100).then(() => {
|
||||||
|
resolve(checkAccessToken());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const executeRequest = (accessToken) => {
|
||||||
const AUTHORIZATION = { headers: {} };
|
const AUTHORIZATION = { headers: {} };
|
||||||
|
|
||||||
AUTHORIZATION.headers["app_id"] = "com.lgshop.app";
|
AUTHORIZATION.headers["app_id"] = "com.lgshop.app";
|
||||||
@@ -116,102 +134,52 @@ export const TAxios = async (
|
|||||||
"additionalDataAllowed,takeOnAllowed,networkAllowed,generalTermsAllowed,chpAllowed,customAdAllowed,acrOnAllowed,voice2Allowed,voiceAllowed,acrAdAllowed";
|
"additionalDataAllowed,takeOnAllowed,networkAllowed,generalTermsAllowed,chpAllowed,customAdAllowed,acrOnAllowed,voice2Allowed,voiceAllowed,acrAdAllowed";
|
||||||
AUTHORIZATION.headers["X-Device-Personalization"] = "Y";
|
AUTHORIZATION.headers["X-Device-Personalization"] = "Y";
|
||||||
|
|
||||||
if (
|
|
||||||
baseUrl !== URLS.GET_AUTHENTICATION_CODE &&
|
|
||||||
!accessToken &&
|
|
||||||
!noTokenRefresh
|
|
||||||
) {
|
|
||||||
console.log("Waiting for access token...");
|
|
||||||
while (!accessToken) {
|
|
||||||
await HelperMethods.wait(100);
|
|
||||||
|
|
||||||
accessToken = getState().device.accessToken;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (accessToken) {
|
if (accessToken) {
|
||||||
AUTHORIZATION.headers["lgsp_auth"] = accessToken;
|
AUTHORIZATION.headers["lgsp_auth"] = accessToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof window === "object") {
|
if (typeof window === "object") {
|
||||||
let url = "";
|
let url = Array.isArray(baseUrl) ? getUrl(baseUrl[0]) : getUrl(baseUrl);
|
||||||
|
|
||||||
if (Array.isArray(baseUrl)) {
|
if (type === "get") {
|
||||||
url = getUrl(baseUrl[0]);
|
|
||||||
} else {
|
|
||||||
url = getUrl(baseUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case "get": {
|
|
||||||
const _urlparams = HelperMethods.createQueryString(urlParams);
|
const _urlparams = HelperMethods.createQueryString(urlParams);
|
||||||
|
|
||||||
url += url ? `?${_urlparams}` : "";
|
url += url ? `?${_urlparams}` : "";
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("TAxios ", type + ": " + url, params);
|
let axiosInstance;
|
||||||
|
|
||||||
if (!noTokenRefresh) {
|
|
||||||
await tokenRefresh(dispatch, getState);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (tokenRefreshing) {
|
|
||||||
await HelperMethods.wait(100);
|
|
||||||
}
|
|
||||||
|
|
||||||
let axiosInstance = null;
|
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "get":
|
case "get":
|
||||||
AUTHORIZATION.headers = { ...AUTHORIZATION.headers, ...params };
|
axiosInstance = axios.get(url, AUTHORIZATION);
|
||||||
axiosInstance = axios[type](url, AUTHORIZATION);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "put":
|
|
||||||
// put이 있다면 구현 필요
|
|
||||||
|
|
||||||
case "post":
|
case "post":
|
||||||
axiosInstance = axios[type](url, params, AUTHORIZATION);
|
axiosInstance = axios.post(url, params, AUTHORIZATION);
|
||||||
break;
|
break;
|
||||||
|
// TODO: 다른 HTTP 메소드 있다면 처리 (chw)
|
||||||
case "delete":
|
|
||||||
// delete가 있다면 구현 필요
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (axiosInstance) {
|
if (axiosInstance) {
|
||||||
axiosInstance
|
axiosInstance
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
console.log("TAxios response", url, res);
|
console.log("TAxios response", url, res);
|
||||||
|
if (onSuccess) onSuccess(res);
|
||||||
if (onSuccess) {
|
|
||||||
onSuccess(res);
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.catch((res) => {
|
.catch((error) => {
|
||||||
const error = res && res.toJSON ? res.toJSON() : {};
|
|
||||||
|
|
||||||
console.error("TAxios ", url, error);
|
console.error("TAxios ", url, error);
|
||||||
|
if (onFail) onFail(error);
|
||||||
if (error.message === "Network Error") {
|
});
|
||||||
dispatch(resetPanels());
|
|
||||||
dispatch(
|
|
||||||
addPanels({
|
|
||||||
name: Config.panel_names.ERROR_PANEL,
|
|
||||||
panelInfo: { reason: "server Error" },
|
|
||||||
})
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
// todo
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (onFail) {
|
|
||||||
onFail(res);
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
checkAccessToken().then((accessToken) => {
|
||||||
|
if (!noTokenRefresh) {
|
||||||
|
tokenRefresh(dispatch, getState)
|
||||||
|
.then(() => executeRequest(accessToken))
|
||||||
|
.catch(() => {
|
||||||
|
/* 토큰 갱신 실패 처리 */
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
console.warn("TAxios invalid case type ", type);
|
executeRequest(accessToken);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
/* ----------------------
|
|
||||||
|
|
||||||
삭제 예정
|
|
||||||
|
|
||||||
---------------------- */
|
|
||||||
|
|
||||||
import axios from "axios";
|
|
||||||
import { store } from "../store/store";
|
|
||||||
import { SHOPTIME_BASE_URL } from "./apiConfig";
|
|
||||||
|
|
||||||
const api = axios.create({
|
|
||||||
baseURL: SHOPTIME_BASE_URL,
|
|
||||||
});
|
|
||||||
|
|
||||||
api.defaults.headers.common["app_id"] = "com.lgshop.app";
|
|
||||||
api.defaults.headers.common["app_ver"] = "1.0.0";
|
|
||||||
api.defaults.headers.common["dvc_id"] = "testdeviceid";
|
|
||||||
api.defaults.headers.common["cntry_cd"] = "US";
|
|
||||||
api.defaults.headers.common["prod_cd"] = "webOSTV 5.0";
|
|
||||||
api.defaults.headers.common["plat_cd"] = "W20H";
|
|
||||||
api.defaults.headers.common["lang_cd"] = "en-US";
|
|
||||||
api.defaults.headers.common["os_ver"] = "3.0";
|
|
||||||
api.defaults.headers.common["sdk_ver"] = "1.0.0";
|
|
||||||
api.defaults.headers.common["publish_flag"] = "Y";
|
|
||||||
|
|
||||||
api.interceptors.request.use(
|
|
||||||
(config) => {
|
|
||||||
const accessToken = store.getState().auth.accessToken;
|
|
||||||
|
|
||||||
if (accessToken) {
|
|
||||||
config.headers["lgsp_auth"] = accessToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
return config;
|
|
||||||
},
|
|
||||||
(error) => {
|
|
||||||
return Promise.reject(error);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
export default api;
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
/* ----------------------
|
|
||||||
|
|
||||||
삭제 예정
|
|
||||||
|
|
||||||
---------------------- */
|
|
||||||
|
|
||||||
import { URLS } from "./apiConfig";
|
|
||||||
import api from "./axiosConfig";
|
|
||||||
|
|
||||||
// 광고주 AD 정보 상세 조회 - Multiple 전시 IF-LGSP-082
|
|
||||||
export async function getAdDetailAMD() {}
|
|
||||||
|
|
||||||
// 광고주 AD 정보 상세 조회 - Single 전시 IF-LGSP-083
|
|
||||||
export async function getAdDetailAPD() {}
|
|
||||||
|
|
||||||
// 광고주 AD 정보 상세 조회 - Theme 전시 IF-LGSP-081
|
|
||||||
export async function getAdDetailATD() {}
|
|
||||||
|
|
||||||
// HOME Main Contents Banner 정보 조회 IF-LGSP-301
|
|
||||||
export async function getHomeMainContents() {}
|
|
||||||
|
|
||||||
// HOME LAYOUT 정보 조회 IF-LGSP-300
|
|
||||||
export async function getHomeLayout() {}
|
|
||||||
|
|
||||||
// 메뉴 목록 조회 IF-LGSP-044
|
|
||||||
export async function getHomeMenu() {}
|
|
||||||
|
|
||||||
// 약관 정보 조회 IF-LGSP-005
|
|
||||||
export async function getHomeTerms() {}
|
|
||||||
|
|
||||||
// Theme 전시 정보 상세 조회 IF-LGSP-060
|
|
||||||
export async function getThemeCurationDetailInfo() {}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
getAdDetailAMD,
|
|
||||||
getAdDetailAPD,
|
|
||||||
getAdDetailATD,
|
|
||||||
getHomeMainContents,
|
|
||||||
getHomeLayout,
|
|
||||||
getHomeMenu,
|
|
||||||
getHomeTerms,
|
|
||||||
getThemeCurationDetailInfo,
|
|
||||||
};
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
/* ----------------------
|
|
||||||
|
|
||||||
삭제 예정
|
|
||||||
|
|
||||||
---------------------- */
|
|
||||||
|
|
||||||
import { URLS } from "./apiConfig";
|
|
||||||
import api from "./axiosConfig";
|
|
||||||
|
|
||||||
// Onsale 조회 IF-LGSP-086
|
|
||||||
export async function getOnSaleInfo(props) {
|
|
||||||
const { lgCatCd, categoryIncFlag } = props;
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await api.get(URLS.GET_ON_SALE_INFO, {
|
|
||||||
params: {
|
|
||||||
categoryIncFlag,
|
|
||||||
lgCatCd,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return response.data.data;
|
|
||||||
} catch (error) {
|
|
||||||
const { response } = error;
|
|
||||||
|
|
||||||
if (response) {
|
|
||||||
const statusCode = response.status;
|
|
||||||
const statusText = response.statusText;
|
|
||||||
|
|
||||||
console.error(`Error: ${statusCode} ${statusText}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useMemo, useEffect, useState } from "react";
|
import React, { useEffect, useMemo, useState } from "react";
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
export default function SmoodShowingAnimation(WrappedComponent) {
|
export default function SmoodShowingAnimation(WrappedComponent) {
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
import React, { useCallback, useRef, useState } from "react";
|
import React, { useCallback, useRef, useState } from "react";
|
||||||
import css from "./TIconButton.module.less";
|
|
||||||
import Spottable from "@enact/spotlight/Spottable";
|
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import { useDispatch } from "react-redux";
|
import { useDispatch } from "react-redux";
|
||||||
|
|
||||||
import { Job } from "@enact/core/util";
|
import { Job } from "@enact/core/util";
|
||||||
|
import Spottable from "@enact/spotlight/Spottable";
|
||||||
|
|
||||||
|
import { popPanel, resetPanels } from "../../actions/panelActions";
|
||||||
import * as Config from "../../utils/Config";
|
import * as Config from "../../utils/Config";
|
||||||
import { popPanel, resetPanels } from "../../features/panels/panelsSlice";
|
import css from "./TIconButton.module.less";
|
||||||
|
|
||||||
const SpottableComponent = Spottable("div");
|
const SpottableComponent = Spottable("div");
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
.leftArrow {
|
.leftArrow {
|
||||||
background-image: url("../../../assets/searchpanel/sch-arr-l.png");
|
background-image: url("../../../assets/searchpanel/sch-arr-l.png");
|
||||||
background-position: center top;
|
background-position: center top;
|
||||||
|
background-size: cover;
|
||||||
width: 47px;
|
width: 47px;
|
||||||
height: 92px;
|
height: 92px;
|
||||||
|
|
||||||
@@ -24,6 +25,7 @@
|
|||||||
.rightArrow {
|
.rightArrow {
|
||||||
background-image: url("../../../assets/searchpanel/sch-arr-r.png");
|
background-image: url("../../../assets/searchpanel/sch-arr-r.png");
|
||||||
background-position: center top;
|
background-position: center top;
|
||||||
|
background-size: cover;
|
||||||
width: 47px;
|
width: 47px;
|
||||||
height: 92px;
|
height: 92px;
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
import React, { forwardRef, useCallback, useRef, useEffect } from "react";
|
import React from "react";
|
||||||
import css from "./TInput.module.less";
|
|
||||||
import { InputField } from "@enact/sandstone/Input";
|
|
||||||
import Spottable from "@enact/spotlight/Spottable";
|
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
|
|
||||||
|
import { InputField } from "@enact/sandstone/Input";
|
||||||
import { SpotlightContainerDecorator } from "@enact/spotlight/SpotlightContainerDecorator";
|
import { SpotlightContainerDecorator } from "@enact/spotlight/SpotlightContainerDecorator";
|
||||||
|
|
||||||
import TIconButton from "../TIconButton/TIconButton";
|
import TIconButton from "../TIconButton/TIconButton";
|
||||||
|
import css from "./TInput.module.less";
|
||||||
|
|
||||||
const Container = SpotlightContainerDecorator("div");
|
const Container = SpotlightContainerDecorator("div");
|
||||||
|
|
||||||
@@ -43,4 +45,4 @@ export default function TInput({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export { KINDS, ICONS, BORDER, COLOR };
|
export { BORDER, COLOR, ICONS, KINDS };
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: center top;
|
background-position: center top;
|
||||||
|
background-size: cover;
|
||||||
width: 41px;
|
width: 41px;
|
||||||
height: 41px;
|
height: 41px;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
|
import React, { useCallback } from "react";
|
||||||
|
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import React, { useCallback, useEffect } from "react";
|
import { useDispatch } from "react-redux";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
|
||||||
import { Panel } from "@enact/sandstone/Panels";
|
import { Panel } from "@enact/sandstone/Panels";
|
||||||
import { Cancelable } from "@enact/ui/Cancelable";
|
import { Cancelable } from "@enact/ui/Cancelable";
|
||||||
import css from "./TPanel.module.less";
|
|
||||||
|
import { popPanel } from "../../actions/panelActions";
|
||||||
import SmoodShowingAnimation from "../SmoodShowingAnimation/SmoodShowingAnimation";
|
import SmoodShowingAnimation from "../SmoodShowingAnimation/SmoodShowingAnimation";
|
||||||
import { popPanel } from "../../features/panels/panelsSlice";
|
import css from "./TPanel.module.less";
|
||||||
|
|
||||||
const CancelablePanel = Cancelable(
|
const CancelablePanel = Cancelable(
|
||||||
{ modal: true, onCancel: "handleCancel" },
|
{ modal: true, onCancel: "handleCancel" },
|
||||||
@@ -37,8 +40,6 @@ const TPanel = ({
|
|||||||
[dispatch, handleCancel, isTabActivated]
|
[dispatch, handleCancel, isTabActivated]
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log(isTabActivated);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CancelablePanel
|
<CancelablePanel
|
||||||
{...rest}
|
{...rest}
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
import classNames from "classnames";
|
|
||||||
import React, { useCallback, useEffect, useRef, useState } from "react";
|
import React, { useCallback, useEffect, useRef, useState } from "react";
|
||||||
import Scroller from "@enact/sandstone/Scroller";
|
|
||||||
|
import classNames from "classnames";
|
||||||
|
|
||||||
|
import { off, on } from "@enact/core/dispatcher";
|
||||||
import { Job } from "@enact/core/util";
|
import { Job } from "@enact/core/util";
|
||||||
import { on, off } from "@enact/core/dispatcher";
|
import Scroller from "@enact/sandstone/Scroller";
|
||||||
|
|
||||||
import css from "./TScroller.module.less";
|
import css from "./TScroller.module.less";
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
import React, {
|
||||||
|
useCallback,
|
||||||
|
useEffect,
|
||||||
|
useMemo,
|
||||||
|
useRef,
|
||||||
|
useState,
|
||||||
|
} from "react";
|
||||||
|
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import compose from "ramda/src/compose";
|
import compose from "ramda/src/compose";
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import { Cancelable } from "@enact/ui/Cancelable";
|
|||||||
//이미지
|
//이미지
|
||||||
import shoptimeFullIcon from "../../../assets/icons/ic-lnb-logo-shoptime@3x.png";
|
import shoptimeFullIcon from "../../../assets/icons/ic-lnb-logo-shoptime@3x.png";
|
||||||
import shopTimeIcon from "../../../assets/icons/ic-lnb-shoptime-symbol@3x.png";
|
import shopTimeIcon from "../../../assets/icons/ic-lnb-shoptime-symbol@3x.png";
|
||||||
import { resetPanels } from "../../features/panels/panelsSlice";
|
import { resetPanels } from "../../actions/panelActions";
|
||||||
import { panel_names } from "../../utils/Config";
|
import { panel_names } from "../../utils/Config";
|
||||||
import CartIcon from "./iconComponents/CartIcon";
|
import CartIcon from "./iconComponents/CartIcon";
|
||||||
import CategoryIcon from "./iconComponents/CategoryIcon";
|
import CategoryIcon from "./iconComponents/CategoryIcon";
|
||||||
@@ -34,6 +34,8 @@ import TrendingNowIcon from "./iconComponents/TrendingNowIcon";
|
|||||||
import TabItem from "./TabItem";
|
import TabItem from "./TabItem";
|
||||||
import css from "./TabLayout.module.less";
|
import css from "./TabLayout.module.less";
|
||||||
|
|
||||||
|
//이미지
|
||||||
|
|
||||||
const Container = SpotlightContainerDecorator(
|
const Container = SpotlightContainerDecorator(
|
||||||
{ enterTo: "default-element" },
|
{ enterTo: "default-element" },
|
||||||
"div"
|
"div"
|
||||||
@@ -430,6 +432,7 @@ export default function TabLayout({ topPanelName, onTabActivated }) {
|
|||||||
<TabItem
|
<TabItem
|
||||||
key={"tabitem" + index}
|
key={"tabitem" + index}
|
||||||
expanded={false}
|
expanded={false}
|
||||||
|
selected={mainSelectedIndex === index}
|
||||||
index={index}
|
index={index}
|
||||||
onClick={handleNavigation}
|
onClick={handleNavigation}
|
||||||
icons={item.icons}
|
icons={item.icons}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
import { convertThemeColor } from "./convertThemeColor";
|
import { convertThemeColor } from "./convertThemeColor";
|
||||||
|
|
||||||
const CartIcon = ({ iconType = "normal" }) => {
|
const CartIcon = ({ iconType = "normal" }) => {
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
import { convertThemeColor } from "./convertThemeColor";
|
import { convertThemeColor } from "./convertThemeColor";
|
||||||
|
|
||||||
const CategoryIcon = ({ iconType = "normal" }) => {
|
const CategoryIcon = ({ iconType = "normal" }) => {
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
import { convertThemeColor } from "./convertThemeColor";
|
import { convertThemeColor } from "./convertThemeColor";
|
||||||
|
|
||||||
const FeaturedBrandIcon = ({ iconType = "normal" }) => {
|
const FeaturedBrandIcon = ({ iconType = "normal" }) => {
|
||||||
return (
|
return (
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48">
|
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48">
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
import { convertThemeColor } from "./convertThemeColor";
|
import { convertThemeColor } from "./convertThemeColor";
|
||||||
|
|
||||||
const HomeIcon = ({ iconType = "normal" }) => {
|
const HomeIcon = ({ iconType = "normal" }) => {
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
import { convertThemeColor } from "./convertThemeColor";
|
import { convertThemeColor } from "./convertThemeColor";
|
||||||
|
|
||||||
const HotPicksIcon = ({ iconType = "normal" }) => {
|
const HotPicksIcon = ({ iconType = "normal" }) => {
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
import { convertThemeColor } from "./convertThemeColor";
|
import { convertThemeColor } from "./convertThemeColor";
|
||||||
|
|
||||||
const MyPageIcon = ({ iconType = "normal" }) => {
|
const MyPageIcon = ({ iconType = "normal" }) => {
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
import { convertThemeColor } from "./convertThemeColor";
|
import { convertThemeColor } from "./convertThemeColor";
|
||||||
|
|
||||||
const OnSaleIcon = ({ iconType = "normal" }) => {
|
const OnSaleIcon = ({ iconType = "normal" }) => {
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
import { convertThemeColor } from "./convertThemeColor";
|
import { convertThemeColor } from "./convertThemeColor";
|
||||||
|
|
||||||
const SearchIcon = ({ iconType = "normal" }) => {
|
const SearchIcon = ({ iconType = "normal" }) => {
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
import { convertThemeColor } from "./convertThemeColor";
|
import { convertThemeColor } from "./convertThemeColor";
|
||||||
|
|
||||||
const TrendingNowIcon = ({ iconType = "normal" }) => {
|
const TrendingNowIcon = ({ iconType = "normal" }) => {
|
||||||
return (
|
return (
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48">
|
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48">
|
||||||
|
|||||||
@@ -3,9 +3,7 @@ export const convertThemeColor = (iconType) => {
|
|||||||
const theme = {
|
const theme = {
|
||||||
light: {
|
light: {
|
||||||
normal: "#353535",
|
normal: "#353535",
|
||||||
expanded: "#353535",
|
expanded: "#FEFEFE",
|
||||||
selected: "#FEFEFE",
|
|
||||||
focused: "#FEFEFE",
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
BIN
com.twin.app.shoptime/src/features/.DS_Store
vendored
BIN
com.twin.app.shoptime/src/features/.DS_Store
vendored
Binary file not shown.
@@ -1,19 +0,0 @@
|
|||||||
import { createSlice } from "@reduxjs/toolkit";
|
|
||||||
|
|
||||||
export const appDataSlice = createSlice({
|
|
||||||
name: "appData",
|
|
||||||
initialState: {
|
|
||||||
mainIndex: null,
|
|
||||||
},
|
|
||||||
reducers: {
|
|
||||||
addMainIndex: (state, action) => {
|
|
||||||
state.mainIndex = action.payload;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Action creators are generated for each case reducer function
|
|
||||||
export const { addMainIndex, decrement, incrementByAmount } =
|
|
||||||
appDataSlice.actions;
|
|
||||||
|
|
||||||
export default appDataSlice.reducer;
|
|
||||||
@@ -1,122 +0,0 @@
|
|||||||
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
|
|
||||||
|
|
||||||
import { URLS } from "../../api/apiConfig";
|
|
||||||
import { TAxios } from "../../api/TAxios";
|
|
||||||
|
|
||||||
// Featured Brands 정보 조회 IF-LGSP-304
|
|
||||||
// @@pyh Todo, 기존의 key가 brandList에서 brandInfo로 변경 됨에 따라 함수명 또한 바뀔 수 있음 (문서 확인 후 변경 처리)
|
|
||||||
export const getBrandList = createAsyncThunk(
|
|
||||||
"brand/getBrandList",
|
|
||||||
|
|
||||||
async (_, thunkAPI) => {
|
|
||||||
const onSuccess = (response) => {
|
|
||||||
console.log("@@ getBrandList onSuccess ", response.data);
|
|
||||||
|
|
||||||
thunkAPI.dispatch(brandSlice.actions.updateBrandInfo(response.data.data));
|
|
||||||
};
|
|
||||||
|
|
||||||
const onFail = (error) => {
|
|
||||||
console.log("@@ getBrandList onFail", error);
|
|
||||||
};
|
|
||||||
|
|
||||||
TAxios(
|
|
||||||
thunkAPI.dispatch,
|
|
||||||
thunkAPI.getState,
|
|
||||||
"get",
|
|
||||||
URLS.GET_BRAND_LIST,
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
onSuccess,
|
|
||||||
onFail
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// Featured Brands LAYOUT (shelf) 정보 조회 IF-LGSP-305
|
|
||||||
export const getBrandLayoutInfo = createAsyncThunk(
|
|
||||||
"brand/getBrandLayoutInfo",
|
|
||||||
|
|
||||||
async (props, thunkAPI) => {
|
|
||||||
const { patnrId } = props;
|
|
||||||
|
|
||||||
const onSuccess = (response) => {
|
|
||||||
console.log("@@ getBrandLayoutInfo onSuccess ", response.data);
|
|
||||||
|
|
||||||
thunkAPI.dispatch(brandSlice.actions.updateLayoutBrandInfo(response.data.data));
|
|
||||||
};
|
|
||||||
|
|
||||||
const onFail = (error) => {
|
|
||||||
console.log("@@ getBrandLayoutInfo onFail ", error);
|
|
||||||
};
|
|
||||||
|
|
||||||
TAxios(
|
|
||||||
thunkAPI.dispatch,
|
|
||||||
thunkAPI.getState,
|
|
||||||
"get",
|
|
||||||
URLS.GET_BRAND_LAYOUT_INFO,
|
|
||||||
{ patnrId },
|
|
||||||
{},
|
|
||||||
onSuccess,
|
|
||||||
onFail
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// Featured Brands Live 채널 정보 조회 IF-LGSP-306
|
|
||||||
export const getBrandLiveChannelInfo = createAsyncThunk(
|
|
||||||
"brand/getBrandLiveChannelInfo",
|
|
||||||
|
|
||||||
async (props, thunkAPI) => {
|
|
||||||
const { patnrId } = props;
|
|
||||||
|
|
||||||
const onSuccess = (response) => {
|
|
||||||
console.log("@@ getBrandLiveChannelInfo onSuccess ", response.data);
|
|
||||||
|
|
||||||
thunkAPI.dispatch(brandSlice.actions.updateBrandLiveChannelInfo(response.data.data));
|
|
||||||
};
|
|
||||||
|
|
||||||
const onFail = (error) => {
|
|
||||||
console.log("@@ getBrandLiveChannelInfo onFail ", error);
|
|
||||||
};
|
|
||||||
|
|
||||||
TAxios(
|
|
||||||
thunkAPI.dispatch,
|
|
||||||
thunkAPI.getState,
|
|
||||||
"get",
|
|
||||||
URLS.GET_BRAND_LIVE_CHANNEL_INFO,
|
|
||||||
{ patnrId },
|
|
||||||
{},
|
|
||||||
onSuccess,
|
|
||||||
onFail
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const initialState = {
|
|
||||||
brandInfoData: {},
|
|
||||||
brandLayoutInfoData: {},
|
|
||||||
brandLiveChannelInfoData: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const brandSlice = createSlice({
|
|
||||||
name: "brand",
|
|
||||||
initialState,
|
|
||||||
reducers: {
|
|
||||||
updateBrandInfo: (state, action) => {
|
|
||||||
state.brandInfoData = action.payload;
|
|
||||||
},
|
|
||||||
|
|
||||||
updateLayoutBrandInfo: (state, action) => {
|
|
||||||
state.brandLayoutInfoData = action.payload;
|
|
||||||
},
|
|
||||||
|
|
||||||
updateBrandLiveChannelInfo: (state, action) => {
|
|
||||||
state.brandLiveChannelInfoData = action.payload;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const { updateBrandInfo, updateLayoutBrandInfo, updateBrandLiveChannelInfo } =
|
|
||||||
brandSlice.actions;
|
|
||||||
|
|
||||||
export default brandSlice.reducer;
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
|
|
||||||
import { URLS } from "../../api/apiConfig";
|
|
||||||
import { TAxios } from "../../api/TAxios";
|
|
||||||
|
|
||||||
// 인증코드 요청 IF-LGSP-000
|
|
||||||
export const getAuthenticationCode = createAsyncThunk(
|
|
||||||
"auth/getAuthenticationCode",
|
|
||||||
|
|
||||||
async (_, thunkAPI) => {
|
|
||||||
const onSuccess = (response) => {
|
|
||||||
console.log("getAuthenticationCode onSuccess ", response.data);
|
|
||||||
|
|
||||||
thunkAPI.dispatch(
|
|
||||||
deviceSlice.actions.updateAccessToken(response.data.data.accessToken)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const onFail = (error) => {
|
|
||||||
console.error("getAuthenticationCode onFail ", error);
|
|
||||||
};
|
|
||||||
|
|
||||||
TAxios(
|
|
||||||
thunkAPI.dispatch,
|
|
||||||
thunkAPI.getState,
|
|
||||||
"get",
|
|
||||||
URLS.GET_AUTHENTICATION_CODE,
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
onSuccess,
|
|
||||||
onFail
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const initialState = {
|
|
||||||
accessToken: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
export const deviceSlice = createSlice({
|
|
||||||
name: "device",
|
|
||||||
initialState,
|
|
||||||
reducers: {
|
|
||||||
updateAccessToken: (state, action) => {
|
|
||||||
state.accessToken = action.payload;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const { updateAccessToken } = deviceSlice.actions;
|
|
||||||
|
|
||||||
export default deviceSlice.reducer;
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
|
|
||||||
|
|
||||||
import { URLS } from "../../api/apiConfig";
|
|
||||||
import { TAxios } from "../../api/TAxios";
|
|
||||||
|
|
||||||
// 이벤트 정보 조회 IF-LGSP-070 :
|
|
||||||
export const getWelcomeEventInfo = createAsyncThunk(
|
|
||||||
"event/getWelcomeEventInfo",
|
|
||||||
|
|
||||||
async (_, thunkAPI) => {
|
|
||||||
const onSuccess = (response) => {
|
|
||||||
console.log("getWelcomeEventInfo onSuccess ", response.data);
|
|
||||||
|
|
||||||
thunkAPI.dispatch(eventSlice.actions.updateEventData(response.data.data));
|
|
||||||
};
|
|
||||||
|
|
||||||
const onFail = (error) => {
|
|
||||||
console.error("getWelcomeEventInfo onFail ", error);
|
|
||||||
};
|
|
||||||
|
|
||||||
TAxios(
|
|
||||||
thunkAPI.dispatch,
|
|
||||||
thunkAPI.getState,
|
|
||||||
"get",
|
|
||||||
URLS.GET_WELCOME_EVENT_INFO,
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
onSuccess,
|
|
||||||
onFail
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const initialState = {
|
|
||||||
eventData: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const eventSlice = createSlice({
|
|
||||||
name: "event",
|
|
||||||
initialState,
|
|
||||||
reducers: {
|
|
||||||
updateEventData: (state, action) => {
|
|
||||||
// console.log("#action", action);
|
|
||||||
state.eventData = action.payload;
|
|
||||||
// console.log("#state", state.eventData);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const { updateEventData } = eventSlice.actions;
|
|
||||||
export default eventSlice.reducer;
|
|
||||||
@@ -1,186 +0,0 @@
|
|||||||
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
|
|
||||||
import { URLS } from "../../api/apiConfig";
|
|
||||||
import { TAxios } from "../../api/TAxios";
|
|
||||||
|
|
||||||
// 약관 정보 조회 IF-LGSP-005
|
|
||||||
export const getHomeTerms = createAsyncThunk(
|
|
||||||
"home/getHomeTerms",
|
|
||||||
|
|
||||||
async (props, thunkAPI) => {
|
|
||||||
const { trmsTpCdList, mbrNo } = props;
|
|
||||||
|
|
||||||
const onSuccess = (response) => {
|
|
||||||
console.log("getHomeTerms onSuccess ", response.data);
|
|
||||||
|
|
||||||
thunkAPI.dispatch(homeSlice.actions.updateTermsData(response.data));
|
|
||||||
};
|
|
||||||
|
|
||||||
const onFail = (error) => {
|
|
||||||
console.error("getHomeTerms onFail ", error);
|
|
||||||
};
|
|
||||||
|
|
||||||
TAxios(
|
|
||||||
thunkAPI.dispatch,
|
|
||||||
thunkAPI.getState,
|
|
||||||
"get",
|
|
||||||
URLS.GET_HOME_TERMS,
|
|
||||||
{ trmsTpCdList, mbrNo },
|
|
||||||
{},
|
|
||||||
onSuccess,
|
|
||||||
onFail
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// 메뉴 목록 조회 IF-LGSP-044
|
|
||||||
export const getHomeMenu = createAsyncThunk(
|
|
||||||
"home/getHomeMenu",
|
|
||||||
|
|
||||||
async (_, thunkAPI) => {
|
|
||||||
const onSuccess = (response) => {
|
|
||||||
console.log("getHomeMenu onSuccess ", response.data);
|
|
||||||
|
|
||||||
thunkAPI.dispatch(homeSlice.actions.updateMenuData(response.data));
|
|
||||||
};
|
|
||||||
|
|
||||||
const onFail = (error) => {
|
|
||||||
console.error("getHomeMenu onFail ", error);
|
|
||||||
};
|
|
||||||
|
|
||||||
TAxios(
|
|
||||||
thunkAPI.dispatch,
|
|
||||||
thunkAPI.getState,
|
|
||||||
"get",
|
|
||||||
URLS.GET_HOME_MENU,
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
onSuccess,
|
|
||||||
onFail
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// HOME LAYOUT 정보 조회 IF-LGSP-300
|
|
||||||
export const getHomeLayout = createAsyncThunk(
|
|
||||||
"home/getHomeLayout",
|
|
||||||
|
|
||||||
async (_, thunkAPI) => {
|
|
||||||
const onSuccess = (response) => {
|
|
||||||
console.log("getHomeLayout onSuccess", response.data);
|
|
||||||
|
|
||||||
thunkAPI.dispatch(homeSlice.actions.updateLayoutData(response.data.data));
|
|
||||||
};
|
|
||||||
|
|
||||||
const onFail = (error) => {
|
|
||||||
console.error("getHomeLayout onFail", error);
|
|
||||||
};
|
|
||||||
|
|
||||||
TAxios(
|
|
||||||
thunkAPI.dispatch,
|
|
||||||
thunkAPI.getState,
|
|
||||||
"get",
|
|
||||||
URLS.GET_HOME_LAYOUT,
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
onSuccess,
|
|
||||||
onFail
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// HOME Main Contents Banner 정보 조회 IF-LGSP-301
|
|
||||||
export const getHomeMainContents = createAsyncThunk(
|
|
||||||
"home/getHomeMainContents",
|
|
||||||
|
|
||||||
async (_, thunkAPI) => {
|
|
||||||
const onSuccess = (response) => {
|
|
||||||
console.log("getHomeMainContents onSuccess", response.data);
|
|
||||||
|
|
||||||
thunkAPI.dispatch(homeSlice.actions.updateMainContentsData(response.data.data));
|
|
||||||
};
|
|
||||||
|
|
||||||
const onFail = (error) => {
|
|
||||||
console.error("getHomeMainContents onFail", error);
|
|
||||||
};
|
|
||||||
|
|
||||||
TAxios(
|
|
||||||
thunkAPI.dispatch,
|
|
||||||
thunkAPI.getState,
|
|
||||||
"get",
|
|
||||||
URLS.GET_HOME_MAIN_CONTENTS,
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
onSuccess,
|
|
||||||
onFail
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// Theme 전시 정보 조회 : IF-LGSP-045
|
|
||||||
export const getThemeCurationInfo = createAsyncThunk(
|
|
||||||
"home/getThemeCurationInfo",
|
|
||||||
|
|
||||||
async (_, thunkAPI) => {
|
|
||||||
const onSuccess = (response) => {
|
|
||||||
console.log("getThemeCurationInfo onSuccess", response.data);
|
|
||||||
|
|
||||||
thunkAPI.dispatch(homeSlice.actions.updateThemeCurationInfoDataData(response.data.data));
|
|
||||||
};
|
|
||||||
|
|
||||||
const onFail = (error) => {
|
|
||||||
console.error("getThemeCurationInfo onFail", error);
|
|
||||||
};
|
|
||||||
|
|
||||||
TAxios(
|
|
||||||
thunkAPI.dispatch,
|
|
||||||
thunkAPI.getState,
|
|
||||||
"get",
|
|
||||||
URLS.GET_THEME_CURATION_INFO,
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
onSuccess,
|
|
||||||
onFail
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const initialState = {
|
|
||||||
termsData: {},
|
|
||||||
menuData: {},
|
|
||||||
layoutData: {},
|
|
||||||
mainContentsData: {},
|
|
||||||
themeCurationInfoData: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const homeSlice = createSlice({
|
|
||||||
name: "home",
|
|
||||||
initialState,
|
|
||||||
reducers: {
|
|
||||||
updateTermsData: (state, action) => {
|
|
||||||
state.termsData = action.payload;
|
|
||||||
},
|
|
||||||
updateMenuData: (state, action) => {
|
|
||||||
//임시코드
|
|
||||||
state.menuData = action.payload;
|
|
||||||
},
|
|
||||||
updateLayoutData: (state, action) => {
|
|
||||||
state.layoutData = action.payload;
|
|
||||||
},
|
|
||||||
updateMainContentsData: (state, action) => {
|
|
||||||
state.mainContentsData = action.payload;
|
|
||||||
},
|
|
||||||
updateThemeCurationInfoDataData: (state, action) => {
|
|
||||||
state.themeCurationInfoData = action.payload;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const {
|
|
||||||
updateTermsData,
|
|
||||||
updateMenuData,
|
|
||||||
updateLayoutData,
|
|
||||||
updateMainContentsData,
|
|
||||||
updateThemeCurationInfoDataData,
|
|
||||||
} = homeSlice.actions;
|
|
||||||
|
|
||||||
export default homeSlice.reducer;
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
|
|
||||||
|
|
||||||
import { URLS } from "../../api/apiConfig";
|
|
||||||
import { TAxios } from "../../api/TAxios";
|
|
||||||
|
|
||||||
//서브카테고리 조회 IF-LGSP-051
|
|
||||||
export const getSubCategory = createAsyncThunk(
|
|
||||||
"main/getSubCategory",
|
|
||||||
|
|
||||||
async (props, thunkAPI) => {
|
|
||||||
const { lgCatCd, patnrIdList, pageSize, tabType, filterType } = props;
|
|
||||||
|
|
||||||
const onSuccess = (response) => {
|
|
||||||
console.log("getSubCategory onSuccess ", response.data);
|
|
||||||
|
|
||||||
thunkAPI.dispatch(
|
|
||||||
mainSlice.actions.updateSubCategoryData(response.data.data)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const onFail = (error) => {
|
|
||||||
console.log("getSubCategory onFail", error);
|
|
||||||
};
|
|
||||||
|
|
||||||
TAxios(
|
|
||||||
thunkAPI.dispatch,
|
|
||||||
thunkAPI.getState,
|
|
||||||
"get",
|
|
||||||
URLS.GET_SUB_CATEGORY,
|
|
||||||
{ lgCatCd, patnrIdList, pageSize, tabType, filterType },
|
|
||||||
{},
|
|
||||||
onSuccess,
|
|
||||||
onFail
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
//TOP20 영상 목록 조회 IF-LGSP-069
|
|
||||||
export const getTop20Show = createAsyncThunk(
|
|
||||||
"main/getTop20Show",
|
|
||||||
|
|
||||||
async (_, thunkAPI) => {
|
|
||||||
const onSuccess = (response) => {
|
|
||||||
console.log("getTop20Show onSuccess ", response.data);
|
|
||||||
|
|
||||||
thunkAPI.dispatch(
|
|
||||||
mainSlice.actions.updateTop20ShowData(response.data.data)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
const onFail = (error) => {
|
|
||||||
console.log("getTop20Show onFail", error);
|
|
||||||
};
|
|
||||||
|
|
||||||
TAxios(
|
|
||||||
thunkAPI.dispatch,
|
|
||||||
thunkAPI.getState,
|
|
||||||
"get",
|
|
||||||
URLS.GET_TOP20_SHOW,
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
onSuccess,
|
|
||||||
onFail
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const initialState = {
|
|
||||||
subCategoryData: {},
|
|
||||||
top20ShowData: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const mainSlice = createSlice({
|
|
||||||
name: "mainSlice",
|
|
||||||
initialState,
|
|
||||||
reducers: {
|
|
||||||
updateSubCategoryData: (state, action) => {
|
|
||||||
state.subCategoryData = action.payload;
|
|
||||||
},
|
|
||||||
updateTop20ShowData: (state, action) => {
|
|
||||||
state.top20ShowData = action.payload;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const { updateSubCategoryData, updateTop20Show } = mainSlice.actions;
|
|
||||||
|
|
||||||
export default mainSlice.reducer;
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
|
|
||||||
|
|
||||||
import { URLS } from "../../api/apiConfig";
|
|
||||||
import { TAxios } from "../../api/TAxios";
|
|
||||||
|
|
||||||
// 추천 Keyword 목록 조회 IF-LGSP-055
|
|
||||||
export const getMyRecommandedKeyword = createAsyncThunk(
|
|
||||||
"myPage/getMyRecommandedKeyword",
|
|
||||||
|
|
||||||
async (_, thunkAPI) => {
|
|
||||||
const onSuccess = (response) => {
|
|
||||||
console.log("getMyRecommandedKeyword onSuccess ", response.data);
|
|
||||||
|
|
||||||
thunkAPI.dispatch(
|
|
||||||
myPageSlice.actions.updateRecommandedKeywordData(response.data)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const onFail = (error) => {
|
|
||||||
console.error("getMyRecommandedKeyword onFail ", error);
|
|
||||||
};
|
|
||||||
|
|
||||||
TAxios(
|
|
||||||
thunkAPI.dispatch,
|
|
||||||
thunkAPI.getState,
|
|
||||||
"get",
|
|
||||||
URLS.GET_MY_RECOMMANDED_KEYWORD,
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
onSuccess,
|
|
||||||
onFail
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const initialState = {
|
|
||||||
recommandedKeywordData: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const myPageSlice = createSlice({
|
|
||||||
name: "myPage",
|
|
||||||
initialState,
|
|
||||||
reducers: {
|
|
||||||
updateRecommandedKeywordData: (state, action) => {
|
|
||||||
state.recommandedKeywordData = action.payload;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const { updateRecommandedKeywordData } = myPageSlice.actions;
|
|
||||||
|
|
||||||
export default myPageSlice.reducer;
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
|
|
||||||
|
|
||||||
import { URLS } from "../../api/apiConfig";
|
|
||||||
import { TAxios } from "../../api/TAxios";
|
|
||||||
|
|
||||||
// On Sale 조회 IF-LGSP-086
|
|
||||||
export const getOnSaleInfo = createAsyncThunk(
|
|
||||||
"onSale/getOnSaleInfo",
|
|
||||||
|
|
||||||
async (props, thunkAPI) => {
|
|
||||||
const { categoryIncFlag, lgCatCd } = props;
|
|
||||||
const onSuccess = (response) => {
|
|
||||||
console.log("getOnSaleInfo onSuccess ", response.data);
|
|
||||||
|
|
||||||
thunkAPI.dispatch(onSaleSlice.actions.updateOnSaleData(response.data.data));
|
|
||||||
};
|
|
||||||
|
|
||||||
const onFail = (error) => {
|
|
||||||
console.log("getOnSaleInfo onFail", error);
|
|
||||||
};
|
|
||||||
|
|
||||||
TAxios(
|
|
||||||
thunkAPI.dispatch,
|
|
||||||
thunkAPI.getState,
|
|
||||||
"get",
|
|
||||||
URLS.GET_ON_SALE_INFO,
|
|
||||||
{ categoryIncFlag, lgCatCd },
|
|
||||||
{},
|
|
||||||
onSuccess,
|
|
||||||
onFail
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const initialState = {
|
|
||||||
onSaleData: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const onSaleSlice = createSlice({
|
|
||||||
name: "onSale",
|
|
||||||
initialState,
|
|
||||||
reducers: {
|
|
||||||
updateOnSaleData: (state, action) => {
|
|
||||||
state.onSaleData = action.payload;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const { updateOnSaleData } = onSaleSlice.actions;
|
|
||||||
|
|
||||||
export default onSaleSlice.reducer;
|
|
||||||
@@ -1,118 +0,0 @@
|
|||||||
import { createSlice } from "@reduxjs/toolkit";
|
|
||||||
|
|
||||||
import { panel_names } from "../../utils/Config";
|
|
||||||
|
|
||||||
const initialState = {
|
|
||||||
panels: [],
|
|
||||||
isModalOpen: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
const forceTopPanels = [
|
|
||||||
panel_names.ERROR_PANEL,
|
|
||||||
panel_names.DEBUG_PANEL,
|
|
||||||
panel_names.INTRO_PANEL,
|
|
||||||
];
|
|
||||||
|
|
||||||
export const panels = createSlice({
|
|
||||||
name: "panels",
|
|
||||||
initialState,
|
|
||||||
reducers: {
|
|
||||||
addPanels: (state, action) => {
|
|
||||||
if (!action.payload.panelInfo) {
|
|
||||||
action.payload.panelInfo = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
const forceTopPanelsInfo = [];
|
|
||||||
const newState = [];
|
|
||||||
let forceTopIndex;
|
|
||||||
|
|
||||||
for (let index in state.panels) {
|
|
||||||
forceTopIndex = forceTopPanels.indexOf(state.panels[index].name);
|
|
||||||
if (forceTopIndex >= 0) {
|
|
||||||
forceTopPanelsInfo[forceTopIndex] = state.panels[index];
|
|
||||||
} else if (state.panels[index].name !== action.payload.name) {
|
|
||||||
newState.push(state.panels[index]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
forceTopIndex = forceTopPanels.indexOf(action.payload.name);
|
|
||||||
|
|
||||||
if (forceTopIndex >= 0) {
|
|
||||||
forceTopPanelsInfo[forceTopIndex] = action.payload;
|
|
||||||
} else {
|
|
||||||
newState.push(action.payload);
|
|
||||||
}
|
|
||||||
for (let i = 0; i < forceTopPanels.length; i++) {
|
|
||||||
if (forceTopPanelsInfo[i]) {
|
|
||||||
newState.push(forceTopPanelsInfo[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
state.panels = newState;
|
|
||||||
},
|
|
||||||
popPanel: (state, action) => {
|
|
||||||
let existIndex = -1;
|
|
||||||
|
|
||||||
if (action?.payload) {
|
|
||||||
for (let index in state.panels) {
|
|
||||||
if (state.panels[index].name === action.payload) {
|
|
||||||
existIndex = index;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (existIndex >= 0) {
|
|
||||||
// exist
|
|
||||||
state.panels = [
|
|
||||||
...state.panels.filter((value) => value.name !== action.payload),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!action.payload) {
|
|
||||||
state.panels = [...state.panels.slice(0, state.panels.length - 1)];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
updatePanel: (state, action) => {
|
|
||||||
let existIndex = -1;
|
|
||||||
|
|
||||||
for (let index in state.panels) {
|
|
||||||
if (state.panels[index].name === action.payload.name) {
|
|
||||||
existIndex = index;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (existIndex >= 0 && action.payload.panelInfo) {
|
|
||||||
state.panels[existIndex].panelInfo = Object.assign(
|
|
||||||
{},
|
|
||||||
state.panels[existIndex].panelInfo,
|
|
||||||
action.payload.panelInfo
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
updateModalStatus: (state, action) => {
|
|
||||||
state.isModalOpen = action.payload;
|
|
||||||
},
|
|
||||||
resetPanels: (state, action) => {
|
|
||||||
state.isModalOpen = false;
|
|
||||||
|
|
||||||
if (action.payload) {
|
|
||||||
action.payload.forEach(function (panel) {
|
|
||||||
if (!panel.panelInfo) {
|
|
||||||
panel.panelInfo = {};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
state.panels = action.payload ? action.payload : [];
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const {
|
|
||||||
addPanels,
|
|
||||||
popPanel,
|
|
||||||
updatePanel,
|
|
||||||
updateModalStatus,
|
|
||||||
resetPanels,
|
|
||||||
} = panels.actions;
|
|
||||||
|
|
||||||
export default panels.reducer;
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
|
|
||||||
import { URLS } from "../../api/apiConfig";
|
|
||||||
import { TAxios } from "../../api/TAxios";
|
|
||||||
|
|
||||||
// Best Seller 상품 목록 조회 IF-LGSP-303
|
|
||||||
export const getBestSeller = createAsyncThunk(
|
|
||||||
"bestSeller/getBestSeller",
|
|
||||||
async (_, thunkAPI) => {
|
|
||||||
const onSuccess = (response) => {
|
|
||||||
console.log("getBestSeller onSuccess", response.data);
|
|
||||||
|
|
||||||
thunkAPI.dispatch(
|
|
||||||
productSlice.actions.updateBestSellerData(response.data.data)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const onFail = (error) => {
|
|
||||||
console.log("getBestSeller onFail", error);
|
|
||||||
};
|
|
||||||
|
|
||||||
TAxios(
|
|
||||||
thunkAPI.dispatch,
|
|
||||||
thunkAPI.getState,
|
|
||||||
"get",
|
|
||||||
URLS.GET_PRODUCT_BESTSELLER,
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
onSuccess,
|
|
||||||
onFail
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const initialState = {
|
|
||||||
bestSellerData: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const productSlice = createSlice({
|
|
||||||
name: "product",
|
|
||||||
initialState,
|
|
||||||
reducers: {
|
|
||||||
updateBestSellerData: (state, action) => {
|
|
||||||
state.bestSellerData = action.payload;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const { updateBestSellerData } = productSlice.actions;
|
|
||||||
export default productSlice.reducer;
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
|
|
||||||
import { URLS } from "../../api/apiConfig";
|
|
||||||
import { TAxios } from "../../api/TAxios";
|
|
||||||
|
|
||||||
// Search 통합검색 (IBS) 데이터 조회 IF-LGSP-090
|
|
||||||
export const getSearch = createAsyncThunk(
|
|
||||||
"search/getSearch",
|
|
||||||
|
|
||||||
async (params, thunkAPI) => {
|
|
||||||
const { service, query, startIndex, maxResults, domain } = params;
|
|
||||||
|
|
||||||
const onSuccess = (response) => {
|
|
||||||
console.log("getSearch onSuccess: ", response.data);
|
|
||||||
|
|
||||||
thunkAPI.dispatch(updateSearchData(response.data));
|
|
||||||
};
|
|
||||||
|
|
||||||
const onFail = (error) => {
|
|
||||||
console.error("getSearch onFail: ", error);
|
|
||||||
};
|
|
||||||
|
|
||||||
TAxios(
|
|
||||||
thunkAPI.dispatch,
|
|
||||||
thunkAPI.getState,
|
|
||||||
"post",
|
|
||||||
URLS.GET_SEARCH,
|
|
||||||
{},
|
|
||||||
{ service, query, startIndex, maxResults, domain },
|
|
||||||
onSuccess,
|
|
||||||
onFail
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const initialState = {
|
|
||||||
searchDatas: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const searchSlice = createSlice({
|
|
||||||
name: "search",
|
|
||||||
initialState,
|
|
||||||
reducers: {
|
|
||||||
updateSearchData: (state, action) => {
|
|
||||||
state.searchDatas = action.payload;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const { updateSearchData } = searchSlice.actions;
|
|
||||||
|
|
||||||
export default searchSlice.reducer;
|
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
import { createRoot } from "react-dom/client";
|
import React from "react";
|
||||||
import { store } from "./store/store";
|
import { render } from "react-dom";
|
||||||
|
|
||||||
import { Provider } from "react-redux";
|
import { Provider } from "react-redux";
|
||||||
|
|
||||||
import App from "./App";
|
import App from "./App";
|
||||||
|
import { store } from "./store/store";
|
||||||
|
|
||||||
let appElement = (
|
let appElement = (
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
@@ -10,11 +12,12 @@ let appElement = (
|
|||||||
</Provider>
|
</Provider>
|
||||||
);
|
);
|
||||||
|
|
||||||
// In a browser environment, render instead of exporting
|
|
||||||
if (typeof window === "object") {
|
if (typeof window === "object") {
|
||||||
createRoot(document.getElementById("root")).render(appElement);
|
|
||||||
appElement = null;
|
|
||||||
window.store = store;
|
window.store = store;
|
||||||
|
|
||||||
|
render(appElement, document.getElementById("root"));
|
||||||
|
|
||||||
|
appElement = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default appElement;
|
export default appElement;
|
||||||
|
|||||||
18
com.twin.app.shoptime/src/reducers/appDataReducer.js
Normal file
18
com.twin.app.shoptime/src/reducers/appDataReducer.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { types } from "../actions/actionTypes";
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
mainIndex: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const appDataReducer = (state = initialState, action) => {
|
||||||
|
switch (action.type) {
|
||||||
|
case types.ADD_MAIN_INDEX:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
mainIndex: action.payload,
|
||||||
|
};
|
||||||
|
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
};
|
||||||
32
com.twin.app.shoptime/src/reducers/brandReducer.js
Normal file
32
com.twin.app.shoptime/src/reducers/brandReducer.js
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import { types } from "../actions/actionTypes";
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
brandInfoData: {},
|
||||||
|
brandLayoutInfoData: {},
|
||||||
|
brandLiveChannelInfoData: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const brandReducer = (state = initialState, action) => {
|
||||||
|
switch (action.type) {
|
||||||
|
case types.GET_BRAND_LIST:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
brandInfoData: action.payload,
|
||||||
|
};
|
||||||
|
|
||||||
|
case types.GET_BRAND_LAYOUT_INFO:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
brandLayoutInfoData: action.payload,
|
||||||
|
};
|
||||||
|
|
||||||
|
case types.GET_BRAND_LIVE_CHANNEL_INFO:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
brandLiveChannelInfoData: action.payload,
|
||||||
|
};
|
||||||
|
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
import { createSlice } from "@reduxjs/toolkit";
|
import { types } from "../actions/actionTypes";
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
// TODO: 각종 Status 추가
|
|
||||||
appStatus: {
|
appStatus: {
|
||||||
showLoadingPanel: { show: true, type: "launching" },
|
showLoadingPanel: { show: true, type: "launching" },
|
||||||
isLoading: true,
|
isLoading: true,
|
||||||
@@ -9,12 +8,11 @@ const initialState = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const commonSlice = createSlice({
|
export const commonReducer = (state = initialState, action) => {
|
||||||
name: "common",
|
switch (action.type) {
|
||||||
initialState,
|
case types.CHANGE_APP_STATUS: {
|
||||||
reducers: {
|
|
||||||
changeAppStatus: (state, action) => {
|
|
||||||
let isUpdated = false;
|
let isUpdated = false;
|
||||||
|
|
||||||
for (let i in action.payload) {
|
for (let i in action.payload) {
|
||||||
if (typeof action.payload[i] === "object") {
|
if (typeof action.payload[i] === "object") {
|
||||||
if (
|
if (
|
||||||
@@ -22,20 +20,28 @@ export const commonSlice = createSlice({
|
|||||||
JSON.stringify(state.appStatus[i])
|
JSON.stringify(state.appStatus[i])
|
||||||
) {
|
) {
|
||||||
isUpdated = true;
|
isUpdated = true;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (state.appStatus[i] !== action.payload[i]) {
|
} else if (state.appStatus[i] !== action.payload[i]) {
|
||||||
isUpdated = true;
|
isUpdated = true;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isUpdated) {
|
if (isUpdated) {
|
||||||
state.appStatus = { ...state.appStatus, ...action.payload };
|
return {
|
||||||
|
...state,
|
||||||
|
appStatus: { ...state.appStatus, ...action.payload },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return state;
|
||||||
}
|
}
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const { changeAppStatus } = commonSlice.actions;
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export default commonSlice.reducer;
|
export default commonReducer;
|
||||||
18
com.twin.app.shoptime/src/reducers/deviceReducer.js
Normal file
18
com.twin.app.shoptime/src/reducers/deviceReducer.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { types } from "../actions/actionTypes";
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
accessToken: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deviceReducer = (state = initialState, action) => {
|
||||||
|
switch (action.type) {
|
||||||
|
case types.GET_AUTHENTICATION_CODE:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
accessToken: action.payload,
|
||||||
|
};
|
||||||
|
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
};
|
||||||
18
com.twin.app.shoptime/src/reducers/eventReducer.js
Normal file
18
com.twin.app.shoptime/src/reducers/eventReducer.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { types } from "../actions/actionTypes";
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
eventData: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const eventReducer = (state = initialState, action) => {
|
||||||
|
switch (action.type) {
|
||||||
|
case types.GET_WELCOME_EVENT_INFO:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
eventData: action.payload,
|
||||||
|
};
|
||||||
|
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
};
|
||||||
46
com.twin.app.shoptime/src/reducers/homeReducer.js
Normal file
46
com.twin.app.shoptime/src/reducers/homeReducer.js
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
import { types } from "../actions/actionTypes";
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
termsData: {},
|
||||||
|
menuData: {},
|
||||||
|
layoutData: {},
|
||||||
|
mainContentsData: {},
|
||||||
|
themeCurationInfoData: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const homeReducer = (state = initialState, action) => {
|
||||||
|
switch (action.type) {
|
||||||
|
case types.GET_HOME_TERMS:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
termsData: action.payload,
|
||||||
|
};
|
||||||
|
|
||||||
|
case types.GET_HOME_MENU:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
menuData: action.payload,
|
||||||
|
};
|
||||||
|
|
||||||
|
case types.GET_HOME_LAYOUT:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
layoutData: action.payload,
|
||||||
|
};
|
||||||
|
|
||||||
|
case types.GET_HOME_MAIN_CONTENTS:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
mainContentsData: action.payload,
|
||||||
|
};
|
||||||
|
|
||||||
|
case types.GET_THEME_CURATION_INFO:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
themeCurationInfoData: action.payload,
|
||||||
|
};
|
||||||
|
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
};
|
||||||
25
com.twin.app.shoptime/src/reducers/mainReducer.js
Normal file
25
com.twin.app.shoptime/src/reducers/mainReducer.js
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { types } from "../actions/actionTypes";
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
subCategoryData: {},
|
||||||
|
top20ShowData: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const mainReducer = (state = initialState, action) => {
|
||||||
|
switch (action.type) {
|
||||||
|
case types.GET_SUB_CATEGORY:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
subCategoryData: action.payload,
|
||||||
|
};
|
||||||
|
|
||||||
|
case types.GET_TOP_20_SHOW:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
top20ShowData: action.payload,
|
||||||
|
};
|
||||||
|
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
};
|
||||||
18
com.twin.app.shoptime/src/reducers/myPageReducer.js
Normal file
18
com.twin.app.shoptime/src/reducers/myPageReducer.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { types } from "../actions/actionTypes";
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
recommandedKeywordData: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const myPageReducer = (state = initialState, action) => {
|
||||||
|
switch (action.type) {
|
||||||
|
case types.GET_MY_RECOMMANDED_KEYWORD:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
recommandedKeywordData: action.payload,
|
||||||
|
};
|
||||||
|
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
};
|
||||||
18
com.twin.app.shoptime/src/reducers/onSaleReducer.js
Normal file
18
com.twin.app.shoptime/src/reducers/onSaleReducer.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { types } from "../actions/actionTypes";
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
onSaleData: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const onSaleReducer = (state = initialState, action) => {
|
||||||
|
switch (action.type) {
|
||||||
|
case types.GET_ON_SALE_INFO:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
onSaleData: action.payload,
|
||||||
|
};
|
||||||
|
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
};
|
||||||
105
com.twin.app.shoptime/src/reducers/panelReducer.js
Normal file
105
com.twin.app.shoptime/src/reducers/panelReducer.js
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
import { types } from "../actions/actionTypes";
|
||||||
|
import { panel_names } from "../utils/Config";
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
panels: [],
|
||||||
|
isModalOpen: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
const forceTopPanels = [
|
||||||
|
panel_names.ERROR_PANEL,
|
||||||
|
panel_names.DEBUG_PANEL,
|
||||||
|
panel_names.INTRO_PANEL,
|
||||||
|
];
|
||||||
|
|
||||||
|
export const panelsReducer = (state = initialState, action) => {
|
||||||
|
switch (action.type) {
|
||||||
|
case types.PUSH_PANEL: {
|
||||||
|
const panelInfo = action.payload.panelInfo || {};
|
||||||
|
const forceTopPanelsInfo = [];
|
||||||
|
const newState = [];
|
||||||
|
|
||||||
|
state.panels.forEach((panel) => {
|
||||||
|
const forceTopIndex = forceTopPanels.indexOf(panel.name);
|
||||||
|
|
||||||
|
if (forceTopIndex >= 0) {
|
||||||
|
forceTopPanelsInfo[forceTopIndex] = panel;
|
||||||
|
} else if (panel.name !== action.payload.name) {
|
||||||
|
newState.push(panel);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const newPanelForceTopIndex = forceTopPanels.indexOf(action.payload.name);
|
||||||
|
|
||||||
|
if (newPanelForceTopIndex >= 0) {
|
||||||
|
forceTopPanelsInfo[newPanelForceTopIndex] = {
|
||||||
|
...action.payload,
|
||||||
|
panelInfo,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
newState.push({ ...action.payload, panelInfo });
|
||||||
|
}
|
||||||
|
|
||||||
|
forceTopPanels.forEach((_, index) => {
|
||||||
|
if (forceTopPanelsInfo[index]) {
|
||||||
|
newState.push(forceTopPanelsInfo[index]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
panels: newState,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
case types.POP_PANEL:
|
||||||
|
if (action.payload) {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
panels: state.panels.filter((panel) => panel.name !== action.payload),
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
panels: state.panels.slice(0, state.panels.length - 1),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
case types.UPDATE_PANEL:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
panels: state.panels.map((panel) =>
|
||||||
|
panel.name === action.payload.name
|
||||||
|
? {
|
||||||
|
...panel,
|
||||||
|
panelInfo: { ...panel.panelInfo, ...action.payload.panelInfo },
|
||||||
|
}
|
||||||
|
: panel
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
case types.UPDATE_MODAL_STATUS:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
isModalOpen: action.payload,
|
||||||
|
};
|
||||||
|
|
||||||
|
case types.RESET_PANELS: {
|
||||||
|
const updatedPanels = action.payload
|
||||||
|
? action.payload.map((panel) => ({
|
||||||
|
...panel,
|
||||||
|
panelInfo: panel.panelInfo || {},
|
||||||
|
}))
|
||||||
|
: [];
|
||||||
|
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
panels: updatedPanels,
|
||||||
|
isModalOpen: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
};
|
||||||
18
com.twin.app.shoptime/src/reducers/productReducer.js
Normal file
18
com.twin.app.shoptime/src/reducers/productReducer.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { types } from "../actions/actionTypes";
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
bestSellerData: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const productReducer = (state = initialState, action) => {
|
||||||
|
switch (action.type) {
|
||||||
|
case types.GET_BEST_SELLER:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
bestSellerData: action.payload,
|
||||||
|
};
|
||||||
|
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
};
|
||||||
25
com.twin.app.shoptime/src/reducers/searchReducer.js
Normal file
25
com.twin.app.shoptime/src/reducers/searchReducer.js
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { types } from "../actions/actionTypes";
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
searchDatas: {},
|
||||||
|
searchPerformed: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const searchReducer = (state = initialState, action) => {
|
||||||
|
switch (action.type) {
|
||||||
|
case types.GET_SEARCH:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
searchDatas: action.payload,
|
||||||
|
searchPerformed: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
case types.RESET_SEARCH:
|
||||||
|
return {
|
||||||
|
...initialState,
|
||||||
|
};
|
||||||
|
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1,31 +1,32 @@
|
|||||||
import { configureStore } from "@reduxjs/toolkit";
|
import { applyMiddleware, combineReducers, createStore } from "redux";
|
||||||
|
import thunk from "redux-thunk";
|
||||||
|
|
||||||
import appDataReducer from "../features/appData/appDataSlice";
|
import { appDataReducer } from "../reducers/appDataReducer";
|
||||||
import brandReducer from "../features/brand/brandsSlice";
|
import { brandReducer } from "../reducers/brandReducer";
|
||||||
import commonReducer from "../features/common/commonSlice";
|
import { commonReducer } from "../reducers/commonReducer";
|
||||||
import deviceReducer from "../features/device/deviceSlice";
|
import { deviceReducer } from "../reducers/deviceReducer";
|
||||||
import eventReducer from "../features/event/eventSlice";
|
import { eventReducer } from "../reducers/eventReducer";
|
||||||
import homeReducer from "../features/home/homeSlice";
|
import { homeReducer } from "../reducers/homeReducer";
|
||||||
import mainReducer from "../features/main/mainSlice";
|
import { mainReducer } from "../reducers/mainReducer";
|
||||||
import myPageReducer from "../features/mypage/myPageSlice";
|
import { myPageReducer } from "../reducers/myPageReducer";
|
||||||
import onSaleReducer from "../features/onSale/onSaleSlice";
|
import { onSaleReducer } from "../reducers/onSaleReducer";
|
||||||
import panelsReducer from "../features/panels/panelsSlice";
|
import { panelsReducer } from "../reducers/panelReducer";
|
||||||
import productReducer from "../features/product/productSlice";
|
import { productReducer } from "../reducers/productReducer";
|
||||||
import searchReducer from "../features/search/searchSlice";
|
import { searchReducer } from "../reducers/searchReducer";
|
||||||
|
|
||||||
export const store = configureStore({
|
const rootReducer = combineReducers({
|
||||||
reducer: {
|
|
||||||
panels: panelsReducer,
|
panels: panelsReducer,
|
||||||
device: deviceReducer,
|
device: deviceReducer,
|
||||||
appData: appDataReducer,
|
|
||||||
common: commonReducer,
|
common: commonReducer,
|
||||||
|
appData: appDataReducer,
|
||||||
home: homeReducer,
|
home: homeReducer,
|
||||||
onSale: onSaleReducer,
|
|
||||||
brand: brandReducer,
|
brand: brandReducer,
|
||||||
myPage: myPageReducer,
|
|
||||||
search: searchReducer,
|
|
||||||
product: productReducer,
|
|
||||||
main: mainReducer,
|
main: mainReducer,
|
||||||
event: eventReducer,
|
myPage: myPageReducer,
|
||||||
},
|
onSale: onSaleReducer,
|
||||||
|
product: productReducer,
|
||||||
|
search: searchReducer,
|
||||||
|
evemt: eventReducer,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const store = createStore(rootReducer, applyMiddleware(thunk));
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
@BG_COLOR_01: #f8f8f8;
|
@BG_COLOR_01: #f8f8f8;
|
||||||
@BG_COLOR_02: #f2f2f2;
|
@BG_COLOR_02: #f2f2f2;
|
||||||
@BG_COLOR_03: #f2f6fb;
|
@BG_COLOR_03: #f2f6fb;
|
||||||
|
@BG_COLOR_04: #f5f5f5;
|
||||||
|
|
||||||
/* MAIN COLOR */
|
/* MAIN COLOR */
|
||||||
@PRIMARY_COLOR_RED: #c70850;
|
@PRIMARY_COLOR_RED: #c70850;
|
||||||
@@ -54,6 +55,7 @@
|
|||||||
@COLOR_GRAY06: #333333;
|
@COLOR_GRAY06: #333333;
|
||||||
@COLOR_GRAY07: #222222;
|
@COLOR_GRAY07: #222222;
|
||||||
@COLOR_GRAY08: #1a1a1a;
|
@COLOR_GRAY08: #1a1a1a;
|
||||||
|
@COLOR_GRAY09: #999999;
|
||||||
|
|
||||||
@COLOR_BLACK: #000000;
|
@COLOR_BLACK: #000000;
|
||||||
@COLOR_NAVY: #2c343f;
|
@COLOR_NAVY: #2c343f;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import Enact_$L from "@enact/i18n/$L";
|
import Enact_$L from "@enact/i18n/$L";
|
||||||
|
|
||||||
import stringReSource from "../../resources/de/strings.json";
|
import stringReSource from "../../resources/de/strings.json";
|
||||||
|
|
||||||
export const $L = (str) => {
|
export const $L = (str) => {
|
||||||
@@ -70,3 +71,17 @@ export const wait = (time) => {
|
|||||||
}, time);
|
}, time);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const scaleW = (value) => {
|
||||||
|
if (typeof window === "object") {
|
||||||
|
return value * (window.innerWidth / 1920);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const scaleH = (value) => {
|
||||||
|
if (typeof window === "object") {
|
||||||
|
return value * (window.innerHeight / 1080);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
import TPanel from "../../components/TPanel/TPanel";
|
import TPanel from "../../components/TPanel/TPanel";
|
||||||
|
|
||||||
export default function CartPanel() {
|
export default function CartPanel() {
|
||||||
|
|||||||
@@ -2,11 +2,11 @@ import React, { useEffect, useState } from "react";
|
|||||||
|
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
|
|
||||||
import TPanel from "../../components/TPanel/TPanel";
|
|
||||||
import {
|
import {
|
||||||
getBrandLayoutInfo,
|
getBrandLayoutInfo,
|
||||||
getBrandLiveChannelInfo,
|
getBrandLiveChannelInfo,
|
||||||
} from "../../features/brand/brandsSlice";
|
} from "../../actions/brandActions";
|
||||||
|
import TPanel from "../../components/TPanel/TPanel";
|
||||||
import Banner from "./Banner/Banner";
|
import Banner from "./Banner/Banner";
|
||||||
import css from "./FeaturedBrandsPanel.module.less";
|
import css from "./FeaturedBrandsPanel.module.less";
|
||||||
import LiveChannels from "./LiveChannels/LiveChannels";
|
import LiveChannels from "./LiveChannels/LiveChannels";
|
||||||
|
|||||||
@@ -1,20 +1,12 @@
|
|||||||
import React, {
|
import React, { useEffect } from "react";
|
||||||
useCallback,
|
|
||||||
useEffect,
|
|
||||||
useState,
|
|
||||||
useMemo,
|
|
||||||
useRef,
|
|
||||||
} from "react";
|
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import classNames from "classnames";
|
|
||||||
import { $L } from "../../../utils/helperMethods";
|
|
||||||
import { Job } from "@enact/core/util";
|
|
||||||
import { SpotlightContainerDecorator } from "@enact/spotlight/SpotlightContainerDecorator";
|
import { SpotlightContainerDecorator } from "@enact/spotlight/SpotlightContainerDecorator";
|
||||||
import Spotlight from "@enact/spotlight";
|
|
||||||
import Spottable from "@enact/spotlight/Spottable";
|
import Spottable from "@enact/spotlight/Spottable";
|
||||||
|
|
||||||
import { getOnSaleInfo } from "../../../features/onSale/onSaleSlice";
|
import { getOnSaleInfo } from "../../../actions/onSaleActions";
|
||||||
|
import { $L } from "../../../utils/helperMethods";
|
||||||
import css from "./OnSale.module.less";
|
import css from "./OnSale.module.less";
|
||||||
|
|
||||||
const Container = SpotlightContainerDecorator(
|
const Container = SpotlightContainerDecorator(
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect } from "react";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
|
||||||
import { $L } from "../../../utils/helperMethods";
|
|
||||||
import { Job } from "@enact/core/util";
|
|
||||||
import { SpotlightContainerDecorator } from "@enact/spotlight/SpotlightContainerDecorator";
|
|
||||||
|
|
||||||
import Spottable from "@enact/spotlight/Spottable";
|
|
||||||
import Scroller from "@enact/sandstone/Scroller";
|
|
||||||
import { getTop20Show } from "../../../features/main/mainSlice";
|
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
|
|
||||||
|
import { SpotlightContainerDecorator } from "@enact/spotlight/SpotlightContainerDecorator";
|
||||||
|
import Spottable from "@enact/spotlight/Spottable";
|
||||||
|
|
||||||
|
import { getTop20Show } from "../../../actions/mainActions";
|
||||||
|
import { $L } from "../../../utils/helperMethods";
|
||||||
import css from "../PopularShow/PopularShow.module.less";
|
import css from "../PopularShow/PopularShow.module.less";
|
||||||
|
|
||||||
const Container = SpotlightContainerDecorator(
|
const Container = SpotlightContainerDecorator(
|
||||||
|
|||||||
@@ -2,19 +2,14 @@ import React, { useEffect, useState } from "react";
|
|||||||
|
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
|
|
||||||
import { Job } from "@enact/core/util";
|
|
||||||
import Spotlight from "@enact/spotlight";
|
|
||||||
import { SpotlightContainerDecorator } from "@enact/spotlight/SpotlightContainerDecorator";
|
import { SpotlightContainerDecorator } from "@enact/spotlight/SpotlightContainerDecorator";
|
||||||
import Spottable from "@enact/spotlight/Spottable";
|
import Spottable from "@enact/spotlight/Spottable";
|
||||||
|
|
||||||
|
import { getSubCategory } from "../../../actions/mainActions";
|
||||||
|
import { getOnSaleInfo } from "../../../actions/onSaleActions";
|
||||||
import TGrid from "../../../components/TGrid/TGrid";
|
import TGrid from "../../../components/TGrid/TGrid";
|
||||||
import TItemCard from "../../../components/TItemCard/TItemCard";
|
import TItemCard from "../../../components/TItemCard/TItemCard";
|
||||||
import TScroller from "../../../components/TScroller/TScroller";
|
|
||||||
import { getSubCategory } from "../../../features/main/mainSlice";
|
|
||||||
import { getOnSaleInfo } from "../../../features/onSale/onSaleSlice";
|
|
||||||
import { $L } from "../../../utils/helperMethods";
|
|
||||||
import CategoryNav from "../../OnSalePanel/CategoryNav/CategoryNav";
|
import CategoryNav from "../../OnSalePanel/CategoryNav/CategoryNav";
|
||||||
import css from "./SubCategory.module.less";
|
|
||||||
|
|
||||||
const Container = SpotlightContainerDecorator(
|
const Container = SpotlightContainerDecorator(
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
import TPanel from "../../components/TPanel/TPanel";
|
import TPanel from "../../components/TPanel/TPanel";
|
||||||
|
|
||||||
export default function HotPicksPanel() {
|
export default function HotPicksPanel() {
|
||||||
|
|||||||
@@ -1,19 +1,18 @@
|
|||||||
import React, { useState, useEffect, useCallback } from "react";
|
import React, { useCallback, useEffect, useState } from "react";
|
||||||
|
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import * as Config from "../../utils/Config";
|
|
||||||
import TButton, { TYPES, SIZES } from "../../components/TButton/TButton";
|
|
||||||
|
|
||||||
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
|
|
||||||
import Spotlight from "@enact/spotlight";
|
import Spotlight from "@enact/spotlight";
|
||||||
|
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
|
||||||
|
|
||||||
|
import { getHomeTerms } from "../../actions/homeActions";
|
||||||
|
import { popPanel } from "../../actions/panelActions";
|
||||||
|
import TButton, { TYPES } from "../../components/TButton/TButton";
|
||||||
import TPanel from "../../components/TPanel/TPanel";
|
import TPanel from "../../components/TPanel/TPanel";
|
||||||
import TPopUp from "../../components/TPopUp/TPopUp";
|
import TPopUp from "../../components/TPopUp/TPopUp";
|
||||||
|
import * as Config from "../../utils/Config";
|
||||||
import css from "./IntroPanel.module.less";
|
|
||||||
import classNames from "classnames";
|
|
||||||
import { $L } from "../../utils/helperMethods";
|
import { $L } from "../../utils/helperMethods";
|
||||||
import { addPanels, popPanel } from "../../features/panels/panelsSlice";
|
import css from "./IntroPanel.module.less";
|
||||||
import { getHomeTerms } from "../../features/home/homeSlice";
|
|
||||||
|
|
||||||
const Container = SpotlightContainerDecorator(
|
const Container = SpotlightContainerDecorator(
|
||||||
{ enterTo: "last-focused" },
|
{ enterTo: "last-focused" },
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
import { useState, useEffect, useCallback } from "react";
|
import React, { useCallback, useEffect, useState } from "react";
|
||||||
|
|
||||||
import { useDispatch } from "react-redux";
|
import { useDispatch } from "react-redux";
|
||||||
|
|
||||||
import { Job } from "@enact/core/util";
|
import { Job } from "@enact/core/util";
|
||||||
|
import { Panel } from "@enact/sandstone/Panels";
|
||||||
|
import Cancelable from "@enact/ui/Cancelable";
|
||||||
|
|
||||||
import LoadingAnimation from "../../../assets/intro/splash_03_end.webp";
|
import LoadingAnimation from "../../../assets/intro/splash_03_end.webp";
|
||||||
import css from "./LoadingPanel.module.less";
|
import { changeAppStatus } from "../../actions/commonActions";
|
||||||
import classNames from "classnames";
|
|
||||||
import Cancelable from "@enact/ui/Cancelable";
|
|
||||||
import { Panel } from "@enact/sandstone/Panels";
|
|
||||||
|
|
||||||
import { changeAppStatus } from "../../features/common/commonSlice";
|
|
||||||
import { $L } from "../../utils/helperMethods";
|
|
||||||
import PreloadImage from "../../components/PreloadImage/PreloadImage";
|
|
||||||
import CustomImage from "../../components/CustomImage/CustomImage";
|
import CustomImage from "../../components/CustomImage/CustomImage";
|
||||||
|
import PreloadImage from "../../components/PreloadImage/PreloadImage";
|
||||||
|
import { $L } from "../../utils/helperMethods";
|
||||||
|
import css from "./LoadingPanel.module.less";
|
||||||
|
|
||||||
const MIN_SHOWING_TIME = { launching: 2000, wait: 1000, default: 1000 };
|
const MIN_SHOWING_TIME = { launching: 2000, wait: 1000, default: 1000 };
|
||||||
const MAX_SHOWING_TIME = 20000;
|
const MAX_SHOWING_TIME = 20000;
|
||||||
|
|||||||
@@ -1,35 +1,32 @@
|
|||||||
import Panels from "@enact/sandstone/Panels";
|
|
||||||
import platform from "@enact/core/platform";
|
|
||||||
|
|
||||||
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
|
||||||
import { addPanels, popPanel } from "../../features/panels/panelsSlice";
|
|
||||||
|
|
||||||
import css from "./MainView.module.less";
|
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
|
|
||||||
import * as Config from "../../utils/Config";
|
import platform from "@enact/core/platform";
|
||||||
|
|
||||||
import LoadingPanel from "../LoadingPanel/LoadingPanel";
|
|
||||||
import IntroPanel from "../IntroPanel/IntroPanel";
|
|
||||||
import HomePanel from "../HomePanel/HomePanel";
|
|
||||||
import MyPagePanel from "../MyPagePanel/MyPagePanel";
|
|
||||||
import CategoryPanel from "../CategoryPanel/CategoryPanel";
|
|
||||||
import SearchPanel from "../SearchPanel/SearchPanel";
|
|
||||||
import OnSalePanel from "../OnSalePanel/OnSalePanel";
|
|
||||||
import TrendingNowPanel from "../TrendingNowPanel/TrendingNowPanel";
|
|
||||||
import HotPicksPanel from "../HotPicksPanel/HotPicksPanel";
|
|
||||||
import FeaturedBrandsPanel from "../FeaturedBrandsPanel/FeaturedBrandsPanel";
|
|
||||||
import ErrorPanel from "../ErrorPanel/ErrorPanel";
|
|
||||||
import DebugPanel from "../DebugPanel/DebugPanel";
|
|
||||||
import TabLayout from "../../components/TabLayout/TabLayout";
|
|
||||||
import Spotlight from "@enact/spotlight";
|
import Spotlight from "@enact/spotlight";
|
||||||
|
|
||||||
import { changeAppStatus } from "../../features/common/commonSlice";
|
|
||||||
|
|
||||||
// 테스트용 - TODO: 메인 홈 화면에 나와야 하는 이미지들 추가 후 preloadImages에 추가
|
// 테스트용 - TODO: 메인 홈 화면에 나와야 하는 이미지들 추가 후 preloadImages에 추가
|
||||||
import testImage from "../../../assets/img-banner-myinfo-login@3x.png";
|
import testImage from "../../../assets/img-banner-myinfo-login@3x.png";
|
||||||
|
import { changeAppStatus } from "../../actions/commonActions";
|
||||||
|
import { pushPanel } from "../../actions/panelActions";
|
||||||
import PreloadImage from "../../components/PreloadImage/PreloadImage";
|
import PreloadImage from "../../components/PreloadImage/PreloadImage";
|
||||||
|
import TabLayout from "../../components/TabLayout/TabLayout";
|
||||||
|
import * as Config from "../../utils/Config";
|
||||||
|
import CartPanel from "../CartPanel/CartPanel";
|
||||||
|
import CategoryPanel from "../CategoryPanel/CategoryPanel";
|
||||||
|
import DebugPanel from "../DebugPanel/DebugPanel";
|
||||||
|
import ErrorPanel from "../ErrorPanel/ErrorPanel";
|
||||||
|
import FeaturedBrandsPanel from "../FeaturedBrandsPanel/FeaturedBrandsPanel";
|
||||||
|
import HomePanel from "../HomePanel/HomePanel";
|
||||||
|
import HotPicksPanel from "../HotPicksPanel/HotPicksPanel";
|
||||||
|
import IntroPanel from "../IntroPanel/IntroPanel";
|
||||||
|
import LoadingPanel from "../LoadingPanel/LoadingPanel";
|
||||||
|
import MyPagePanel from "../MyPagePanel/MyPagePanel";
|
||||||
|
import OnSalePanel from "../OnSalePanel/OnSalePanel";
|
||||||
|
import SearchPanel from "../SearchPanel/SearchPanel";
|
||||||
|
import TrendingNowPanel from "../TrendingNowPanel/TrendingNowPanel";
|
||||||
|
import css from "./MainView.module.less";
|
||||||
|
|
||||||
const preloadImages = [testImage];
|
const preloadImages = [testImage];
|
||||||
|
|
||||||
@@ -43,6 +40,7 @@ const panelMap = {
|
|||||||
[Config.panel_names.TRENDING_NOW_PANEL]: TrendingNowPanel,
|
[Config.panel_names.TRENDING_NOW_PANEL]: TrendingNowPanel,
|
||||||
[Config.panel_names.HOT_PICKS_PANEL]: HotPicksPanel,
|
[Config.panel_names.HOT_PICKS_PANEL]: HotPicksPanel,
|
||||||
[Config.panel_names.FEATURED_BRANDS_PANEL]: FeaturedBrandsPanel,
|
[Config.panel_names.FEATURED_BRANDS_PANEL]: FeaturedBrandsPanel,
|
||||||
|
[Config.panel_names.CART_PANEL]: CartPanel,
|
||||||
[Config.panel_names.ERROR_PANEL]: ErrorPanel,
|
[Config.panel_names.ERROR_PANEL]: ErrorPanel,
|
||||||
[Config.panel_names.DEBUG_PANEL]: DebugPanel,
|
[Config.panel_names.DEBUG_PANEL]: DebugPanel,
|
||||||
};
|
};
|
||||||
@@ -106,7 +104,7 @@ export default function MainView() {
|
|||||||
if (isTermAgreed) {
|
if (isTermAgreed) {
|
||||||
} else {
|
} else {
|
||||||
dispatch(
|
dispatch(
|
||||||
addPanels({ name: Config.panel_names.INTRO_PANEL, panelInfo: {} })
|
pushPanel({ name: Config.panel_names.INTRO_PANEL, panelInfo: {} })
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ import React, { useEffect, useState } from "react";
|
|||||||
|
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
|
|
||||||
|
import { getOnSaleInfo } from "../../actions/onSaleActions";
|
||||||
import TBody from "../../components/TBody/TBody";
|
import TBody from "../../components/TBody/TBody";
|
||||||
import TItemCard from "../../components/TItemCard/TItemCard";
|
import TItemCard from "../../components/TItemCard/TItemCard";
|
||||||
import TPanel from "../../components/TPanel/TPanel";
|
import TPanel from "../../components/TPanel/TPanel";
|
||||||
import { getOnSaleInfo } from "../../features/onSale/onSaleSlice";
|
|
||||||
import CategoryNav from "../OnSalePanel/CategoryNav/CategoryNav";
|
import CategoryNav from "../OnSalePanel/CategoryNav/CategoryNav";
|
||||||
import OnSaleProductsGrid from "../OnSalePanel/OnSaleProductsGrid/OnSaleProductsGrid";
|
import OnSaleProductsGrid from "../OnSalePanel/OnSaleProductsGrid/OnSaleProductsGrid";
|
||||||
import css from "./OnSalePanel.module.less";
|
import css from "./OnSalePanel.module.less";
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
import Scroller from "@enact/sandstone/Scroller";
|
import Scroller from "@enact/sandstone/Scroller";
|
||||||
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
|
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
|
||||||
|
import NoSearchResultsImage from "../../../../assets/searchpanel/img-search-nodata.png";
|
||||||
|
import SectionTitle from "../../../components/SectionTitle/SectionTitle";
|
||||||
|
import TGrid from "../../../components/TGrid/TGrid";
|
||||||
|
import TItemCard from "../../../components/TItemCard/TItemCard";
|
||||||
|
import { $L } from "../../../utils/helperMethods";
|
||||||
|
import css from "./NoSearchResults.module.less";
|
||||||
|
|
||||||
|
export default function NoSearchResults() {
|
||||||
|
const bestSellerDatas = useSelector(
|
||||||
|
(state) => state.product.bestSellerData.bestSeller
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={css.container}>
|
||||||
|
<div className={css.info}>
|
||||||
|
<img src={NoSearchResultsImage} alt="No Datas" />
|
||||||
|
<p>{$L("SORRY, NO RESULTS MATCHING YOUR SEARCH")}</p>
|
||||||
|
</div>
|
||||||
|
<div className={css.bestSellerWrap}>
|
||||||
|
<SectionTitle title={$L("BEST SELLER")} />
|
||||||
|
<TGrid>
|
||||||
|
{bestSellerDatas &&
|
||||||
|
bestSellerDatas
|
||||||
|
.slice(0, 5)
|
||||||
|
.map((bestSeller) => (
|
||||||
|
<TItemCard
|
||||||
|
key={bestSeller.rankOrd}
|
||||||
|
imageSource={bestSeller.imgUrl}
|
||||||
|
imageAlt={bestSeller.prdtNm}
|
||||||
|
productName={bestSeller.prdtNm}
|
||||||
|
priceInfo={bestSeller.priceInfo}
|
||||||
|
rank={bestSeller.rankOrd}
|
||||||
|
isBestSeller
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</TGrid>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
@import "../../../style/CommonStyle.module.less";
|
||||||
|
@import "../../../style/utils.module.less";
|
||||||
|
|
||||||
|
.container {
|
||||||
|
margin-top: 30px;
|
||||||
|
|
||||||
|
.info {
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
> p {
|
||||||
|
.font (@fontFamily: @baseFontBold, @fontSize: 36px);
|
||||||
|
color: #a3a3a3;
|
||||||
|
margin-top: 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bestSellerWrap {
|
||||||
|
padding: 60px 60px 78px;
|
||||||
|
|
||||||
|
> h2 {
|
||||||
|
margin: 134px 0 34px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
import classNames from "classnames";
|
||||||
|
|
||||||
|
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
|
||||||
|
|
||||||
|
import TButton from "../../../components/TButton/TButton";
|
||||||
|
import TIconButton, {
|
||||||
|
ICON_TYPES,
|
||||||
|
} from "../../../components/TIconButton/TIconButton";
|
||||||
|
import css from "./RecommendedKeywords.module.less";
|
||||||
|
|
||||||
|
const Container = SpotlightContainerDecorator(
|
||||||
|
{ enterTo: "last-focused" },
|
||||||
|
"div"
|
||||||
|
);
|
||||||
|
|
||||||
|
export default function RecommendedKeywords({
|
||||||
|
keywords,
|
||||||
|
onPrev,
|
||||||
|
onNext,
|
||||||
|
hasPrevPage,
|
||||||
|
hasNextPage,
|
||||||
|
handleSearchSubmit,
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div className={css.container}>
|
||||||
|
{hasPrevPage && (
|
||||||
|
<TIconButton
|
||||||
|
iconType={ICON_TYPES.leftArrow}
|
||||||
|
className={classNames(css.arrow, css.arrowLeft)}
|
||||||
|
onClick={onPrev}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<Container className={css.keywordsGrid}>
|
||||||
|
{keywords.map((keyword, index) => (
|
||||||
|
<TButton
|
||||||
|
key={index}
|
||||||
|
spotlightId={index === 0 ? "first-keyword-button" : undefined}
|
||||||
|
className={classNames(css.keywordBox)}
|
||||||
|
onClick={() => handleSearchSubmit(keyword.keywd)}
|
||||||
|
>
|
||||||
|
{keyword.keywd}
|
||||||
|
</TButton>
|
||||||
|
))}
|
||||||
|
</Container>
|
||||||
|
{hasNextPage && (
|
||||||
|
<TIconButton
|
||||||
|
iconType={ICON_TYPES.rightArrow}
|
||||||
|
className={classNames(css.arrow, css.arrowRight)}
|
||||||
|
onClick={onNext}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
@import "../../../style/CommonStyle.module.less";
|
||||||
|
@import "../../../style/utils.module.less";
|
||||||
|
|
||||||
|
.container {
|
||||||
|
margin-top: 180px;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.arrow {
|
||||||
|
position: absolute;
|
||||||
|
top: 140px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arrowLeft {
|
||||||
|
left: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arrowRight {
|
||||||
|
right: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.keywordsGrid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
grid-gap: 40px 80px;
|
||||||
|
width: 100%;
|
||||||
|
place-items: center;
|
||||||
|
padding: 0 233px;
|
||||||
|
|
||||||
|
.keywordBox {
|
||||||
|
width: 390px;
|
||||||
|
height: 97px;
|
||||||
|
line-height: 97px;
|
||||||
|
letter-spacing: -1px;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 4px 8px 0 rgba(2, 3, 3, 0.2);
|
||||||
|
border: 1px solid @COLOR_GRAY09;
|
||||||
|
background-color: @BG_COLOR_04;
|
||||||
|
color: #333;
|
||||||
|
.font(@fontFamily: @baseFontBold, @fontSize: 40px);
|
||||||
|
|
||||||
|
> div {
|
||||||
|
overflow: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus-within {
|
||||||
|
box-shadow: inset 0 0 0 4px @PRIMARY_COLOR_RED,
|
||||||
|
0 0 50px 0 rgba(11, 8, 8, 0.5);
|
||||||
|
color: @PRIMARY_COLOR_RED;
|
||||||
|
background-color: @BG_COLOR_04;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,43 +1,40 @@
|
|||||||
import React, { useCallback, useEffect, useState, useRef } from "react";
|
import React, { useCallback, useEffect, useState } from "react";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
|
||||||
import TInput, { KINDS, ICONS } from "../../components/TInput/TInput";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import TPanel from "../../components/TPanel/TPanel";
|
|
||||||
import TButton from "../../components/TButton/TButton";
|
|
||||||
import { $L } from "../../utils/helperMethods";
|
|
||||||
import css from "./SearchPanel.module.less";
|
|
||||||
import TIconButton, { ICON_TYPES, SIZES } from "../../components/TIconButton/TIconButton";
|
|
||||||
import classNames from "classnames";
|
|
||||||
|
|
||||||
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
|
|
||||||
import Spotlight from "@enact/spotlight";
|
import Spotlight from "@enact/spotlight";
|
||||||
|
|
||||||
import { changeAppStatus } from "../../features/common/commonSlice";
|
import { getSearch, resetSearch } from "../../actions/searchActions";
|
||||||
import { getSearch } from "../../features/search/searchSlice";
|
import TBody from "../../components/TBody/TBody";
|
||||||
|
import TInput, { ICONS, KINDS } from "../../components/TInput/TInput";
|
||||||
import SearchNoDataImage from "../../../assets/searchpanel/img-search-nodata.png";
|
import TPanel from "../../components/TPanel/TPanel";
|
||||||
import TGrid from "../../components/TGrid/TGrid";
|
import NoSearchResults from "./NoSearchResults/NoSearchResults";
|
||||||
import TItemCard from "../../components/TItemCard/TItemCard";
|
import RecommendedKeywords from "./RecommendedKeywords/RecommendedKeywords";
|
||||||
import SectionTitle from "../../components/SectionTitle/SectionTitle";
|
import css from "./SearchPanel.module.less";
|
||||||
|
import SearchResults from "./SearchResults/SearchResults";
|
||||||
const Container = SpotlightContainerDecorator({ enterTo: "last-focused" }, "div");
|
|
||||||
|
|
||||||
const ITEMS_PER_PAGE = 9;
|
const ITEMS_PER_PAGE = 9;
|
||||||
|
|
||||||
export default function SearchPanel() {
|
export default function SearchPanel() {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
const { showLoadingPanel } = useSelector((state) => state.common.appStatus);
|
|
||||||
const recommandedKeywords = useSelector(
|
const recommandedKeywords = useSelector(
|
||||||
(state) => state.myPage.recommandedKeywordData.data?.keywords
|
(state) => state.myPage.recommandedKeywordData.data?.keywords
|
||||||
);
|
);
|
||||||
const searchDatas = useSelector((state) => state.search.searchDatas.data?.result.results);
|
const searchDatas = useSelector(
|
||||||
const bestSellerDatas = useSelector((state) => state.product.bestSellerData.bestSeller);
|
(state) => state.search.searchDatas.data?.result.results
|
||||||
|
);
|
||||||
|
const searchPerformed = useSelector((state) => state.search.searchPerformed);
|
||||||
|
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
const [paginatedKeywords, setPaginatedKeywords] = useState([]);
|
const [paginatedKeywords, setPaginatedKeywords] = useState([]);
|
||||||
const [pageChanged, setPageChanged] = useState(false);
|
const [pageChanged, setPageChanged] = useState(false);
|
||||||
|
|
||||||
const [searchQuery, setSearchQuery] = useState("");
|
const [searchQuery, setSearchQuery] = useState("");
|
||||||
const [searchPerformed, setSearchPerformed] = useState(false);
|
|
||||||
|
useEffect(() => {
|
||||||
|
dispatch(resetSearch());
|
||||||
|
}, [dispatch]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (recommandedKeywords) {
|
if (recommandedKeywords) {
|
||||||
@@ -66,17 +63,10 @@ export default function SearchPanel() {
|
|||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const performSearch = useCallback(
|
const handleSearchSubmit = useCallback(
|
||||||
async (query) => {
|
(query) => {
|
||||||
if (!query || query.trim() === "") {
|
if (query.trim()) {
|
||||||
setSearchPerformed(false);
|
dispatch(
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setSearchPerformed(true);
|
|
||||||
|
|
||||||
try {
|
|
||||||
await dispatch(
|
|
||||||
getSearch({
|
getSearch({
|
||||||
service: "com.lgshop.app",
|
service: "com.lgshop.app",
|
||||||
query: query,
|
query: query,
|
||||||
@@ -84,23 +74,12 @@ export default function SearchPanel() {
|
|||||||
maxResults: 10,
|
maxResults: 10,
|
||||||
domain: "theme,show,item",
|
domain: "theme,show,item",
|
||||||
})
|
})
|
||||||
).unwrap();
|
);
|
||||||
} catch (error) {
|
} else {
|
||||||
console.error("Search request failed: ", error);
|
dispatch(resetSearch());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[dispatch]
|
[dispatch, searchQuery]
|
||||||
);
|
|
||||||
|
|
||||||
const handleSearchSubmit = useCallback(() => {
|
|
||||||
performSearch(searchQuery);
|
|
||||||
}, [searchQuery, dispatch]);
|
|
||||||
|
|
||||||
const handleKeywordSearch = useCallback(
|
|
||||||
(keyword) => {
|
|
||||||
performSearch(keyword);
|
|
||||||
},
|
|
||||||
[performSearch]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleNext = useCallback(() => {
|
const handleNext = useCallback(() => {
|
||||||
@@ -114,76 +93,12 @@ export default function SearchPanel() {
|
|||||||
}, [currentPage]);
|
}, [currentPage]);
|
||||||
|
|
||||||
const hasPrevPage = currentPage > 1;
|
const hasPrevPage = currentPage > 1;
|
||||||
const hasNextPage = currentPage * ITEMS_PER_PAGE < recommandedKeywords?.length;
|
const hasNextPage =
|
||||||
|
currentPage * ITEMS_PER_PAGE < recommandedKeywords?.length;
|
||||||
|
|
||||||
const renderContents = () => {
|
|
||||||
if (searchPerformed) {
|
|
||||||
if (searchDatas && searchDatas.length > 0) {
|
|
||||||
return <div>data!!</div>;
|
|
||||||
} else {
|
|
||||||
return (
|
return (
|
||||||
<Container className={css.noDataWrap}>
|
<TPanel className={css.container}>
|
||||||
<div className={css.noDataResult}>
|
<TBody className={css.tBody}>
|
||||||
<img src={SearchNoDataImage} alt="No Datas" />
|
|
||||||
<p>{$L("SORRY, NO RESULTS MATCHING YOUR SEARCH")}</p>
|
|
||||||
</div>
|
|
||||||
<div className={css.bestSellerWrap}>
|
|
||||||
<SectionTitle title={$L(`BEST SELLER`)} />
|
|
||||||
<TGrid>
|
|
||||||
{bestSellerDatas &&
|
|
||||||
bestSellerDatas
|
|
||||||
.slice(0, 5)
|
|
||||||
.map((bestSeller) => (
|
|
||||||
<TItemCard
|
|
||||||
key={bestSeller.rankOrd}
|
|
||||||
imageSource={bestSeller.imgUrl}
|
|
||||||
imageAlt={bestSeller.prdtNm}
|
|
||||||
productName={bestSeller.prdtNm}
|
|
||||||
priceInfo={bestSeller.priceInfo}
|
|
||||||
rank={bestSeller.rankOrd}
|
|
||||||
isBestSeller
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</TGrid>
|
|
||||||
</div>
|
|
||||||
</Container>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
<div className={css.keywordWrap}>
|
|
||||||
{hasPrevPage && (
|
|
||||||
<TIconButton
|
|
||||||
iconType={ICON_TYPES.leftArrow}
|
|
||||||
className={classNames(css.arrow, css.arrowLeft)}
|
|
||||||
onClick={handlePrev}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<Container className={css.keywordsGrid}>
|
|
||||||
{paginatedKeywords.map((keyword, index) => (
|
|
||||||
<TButton
|
|
||||||
key={index}
|
|
||||||
spotlightId={index === 0 ? "first-keyword-button" : undefined}
|
|
||||||
className={classNames(css.keywordBox)}
|
|
||||||
onClick={() => handleKeywordSearch(keyword.keywd)}
|
|
||||||
>
|
|
||||||
{keyword.keywd}
|
|
||||||
</TButton>
|
|
||||||
))}
|
|
||||||
</Container>
|
|
||||||
{hasNextPage && (
|
|
||||||
<TIconButton
|
|
||||||
iconType={ICON_TYPES.rightArrow}
|
|
||||||
className={classNames(css.arrow, css.arrowRight)}
|
|
||||||
onClick={handleNext}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<TPanel className={css.panel}>
|
|
||||||
<TInput
|
<TInput
|
||||||
className={css.input}
|
className={css.input}
|
||||||
autoFocus
|
autoFocus
|
||||||
@@ -191,9 +106,25 @@ export default function SearchPanel() {
|
|||||||
icon={ICONS.search}
|
icon={ICONS.search}
|
||||||
value={searchQuery}
|
value={searchQuery}
|
||||||
onChange={handleSearchChange}
|
onChange={handleSearchChange}
|
||||||
onIconClick={handleSearchSubmit}
|
onIconClick={() => handleSearchSubmit(searchQuery)}
|
||||||
/>
|
/>
|
||||||
{renderContents()}
|
{searchPerformed ? (
|
||||||
|
searchDatas && searchDatas.length > 0 ? (
|
||||||
|
<SearchResults contents={searchDatas} />
|
||||||
|
) : (
|
||||||
|
<NoSearchResults />
|
||||||
|
)
|
||||||
|
) : (
|
||||||
|
<RecommendedKeywords
|
||||||
|
keywords={paginatedKeywords}
|
||||||
|
onPrev={handlePrev}
|
||||||
|
onNext={handleNext}
|
||||||
|
hasPrevPage={hasPrevPage}
|
||||||
|
hasNextPage={hasNextPage}
|
||||||
|
handleSearchSubmit={handleSearchSubmit}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</TBody>
|
||||||
</TPanel>
|
</TPanel>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,82 +1,15 @@
|
|||||||
@import "../../style/CommonStyle.module.less";
|
@import "../../style/CommonStyle.module.less";
|
||||||
@import "../../style/utils.module.less";
|
@import "../../style/utils.module.less";
|
||||||
|
|
||||||
.panel {
|
.container {
|
||||||
background-color: @BG_COLOR_01;
|
background-color: @BG_COLOR_01;
|
||||||
width: 100%;
|
|
||||||
|
.tBody {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.input {
|
.input {
|
||||||
width: 880px;
|
|
||||||
margin: 180px auto 0;
|
margin: 180px auto 0;
|
||||||
}
|
width: 880px;
|
||||||
|
|
||||||
.keywordWrap {
|
|
||||||
position: relative;
|
|
||||||
margin: 180px 0 0 0;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
.arrow {
|
|
||||||
position: absolute;
|
|
||||||
top: 140px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.arrowLeft {
|
|
||||||
left: 60px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.arrowRight {
|
|
||||||
right: 60px;
|
|
||||||
}
|
|
||||||
.keywordsGrid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(3, 1fr);
|
|
||||||
grid-gap: 40px 80px;
|
|
||||||
width: 100%;
|
|
||||||
place-items: center;
|
|
||||||
padding: 0 233px;
|
|
||||||
|
|
||||||
.keywordBox {
|
|
||||||
width: 390px;
|
|
||||||
height: 97px;
|
|
||||||
line-height: 97px;
|
|
||||||
letter-spacing: -1px;
|
|
||||||
border-radius: 10px;
|
|
||||||
box-shadow: 0 4px 8px 0 rgba(2, 3, 3, 0.2);
|
|
||||||
border: 1px solid #999;
|
|
||||||
background-color: #f5f5f5;
|
|
||||||
color: #333;
|
|
||||||
.font (@fontFamily: @baseFontBold, @fontSize: 40px);
|
|
||||||
|
|
||||||
> div {
|
|
||||||
overflow: unset;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:focus-within {
|
|
||||||
box-shadow: inset 0 0 0 4px @PRIMARY_COLOR_RED,
|
|
||||||
0 0 50px 0 rgba(11, 8, 8, 0.5);
|
|
||||||
color: #c70850;
|
|
||||||
background-color: #f5f5f5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.noDataWrap {
|
|
||||||
margin-top: 30px;
|
|
||||||
> .noDataResult {
|
|
||||||
text-align: center;
|
|
||||||
> p {
|
|
||||||
.font (@fontFamily:@baseFontBold, @fontSize:36px);
|
|
||||||
color: #a3a3a3;
|
|
||||||
margin-top: 6px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.bestSellerWrap {
|
|
||||||
padding: 60px 60px 78px;
|
|
||||||
> h2 {
|
|
||||||
margin: 134px 0 34px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
export default function SearchResults({ datas }) {
|
||||||
|
return <p>data</p>;
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
@import "../../../style/CommonStyle.module.less";
|
||||||
|
@import "../../../style/utils.module.less";
|
||||||
|
|
||||||
|
.container {
|
||||||
|
background-color: yellowgreen;
|
||||||
|
|
||||||
|
&:focus-within {
|
||||||
|
border: 1px solid red;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.container2 {
|
||||||
|
height: 240px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.itemList {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
|
|
||||||
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
|
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
|
||||||
@@ -9,10 +11,15 @@ import TPanel from "../../components/TPanel/TPanel";
|
|||||||
import { $L } from "../../utils/helperMethods";
|
import { $L } from "../../utils/helperMethods";
|
||||||
import css from "./TrendingNowPanel.module.less";
|
import css from "./TrendingNowPanel.module.less";
|
||||||
|
|
||||||
const Container = SpotlightContainerDecorator({ enterTo: "last-focused" }, "div");
|
const Container = SpotlightContainerDecorator(
|
||||||
|
{ enterTo: "last-focused" },
|
||||||
|
"div"
|
||||||
|
);
|
||||||
|
|
||||||
export default function TrendingNowPanel() {
|
export default function TrendingNowPanel() {
|
||||||
const bestSellerDatas = useSelector((state) => state.product.bestSellerData.bestSeller);
|
const bestSellerDatas = useSelector(
|
||||||
|
(state) => state.product.bestSellerData.bestSeller
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TPanel>
|
<TPanel>
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ import { useDispatch, useSelector } from "react-redux";
|
|||||||
import Spotlight from "@enact/spotlight";
|
import Spotlight from "@enact/spotlight";
|
||||||
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
|
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
|
||||||
|
|
||||||
|
import { getWelcomeEventInfo } from "../../actions/eventActions";
|
||||||
import TButton, { TYPES } from "../../components/TButton/TButton";
|
import TButton, { TYPES } from "../../components/TButton/TButton";
|
||||||
import TPanel from "../../components/TPanel/TPanel";
|
import TPanel from "../../components/TPanel/TPanel";
|
||||||
import { getWelcomeEventInfo } from "../../features/event/eventSlice";
|
|
||||||
import { $L } from "../../utils/helperMethods";
|
import { $L } from "../../utils/helperMethods";
|
||||||
import css from "../WelcomeEventPanel/WelcomeEventPanel.module.less";
|
import css from "../WelcomeEventPanel/WelcomeEventPanel.module.less";
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user