diff --git a/com.twin.app.shoptime/assets/fonts/tahoma/tahoma.ttf b/com.twin.app.shoptime/assets/fonts/tahoma/tahoma.ttf new file mode 100644 index 00000000..b7b70863 Binary files /dev/null and b/com.twin.app.shoptime/assets/fonts/tahoma/tahoma.ttf differ diff --git a/com.twin.app.shoptime/assets/fonts/tahoma/tahomabd.ttf b/com.twin.app.shoptime/assets/fonts/tahoma/tahomabd.ttf new file mode 100644 index 00000000..2b694bf1 Binary files /dev/null and b/com.twin.app.shoptime/assets/fonts/tahoma/tahomabd.ttf differ diff --git a/com.twin.app.shoptime/assets/searchpanel/bg_srch_curation.png b/com.twin.app.shoptime/assets/searchpanel/bg_srch_curation.png new file mode 100644 index 00000000..d76ac12e Binary files /dev/null and b/com.twin.app.shoptime/assets/searchpanel/bg_srch_curation.png differ diff --git a/com.twin.app.shoptime/src/actions/actionTypes.js b/com.twin.app.shoptime/src/actions/actionTypes.js index 11de27a2..774fb503 100644 --- a/com.twin.app.shoptime/src/actions/actionTypes.js +++ b/com.twin.app.shoptime/src/actions/actionTypes.js @@ -43,6 +43,7 @@ export const types = { // search actions GET_SEARCH: "GET_SEARCH", RESET_SEARCH: "RESET_SEARCH", + GET_SEARCH_PROCESSED: "GET_SEARCH_PROCESSED", // event actions GET_WELCOME_EVENT_INFO: "GET_WELCOME_EVENT_INFO", diff --git a/com.twin.app.shoptime/src/actions/searchActions.js b/com.twin.app.shoptime/src/actions/searchActions.js index 97fa7f47..0daf7219 100644 --- a/com.twin.app.shoptime/src/actions/searchActions.js +++ b/com.twin.app.shoptime/src/actions/searchActions.js @@ -13,6 +13,21 @@ export const getSearch = (params) => (dispatch, getState) => { type: types.GET_SEARCH, payload: response.data, }); + + const processedData = response.data.data.result.results.reduce( + (acc, current) => { + acc.data[current.type] = current.docs; + acc.totalCount[current.type] = current.total_count; + + return acc; + }, + { data: {}, totalCount: {} } + ); + + dispatch({ + type: types.GET_SEARCH_PROCESSED, + payload: processedData, + }); }; const onFail = (error) => { diff --git a/com.twin.app.shoptime/src/reducers/searchReducer.js b/com.twin.app.shoptime/src/reducers/searchReducer.js index 0651bd8f..2c881e68 100644 --- a/com.twin.app.shoptime/src/reducers/searchReducer.js +++ b/com.twin.app.shoptime/src/reducers/searchReducer.js @@ -2,6 +2,10 @@ import { types } from "../actions/actionTypes"; const initialState = { searchDatas: {}, + processedDatas: { + data: {}, + totalCount: {}, + }, searchPerformed: false, }; @@ -14,6 +18,13 @@ export const searchReducer = (state = initialState, action) => { searchPerformed: true, }; + case types.GET_SEARCH_PROCESSED: + return { + ...state, + processedDatas: action.payload, + searchPerformed: true, + }; + case types.RESET_SEARCH: return { ...initialState, diff --git a/com.twin.app.shoptime/src/style/CommonStyle.module.less b/com.twin.app.shoptime/src/style/CommonStyle.module.less index 2aaf1de4..c8045b3d 100644 --- a/com.twin.app.shoptime/src/style/CommonStyle.module.less +++ b/com.twin.app.shoptime/src/style/CommonStyle.module.less @@ -24,12 +24,22 @@ font-family: "RobotoBold"; src: url("../../assets/fonts/roboto/Roboto-Bold.woff") format("woff"); } +@font-face { + font-family: "Tahoma"; + src: url("../../assets/fonts/tahoma/tahoma.ttf") format("ttf"); +} +@font-face { + font-family: "TahomaBold"; + src: url("../../assets/fonts/tahoma/tahomabd.ttf") format("ttf"); +} @baseFont: "LGSmartUI"; @baseFontBold: "LGSmartUIBold"; @arialFont: "Arial"; @arialFontBold: "ArialBold"; @robotoFont: "Roboto"; @robotoFontBold: "RobotoBold"; +@tahomaFont: "Tahoma"; +@tahomaFontBold: "TahomaBold"; @globalHeight: 1080px; @globalWidth: 1920px; @@ -60,6 +70,7 @@ @COLOR_BLACK: #000000; @COLOR_NAVY: #2c343f; @COLOR_SKYBLUE: #e7ebef; +@COLOR_LIGHT_SKYBLUE: #edeff3; /* ----- 추가 CommonStyles (chw) ----- */ diff --git a/com.twin.app.shoptime/src/views/SearchPanel/SearchPanel.jsx b/com.twin.app.shoptime/src/views/SearchPanel/SearchPanel.jsx index 31f14a81..e6acb55e 100644 --- a/com.twin.app.shoptime/src/views/SearchPanel/SearchPanel.jsx +++ b/com.twin.app.shoptime/src/views/SearchPanel/SearchPanel.jsx @@ -24,6 +24,16 @@ export default function SearchPanel() { const searchDatas = useSelector( (state) => state.search.searchDatas.data?.result.results ); + const { + theme: themeDatas, + show: showDatas, + item: itemDatas, + } = useSelector((state) => state.search.processedDatas.data); + const { + theme: themeCount, + show: showCount, + item: itemCount, + } = useSelector((state) => state.search.processedDatas.totalCount); const searchPerformed = useSelector((state) => state.search.searchPerformed); const [currentPage, setCurrentPage] = useState(1); @@ -110,7 +120,15 @@ export default function SearchPanel() { /> {searchPerformed ? ( searchDatas && searchDatas.length > 0 ? ( - + ) : ( ) diff --git a/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchItemResults/SearchItemCard/SearchItemCard.jsx b/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchItemResults/SearchItemCard/SearchItemCard.jsx new file mode 100644 index 00000000..d098256b --- /dev/null +++ b/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchItemResults/SearchItemCard/SearchItemCard.jsx @@ -0,0 +1,35 @@ +import React, { memo } from "react"; + +import Spottable from "@enact/spotlight/Spottable"; + +import css from "./SearchItemCard.module.less"; + +const ItemContainer = Spottable("div"); + +export default memo(function SearchItemCard({ + dcPrice, + partnerLogo, + partnerName, + price, + reviewGrade, + soldout, + thumbnail, + title, + contentId, + ...rest +}) { + return ( + +
+ {title} +
+
+

{title}

+
+ {price} + {dcPrice} +
+
+
+ ); +}); diff --git a/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchItemResults/SearchItemCard/SearchItemCard.module.less b/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchItemResults/SearchItemCard/SearchItemCard.module.less new file mode 100644 index 00000000..0ac68fe1 --- /dev/null +++ b/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchItemResults/SearchItemCard/SearchItemCard.module.less @@ -0,0 +1,58 @@ +@import "../../../../../style/CommonStyle.module.less"; +@import "../../../../../style/utils.module.less"; + +.card { + .size(@w: 561px, @h:150px); + background-color: @COLOR_LIGHT_SKYBLUE; + overflow: hidden; + border: 1px solid #ccc; + .flex(); + + .imageBox { + .size(@w: 150px, @h: 100%); + background-color: @COLOR_WHITE; + background-size: cover; + + > img { + object-fit: cover; + width: 100%; + height: 100%; + } + } + + .infoWrap { + .size(@w: calc(100% - 150px), @h: 100%); + padding-left: 24px; + .flex(@direction: column, @alignCenter: flex-start); + + .title { + color: @COLOR_GRAY06; + .font(@fontFamily: @arialFont, @fontSize: 24px); + .elip(@clamp: 2); + line-height: 1.33; + letter-spacing: -0.6px; + margin-bottom: 20px; + } + + .price { + color: @COLOR_GRAY06; + .font(@fontFamily: @arialFont, @fontSize: 20px); + line-height: 1.2; + letter-spacing: -0.5px; + text-decoration: line-through; + } + + .dcPrice { + color: @PRIMARY_COLOR_RED; + .font(@fontFamily: @arialFontBold, @fontSize: 28px); + line-height: 0.86; + letter-spacing: -0.7px; + margin-left: 10px; + } + } + + &:focus-within { + border: 4px solid @PRIMARY_COLOR_RED; + box-shadow: 0 0 50px 0 rgba(11, 8, 8, 0.5); + } +} diff --git a/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchItemResults/SearchItemResults.jsx b/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchItemResults/SearchItemResults.jsx new file mode 100644 index 00000000..1954d377 --- /dev/null +++ b/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchItemResults/SearchItemResults.jsx @@ -0,0 +1,54 @@ +import React, { useCallback } from "react"; + +import { VirtualGridList } from "@enact/sandstone/VirtualList"; +import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator"; +import ri from "@enact/ui/resolution"; + +import SearchItemCard from "./SearchItemCard/SearchItemCard"; +import css from "./SearchItemResults.module.less"; + +const LIST_ITEM_CONF = { + ITEM_WIDTH: 561 * 2, + ITEM_HEIGHT: 150 * 2, + SPACING: 30 * 2, +}; + +const Container = SpotlightContainerDecorator( + { leaveFor: { right: "" }, enterTo: "last-focused" }, + "div" +); + +export default function SearchItemResults({ itemDatas, itemCount, ...rest }) { + const renderItem = useCallback( + ({ index, ...rest }) => { + const itemData = itemDatas[index]; + + return ( + + ); + }, + [itemDatas] + ); + + return ( + + {itemDatas && ( + + )} + + ); +} diff --git a/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchItemResults/SearchItemResults.module.less b/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchItemResults/SearchItemResults.module.less new file mode 100644 index 00000000..80e4922c --- /dev/null +++ b/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchItemResults/SearchItemResults.module.less @@ -0,0 +1,17 @@ +@import "../../../../style/CommonStyle.module.less"; +@import "../../../../style/utils.module.less"; + +.container { + .flex(); + margin: 30px 0 50px; + width: 100%; +} + +.grid { + height: 150px; + overflow: unset; + + > div { + overflow: unset !important; + } +} diff --git a/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchResults.jsx b/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchResults.jsx index 568f59ac..390ee74c 100644 --- a/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchResults.jsx +++ b/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchResults.jsx @@ -1,5 +1,52 @@ import React from "react"; -export default function SearchResults({ datas }) { - return

data

; +import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator"; + +import SectionTitle from "../../../components/SectionTitle/SectionTitle"; +import { $L } from "../../../utils/helperMethods"; +import SearchItemResults from "./SearchItemResults/SearchItemResults"; +import css from "./SearchResults.module.less"; +import SearchShowResults from "./SearchShowResults/SearchShowResults"; +import SearchThemeResults from "./SearchThemeResults/SearchThemeResults"; + +const Container = SpotlightContainerDecorator( + { enterTo: "last-focused" }, + "div" +); + +export default function SearchResults({ + themeDatas, + itemDatas, + showDatas, + themeCount, + itemCount, + showCount, + query, +}) { + return ( + + {themeDatas && ( + <> + + + + )} + {showDatas && ( + <> + + + + )} + {itemDatas && ( + <> + + + + )} + + ); } diff --git a/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchResults.module.less b/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchResults.module.less index f408bed0..d8633a9b 100644 --- a/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchResults.module.less +++ b/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchResults.module.less @@ -1,19 +1,3 @@ -@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%; + padding: 94px 60px 0 60px; } diff --git a/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchShowResults/SearchShowCard/SearchShowCard.jsx b/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchShowResults/SearchShowCard/SearchShowCard.jsx new file mode 100644 index 00000000..2db6738d --- /dev/null +++ b/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchShowResults/SearchShowCard/SearchShowCard.jsx @@ -0,0 +1,35 @@ +import React, { memo } from "react"; + +import Spottable from "@enact/spotlight/Spottable"; + +import IcLiveShow from "../../../../../../assets/icon/tag/tag-liveshow.svg"; +import css from "./SearchShowCard.module.less"; + +const CardContainer = Spottable("div"); + +export default memo(function SearchShowCard({ + endTime, + liveFlag, + partnerId, + partnerLogo, + partnerName, + startTime, + thumbnail, + title, + contentId, + ...rest +}) { + return ( + +
+ {liveFlag === "Y" && ( + + LIVE + + )} + {title} +
+

{title}

+
+ ); +}); diff --git a/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchShowResults/SearchShowCard/SearchShowCard.module.less b/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchShowResults/SearchShowCard/SearchShowCard.module.less new file mode 100644 index 00000000..06c3ea46 --- /dev/null +++ b/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchShowResults/SearchShowCard/SearchShowCard.module.less @@ -0,0 +1,52 @@ +@import "../../../../../style/CommonStyle.module.less"; +@import "../../../../../style/utils.module.less"; + +.card { + .size(@w: 344px, @h: 281px); + background-color: @COLOR_LIGHT_SKYBLUE; + border-radius: 10px; + overflow: hidden; + transform: scale(0.9); + transition: all 0.15s ease-in-out; + + .imageBox { + .size(@w: 100%, @h: 182px); + background-color: @COLOR_WHITE; + background-size: cover; + position: relative; + + .liveBadge { + position: absolute; + top: 10px; + right: 10px; + } + + > img { + object-fit: cover; + width: 100%; + height: 100%; + } + } + + .title { + width: 100%; + height: calc(100% - 182px); + color: @COLOR_GRAY06; + .font(@fontFamily: @arialFont, @fontSize: 20px); + .elip(@clamp:1); + line-height: 1.2; + letter-spacing: -0.5px; + display: flex; + align-items: center; + padding: 0 15px; + } + + &:focus-within { + border: 4px solid @PRIMARY_COLOR_RED; + background-color: @COLOR_WHITE; + box-shadow: 0 0 50px 0 rgba(11, 8, 8, 0.5); + .elip(@clamp:2); + line-height: 1.5; + transform: scale(1); + } +} diff --git a/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchShowResults/SearchShowResults.jsx b/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchShowResults/SearchShowResults.jsx new file mode 100644 index 00000000..63da1a48 --- /dev/null +++ b/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchShowResults/SearchShowResults.jsx @@ -0,0 +1,53 @@ +import React, { useCallback } from "react"; + +import VirtualGridList from "@enact/sandstone/VirtualList"; +import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator"; +import ri from "@enact/ui/resolution"; + +import SearchShowCard from "./SearchShowCard/SearchShowCard"; +import css from "./SearchShowResults.module.less"; + +const LIST_ITEM_CONF = { + ITEM_WIDTH: 344 * 2, + ITEM_HEIGHT: 281 * 2, + SPACING: 0, +}; + +const Container = SpotlightContainerDecorator( + { leaveFor: { right: "" }, enterTo: "last-focused" }, + "div" +); + +export default function SearchShowResults({ showDatas, showCount, ...rest }) { + const renderItem = useCallback( + ({ index, ...rest }) => { + const showData = showDatas[index]; + + return ( + + ); + }, + [showDatas] + ); + + return ( + + {showDatas && ( + + )} + + ); +} diff --git a/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchShowResults/SearchShowResults.module.less b/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchShowResults/SearchShowResults.module.less new file mode 100644 index 00000000..6abf5ac1 --- /dev/null +++ b/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchShowResults/SearchShowResults.module.less @@ -0,0 +1,17 @@ +@import "../../../../style/CommonStyle.module.less"; +@import "../../../../style/utils.module.less"; + +.container { + .flex(); + margin: 30px 0 50px; + width: 100%; +} + +.grid { + height: 281px; + overflow: unset; + + > div { + overflow: unset !important; + } +} diff --git a/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchThemeResults/SearchThemeCard/SearchThemeCard.jsx b/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchThemeResults/SearchThemeCard/SearchThemeCard.jsx new file mode 100644 index 00000000..e737a68e --- /dev/null +++ b/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchThemeResults/SearchThemeCard/SearchThemeCard.jsx @@ -0,0 +1,32 @@ +import React, { memo } from "react"; + +import Spottable from "@enact/spotlight/Spottable"; + +import css from "./SearchThemeCard.module.less"; + +const ThemeContainer = Spottable("div"); + +export default memo(function SearchThemeCard({ + endTime, + keyword, + partnerLogo, + partnerName, + startTime, + title, + contentId, + ...rest +}) { + return ( + +

