Skip to content

Commit cf0e8b0

Browse files
feat: add new search banner in the search suggestions
1 parent 96c6821 commit cf0e8b0

File tree

11 files changed

+215
-16
lines changed

11 files changed

+215
-16
lines changed

packages/template-retail-react-app/app/components/search/index.jsx

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,10 +140,19 @@ const Search = (props) => {
140140
const appOrigin = useAppOrigin()
141141
const sfLanguage = normalizeLocaleToSalesforce(locale.id)
142142

143-
const askAgentOnSearchEnabled = useMemo(() => {
144-
const {enabled, askAgentOnSearch} = getCommerceAgentConfig()
145-
return isAskAgentOnSearchEnabled(enabled, askAgentOnSearch)
146-
}, [config.app.commerceAgent])
143+
const commerceAgentConfig = useMemo(
144+
() => getCommerceAgentConfig(),
145+
[config.app?.commerceAgent, config.app?.commerceAgentSettings]
146+
)
147+
const askAgentOnSearchEnabled = useMemo(
148+
() =>
149+
isAskAgentOnSearchEnabled(
150+
commerceAgentConfig?.enabled,
151+
commerceAgentConfig?.askAgentOnSearch
152+
),
153+
[commerceAgentConfig]
154+
)
155+
const enableAgentFromSearchSuggestions = commerceAgentConfig?.enableAgentFromSearchSuggestions
147156

148157
const [isOpen, setIsOpen] = useState(false)
149158
const [searchQuery, setSearchQuery] = useState('')
@@ -331,6 +340,11 @@ const Search = (props) => {
331340
}
332341
}
333342

