homeflowjs 0.10.19 → 0.10.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/actions/search.actions.js +9 -4
- package/app/hf-initialize.jsx +0 -13
- package/app/user-history.js +0 -269
- package/branches/branches-search-form/branches-search-input.component.jsx +2 -1
- package/hooks/index.js +2 -0
- package/hooks/use-outside-click.js +18 -0
- package/instant-valuation/instant-valuation/instant-valuation.component.jsx +2 -1
- package/package.json +1 -1
- package/properties/load-more-button/load-more-button.component.jsx +16 -25
- package/search/location-input/location-input.component.jsx +2 -1
- package/search/search-form/search-form.component.jsx +1 -0
- package/user/default-profile/user-profile/user-profile-modal.component.jsx +12 -2
- package/utils/index.js +11 -13
@@ -1,16 +1,21 @@
|
|
1
1
|
import SearchActionTypes from './search.types';
|
2
2
|
// eslint-disable-next-line import/no-cycle
|
3
3
|
import { buildQueryString } from '../search/property-search/property-search';
|
4
|
+
import { addSearchToLocalStorage } from '../app/user-history';
|
4
5
|
|
5
6
|
export const setSearch = (payload) => ({
|
6
7
|
type: SearchActionTypes.SET_SEARCH,
|
7
8
|
payload,
|
8
9
|
});
|
9
10
|
|
10
|
-
export const setInitialSearch = (payload) =>
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
export const setInitialSearch = (payload) => {
|
12
|
+
addSearchToLocalStorage(payload);
|
13
|
+
|
14
|
+
return {
|
15
|
+
type: SearchActionTypes.SET_INITIAL_SEARCH,
|
16
|
+
payload,
|
17
|
+
};
|
18
|
+
};
|
14
19
|
|
15
20
|
export const setSuggestions = (payload) => ({
|
16
21
|
type: SearchActionTypes.SET_SUGGESTIONS,
|
package/app/hf-initialize.jsx
CHANGED
@@ -7,7 +7,6 @@ import initCookieConsent from '../cookie-consent/cookie-consent';
|
|
7
7
|
import notify from './notify';
|
8
8
|
import antiCSRF from './anti-csrf';
|
9
9
|
import recaptcha from './recaptcha';
|
10
|
-
import { addSearchToLocalStorage } from './user-history';
|
11
10
|
|
12
11
|
import bookingCalendar from '../booking-calendar/booking-calendar';
|
13
12
|
import { setThemePreferences, setThemeSettings, setAuthenticityToken } from '../actions/app.actions';
|
@@ -103,18 +102,6 @@ const hfInitialize = () => {
|
|
103
102
|
store.dispatch(setArticles(Homeflow.get('articles')));
|
104
103
|
}
|
105
104
|
|
106
|
-
// Add search to add to userHstory in localStorage if this is a search results page
|
107
|
-
if (
|
108
|
-
pageRoute === 'properties#index'
|
109
|
-
|| pageRoute === 'postcodes#show'
|
110
|
-
|| pageRoute === 'locations#show'
|
111
|
-
|| pageRoute === 'counties#show'
|
112
|
-
|| pageRoute === 'countries#show'
|
113
|
-
) {
|
114
|
-
const { search: { currentSearch } } = store.getState();
|
115
|
-
addSearchToLocalStorage(currentSearch);
|
116
|
-
}
|
117
|
-
|
118
105
|
return null;
|
119
106
|
};
|
120
107
|
|
package/app/user-history.js
CHANGED
@@ -33,272 +33,3 @@ export const addSearchToLocalStorage = (search) => {
|
|
33
33
|
localStorage.setItem('searchHistory', JSON.stringify(searchHistory.slice(0, 10)));
|
34
34
|
}
|
35
35
|
};
|
36
|
-
|
37
|
-
// const userHistory = () => {
|
38
|
-
// // have to set timeout here to wait until entire search has been populated
|
39
|
-
// // should find a better way of doing this
|
40
|
-
// setTimeout(() => {
|
41
|
-
// const { search: { currentSearch } } = store.getState();
|
42
|
-
|
43
|
-
// debugger;
|
44
|
-
|
45
|
-
// if (currentSearch) {
|
46
|
-
// addSearchToLocalStorage(currentSearch);
|
47
|
-
// }
|
48
|
-
// }, 20000);
|
49
|
-
// };
|
50
|
-
|
51
|
-
// export default userHistory;
|
52
|
-
|
53
|
-
// class Ctesius.Collections.UserHistory extends Backbone.Collection
|
54
|
-
|
55
|
-
// model: Ctesius.Models.Search
|
56
|
-
|
57
|
-
// localStorage: new Backbone.LocalStorage("UserHistory")
|
58
|
-
|
59
|
-
// id: 'UserHistoryCollection-17072013'
|
60
|
-
|
61
|
-
// walks: 1
|
62
|
-
|
63
|
-
// inBrowserStorageEnabled: ->
|
64
|
-
// true
|
65
|
-
|
66
|
-
// @boot: ->
|
67
|
-
// _collection = new Ctesius.Collections.UserHistory()
|
68
|
-
// _collection.fetch({async:true, reset: true})
|
69
|
-
// _collection.getMostRecentSearch().done (search) =>
|
70
|
-
// _collection.mostRecentSearchValue = search
|
71
|
-
// _collection.getOrCreatMostRecentSearchView().render()
|
72
|
-
// _collection.getOrCreatNextAndPreviousPropertyView().render() if _collection.currentPageIsPropertyPage()
|
73
|
-
// Homeflow.kickEvent('user_history_ready', _collection)
|
74
|
-
// return _collection
|
75
|
-
|
76
|
-
// toJSON: (a) ->
|
77
|
-
// k = super(a)
|
78
|
-
// _.select(k, (n)->
|
79
|
-
// Object.keys(n).length != 0
|
80
|
-
// )
|
81
|
-
|
82
|
-
// mostRecentSearch:() ->
|
83
|
-
// @mostRecentSearchValue
|
84
|
-
|
85
|
-
|
86
|
-
// getMostRecentSearch:() ->
|
87
|
-
// if @mrsR && @mrsR.state() == 'pending'
|
88
|
-
// return @mrsR
|
89
|
-
// else
|
90
|
-
// @mrsR = new jQuery.Deferred()
|
91
|
-
// if @currentPageIsPropertyPage()
|
92
|
-
// search = @at(@mostRecentSearchPositionForCurrentProperty())
|
93
|
-
// if search
|
94
|
-
// @mrsR.resolve(search)
|
95
|
-
// else
|
96
|
-
// @createSearchFromProperty().done( (s) => @mrsR.resolve(s))
|
97
|
-
// return @mrsR
|
98
|
-
|
99
|
-
// createSearchFromProperty: ->
|
100
|
-
// property = Ctesius.getProperty()
|
101
|
-
// if Ctesius.getConfig('search_from_property')?
|
102
|
-
// walkR = new jQuery.Deferred()
|
103
|
-
// search = Ctesius.getConfig('search_from_property').call(property)
|
104
|
-
// search.performAsData =>
|
105
|
-
// walkR.resolve(search)
|
106
|
-
// @addSearch(search, Homeflow.kickEvent('search_from_property_added'))
|
107
|
-
// return walkR
|
108
|
-
// else
|
109
|
-
// search = property.generatedSearch()
|
110
|
-
// @walkAlongSearchUntilPropertyFound(search, @currentPropertyId())
|
111
|
-
|
112
|
-
// walkAlongSearchUntilPropertyFound:(search, property_id) ->
|
113
|
-
// walkR = new jQuery.Deferred()
|
114
|
-
// search.performAsData =>
|
115
|
-
// property = _.find search.get('performed_data').properties, (p)->
|
116
|
-
// ("" + p.property_id) == property_id
|
117
|
-
// if property
|
118
|
-
// @addSearch search, =>
|
119
|
-
// @_most_recent = undefined
|
120
|
-
// @getOrCreatNextAndPreviousPropertyView().render()
|
121
|
-
// @getOrCreatMostRecentSearchView().render()
|
122
|
-
// return walkR.resolve(search)
|
123
|
-
// else if search.get('performed_data').pagination.has_next_page
|
124
|
-
// current_page = search.get('page')
|
125
|
-
// current_page = 1 unless current_page
|
126
|
-
// search.unset('performed_data')
|
127
|
-
// search.set('page', ( current_page + 1 ))
|
128
|
-
// @walks = @walks + 1
|
129
|
-
// if @walks < 10
|
130
|
-
// return @walkAlongSearchUntilPropertyFound(search, property_id).done (s)=>
|
131
|
-
// walkR.resolve(s)
|
132
|
-
// return walkR
|
133
|
-
|
134
|
-
// mostRecentSearchPositionForCurrentProperty:() ->
|
135
|
-
// unless @_most_recent?
|
136
|
-
// if @currentPageIsPropertyPage()
|
137
|
-
// @_most_recent = false
|
138
|
-
// property_id = @currentPropertyId()
|
139
|
-
// search_locations = []
|
140
|
-
// for search, i in @models
|
141
|
-
// if search
|
142
|
-
// data = search.get('performed_data')
|
143
|
-
// if data
|
144
|
-
// property = _.find search.get('performed_data').properties, (p)->
|
145
|
-
// ("" + p.property_id) == property_id
|
146
|
-
// if property
|
147
|
-
// search_locations.push(i)
|
148
|
-
// @_most_recent = _.max(search_locations)
|
149
|
-
// @_most_recent
|
150
|
-
|
151
|
-
// currentPageIsPropertyPage:() ->
|
152
|
-
// Ctesius.getPathManager().isPath('property_show')
|
153
|
-
|
154
|
-
// lastSearchContainsCurrentProperty:()->
|
155
|
-
// current_property_id = @currentPropertyId()
|
156
|
-
// last_search = @last()
|
157
|
-
// property = _.find last_search.get('performed_data').properties, (p)->
|
158
|
-
// ("" + p.property_id) == current_property_id
|
159
|
-
// return property
|
160
|
-
|
161
|
-
|
162
|
-
// currentPropertyId:() ->
|
163
|
-
// match = window.location.pathname.match(/.*\/properties\/(\d*)\/(sales|lettings)/)
|
164
|
-
// match[1] if match?
|
165
|
-
|
166
|
-
// refererWasASearchPage:() ->
|
167
|
-
// @urlIsASearchPage(document.referrer)
|
168
|
-
|
169
|
-
|
170
|
-
// urlIsASearchPage: ->
|
171
|
-
// Ctesius.getPathManager().isPath('property_show')
|
172
|
-
|
173
|
-
// containsSearch:(search) ->
|
174
|
-
// found = false
|
175
|
-
// _.each @models, (v,i) =>
|
176
|
-
// found = true if v.equalTo(search)
|
177
|
-
// found
|
178
|
-
|
179
|
-
// addSearch:(search, callback)->
|
180
|
-
// @each (a)=>
|
181
|
-
// @remove(a) if search.equalTo(a, true)
|
182
|
-
// search.set('added', new Date().getTime())
|
183
|
-
// search.performAsData =>
|
184
|
-
// @add(search)
|
185
|
-
// #if @length > 3
|
186
|
-
// # @reset(@last(3))
|
187
|
-
// @save(callback)
|
188
|
-
// if @length > 9
|
189
|
-
// @remove(@at(0))
|
190
|
-
|
191
|
-
|
192
|
-
// comparator: 'added'
|
193
|
-
|
194
|
-
// removeSearchById : (search_id)->
|
195
|
-
// search = null
|
196
|
-
// search = @get(search_id)
|
197
|
-
// @remove(search)
|
198
|
-
// @store({remove:search})
|
199
|
-
|
200
|
-
// toLiquid : () ->
|
201
|
-
// o = _.collect @models, (m)->
|
202
|
-
// if m.get('channel')?
|
203
|
-
// j = m.toJSON()
|
204
|
-
// unless j.search_id?
|
205
|
-
// j.search_id = m.cid
|
206
|
-
// j.link = m.link()
|
207
|
-
// j.description = m.description()
|
208
|
-
// j
|
209
|
-
// else
|
210
|
-
// {}
|
211
|
-
// _.select(o, (n)->
|
212
|
-
// Object.keys(n).length > 2
|
213
|
-
// )
|
214
|
-
|
215
|
-
// positionOfPropertyInSearch:(property_id, search) ->
|
216
|
-
// search = @mostRecentSearch() unless search?
|
217
|
-
// index = null
|
218
|
-
// for property, i in search.get('performed_data').properties
|
219
|
-
// index = i if ("" + property.property_id) == property_id
|
220
|
-
// index
|
221
|
-
|
222
|
-
// getNextProperty:()->
|
223
|
-
// return @_next_property if @_next_property
|
224
|
-
// property = @propertyAfter(@currentPropertyId())
|
225
|
-
// if property?
|
226
|
-
// return @_next_property = property
|
227
|
-
// else
|
228
|
-
// if (@mostRecentSearch().get('performed_data').properties.length - 1) == @positionOfPropertyInSearch(@currentPropertyId()) && @mostRecentSearch().get('performed_data').pagination.has_next_page
|
229
|
-
// #get next page
|
230
|
-
// new_search = @mostRecentSearch().clone()
|
231
|
-
// current_page = @mostRecentSearch().get('page')
|
232
|
-
// current_page = 1 unless current_page
|
233
|
-
// new_search.unset('performed_data')
|
234
|
-
// new_search.set('page', ( current_page + 1 ))
|
235
|
-
// new_search.performAsData =>
|
236
|
-
// @addSearch(new_search)
|
237
|
-
// @_next_property = new_search.get('performed_data').properties[0]
|
238
|
-
// @_most_recent = undefined
|
239
|
-
// @getOrCreatNextAndPreviousPropertyView().render()
|
240
|
-
// return null
|
241
|
-
|
242
|
-
|
243
|
-
// getPreviousProperty:->
|
244
|
-
// return @_prev_property if @_prev_property
|
245
|
-
|
246
|
-
// property = @propertyBefore(@currentPropertyId())
|
247
|
-
// if property?
|
248
|
-
// return @_prev_property = property
|
249
|
-
// else
|
250
|
-
// if @positionOfPropertyInSearch(@currentPropertyId()) == 0
|
251
|
-
// #get next page
|
252
|
-
// new_search = @mostRecentSearch().clone()
|
253
|
-
// current_page = @mostRecentSearch().get('page')
|
254
|
-
// if current_page
|
255
|
-
// new_search.unset('performed_data')
|
256
|
-
// new_search.set('page', ( current_page - 1 ))
|
257
|
-
// new_search.performAsData =>
|
258
|
-
// @addSearch(new_search)
|
259
|
-
// @_prev_property = new_search.get('performed_data').properties[@getPropertySizeFromPagination(new_search)]
|
260
|
-
// @_most_recent = undefined
|
261
|
-
// @getOrCreatNextAndPreviousPropertyView().render() if @_prev_property
|
262
|
-
// return null
|
263
|
-
|
264
|
-
// getPropertySizeFromPagination: (new_search) ->
|
265
|
-
// pagination_size = new_search.attributes.performed_data.pagination.to_record
|
266
|
-
// if pagination_size != ""
|
267
|
-
// return properties_size_from_pagination_size = pagination_size - 1
|
268
|
-
// else
|
269
|
-
// return property_value_from_pagination_size = 9
|
270
|
-
|
271
|
-
|
272
|
-
// propertyAfter: (property_id, search) ->
|
273
|
-
// search = @mostRecentSearch() unless search?
|
274
|
-
// search.get('performed_data').properties[@positionOfPropertyInSearch(property_id, search)+1]
|
275
|
-
|
276
|
-
// propertyBefore: (property_id) ->
|
277
|
-
// search = @mostRecentSearch()
|
278
|
-
// search.get('performed_data').properties[@positionOfPropertyInSearch(property_id, search)-1]
|
279
|
-
|
280
|
-
|
281
|
-
// getOrCreatMostRecentSearchView: () ->
|
282
|
-
// if @mostRecentSearchView?
|
283
|
-
// return @mostRecentSearchView
|
284
|
-
// else
|
285
|
-
// return @mostRecentSearchView = new Ctesius.Views.MostRecentSearch({model: @})
|
286
|
-
|
287
|
-
// getOrCreatNextAndPreviousPropertyView: () ->
|
288
|
-
// if @NextAndPreviousPropertyView?
|
289
|
-
// return @NextAndPreviousPropertyView
|
290
|
-
// else
|
291
|
-
// return @NextAndPreviousPropertyView = new Ctesius.Views.NextAndPreviousProperty({model: @})
|
292
|
-
|
293
|
-
|
294
|
-
// initialize: (inits) ->
|
295
|
-
|
296
|
-
|
297
|
-
// save : (callback) ->
|
298
|
-
// Backbone.sync("update", @,
|
299
|
-
// success : =>
|
300
|
-
// callback() if callback
|
301
|
-
// Homeflow.kickEvent('user_history_search_added', @)
|
302
|
-
|
303
|
-
// error: ->
|
304
|
-
// )
|
@@ -6,6 +6,7 @@ import PropTypes from 'prop-types';
|
|
6
6
|
import Autosuggest from 'react-autosuggest';
|
7
7
|
import debounce from 'lodash.debounce';
|
8
8
|
import { setBranchesSearch } from '../../actions/branches.actions';
|
9
|
+
import { DEBOUNCE_DELAY } from '../../utils';
|
9
10
|
|
10
11
|
const BranchesSearchInput = ({
|
11
12
|
placeholder,
|
@@ -53,7 +54,7 @@ const BranchesSearchInput = ({
|
|
53
54
|
setSuggestions(suggestions);
|
54
55
|
});
|
55
56
|
|
56
|
-
const debouncedGetSuggestions = useCallback(debounce(getSuggestions,
|
57
|
+
const debouncedGetSuggestions = useCallback(debounce(getSuggestions, DEBOUNCE_DELAY), []);
|
57
58
|
|
58
59
|
const renderSuggestion = (suggestion) => (
|
59
60
|
<span className="react-autosuggest_span">{suggestion}</span>
|
package/hooks/index.js
CHANGED
@@ -0,0 +1,18 @@
|
|
1
|
+
import { useEffect } from 'react';
|
2
|
+
|
3
|
+
const useOutsideClick = (ref, callback) => {
|
4
|
+
useEffect(() => {
|
5
|
+
const handleClick = (e) => {
|
6
|
+
if (ref.current && !ref.current.contains(e.target)) {
|
7
|
+
callback();
|
8
|
+
}
|
9
|
+
};
|
10
|
+
document.addEventListener('mousedown', handleClick);
|
11
|
+
return () => {
|
12
|
+
document.removeEventListener('mousedown', handleClick);
|
13
|
+
};
|
14
|
+
}, [ref]);
|
15
|
+
return ref;
|
16
|
+
};
|
17
|
+
|
18
|
+
export default useOutsideClick;
|
@@ -10,6 +10,7 @@ import IntroStep from '../intro-step/intro-step.component';
|
|
10
10
|
import YourDetailsStep from '../your-details-step/your-details-step.component';
|
11
11
|
import SimilarPropertiesStep from '../similar-properties-step/similar-properties-step.component';
|
12
12
|
import ResultStep from '../result-step/result-step.component';
|
13
|
+
import { DEBOUNCE_DELAY } from '../../utils';
|
13
14
|
|
14
15
|
import './instant-valuation.styles.scss';
|
15
16
|
|
@@ -82,7 +83,7 @@ class InstantValuation extends Component {
|
|
82
83
|
this.getSimilarProperties = this.getSimilarProperties.bind(this);
|
83
84
|
this.toggleSimilarProperty = this.toggleSimilarProperty.bind(this);
|
84
85
|
this.getValuation = this.getValuation.bind(this);
|
85
|
-
this.addressLookup = debounce(this.addressLookup,
|
86
|
+
this.addressLookup = debounce(this.addressLookup, DEBOUNCE_DELAY).bind(this);
|
86
87
|
this.reset = this.reset.bind(this);
|
87
88
|
this.setMessage = this.setMessage.bind(this);
|
88
89
|
}
|
package/package.json
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
import React, { useState
|
2
|
-
import {
|
1
|
+
import React, { useState } from 'react';
|
2
|
+
import { useSelector, useDispatch } from 'react-redux';
|
3
3
|
import PropTypes from 'prop-types';
|
4
4
|
|
5
5
|
import { loadNext } from '../../actions/properties.actions';
|
@@ -7,21 +7,18 @@ import DefaultLoader from '../../shared/loader.component';
|
|
7
7
|
import { addSearchToLocalStorage } from '../../app/user-history';
|
8
8
|
|
9
9
|
const LoadMoreButton = (props) => {
|
10
|
+
const dispatch = useDispatch();
|
11
|
+
const currentSearch = useSelector((state) => state.search?.currentSearch);
|
12
|
+
const pagination = useSelector((state) => state.properties?.pagination);
|
13
|
+
|
10
14
|
const {
|
11
|
-
loadNext,
|
12
|
-
pagination,
|
13
15
|
children,
|
14
|
-
Loader
|
15
|
-
currentSearch,
|
16
|
+
Loader,
|
16
17
|
...otherProps
|
17
18
|
} = props;
|
18
19
|
|
19
20
|
const [loading, setLoading] = useState(false);
|
20
21
|
|
21
|
-
useEffect(() => {
|
22
|
-
addSearchToLocalStorage(currentSearch);
|
23
|
-
}, [pagination])
|
24
|
-
|
25
22
|
if (!pagination.has_next_page) return null;
|
26
23
|
|
27
24
|
if (loading) return <Loader height="24px" />;
|
@@ -32,8 +29,11 @@ const LoadMoreButton = (props) => {
|
|
32
29
|
onClick={(e) => {
|
33
30
|
e.currentTarget.blur();
|
34
31
|
setLoading(true);
|
35
|
-
loadNext()
|
36
|
-
.then(() =>
|
32
|
+
dispatch(loadNext())
|
33
|
+
.then(() => {
|
34
|
+
setLoading(false);
|
35
|
+
addSearchToLocalStorage(currentSearch);
|
36
|
+
});
|
37
37
|
}}
|
38
38
|
{...otherProps}
|
39
39
|
>
|
@@ -43,21 +43,12 @@ const LoadMoreButton = (props) => {
|
|
43
43
|
};
|
44
44
|
|
45
45
|
LoadMoreButton.propTypes = {
|
46
|
-
loadNext: PropTypes.func.isRequired,
|
47
|
-
pagination: PropTypes.object.isRequired,
|
48
46
|
children: PropTypes.node.isRequired,
|
47
|
+
Loader: PropTypes.elementType,
|
49
48
|
};
|
50
49
|
|
51
|
-
|
52
|
-
|
53
|
-
currentSearch: state.search.currentSearch,
|
54
|
-
});
|
55
|
-
|
56
|
-
const mapDispatchToProps = {
|
57
|
-
loadNext,
|
50
|
+
LoadMoreButton.defaultProps = {
|
51
|
+
Loader: DefaultLoader,
|
58
52
|
};
|
59
53
|
|
60
|
-
export default
|
61
|
-
mapStateToProps,
|
62
|
-
mapDispatchToProps,
|
63
|
-
)(LoadMoreButton);
|
54
|
+
export default LoadMoreButton;
|
@@ -6,6 +6,7 @@ import Autosuggest from 'react-autosuggest';
|
|
6
6
|
|
7
7
|
import { setSuggestions, setSearchField } from '../../actions/search.actions';
|
8
8
|
import propertySearch from '../property-search/property-search';
|
9
|
+
import { DEBOUNCE_DELAY } from '../../utils';
|
9
10
|
|
10
11
|
import { autosuggestTheme } from './location-input.styles';
|
11
12
|
|
@@ -15,7 +16,7 @@ class LocationInput extends Component {
|
|
15
16
|
|
16
17
|
this.onLocationChange = this.onLocationChange.bind(this);
|
17
18
|
// wait half a second after typing stops before fetching results
|
18
|
-
this.debouncedLoadSuggestions = debounce(this.loadSuggestions,
|
19
|
+
this.debouncedLoadSuggestions = debounce(this.loadSuggestions, DEBOUNCE_DELAY);
|
19
20
|
}
|
20
21
|
|
21
22
|
onLocationChange(event, { newValue }) {
|
@@ -1,10 +1,11 @@
|
|
1
|
-
import React from 'react';
|
1
|
+
import React, { useRef } from 'react';
|
2
2
|
import { connect } from 'react-redux';
|
3
3
|
import {
|
4
4
|
HashRouter as Router,
|
5
5
|
Route,
|
6
6
|
Switch,
|
7
7
|
NavLink,
|
8
|
+
useHistory
|
8
9
|
} from 'react-router-dom';
|
9
10
|
import PropTypes from 'prop-types';
|
10
11
|
|
@@ -17,6 +18,7 @@ import ForgottenPassword from '../forgotten-password/forgotten-password.componen
|
|
17
18
|
import SignOutButton from '../../sign-out-button/sign-out-button.component';
|
18
19
|
import Loader from '../../../shared/loader.component';
|
19
20
|
import { loadingStyles } from '../../../modal/modal.component';
|
21
|
+
import useOutsideClick from '../../../hooks/use-outside-click';
|
20
22
|
|
21
23
|
import './user-profile.styles.scss';
|
22
24
|
|
@@ -32,9 +34,17 @@ const UserProfileModal = ({ currentUser, loading }) => {
|
|
32
34
|
}
|
33
35
|
|
34
36
|
const logo = Homeflow.get('agency_logo');
|
37
|
+
const history = useHistory();
|
38
|
+
const ref = useRef();
|
39
|
+
|
40
|
+
const handleClickOutside = () => {
|
41
|
+
history.push('/')
|
42
|
+
};
|
43
|
+
|
44
|
+
useOutsideClick(ref, handleClickOutside);
|
35
45
|
|
36
46
|
return (
|
37
|
-
<div className="user-profile hf-modal">
|
47
|
+
<div className="user-profile hf-modal" ref={ref}>
|
38
48
|
<div className="user-profile__side">
|
39
49
|
<img src={logo} alt="Logo" className="user-profile__agency-logo" />
|
40
50
|
|
package/utils/index.js
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
export { default as stampDutyCalculator } from './stamp-duty-calculator/stamp-duty-calculator';
|
2
2
|
|
3
|
-
export const capitalizeFirstLetter = str => (
|
3
|
+
export const capitalizeFirstLetter = (str) => (
|
4
4
|
str.charAt(0).toUpperCase() + str.slice(1)
|
5
|
-
)
|
5
|
+
);
|
6
6
|
|
7
|
-
export const camelToSnakeCase = str => (
|
8
|
-
str.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`)
|
9
|
-
)
|
7
|
+
export const camelToSnakeCase = (str) => (
|
8
|
+
str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`)
|
9
|
+
);
|
10
10
|
|
11
11
|
export const isEmpty = (obj) => {
|
12
12
|
for (const key in obj) {
|
@@ -16,9 +16,7 @@ export const isEmpty = (obj) => {
|
|
16
16
|
return true;
|
17
17
|
};
|
18
18
|
|
19
|
-
export const numberWithCommas = (num) => {
|
20
|
-
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
21
|
-
}
|
19
|
+
export const numberWithCommas = (num) => num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
22
20
|
|
23
21
|
// TODO: DRY these two functions up
|
24
22
|
export const findSavedSearchIndex = (savedSearches, search) => {
|
@@ -64,9 +62,7 @@ export const formatMoney = (num) => {
|
|
64
62
|
return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "");
|
65
63
|
};
|
66
64
|
|
67
|
-
export const uniqueKey = () =>
|
68
|
-
return Math.random().toString(36).substring(7);
|
69
|
-
};
|
65
|
+
export const uniqueKey = () => Math.random().toString(36).substring(7);
|
70
66
|
|
71
67
|
export const objectDiff = (oldObject, newObject) => {
|
72
68
|
const changed = {};
|
@@ -78,8 +74,10 @@ export const objectDiff = (oldObject, newObject) => {
|
|
78
74
|
}
|
79
75
|
|
80
76
|
return changed;
|
81
|
-
}
|
77
|
+
};
|
82
78
|
|
83
|
-
export const compact = (array) => array.filter(item => typeof item !== 'undefined' && item !== null);
|
79
|
+
export const compact = (array) => array.filter((item) => typeof item !== 'undefined' && item !== null);
|
84
80
|
|
85
81
|
export const sanitizeText = (string) => new Option(string).innerHTML;
|
82
|
+
|
83
|
+
export const DEBOUNCE_DELAY = 200;
|