homeflowjs 0.9.2 → 0.9.5

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.
@@ -92,6 +92,8 @@ export const createUser = (payload) => (dispatch, getState) => {
92
92
  });
93
93
  }
94
94
 
95
+ Homeflow.kickEvent('user_signed_up');
96
+
95
97
  return Promise.all(promises);
96
98
  })
97
99
  .then(() => dispatch(fetchUser()));
@@ -0,0 +1,109 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import Loader from '../shared/loader.component';
4
+
5
+ const ArticlesGrid = ({
6
+ handleIsLoading,
7
+ pageSize,
8
+ gridClass,
9
+ articleItem,
10
+ loadMoreButtonContainerClass,
11
+ loadMoreButtonClass,
12
+ loadMoreButtonText,
13
+ // eslint-disable-next-line react/prop-types
14
+ customLoader,
15
+ }) => {
16
+ const [pagination, setPagination] = useState({});
17
+ const [articles, setArticles] = useState([]);
18
+ const [page, setPage] = useState(1);
19
+ const [showMore, setShowMore] = useState(true);
20
+ const [isLoading, setIsLoading] = useState(true);
21
+ const [loadingMore, setLoadingMore] = useState(false);
22
+
23
+ const agent = `${window.location.protocol}//${window.location.host}`;
24
+ const path = window.location.pathname;
25
+ const topicPath = '/articles/topic-';
26
+
27
+ const topic = path.includes(topicPath)
28
+ ? `&topic=${path.slice(path.indexOf(topicPath) + topicPath.length).replace('#/', '')}`
29
+ : '';
30
+ const url = `${agent}/articles.ljson?page=${page}&page_size=${pageSize}${topic}`;
31
+
32
+ const loader = () => {
33
+ if (customLoader) return customLoader;
34
+ return <Loader containerClass={loadMoreButtonContainerClass} />;
35
+ };
36
+
37
+ const fetchArticles = (firstRender = false) => {
38
+ fetch(url)
39
+ .then((response) => response.json())
40
+ .then((json) => {
41
+ setArticles((prev) => [...prev, ...json.articles]);
42
+ setPagination(json.pagination);
43
+ setShowMore(json.pagination.has_next_page);
44
+ setPage(json.pagination.current_page + 1);
45
+ setIsLoading(false);
46
+ setLoadingMore(false);
47
+ if (handleIsLoading && firstRender) handleIsLoading(false);
48
+ })
49
+ .catch((e) => console.log('error', e));
50
+ };
51
+
52
+ const loadMore = () => {
53
+ if (pagination.has_next_page) {
54
+ setLoadingMore(true);
55
+ fetchArticles();
56
+ }
57
+ return false;
58
+ };
59
+
60
+ useEffect(() => {
61
+ if (handleIsLoading) handleIsLoading(true);
62
+ fetchArticles(true);
63
+ }, []);
64
+
65
+ return (
66
+ <>
67
+ <div className={gridClass}>
68
+ {articles.map((article) => articleItem(article))}
69
+ </div>
70
+ <div className={loadMoreButtonContainerClass}>
71
+ {(showMore && !isLoading) && (
72
+ <>
73
+ {loadingMore ? (
74
+ loader()
75
+ ) : (
76
+ <button
77
+ type="button"
78
+ onClick={loadMore}
79
+ className={loadMoreButtonClass}
80
+ >
81
+ {loadMoreButtonText}
82
+ </button>
83
+ )}
84
+ </>
85
+ )}
86
+ </div>
87
+ </>
88
+ );
89
+ };
90
+
91
+ ArticlesGrid.propTypes = {
92
+ gridClass: PropTypes.string.isRequired,
93
+ articleItem: PropTypes.elementType.isRequired,
94
+ handleIsLoading: PropTypes.elementType,
95
+ loadMoreButtonClass: PropTypes.string,
96
+ loadMoreButtonText: PropTypes.string,
97
+ loadMoreButtonContainerClass: PropTypes.string,
98
+ pageSize: PropTypes.number,
99
+ };
100
+
101
+ ArticlesGrid.defaultProps = {
102
+ loadMoreButtonClass: '',
103
+ loadMoreButtonContainerClass: '',
104
+ loadMoreButtonText: 'Load more',
105
+ handleIsLoading: null,
106
+ pageSize: 12,
107
+ };
108
+
109
+ export default ArticlesGrid;
@@ -0,0 +1,5 @@
1
+ import ArticlesGrid from './articles-grid.component';
2
+
3
+ export {
4
+ ArticlesGrid,
5
+ };
@@ -239,6 +239,8 @@ class InstantValuation extends Component {
239
239
 
240
240
  const largeModalStyles = { width: 1000, height: 800 };
241
241
 
242
+ Homeflow.kickEvent('valuation_opened');
243
+
242
244
  return (
243
245
  <div
244
246
  className="instant-valuation hf-modal"
@@ -22,6 +22,10 @@ const ResultStep = ({
22
22
  getValuation();
23
23
  }, []);
24
24
 
25
+ useEffect(() => {
26
+ if (valuation) Homeflow.kickEvent('valuation_successful');
27
+ }, [valuation])
28
+
25
29
  const formatPrice = (price) => (
26
30
  `£${Math.round(price)}${selectedChannel === 'lettings' ? '/month' : ''}`
27
31
  .replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,')
@@ -170,72 +174,3 @@ const ResultStep = ({
170
174
  };
171
175
 
172
176
  export default ResultStep;
173
-
174
- // doesn't work
175
- // /valuations.json?search%5Bpaon%5D=&search%5Bpostcode%5D=bn2+9sq&search%5Bproperty_type%5D=t&search%5Bbedrooms%5D=2&lead%5Bfirst_name%5D=fwkjenk&lead%5Blast_name%5D=kjnfkwejf&lead%5Btel_home%5D=07589347534&lead%5Bemail%5D=kjnfkjew%40fkjwenkfj.com&lead%5Bmoving_plans%5D=3+months&lead%5Breason%5D=selling&lead%5Bplans%5D=3+months&lead%5Bfull_address%5D=1+Coleman+Street%2C++Brighton%2C++East+Sussex&lead%5Bis_branch_lead%5D=&lead%5Bis_valuation_request%5D=1&lead%5Bbranch_id%5D=&lead%5Baccount_confirmation_status%5D=false&lead%5Bopt_in_marketing%5D=false&lead%5Bopt_in_terms%5D=true&lead%5Bopt_in_marketing_statement%5D=&lead%5Bopt_in_marketing_url%5D=http%3A%2F%2Flocalhost%3A3000%2F%23%2Fvaluation&lead%5Bcontact_by_phone%5D=false&lead%5Bcontact_by_email%5D=false&lead%5Bcontact_by_sms%5D=false&lead%5Bcontact_by_post%5D=false&search%5Bproperties%5D%5B%5D=13713068
176
-
177
- // works
178
- // /valuations.json?search%5Bpaon%5D=1&search%5Bpostcode%5D=BN2+9SQ&search%5Bproperties%5D%5B%5D=13713078&search%5Bproperty_type%5D=t&search%5Bbedrooms%5D=1&lead%5Bfirst_name%5D=jfkwenk&lead%5Blast_name%5D=jkfnwekf&lead%5Btel_home%5D=07589437534&lead%5Bemail%5D=kjnfwke%40fkmewklf.com&lead%5Bmoving_plans%5D=asap&lead%5Breason%5D=selling&lead%5Bplans%5D=asap&lead%5Bfull_address%5D=1+Coleman+Street%2C++Brighton%2C++East+Sussex&lead%5Baccount_confirmation_status%5D=false&lead%5Bopt_in_marketing%5D=false&lead%5Bopt_in_terms%5D=true&lead%5Bopt_in_marketing_statement%5D=+Get+emails+with+the+latest+news+and+information+on+the+local+property+market%2C+our+products+and+services.+You+can+unsubscribe+at+any+time.+&lead%5Bopt_in_marketing_url%5D=https%3A%2F%2Fsawyerandco.agent.staging.homeflow.co.uk%2F%23%2Fvaluation&lead%5Bcontact_by_phone%5D=false&lead%5Bcontact_by_email%5D=false&lead%5Bcontact_by_sms%5D=false&lead%5Bcontact_by_post%5D=false
179
-
180
- // doesn't work
181
- // search[paon]:
182
- // search[postcode]: bn2 9sq
183
- // search[property_type]: t
184
- // search[bedrooms]: 2
185
- // lead[first_name]: fwkjenk
186
- // lead[last_name]: kjnfkwejf
187
- // lead[tel_home]: 07589347534
188
- // lead[email]: kjnfkjew@fkjwenkfj.com
189
- // lead[moving_plans]: 3 months
190
- // lead[reason]: selling
191
- // lead[plans]: 3 months
192
- // lead[full_address]: 1 Coleman Street, Brighton, East Sussex
193
- // lead[is_branch_lead]:
194
- // lead[is_valuation_request]: 1
195
- // lead[branch_id]:
196
- // lead[account_confirmation_status]: false
197
- // lead[opt_in_marketing]: false
198
- // lead[opt_in_terms]: true
199
- // lead[opt_in_marketing_statement]:
200
- // lead[opt_in_marketing_url]: http://localhost:3000/#/valuation
201
- // lead[contact_by_phone]: false
202
- // lead[contact_by_email]: false
203
- // lead[contact_by_sms]: false
204
- // lead[contact_by_post]: false
205
- // search[properties][]: 13713068
206
-
207
- // works
208
- // search[paon]: 1
209
- // search[postcode]: BN2 9SQ
210
- // search[properties][]: 13713078
211
- // search[property_type]: t
212
- // search[bedrooms]: 1
213
- // lead[first_name]: jfkwenk
214
- // lead[last_name]: jkfnwekf
215
- // lead[tel_home]: 07589437534
216
- // lead[email]: kjnfwke@fkmewklf.com
217
- // lead[moving_plans]: asap
218
- // lead[reason]: selling
219
- // lead[plans]: asap
220
- // lead[full_address]: 1 Coleman Street, Brighton, East Sussex
221
- // lead[account_confirmation_status]: false
222
- // lead[opt_in_marketing]: false
223
- // lead[opt_in_terms]: true
224
- // lead[opt_in_marketing_statement]: Get emails with the latest news and information on the local property market, our products and services.You can unsubscribe at any time.
225
- // lead[opt_in_marketing_url]: https://sawyerandco.agent.staging.homeflow.co.uk/#/valuation
226
- // lead[contact_by_phone]: false
227
- // lead[contact_by_email]: false
228
- // lead[contact_by_sms]: false
229
- // lead[contact_by_post]: false
230
-
231
- // doesn't work
232
- // search[properties][]: 13713068
233
-
234
- // does work
235
- // search[properties][]: 13713078
236
-
237
- // works (without similar props)
238
- // http://localhost:3000/valuations.json?search%5Bpaon%5D=&search%5Bpostcode%5D=bn2+9sq&search%5Bproperty_type%5D=t&search%5Bbedrooms%5D=2&lead%5Bfirst_name%5D=efjwek&lead%5Blast_name%5D=fwenkfn&lead%5Btel_home%5D=07589347594&lead%5Bemail%5D=fewjkf%40fwenfkl.com&lead%5Bmoving_plans%5D=3+months&lead%5Breason%5D=selling&lead%5Bplans%5D=3+months&lead%5Bfull_address%5D=1+Coleman+Street%2C++Brighton%2C++East+Sussex&lead%5Bis_branch_lead%5D=&lead%5Bis_valuation_request%5D=1&lead%5Bbranch_id%5D=&lead%5Baccount_confirmation_status%5D=false&lead%5Bopt_in_marketing%5D=false&lead%5Bopt_in_terms%5D=true&lead%5Bopt_in_marketing_statement%5D=&lead%5Bopt_in_marketing_url%5D=http%3A%2F%2Flocalhost%3A3000%2F%23%2Fvaluation&lead%5Bcontact_by_phone%5D=false&lead%5Bcontact_by_email%5D=false&lead%5Bcontact_by_sms%5D=false&lead%5Bcontact_by_post%5D=false
239
-
240
- // doesn't work (with similar props)
241
- // http://localhost:3000/valuations.json?search%5Bpaon%5D=&search%5Bpostcode%5D=bn2+9sq&search%5Bproperty_type%5D=t&search%5Bbedrooms%5D=2&lead%5Bfirst_name%5D=fjwenjkf&lead%5Blast_name%5D=fjknwekjf&lead%5Btel_home%5D=078593473434&lead%5Bemail%5D=kfnkwejf%40ewkjnfk.com&lead%5Bmoving_plans%5D=3+months&lead%5Breason%5D=selling&lead%5Bplans%5D=3+months&lead%5Bfull_address%5D=1+Coleman+Street%2C++Brighton%2C++East+Sussex&lead%5Bis_branch_lead%5D=&lead%5Bis_valuation_request%5D=1&lead%5Bbranch_id%5D=&lead%5Baccount_confirmation_status%5D=false&lead%5Bopt_in_marketing%5D=false&lead%5Bopt_in_terms%5D=true&lead%5Bopt_in_marketing_statement%5D=&lead%5Bopt_in_marketing_url%5D=http%3A%2F%2Flocalhost%3A3000%2F%23%2Fvaluation&lead%5Bcontact_by_phone%5D=false&lead%5Bcontact_by_email%5D=false&lead%5Bcontact_by_sms%5D=false&lead%5Bcontact_by_post%5D=false&search%5Bproperties%5D%5B%5D=13713068&search%5Bproperties%5D%5B%5D=13713067&search%5Bproperties%5D%5B%5D=13669747
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "homeflowjs",
3
- "version": "0.9.2",
3
+ "version": "0.9.5",
4
4
  "description": "JavaScript toolkit for Homeflow themes",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -17,6 +17,9 @@ const SavedSearch = (props) => {
17
17
  deleteButtonClass,
18
18
  buttonSpanClass,
19
19
  userLoggedIn,
20
+ frequencyLabel,
21
+ visitSearchLabel,
22
+ removeSearchLabel,
20
23
  } = props;
21
24
 
22
25
  const visitSearch = (e) => {
@@ -41,7 +44,7 @@ const SavedSearch = (props) => {
41
44
  <div className="saved-search__body">
42
45
  {userLoggedIn && (
43
46
  <>
44
- Email me matching properties:
47
+ {frequencyLabel}
45
48
  <select
46
49
  className={`saved-search__frequency ${selectClass}`}
47
50
  onChange={handleFrequencyChange}
@@ -60,7 +63,7 @@ const SavedSearch = (props) => {
60
63
  onClick={visitSearch}
61
64
  className={visitButtonClass}
62
65
  >
63
- <span className={buttonSpanClass}>Visit</span>
66
+ <span className={buttonSpanClass}>{visitSearchLabel}</span>
64
67
  </button>
65
68
 
66
69
  <button
@@ -68,7 +71,7 @@ const SavedSearch = (props) => {
68
71
  onClick={removeSearch}
69
72
  className={deleteButtonClass}
70
73
  >
71
- <span className={buttonSpanClass}>Remove</span>
74
+ <span className={buttonSpanClass}>{removeSearchLabel}</span>
72
75
  </button>
73
76
  </div>
74
77
  </div>
@@ -84,6 +87,9 @@ SavedSearch.propTypes = {
84
87
  deleteButtonClass: PropTypes.string,
85
88
  buttonSpanClass: PropTypes.string,
86
89
  userLoggedIn: PropTypes.bool.isRequired,
90
+ frequencyLabel: PropTypes.string,
91
+ visitSearchLabel: PropTypes.string,
92
+ removeSearchLabel: PropTypes.string,
87
93
  };
88
94
 
89
95
  SavedSearch.defaultProps = {
@@ -91,7 +97,10 @@ SavedSearch.defaultProps = {
91
97
  visitButtonClass: '',
92
98
  deleteButtonClass: '',
93
99
  buttonSpanClass: '',
94
- }
100
+ frequencyLabel: 'Email me matching properties:',
101
+ visitSearchLabel: 'Visit',
102
+ removeSearchLabel: 'Remove',
103
+ };
95
104
 
96
105
  const mapStateToProps = (state) => ({
97
106
  userLoggedIn: !!state.user.currentUser.user_id,
@@ -1,17 +1,30 @@
1
1
  import React from 'react';
2
+ import PropTypes from 'prop-types';
2
3
 
3
4
  import './loader.styles.scss';
4
5
 
5
- const Loader = ({ className, message }) => (
6
- <div>
7
- <div className={`la-ball-beat la-dark la-2x ${className ? className : ''}`}>
8
- <div></div>
9
- <div></div>
10
- <div></div>
6
+ const Loader = ({ containerClass, className, message }) => (
7
+ <div className={containerClass}>
8
+ <div className={`la-ball-beat la-dark la-2x ${className}`}>
9
+ <div />
10
+ <div />
11
+ <div />
11
12
  </div>
12
13
 
13
14
  {message && <p style={{ marginTop: '10px' }}>{message}</p>}
14
15
  </div>
15
16
  );
16
17
 
18
+ Loader.propTypes = {
19
+ className: PropTypes.string,
20
+ message: PropTypes.string,
21
+ containerClass: PropTypes.string,
22
+ };
23
+
24
+ Loader.defaultProps = {
25
+ className: '',
26
+ message: '',
27
+ containerClass: '',
28
+ };
29
+
17
30
  export default Loader;