diff --git a/com.twin.app.shoptime/src/App/App.js b/com.twin.app.shoptime/src/App/App.js index 62d27233..46641f1f 100644 --- a/com.twin.app.shoptime/src/App/App.js +++ b/com.twin.app.shoptime/src/App/App.js @@ -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 ; diff --git a/com.twin.app.shoptime/src/api/apiConfig.js b/com.twin.app.shoptime/src/api/apiConfig.js index 43f2a1d2..17232d5c 100644 --- a/com.twin.app.shoptime/src/api/apiConfig.js +++ b/com.twin.app.shoptime/src/api/apiConfig.js @@ -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) => { diff --git a/com.twin.app.shoptime/src/components/TInput/TInput.jsx b/com.twin.app.shoptime/src/components/TInput/TInput.jsx new file mode 100644 index 00000000..c6c712a7 --- /dev/null +++ b/com.twin.app.shoptime/src/components/TInput/TInput.jsx @@ -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 ( + + ); +} + +export { KINDS, ICONS, BORDER, COLOR }; diff --git a/com.twin.app.shoptime/src/components/TInput/TInput.module.less b/com.twin.app.shoptime/src/components/TInput/TInput.module.less new file mode 100644 index 00000000..a91afd68 --- /dev/null +++ b/com.twin.app.shoptime/src/components/TInput/TInput.module.less @@ -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; + } +} diff --git a/com.twin.app.shoptime/src/components/TInput/package.json b/com.twin.app.shoptime/src/components/TInput/package.json new file mode 100644 index 00000000..23268437 --- /dev/null +++ b/com.twin.app.shoptime/src/components/TInput/package.json @@ -0,0 +1,6 @@ +{ + "main": "TInput.jsx", + "styles": [ + "TInput.module.less" + ] +} \ No newline at end of file diff --git a/com.twin.app.shoptime/src/features/mypage/myPageSlice.js b/com.twin.app.shoptime/src/features/mypage/myPageSlice.js new file mode 100644 index 00000000..154d82d1 --- /dev/null +++ b/com.twin.app.shoptime/src/features/mypage/myPageSlice.js @@ -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; diff --git a/com.twin.app.shoptime/src/store/store.js b/com.twin.app.shoptime/src/store/store.js index 812e8de8..69c2f149 100644 --- a/com.twin.app.shoptime/src/store/store.js +++ b/com.twin.app.shoptime/src/store/store.js @@ -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, }, }); diff --git a/com.twin.app.shoptime/src/views/SearchPanel/SearchPanel.jsx b/com.twin.app.shoptime/src/views/SearchPanel/SearchPanel.jsx index c66803dc..244a1fcd 100644 --- a/com.twin.app.shoptime/src/views/SearchPanel/SearchPanel.jsx +++ b/com.twin.app.shoptime/src/views/SearchPanel/SearchPanel.jsx @@ -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 Search; + 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 ( + + +
+ {paginatedKeywords.map((keyword, index) => ( +
{keyword.keywd}
+ ))} +
+
+ + PREV + + = recommandedKeywords?.length} + > + NEXT + +
+
+ ); } diff --git a/com.twin.app.shoptime/src/views/SearchPanel/SearchPanel.module.less b/com.twin.app.shoptime/src/views/SearchPanel/SearchPanel.module.less index e69de29b..988aa7b9 100644 --- a/com.twin.app.shoptime/src/views/SearchPanel/SearchPanel.module.less +++ b/com.twin.app.shoptime/src/views/SearchPanel/SearchPanel.module.less @@ -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); +}