SearchPanel 작업 진행 중 - chw
This commit is contained in:
@@ -10,6 +10,7 @@ import { getHomeMenu } from "../features/home/homeSlice";
|
||||
import { getOnSaleInfo } from "../features/onSale/onSaleSlice";
|
||||
import MainView from "../views/MainView/MainView";
|
||||
import css from "./App.module.less";
|
||||
import { getMyRecommandedKeyword } from "../features/mypage/myPageSlice";
|
||||
|
||||
function AppBase(props) {
|
||||
const dispatch = useDispatch();
|
||||
@@ -19,6 +20,7 @@ function AppBase(props) {
|
||||
dispatch(getHomeMenu());
|
||||
dispatch(getOnSaleInfo({ categoryIncFlag: "Y", lgCatCd: "" }));
|
||||
dispatch(getBrandList());
|
||||
dispatch(getMyRecommandedKeyword());
|
||||
}, [dispatch]);
|
||||
|
||||
return <MainView />;
|
||||
|
||||
@@ -27,6 +27,9 @@ export const URLS = {
|
||||
|
||||
//on-sale controller
|
||||
GET_ON_SALE_INFO: "/lgsp/v1/onsale/onsale.lge",
|
||||
|
||||
//my-page controller
|
||||
GET_MY_RECOMMANDED_KEYWORD: "/lgsp/v1/mypage/reckeyword.lge",
|
||||
};
|
||||
|
||||
export const getUrl = (endStr) => {
|
||||
|
||||
37
com.twin.app.shoptime/src/components/TInput/TInput.jsx
Normal file
37
com.twin.app.shoptime/src/components/TInput/TInput.jsx
Normal file
@@ -0,0 +1,37 @@
|
||||
import classNames from "classnames";
|
||||
import React from "react";
|
||||
import css from "./TInput.module.less";
|
||||
import { InputField } from "@enact/sandstone/Input";
|
||||
import { $L } from "../../utils/helperMethods";
|
||||
|
||||
const KINDS = { withIcon: "withIcon" };
|
||||
const ICONS = { search: "search" };
|
||||
const BORDER = { none: "none" };
|
||||
const COLOR = { transparent: "transparent" };
|
||||
|
||||
export default function TInput({
|
||||
kind = "",
|
||||
icon = null,
|
||||
border = null,
|
||||
color = null,
|
||||
className = null,
|
||||
spotlightDisabled,
|
||||
...rest
|
||||
}) {
|
||||
return (
|
||||
<InputField
|
||||
{...rest}
|
||||
className={classNames(
|
||||
css.input,
|
||||
icon && css[icon],
|
||||
css[kind],
|
||||
css[border],
|
||||
css[color],
|
||||
className
|
||||
)}
|
||||
spotlightDisabled={spotlightDisabled}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export { KINDS, ICONS, BORDER, COLOR };
|
||||
@@ -0,0 +1,29 @@
|
||||
@import "../../style/CommonStyle.module.less";
|
||||
@import "../../style/utils.module.less";
|
||||
|
||||
.input {
|
||||
margin-right: 0;
|
||||
margin-left: 0;
|
||||
height: 100px !important;
|
||||
padding: 20px 40px 20px 50px !important;
|
||||
border-radius: 50px;
|
||||
border: 5px solid #ccc;
|
||||
background-color: #fff !important;
|
||||
|
||||
&:focus-within,
|
||||
&:hover {
|
||||
box-shadow: 0 0 0 2px #fefefe inset;
|
||||
border: 5px solid @PRIMARY_COLOR_RED;
|
||||
}
|
||||
|
||||
> div {
|
||||
display: none;
|
||||
}
|
||||
|
||||
> input {
|
||||
font-family: @baseFont;
|
||||
color: @COLOR_GRAY07 !important;
|
||||
height: inherit !important;
|
||||
line-height: inherit !important;
|
||||
}
|
||||
}
|
||||
6
com.twin.app.shoptime/src/components/TInput/package.json
Normal file
6
com.twin.app.shoptime/src/components/TInput/package.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"main": "TInput.jsx",
|
||||
"styles": [
|
||||
"TInput.module.less"
|
||||
]
|
||||
}
|
||||
52
com.twin.app.shoptime/src/features/mypage/myPageSlice.js
Normal file
52
com.twin.app.shoptime/src/features/mypage/myPageSlice.js
Normal file
@@ -0,0 +1,52 @@
|
||||
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;
|
||||
@@ -7,6 +7,7 @@ import deviceReducer from "../features/device/deviceSlice";
|
||||
import homeReducer from "../features/home/homeSlice";
|
||||
import onSaleReducer from "../features/onSale/onSaleSlice";
|
||||
import panelsReducer from "../features/panels/panelsSlice";
|
||||
import myPageReducer from "../features/mypage/myPageSlice";
|
||||
|
||||
export const store = configureStore({
|
||||
reducer: {
|
||||
@@ -17,5 +18,6 @@ export const store = configureStore({
|
||||
home: homeReducer,
|
||||
onSale: onSaleReducer,
|
||||
featuredBrands: featuredBrandsReducer,
|
||||
myPage: myPageReducer,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,5 +1,59 @@
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import TInput from "../../components/TInput/TInput";
|
||||
import TPanel from "../../components/TPanel/TPanel";
|
||||
import TButton from "../../components/TButton/TButton";
|
||||
import { $L } from "../../utils/helperMethods";
|
||||
import css from "./SearchPanel.module.less";
|
||||
|
||||
const ITEMS_PER_PAGE = 9;
|
||||
|
||||
export default function SearchPanel() {
|
||||
return <TPanel>Search</TPanel>;
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const recommandedKeywords = useSelector(
|
||||
(state) => state.myPage.recommandedKeywordData.data?.keywords
|
||||
);
|
||||
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const [paginatedKeywords, setPaginatedKeywords] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (recommandedKeywords) {
|
||||
const startIndex = (currentPage - 1) * ITEMS_PER_PAGE;
|
||||
const endIndex = startIndex + ITEMS_PER_PAGE;
|
||||
|
||||
setPaginatedKeywords(recommandedKeywords.slice(startIndex, endIndex));
|
||||
}
|
||||
}, [recommandedKeywords, currentPage]);
|
||||
|
||||
const handleNext = useCallback(() => {
|
||||
setCurrentPage((prev) => prev + 1);
|
||||
}, [currentPage]);
|
||||
|
||||
const handlePrev = useCallback(() => {
|
||||
setCurrentPage((prev) => (prev > 1 ? prev - 1 : prev));
|
||||
}, [currentPage]);
|
||||
|
||||
return (
|
||||
<TPanel className={css.panel}>
|
||||
<TInput className={css.input} autoFocus />
|
||||
<div>
|
||||
{paginatedKeywords.map((keyword, index) => (
|
||||
<div key={index}>{keyword.keywd}</div>
|
||||
))}
|
||||
</div>
|
||||
<div>
|
||||
<TButton onClick={handlePrev} disabled={currentPage === 1}>
|
||||
PREV
|
||||
</TButton>
|
||||
<TButton
|
||||
onClick={handleNext}
|
||||
disabled={currentPage * ITEMS_PER_PAGE >= recommandedKeywords?.length}
|
||||
>
|
||||
NEXT
|
||||
</TButton>
|
||||
</div>
|
||||
</TPanel>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
@import "../../style/CommonStyle.module.less";
|
||||
@import "../../style/utils.module.less";
|
||||
|
||||
.panel {
|
||||
background-color: @BG_COLOR_01;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
.flex(@direction: row);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user