Skip to content

Commit 3e9df4f

Browse files
Fixed search bar to get closest results if search keyword is not matched
1 parent d447955 commit 3e9df4f

File tree

6 files changed

+75
-99
lines changed

6 files changed

+75
-99
lines changed

client/src/components/routes/navbar/searchBar.js

Lines changed: 46 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, {useState} from 'react';
1+
import React, {useEffect, useState} from 'react';
22
import TextField from '@material-ui/core/TextField';
33
import Autocomplete from '@material-ui/lab/Autocomplete';
44
import CloseIcon from '@material-ui/icons/Close';
@@ -11,66 +11,75 @@ import {getSearchSuggestions, getDataViaAPI} from "../../../actions";
1111
import {makeStyles} from "@material-ui/core/styles";
1212
import {LOAD_FILTER_PRODUCTS} from "../../../actions/types";
1313
import {PRODUCT_BY_CATEGORY_DATA_API} from "../../../constants/api_routes";
14+
import {Loader} from "semantic-ui-react";
15+
import {StyledSearchBarDimmer} from "../../../styles/semanticUI/customStyles";
1416

15-
export const useSearchBarStyles = makeStyles(() => ({
17+
export const useSearchBarStyles = makeStyles((theme) => ({
1618
paper: {
17-
height: 300
19+
height: 250
1820
},
1921
listbox: {
20-
maxHeight: 340
22+
maxHeight: 290,
23+
},
24+
option: {
25+
[theme.breakpoints.down("xs")]: {
26+
paddingLeft: 40
27+
},
2128
}
2229
}));
2330

2431
function SearchBar(props) {
2532
const [value, setValue] = useState(null);
2633
const searchSuggestions = useSelector(state => state.searchKeywordReducer)
34+
const filterProductsReducer = useSelector(state => state.filterProductsReducer)
2735
const classes = useSearchBarStyles()
36+
const [isLoading, setIsLoading] = useState(false)
37+
let selectedValue = null
38+
39+
useEffect(() => {
40+
log.info(`[SearchBar] Component did mount`)
41+
setIsLoading(false)
42+
}, [filterProductsReducer])
2843

29-
const getSelectedValue = () => {
44+
const getSearchKeyword = () => {
3045
return document.querySelector('input[id="free-solo"]').value
3146
}
3247

33-
const searchKeyword = () => {
34-
const selectedValue = getSelectedValue()
35-
if(selectedValue && !selectedValue.isEmpty) {
48+
const searchKeyword = (value) => {
49+
if (value && !value.isEmpty) {
3650
let queryLink = null
3751
for (let index = 0; index < searchSuggestions.data.length; ++index) {
38-
if (searchSuggestions.data[index].keyword.length === selectedValue.length
39-
&& searchSuggestions.data[index].keyword.localeCompare(selectedValue) === 0) {
52+
if (searchSuggestions.data[index].keyword.length === value.length
53+
&& searchSuggestions.data[index].keyword.localeCompare(value) === 0) {
4054

4155
// complete match
4256
queryLink = searchSuggestions.data[index].link
4357
break;
44-
}
45-
if(searchSuggestions.data[index].keyword.length > selectedValue.length) {
46-
// just stop finding if length exceeds.
47-
if(!queryLink) {
48-
// then match whatever we have.
49-
queryLink = searchSuggestions.data[index].link
50-
}
51-
break;
5258
} else {
53-
// closest match
54-
log.info(``)
5559
queryLink = searchSuggestions.data[index].link
5660
}
5761
}
58-
props.getDataViaAPI(LOAD_FILTER_PRODUCTS,
59-
PRODUCT_BY_CATEGORY_DATA_API + queryLink)
62+
63+
log.info(`queryLink = ${queryLink}, value = ${value}`)
64+
if (queryLink) {
65+
setIsLoading(true)
66+
props.getDataViaAPI(LOAD_FILTER_PRODUCTS,
67+
PRODUCT_BY_CATEGORY_DATA_API + queryLink)
68+
}
6069
}
6170
}
6271

63-
const handleClose = (event, reason) => {
64-
setValue('')
65-
66-
// search is selected
67-
if (reason === "select-option") {
68-
searchKeyword()
72+
const handleClose = () => {
73+
log.info(`selectedValue------2 ===== ${selectedValue}`)
74+
let finalSelectedValue = selectedValue
75+
if (!selectedValue) {
76+
finalSelectedValue = getSearchKeyword()
6977
}
78+
searchKeyword(finalSelectedValue)
7079
}
7180

7281
const onSearchBtnClick = () => {
73-
searchKeyword()
82+
searchKeyword(getSearchKeyword())
7483
props.handleClose()
7584
}
7685

@@ -88,17 +97,17 @@ function SearchBar(props) {
8897
InputProps={{
8998
...params.InputProps,
9099
startAdornment: <ArrowBackIcon onClick={props.handleClose} fontSize="large"/>,
91-
endAdornment: <SearchIcon onClick={onSearchBtnClick} fontSize="large"/>
92100
}}
93101
/>
94102
)
95103
}
96104

97105
const handleInputChange = (event, newValue) => {
106+
selectedValue = newValue
98107
props.getSearchSuggestions(newValue)
99108
}
100109

101-
log.info("[Search Bar] Rendering search bar....")
110+
log.info(`[Search Bar] Rendering search bar....`)
102111

103112
return (
104113
<Grid container alignItems="center">
@@ -144,10 +153,15 @@ function SearchBar(props) {
144153
fullWidth
145154
onClose={handleClose}
146155
size={props.size}
147-
classes={{paper: classes.paper, listbox: classes.listbox}}
156+
classes={{paper: classes.paper, listbox: classes.listbox, option: classes.option}}
148157
renderInput={(params) =>
149158
props.device ? renderMobileTextField(params) : renderDesktopTextField(params)}
150159
/>
160+
{isLoading ?
161+
<StyledSearchBarDimmer active inverted>
162+
<Loader inverted>Loading</Loader>
163+
</StyledSearchBarDimmer> : null}
164+
151165
</Grid>
152166
);
153167
}

client/src/components/routes/navbar/tabList.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ export default function TabList() {
3131
}
3232

3333
const mouseLeaveHandler = event => {
34-
log.info(`[TabList]: mouseLeaveHandler = ${event.pageY}, ${window.scrollY}`)
34+
log.info(`[TabList]: mouseLeaveHandler = ${event.pageX}, ${window.scrollY}`)
3535
// detect the mouse is going out horizontally and vertically upwards.
36-
if(event.pageX < 190 || event.pageX > 700 || (event.pageY - window.scrollY) < 1) {
36+
if(event.pageX < 230 || event.pageX > 700 || (event.pageY - window.scrollY) < 1) {
3737
dispatch({
3838
type: HANDLE_TAB_HOVER_EVENT, payload: {
3939
index: false,

client/src/components/routes/shoppingBag.js

Lines changed: 7 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,13 @@ import Spinner from "../ui/spinner";
1616
import {EmptyShoppingBag} from "../ui/error/emptyShoppingBag";
1717
import {HTTPError} from "../ui/error/httpError";
1818
import PriceDetails from "./priceDetails";
19-
import Modal from "../../components/ui/modal";
2019
import _ from 'lodash';
2120
import Hidden from "@material-ui/core/Hidden";
2221
import {useAddProductsToShoppingBag} from "../../hooks/useAddProductsToShoppingBag";
2322
import {CART_TOTAL_COOKIE, SHOPPERS_PRODUCT_INFO_COOKIE} from "../../constants/cookies";
2423
import {HOME_ROUTE} from "../../constants/react_routes";
2524
import {DocumentTitle} from "../ui/documentTitle";
26-
27-
const modalWidth = 430
25+
import {ModalConfirmation} from "../ui/modalConfirmation";
2826

2927
function ShoppingBag(props) {
3028
const addToCart = useSelector(state => state.addToCartReducer)
@@ -104,47 +102,6 @@ function ShoppingBag(props) {
104102
})
105103
}
106104

107-
const renderItemRemoveConfirmation = () => {
108-
log.info(`Rendering renderRemoveModalWarning`)
109-
return (
110-
<>
111-
<Box display="flex" flexDirection="row">
112-
<Box mx={2.5} mt={2} mb={1}>
113-
{/* eslint-disable-next-line jsx-a11y/img-redundant-alt */}
114-
<img src={shoppingBagProducts.data[itemRemovalModalState.productId].imageName}
115-
width={60} height={90} alt="image"/>
116-
</Box>
117-
<Box mt={2.5} display="flex" flexDirection="column">
118-
<Box style={{color: "#3e4152", fontSize: 14, fontWeight: 200}}>
119-
Remove Item
120-
</Box>
121-
<Box style={{color: "#696b79", fontSize: 14, fontWeight: 200}}>
122-
Are you sure you want to remove this item?
123-
</Box>
124-
</Box>
125-
</Box>
126-
<Box>
127-
<Divider style={{width: modalWidth, height: 1}}/>
128-
</Box>
129-
<Box display="flex" flexDirection="row" alignItems="center" justifyContent="center">
130-
<Box pl={10} onClick={removeConfirmBtnClickHandler} style={{
131-
color: "red"
132-
, width: "50%", fontWeight: "bold", cursor: "pointer"
133-
}}>
134-
REMOVE
135-
</Box>
136-
<Box>
137-
<Divider orientation="vertical" style={{height: 45}}/>
138-
</Box>
139-
<Box pl={10} onClick={closeModalClickHandler}
140-
style={{width: "50%", fontWeight: "bold", cursor: "pointer"}}>
141-
CANCEL
142-
</Box>
143-
</Box>
144-
</>
145-
)
146-
}
147-
148105
const removeConfirmBtnClickHandler = () => {
149106
setItemRemovalModalState({active: false, productId: null})
150107
if (itemRemovalModalState.productId) {
@@ -177,20 +134,7 @@ function ShoppingBag(props) {
177134
} else {
178135
if (shoppingBagProducts.hasOwnProperty("data")) {
179136
if (Object.keys(shoppingBagProducts.data).length === 0) {
180-
return (
181-
<Box display="flex" flexDirection="column">
182-
<Box>
183-
<EmptyShoppingBag/>
184-
</Box>
185-
<Box display="flex" py={2} justifyContent="center">
186-
<Button variant="contained" size="large" color="secondary"
187-
onClick={wannaShopBtnClick}
188-
style={{width: '20%'}}>
189-
Wanna Shop? Click Here
190-
</Button>
191-
</Box>
192-
</Box>
193-
)
137+
return <EmptyShoppingBag btnHandler={wannaShopBtnClick}/>
194138
}
195139
} else {
196140
if (shoppingBagProducts.hasOwnProperty('statusCode')) {
@@ -336,9 +280,11 @@ function ShoppingBag(props) {
336280
</Grid>
337281
</Grid>
338282

339-
{itemRemovalModalState.active ? <Modal renderWarningComponent={renderItemRemoveConfirmation()}
340-
modalWidth={modalWidth}
341-
closeHandler={closeModalClickHandler}/> : null}
283+
{itemRemovalModalState.active ? <ModalConfirmation
284+
title="Remove Item"
285+
question="Are you sure you want to remove this item?"
286+
removeConfirmedHandler={removeConfirmBtnClickHandler}
287+
closeModalHandler={closeModalClickHandler}/> : null}
342288
</>
343289
)
344290
}
Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,22 @@
11
import React from 'react';
22
import emptyCheckoutCartImage from '../../../images/emptyCheckoutCart.png'
33
import {RenderErrorImage} from "./renderErrorImage";
4+
import {Button, Grid} from "@material-ui/core";
45

5-
export const EmptyShoppingBag = () => {
6+
export const EmptyShoppingBag = (props) => {
67

78
return (
8-
<RenderErrorImage image={emptyCheckoutCartImage} name="empty-shopping-bag-image"/>
9+
<>
10+
<RenderErrorImage image={emptyCheckoutCartImage} name="empty-shopping-bag-image"/>
11+
<Grid container justify="center">
12+
<Grid item xs={8} md={2}>
13+
<Button variant="contained" size="large" color="secondary"
14+
onClick={props.btnHandler}
15+
style={{width: '100%'}}>
16+
Wanna Shop? Click Here
17+
</Button>
18+
</Grid>
19+
</Grid>
20+
</>
921
);
1022
};

client/src/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ import '../src/styles/library/swiper/swiper.min.css';
1313
import log from 'loglevel';
1414
import ErrorBoundary from "./ErrorBoundary";
1515

16-
log.disableAll(true)
17-
// log.setLevel("info")
16+
// log.disableAll(true)
17+
log.setLevel("info")
1818

1919
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose();
2020
const store = createStore(

client/src/styles/semanticUI/customStyles.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ export const StyledDimmer = styled(Dimmer)({
1212
backgroundColor: 'rgba(0,0,0,0.2) !important',
1313
});
1414

15+
export const StyledSearchBarDimmer = styled(Dimmer)({
16+
height: '100vh !important',
17+
});
18+
1519
export const StyledLargeDropdown = styled(Dropdown)({
1620
width: "225px"
1721
});

0 commit comments

Comments
 (0)