343+
const onAskAssistantClick = () => {
344+
launchChat()
345+
clearInput()
346+
}
347+
334348
const shouldOpenPopover = () => {
335349
// As per design we only want to show the popover if the input is focused and we have recent searches saved
336350
// or we have search suggestions available and have inputed some text (empty text in this scenario should show recent searches)
@@ -402,6 +416,8 @@ const Search = (props) => {
402416
closeAndNavigate={closeAndNavigate}
403417
recentSearches={recentSearches}
404418
searchSuggestions={searchSuggestions}
419+
enableAgentFromSearchSuggestions={enableAgentFromSearchSuggestions}
420+
onAskAssistantClick={onAskAssistantClick}
405421
/>
406422
</PopoverContent>
407423
</HideOnMobile>
@@ -430,6 +446,8 @@ const Search = (props) => {
430446
closeAndNavigate={closeAndNavigate}
431447
recentSearches={recentSearches}
432448
searchSuggestions={searchSuggestions}
449+
enableAgentFromSearchSuggestions={enableAgentFromSearchSuggestions}
450+
onAskAssistantClick={onAskAssistantClick}
433451
/>
434452
)}
435453
</Flex>
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright (c) 2021, salesforce.com, inc.
3+
* All rights reserved.
4+
* SPDX-License-Identifier: BSD-3-Clause
5+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6+
*/
7+
import React from 'react'
8+
import PropTypes from 'prop-types'
9+
import {Box, Text} from '@salesforce/retail-react-app/app/components/shared/ui'
10+
import {FormattedMessage} from 'react-intl'
11+
import {SparkleIcon, ChevronRightIcon} from '@salesforce/retail-react-app/app/components/icons'
12+
13+
const AskAssistantBanner = ({onClick, styles}) => {
14+
return (
15+
<Box
16+
{...styles.askAssistantBanner}
17+
as="button"
18+
type="button"
19+
width="full"
20+
textAlign="left"
21+
onClick={onClick}
22+
aria-label="Ask Assistant - Discover, compare and shop smarter with your personal shopping assistant"
23+
>
24+
<Box {...styles.askAssistantBannerContent}>
25+
<Box {...styles.askAssistantBannerIcon} as={SparkleIcon} boxSize={6} />
26+
<Box>
27+
<Text {...styles.askAssistantBannerTitle}>
28+
<FormattedMessage
29+
defaultMessage="Ask Shopping Agent"
30+
id="search.suggestions.askAssistant.title"
31+
/>
32+
</Text>
33+
<Text {...styles.askAssistantBannerDescription}>
34+
<FormattedMessage
35+
defaultMessage="Discover, compare, and shop smarter with your personal Shopping Agent."
36+
id="search.suggestions.askAssistant.description"
37+
/>
38+
</Text>
39+
</Box>
40+
</Box>
41+
<Box {...styles.askAssistantBannerArrow} as={ChevronRightIcon} boxSize={5} />
42+
</Box>
43+
)
44+
}
45+
46+
AskAssistantBanner.propTypes = {
47+
onClick: PropTypes.func.isRequired,
48+
styles: PropTypes.object
49+
}
50+
51+
export default AskAssistantBanner

packages/template-retail-react-app/app/components/search/partials/search-suggestions-section.jsx

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,19 @@ import PropTypes from 'prop-types'
99
import {Box} from '@salesforce/retail-react-app/app/components/shared/ui'
1010
import Suggestions from '@salesforce/retail-react-app/app/components/search/partials/suggestions'
1111
import HorizontalSuggestions from '@salesforce/retail-react-app/app/components/search/partials/horizontal-suggestions'
12+
import AskAssistantBanner from '@salesforce/retail-react-app/app/components/search/partials/ask-assistant-banner'
1213
import {FormattedMessage} from 'react-intl'
1314
import {HideOnDesktop, HideOnMobile} from '@salesforce/retail-react-app/app/components/responsive'
1415
import Link from '@salesforce/retail-react-app/app/components/link'
1516
import {searchUrlBuilder} from '@salesforce/retail-react-app/app/utils/url'
1617

17-
const SuggestionSection = ({searchSuggestions, closeAndNavigate, styles}) => {
18+
const SuggestionSection = ({
19+
searchSuggestions,
20+
closeAndNavigate,
21+
styles,
22+
showAskAssistantBanner,
23+
onAskAssistantClick
24+
}) => {
1825
const hasCategories = searchSuggestions?.categorySuggestions?.length
1926
const hasProducts = searchSuggestions?.productSuggestions?.length
2027
const hasPhraseSuggestions = searchSuggestions?.phraseSuggestions?.length
@@ -95,6 +102,9 @@ const SuggestionSection = ({searchSuggestions, closeAndNavigate, styles}) => {
95102
/>
96103
</Fragment>
97104
)}
105+
{showAskAssistantBanner && onAskAssistantClick && (
106+
<AskAssistantBanner onClick={onAskAssistantClick} styles={styles} />
107+
)}
98108
</HideOnDesktop>
99109
{/* Desktop - Vertical and Horizontal alignment */}
100110
<HideOnMobile>
@@ -189,6 +199,9 @@ const SuggestionSection = ({searchSuggestions, closeAndNavigate, styles}) => {
189199
)}
190200
</Box>
191201
</Box>
202+
{showAskAssistantBanner && onAskAssistantClick && (
203+
<AskAssistantBanner onClick={onAskAssistantClick} styles={styles} />
204+
)}
192205
</HideOnMobile>
193206
</Fragment>
194207
)
@@ -197,7 +210,9 @@ const SuggestionSection = ({searchSuggestions, closeAndNavigate, styles}) => {
197210
SuggestionSection.propTypes = {
198211
searchSuggestions: PropTypes.object.isRequired,
199212
closeAndNavigate: PropTypes.func.isRequired,
200-
styles: PropTypes.object.isRequired
213+
styles: PropTypes.object.isRequired,
214+
showAskAssistantBanner: PropTypes.bool,
215+
onAskAssistantClick: PropTypes.func
201216
}
202217

203218
export default SuggestionSection

packages/template-retail-react-app/app/components/search/partials/search-suggestions.jsx

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,15 @@ import PropTypes from 'prop-types'
99
import {Stack, useMultiStyleConfig} from '@salesforce/retail-react-app/app/components/shared/ui'
1010
import RecentSearches from '@salesforce/retail-react-app/app/components/search/partials/recent-searches'
1111
import SuggestionSection from '@salesforce/retail-react-app/app/components/search/partials/search-suggestions-section'
12+
import AskAssistantBanner from '@salesforce/retail-react-app/app/components/search/partials/ask-assistant-banner'
1213

13-
const SearchSuggestions = ({recentSearches, searchSuggestions, closeAndNavigate}) => {
14+
const SearchSuggestions = ({
15+
recentSearches,
16+
searchSuggestions,
17+
closeAndNavigate,
18+
enableAgentFromSearchSuggestions,
19+
onAskAssistantClick
20+
}) => {
1421
const styles = useMultiStyleConfig('SearchSuggestions')
1522
const hasCategories = searchSuggestions?.categorySuggestions?.length
1623
const hasProducts = searchSuggestions?.productSuggestions?.length
@@ -19,6 +26,8 @@ const SearchSuggestions = ({recentSearches, searchSuggestions, closeAndNavigate}
1926
const hasRecentSearches = searchSuggestions?.recentSearchSuggestions?.length
2027
const hasSuggestions =
2128
hasCategories || hasProducts || hasBrands || hasPopularSearches || hasRecentSearches
29+
const showAskAssistantBanner =
30+
enableAgentFromSearchSuggestions === 'true' || enableAgentFromSearchSuggestions === true
2231

2332
return (
2433
<Stack {...styles.container}>
@@ -27,12 +36,19 @@ const SearchSuggestions = ({recentSearches, searchSuggestions, closeAndNavigate}
2736
searchSuggestions={searchSuggestions}
2837
closeAndNavigate={closeAndNavigate}
2938
styles={styles}
39+
showAskAssistantBanner={showAskAssistantBanner}
40+
onAskAssistantClick={onAskAssistantClick}
3041
/>
3142
) : (
32-
<RecentSearches
33-
recentSearches={recentSearches}
34-
closeAndNavigate={closeAndNavigate}
35-
/>
43+
<>
44+
<RecentSearches
45+
recentSearches={recentSearches}
46+
closeAndNavigate={closeAndNavigate}
47+
/>
48+
{showAskAssistantBanner && onAskAssistantClick && (
49+
<AskAssistantBanner onClick={onAskAssistantClick} styles={styles} />
50+
)}
51+
</>
3652
)}
3753
</Stack>
3854
)
@@ -41,7 +57,9 @@ const SearchSuggestions = ({recentSearches, searchSuggestions, closeAndNavigate}
4157
SearchSuggestions.propTypes = {
4258
recentSearches: PropTypes.array,
4359
searchSuggestions: PropTypes.object,
44-
closeAndNavigate: PropTypes.func
60+
closeAndNavigate: PropTypes.func,
61+
enableAgentFromSearchSuggestions: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
62+
onAskAssistantClick: PropTypes.func
4563
}
4664

4765
export default SearchSuggestions

packages/template-retail-react-app/app/static/translations/compiled/en-GB.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3633,6 +3633,18 @@
36333633
"value": "Cancel"
36343634
}
36353635
],
3636+
"search.suggestions.askAssistant.description": [
3637+
{
3638+
"type": 0,
3639+
"value": "Discover, compare, and shop smarter with your personal Shopping Agent."
3640+
}
3641+
],
3642+
"search.suggestions.askAssistant.title": [
3643+
{
3644+
"type": 0,
3645+
"value": "Ask Shopping Agent"
3646+
}
3647+
],
36363648
"search.suggestions.categories": [
36373649
{
36383650
"type": 0,

packages/template-retail-react-app/app/static/translations/compiled/en-US.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3633,6 +3633,18 @@
36333633
"value": "Cancel"
36343634
}
36353635
],
3636+
"search.suggestions.askAssistant.description": [
3637+
{
3638+
"type": 0,
3639+
"value": "Discover, compare, and shop smarter with your personal Shopping Agent."
3640+
}
3641+
],
3642+
"search.suggestions.askAssistant.title": [
3643+
{
3644+
"type": 0,
3645+
"value": "Ask Shopping Agent"
3646+
}
3647+
],
36363648
"search.suggestions.categories": [
36373649
{
36383650
"type": 0,

packages/template-retail-react-app/app/static/translations/compiled/en-XA.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7649,6 +7649,34 @@
76497649
"value": "]"
76507650
}
76517651
],
7652+
"search.suggestions.askAssistant.description": [
7653+
{
7654+
"type": 0,
7655+
"value": "["
7656+
},
7657+
{
7658+
"type": 0,
7659+
"value": "Ḓīşƈǿǿṽḗḗř, ƈǿǿḿƥȧȧřḗḗ, ȧȧƞḓ şħǿǿƥ şḿȧȧřŧḗḗř ẇīŧħ ẏǿǿŭŭř ƥḗḗřşǿǿƞȧȧŀ Şħǿǿƥƥīƞɠ Ȧɠḗḗƞŧ."
7660+
},
7661+
{
7662+
"type": 0,
7663+
"value": "]"
7664+
}
7665+
],
7666+
"search.suggestions.askAssistant.title": [
7667+
{
7668+
"type": 0,
7669+
"value": "["
7670+
},
7671+
{
7672+
"type": 0,
7673+
"value": "Ȧşķ Şħǿǿƥƥīƞɠ Ȧɠḗḗƞŧ"
7674+
},
7675+
{
7676+
"type": 0,
7677+
"value": "]"
7678+
}
7679+
],
76527680
"search.suggestions.categories": [
76537681
{
76547682
"type": 0,

packages/template-retail-react-app/app/theme/components/project/search-suggestions.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,42 @@ export default {
7777
position: 'absolute',
7878
top: 2,
7979
left: 2
80+
},
81+
askAssistantBanner: {
82+
borderRadius: 'md',
83+
padding: 4,
84+
marginTop: 3,
85+
backgroundColor: 'blue.50',
86+
cursor: 'pointer',
87+
display: 'flex',
88+
alignItems: 'center',
89+
justifyContent: 'space-between',
90+
gap: 3,
91+
_hover: {
92+
backgroundColor: 'blue.100'
93+
}
94+
},
95+
askAssistantBannerContent: {
96+
display: 'flex',
97+
alignItems: 'flex-start',
98+
gap: 3,
99+
flex: 1,
100+
minWidth: 0
101+
},
102+
askAssistantBannerTitle: {
103+
fontWeight: 'bold',
104+
fontSize: 'md'
105+
},
106+
askAssistantBannerDescription: {
107+
fontSize: 'sm',
108+
color: 'gray.600',
109+
marginTop: 1
110+
},
111+
askAssistantBannerIcon: {
112+
flexShrink: 0
113+
},
114+
askAssistantBannerArrow: {
115+
flexShrink: 0
80116
}
81117
}
82118
}

packages/template-retail-react-app/app/utils/shopper-agent-utils.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,7 @@ export function launchChat() {
2727
// so the chat window opens correctly (Salesforce Embedded Messaging requirement)
2828
const hideChatButtonOnLoad =
2929
window.embeddedservice_bootstrap?.settings?.hideChatButtonOnLoad === true
30-
if (
31-
hideChatButtonOnLoad &&
32-
typeof utilAPI.showChatButton === 'function'
33-
) {
30+
if (hideChatButtonOnLoad && typeof utilAPI.showChatButton === 'function') {
3431
utilAPI.showChatButton()
3532
}
3633

packages/template-retail-react-app/translations/en-GB.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1520,6 +1520,12 @@
15201520
"search.action.cancel": {
15211521
"defaultMessage": "Cancel"
15221522
},
1523+
"search.suggestions.askAssistant.description": {
1524+
"defaultMessage": "Discover, compare, and shop smarter with your personal Shopping Agent."
1525+
},
1526+
"search.suggestions.askAssistant.title": {
1527+
"defaultMessage": "Ask Shopping Agent"
1528+
},
15231529
"search.suggestions.categories": {
15241530
"defaultMessage": "Categories"
15251531
},

0 commit comments

Comments
 (0)