{title}

+
    + {keyword && + keyword.map((item, index) => ( +
  • + # {item} +
  • + ))} +
+
+ ); +}); diff --git a/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchThemeResults/SearchThemeCard/SearchThemeCard.module.less b/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchThemeResults/SearchThemeCard/SearchThemeCard.module.less new file mode 100644 index 00000000..d03b4015 --- /dev/null +++ b/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchThemeResults/SearchThemeCard/SearchThemeCard.module.less @@ -0,0 +1,51 @@ +@import "../../../../../style/CommonStyle.module.less"; +@import "../../../../../style/utils.module.less"; + +.card { + .size(@w: 560px, @h: 140px); + background-image: url("../../../../../../assets/searchpanel/bg_srch_curation.png"); + border: 2px solid #ccc; + overflow: hidden; + background-size: cover; + background-repeat: no-repeat; + background-position: center top; + padding: 25px 20px; + + .title { + color: @COLOR_GRAY06; + .font(@fontFamily: @tahomaFontBold, @fontSize: 26px); + line-height: 1.31; + letter-spacing: -0.65px; + color: @COLOR_GRAY06; + font-weight: 900; + .elip(@clamp: 2); + } + + .keywordWrap { + margin-top: 1px; + display: flex; + color: #c06; + .font(@fontFamily: @arialFontBold, @fontSize: 24px); + letter-spacing: -0.6px; + line-height: 1.67; + min-height: 26px; + + .keywordList { + margin-right: 14px; + } + } + + &:focus-within { + background-position: center bottom; + border: 4px solid @PRIMARY_COLOR_RED; + box-shadow: 0 0 50px 0 rgba(11, 8, 8, 0.5); + + .title { + color: @COLOR_WHITE; + } + + .keywordWrap { + color: @COLOR_WHITE; + } + } +} diff --git a/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchThemeResults/SearchThemeResults.jsx b/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchThemeResults/SearchThemeResults.jsx new file mode 100644 index 00000000..df42e884 --- /dev/null +++ b/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchThemeResults/SearchThemeResults.jsx @@ -0,0 +1,57 @@ +import React, { useCallback } from "react"; + +import { VirtualGridList } from "@enact/sandstone/VirtualList"; +import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator"; +import ri from "@enact/ui/resolution"; + +import SearchThemeCard from "./SearchThemeCard/SearchThemeCard"; +import css from "./SearchThemeResults.module.less"; + +const LIST_ITEM_CONF = { + ITEM_WIDTH: 560 * 2, + ITEM_HEIGHT: 140 * 2, + SPACING: 30 * 2, +}; + +const Container = SpotlightContainerDecorator( + { leaveFor: { right: "" }, enterTo: "last-focused" }, + "div" +); + +export default function SearchThemeResults({ + themeDatas, + themeCount, + ...rest +}) { + const renderItem = useCallback( + ({ index, ...rest }) => { + const themeData = themeDatas[index]; + + return ( + + ); + }, + [themeDatas] + ); + + return ( + + {themeDatas && ( + + )} + + ); +} diff --git a/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchThemeResults/SearchThemeResults.module.less b/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchThemeResults/SearchThemeResults.module.less new file mode 100644 index 00000000..1b2d5379 --- /dev/null +++ b/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchThemeResults/SearchThemeResults.module.less @@ -0,0 +1,17 @@ +@import "../../../../style/CommonStyle.module.less"; +@import "../../../../style/utils.module.less"; + +.container { + .flex(); + margin: 30px 0 50px; + width: 100%; +} + +.grid { + height: 141px; + overflow: unset; + + > div { + overflow: unset !important; + } +}