bukazu-portal-react 2.1.21 → 3.0.3
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/.github/workflows/dependabot.yml +11 -0
- package/.github/workflows/node.js.yml +31 -0
- package/.prettierrc +3 -6
- package/CHANGELOG.MD +5 -0
- package/babel.config.json +1 -1
- package/build/index.css +1 -2312
- package/build/portal.es.js +35483 -0
- package/build/portal.umd.js +596 -0
- package/{build/calendar.html → calendar.html} +2 -4
- package/coverage/clover.xml +28 -0
- package/coverage/coverage-final.json +2 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/helper.ts.html +142 -0
- package/coverage/lcov-report/index.html +116 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +196 -0
- package/coverage/lcov.info +36 -0
- package/cypress/{integration → e2e}/.examples/actions.spec.js +0 -0
- package/cypress/{integration → e2e}/.examples/aliasing.spec.js +0 -0
- package/cypress/{integration → e2e}/.examples/assertions.spec.js +0 -0
- package/cypress/{integration → e2e}/.examples/connectors.spec.js +0 -0
- package/cypress/{integration → e2e}/.examples/cookies.spec.js +0 -0
- package/cypress/{integration → e2e}/.examples/cypress_api.spec.js +0 -0
- package/cypress/{integration → e2e}/.examples/files.spec.js +0 -0
- package/cypress/{integration → e2e}/.examples/local_storage.spec.js +0 -0
- package/cypress/{integration → e2e}/.examples/location.spec.js +0 -0
- package/cypress/{integration → e2e}/.examples/misc.spec.js +0 -0
- package/cypress/{integration → e2e}/.examples/navigation.spec.js +0 -0
- package/cypress/{integration → e2e}/.examples/network_requests.spec.js +0 -0
- package/cypress/{integration → e2e}/.examples/querying.spec.js +0 -0
- package/cypress/{integration → e2e}/.examples/spies_stubs_clocks.spec.js +0 -0
- package/cypress/{integration → e2e}/.examples/traversal.spec.js +0 -0
- package/cypress/{integration → e2e}/.examples/utilities.spec.js +0 -0
- package/cypress/{integration → e2e}/.examples/viewport.spec.js +0 -0
- package/cypress/{integration → e2e}/.examples/waiting.spec.js +0 -0
- package/cypress/{integration → e2e}/.examples/window.spec.js +0 -0
- package/cypress/{integration → e2e}/booking.spec.js +0 -0
- package/cypress/{integration → e2e}/calendar.spec.js +0 -0
- package/cypress/{integration → e2e}/search.spec.js +0 -0
- package/cypress/support/commands.ts +37 -0
- package/cypress/support/component-index.html +12 -0
- package/cypress/support/component.ts +39 -0
- package/cypress/support/{index.js → e2e.js} +0 -0
- package/cypress.config.ts +15 -0
- package/{dev.js → dev.tsx} +1 -1
- package/index.html +15 -0
- package/{build/invalid-calendar.html → invalid-calendar.html} +0 -0
- package/jest.config.js +195 -0
- package/package.json +35 -40
- package/reviews.html +16 -0
- package/src/_lib/{SearchQueries.js → SearchQueries.ts} +8 -2
- package/src/_lib/{countries.js → countries.ts} +0 -0
- package/src/_lib/date_helper.ts +27 -0
- package/src/_lib/{queries.js → queries.ts} +24 -5
- package/src/components/App.tsx +132 -0
- package/src/components/AppContext.ts +14 -0
- package/src/components/CalendarPage/BookingForm.tsx +42 -0
- package/src/components/CalendarPage/Calendar.tsx +50 -0
- package/src/components/CalendarPage/CalendarPage.tsx +43 -0
- package/src/components/CalendarPage/CalendarParts/CalendarContext.tsx +89 -0
- package/src/components/CalendarPage/CalendarParts/CalendarHeader.tsx +72 -0
- package/src/components/CalendarPage/CalendarParts/DayClasses.ts +111 -0
- package/src/components/CalendarPage/CalendarParts/GenerateCalendar.tsx +64 -0
- package/src/components/CalendarPage/CalendarParts/Legend.tsx +33 -0
- package/src/components/CalendarPage/CalendarParts/MonthHeader.tsx +15 -0
- package/src/components/CalendarPage/CalendarParts/Months.tsx +37 -0
- package/src/components/CalendarPage/CalendarParts/RenderCells.tsx +94 -0
- package/src/components/CalendarPage/CalendarParts/SingleMonth.tsx +72 -0
- package/src/components/CalendarPage/CalendarParts/StartBooking.tsx +17 -0
- package/src/components/CalendarPage/CalendarParts/WeekDays.tsx +27 -0
- package/src/components/CalendarPage/FormCreator.tsx +213 -0
- package/src/components/CalendarPage/FormItems/{Date.js → Date.tsx} +10 -2
- package/src/components/CalendarPage/FormItems/{NumberSelect.js → NumberSelect.tsx} +1 -1
- package/src/components/CalendarPage/FormItems/{Select.js → Select.tsx} +0 -0
- package/src/components/CalendarPage/FormItems/{index.js → index.ts} +0 -0
- package/src/components/CalendarPage/PriceField/Price.tsx +58 -0
- package/src/components/CalendarPage/PriceField/Queries.ts +23 -0
- package/src/components/CalendarPage/PriceField/index.tsx +127 -0
- package/src/components/CalendarPage/Summary/{CostRow.js → CostRow.tsx} +19 -3
- package/src/components/CalendarPage/Summary/{CostSection.js → CostSection.tsx} +5 -1
- package/src/components/CalendarPage/Summary/{CostSummary.js → CostSummary.tsx} +19 -10
- package/src/components/CalendarPage/Summary/Description.tsx +27 -0
- package/src/components/CalendarPage/Summary/{InsurancesAndRequired.js → InsurancesAndRequired.tsx} +21 -2
- package/src/components/CalendarPage/Summary/Object.tsx +59 -0
- package/src/components/CalendarPage/Summary/{OnSite.js → OnSite.tsx} +9 -9
- package/src/components/CalendarPage/Summary/{OptionalNotOnSite.js → OptionalNotOnSite.tsx} +19 -18
- package/src/components/CalendarPage/Summary/{OptionalOnSite.js → OptionalOnSite.tsx} +6 -1
- package/src/components/CalendarPage/Summary/{Queries.js → Queries.ts} +3 -3
- package/src/components/CalendarPage/Summary/RentAndDiscount.tsx +30 -0
- package/src/components/CalendarPage/Summary/{Totals.js → Totals.tsx} +8 -3
- package/src/components/CalendarPage/Summary/cost_types.d.ts +31 -0
- package/src/components/CalendarPage/Summary/index.tsx +24 -0
- package/src/components/CalendarPage/calender_types.d.ts +16 -0
- package/src/components/CalendarPage/formParts/AssistanceMessage.tsx +60 -0
- package/src/components/CalendarPage/formParts/{BookingHelpers.js → BookingHelpers.tsx} +3 -3
- package/src/components/CalendarPage/formParts/{BookingOrOption.js → BookingOrOption.tsx} +6 -1
- package/src/components/CalendarPage/formParts/CancelInsuranceText.tsx +105 -0
- package/src/components/CalendarPage/formParts/{DefaultBookingFields.js → DefaultBookingFields.ts} +3 -1
- package/src/components/CalendarPage/formParts/DiscountCode.tsx +62 -0
- package/src/components/CalendarPage/formParts/{Guests.js → Guests.tsx} +10 -4
- package/src/components/CalendarPage/formParts/{OptionalBookingFields.js → OptionalBookingFields.tsx} +0 -0
- package/src/components/CalendarPage/formParts/{OptionalCosts.js → OptionalCosts.tsx} +1 -2
- package/src/components/CalendarPage/formParts/{SuccessMessage.js → SuccessMessage.tsx} +0 -0
- package/src/components/CalendarPage/formParts/Validations.tsx +78 -0
- package/src/components/CalendarPage/formParts/{discount.js → discount.tsx} +11 -2
- package/src/components/CalendarPage/formParts/form_types.d.ts +38 -0
- package/src/components/CalendarPage/formParts/{insurances.js → insurances.tsx} +14 -10
- package/src/components/CalendarPage/formParts/{radioButtons.js → radioButtons.tsx} +0 -0
- package/src/components/Error/{ApiError.js → ApiError.tsx} +6 -4
- package/src/components/Error/{IntegrationError.js → IntegrationError.tsx} +17 -11
- package/src/components/Error/{index.js → index.ts} +0 -0
- package/src/components/{ErrorBoundary.js → ErrorBoundary.tsx} +13 -5
- package/src/components/Modal/index.tsx +46 -0
- package/src/components/ReviewsPage/Queries.ts +26 -0
- package/src/components/ReviewsPage/ReviewsPage.tsx +43 -0
- package/src/components/ReviewsPage/Score.tsx +25 -0
- package/src/components/ReviewsPage/SingleReview.tsx +38 -0
- package/src/components/SafeBooking.tsx +97 -0
- package/src/components/SearchPage/Field.tsx +75 -0
- package/src/components/SearchPage/Filters.tsx +91 -0
- package/src/components/SearchPage/Paginator.tsx +63 -0
- package/src/components/SearchPage/Results.tsx +129 -0
- package/src/components/SearchPage/{SearchPage.js → SearchPage.tsx} +42 -31
- package/src/components/SearchPage/{SingleResult.js → SingleResult.tsx} +15 -8
- package/src/components/SearchPage/filters/Categories.tsx +57 -0
- package/src/components/SearchPage/filters/DateFilter.tsx +34 -0
- package/src/components/SearchPage/filters/List.tsx +80 -0
- package/src/components/SearchPage/filters/NumberFilter.tsx +37 -0
- package/src/components/SearchPage/filters/Radio.tsx +46 -0
- package/src/components/SearchPage/filters/Select.tsx +85 -0
- package/src/components/SearchPage/filters/__tests__/helper.spec.js +15 -0
- package/src/components/SearchPage/filters/filter_types.d.ts +25 -0
- package/src/components/SearchPage/filters/helper.ts +19 -0
- package/src/components/icons/ArrowLeft.svg.tsx +20 -0
- package/src/components/icons/{ArrowRight.svg.js → ArrowRight.svg.tsx} +0 -0
- package/src/components/icons/{Reload.svg.js → Reload.svg.tsx} +0 -0
- package/src/components/icons/{info.svg.js → info.svg.tsx} +0 -0
- package/src/components/icons/{loading.svg.js → loading.svg.tsx} +1 -1
- package/src/custom.d.ts +10 -0
- package/src/index.tsx +93 -0
- package/src/locales/de.json +4 -3
- package/src/locales/en.json +4 -3
- package/src/locales/es.json +4 -3
- package/src/locales/fr.json +4 -3
- package/src/locales/it.json +4 -3
- package/src/locales/nl.json +4 -3
- package/src/styles/main.css +2 -1
- package/src/styles/modal.css +1 -1
- package/src/styles/pagination.css +25 -23
- package/src/styles/result.css +33 -2
- package/src/styles/reviews.css +76 -0
- package/src/types.d.ts +85 -0
- package/tsconfig.json +17 -0
- package/vite.config.ts +31 -0
- package/build/index.html +0 -16
- package/build/index.js +0 -48528
- package/cypress.json +0 -9
- package/rollup.config.js +0 -30
- package/src/_lib/format.js +0 -16
- package/src/components/App.js +0 -164
- package/src/components/CalendarPage/BookingForm.js +0 -57
- package/src/components/CalendarPage/Calendar.js +0 -373
- package/src/components/CalendarPage/CalendarHeader.js +0 -58
- package/src/components/CalendarPage/CalendarPage.js +0 -158
- package/src/components/CalendarPage/FormCreator.js +0 -278
- package/src/components/CalendarPage/FormItems/Wrapper.js +0 -0
- package/src/components/CalendarPage/PriceField.js +0 -203
- package/src/components/CalendarPage/Summary/Description.js +0 -22
- package/src/components/CalendarPage/Summary/Object.js +0 -46
- package/src/components/CalendarPage/Summary/RentAndDiscount.js +0 -21
- package/src/components/CalendarPage/Summary/index.js +0 -19
- package/src/components/CalendarPage/formParts/AssistanceMessage.js +0 -47
- package/src/components/CalendarPage/formParts/CancelInsuranceText.js +0 -91
- package/src/components/CalendarPage/formParts/DiscountCode.js +0 -62
- package/src/components/CalendarPage/formParts/summary.js +0 -43
- package/src/components/Modal/index.js +0 -58
- package/src/components/ReviewsPage/ReviewsPage.js +0 -15
- package/src/components/SafeBooking.js +0 -69
- package/src/components/SearchPage/Field.js +0 -241
- package/src/components/SearchPage/Filters.js +0 -108
- package/src/components/SearchPage/Paginator.js +0 -59
- package/src/components/SearchPage/Results.js +0 -130
- package/src/components/SearchPage/filters/List.js +0 -63
- package/src/components/icons/ArrowLeft.svg.js +0 -18
- package/src/index.js +0 -74
- package/webpack.config.dev.js +0 -53
- package/webpack.config.js +0 -67
|
@@ -1,241 +0,0 @@
|
|
|
1
|
-
import React, { Component } from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
|
-
import DatePicker from 'react-date-picker';
|
|
4
|
-
import includes from 'array-includes'
|
|
5
|
-
import List from './filters/List';
|
|
6
|
-
import { format } from 'date-fns'
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class Field extends Component {
|
|
10
|
-
constructor(props) {
|
|
11
|
-
super(props);
|
|
12
|
-
this.handleChange = this.handleChange.bind(this);
|
|
13
|
-
this.handleCheckboxChange = this.handleCheckboxChange.bind(this);
|
|
14
|
-
this.handlePropertyChange = this.handlePropertyChange.bind(this);
|
|
15
|
-
this.handleDateChange = this.handleDateChange.bind(this);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
handleChange(event) {
|
|
19
|
-
this.props.onFilterChange(this.props.field.id, event.target.value);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
handleCheckboxChange(event) {
|
|
23
|
-
this.props.onFilterChange(this.props.field.id, event);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
createNumberArray(max_number) {
|
|
27
|
-
return Array.apply(null, { length: max_number + 1 }).map(
|
|
28
|
-
Number.call,
|
|
29
|
-
Number
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
createPriceArray(max_price) {
|
|
34
|
-
let rounded = Math.ceil(max_price / 100);
|
|
35
|
-
return Array.from({ length: rounded }, (v, k) => k * 100);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
handleDateChange(date) {
|
|
39
|
-
if (date) {
|
|
40
|
-
this.props.onFilterChange(this.props.field.id, format(date, 'YYYY-MM-DD'));
|
|
41
|
-
} else {
|
|
42
|
-
this.props.onFilterChange(this.props.field.id, '');
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
handlePropertyChange(event) {
|
|
47
|
-
const value = Number(event.target.value);
|
|
48
|
-
|
|
49
|
-
let properties = this.props.filters.properties || [];
|
|
50
|
-
if (includes(properties, value)) {
|
|
51
|
-
let index = properties.indexOf(value);
|
|
52
|
-
properties.splice(index, 1);
|
|
53
|
-
} else {
|
|
54
|
-
properties.push(value);
|
|
55
|
-
}
|
|
56
|
-
this.props.onFilterChange('properties', properties);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
render() {
|
|
60
|
-
const { PortalSite, field, filters, value } = this.props;
|
|
61
|
-
|
|
62
|
-
let options = [];
|
|
63
|
-
if (includes(['countries', 'cities', 'regions'], field.id)) {
|
|
64
|
-
options = PortalSite[field.id];
|
|
65
|
-
} else if (field.id === 'persons_min' || field.id === 'persons_max') {
|
|
66
|
-
options = this.createNumberArray(PortalSite.max_persons);
|
|
67
|
-
} else if (field.id === 'bedrooms_min') {
|
|
68
|
-
options = this.createNumberArray(PortalSite.max_bedrooms);
|
|
69
|
-
} else if (field.id === 'bathrooms_min') {
|
|
70
|
-
options = this.createNumberArray(PortalSite.max_bathrooms);
|
|
71
|
-
} else if (field.id === 'weekprice_max') {
|
|
72
|
-
options = this.createPriceArray(PortalSite.max_weekprice);
|
|
73
|
-
} else {
|
|
74
|
-
options = this.createNumberArray(PortalSite[field.id]);
|
|
75
|
-
}
|
|
76
|
-
let input;
|
|
77
|
-
const countries = filters.countries ;
|
|
78
|
-
const regions = Array.isArray(filters.regions)
|
|
79
|
-
? filters.regions
|
|
80
|
-
: [filters.regions];
|
|
81
|
-
const properties = this.props.filters.properties || [];
|
|
82
|
-
|
|
83
|
-
if (field.id === 'properties') {
|
|
84
|
-
let requiredCategories = PortalSite.options.filtersForm.categories;
|
|
85
|
-
input = [];
|
|
86
|
-
PortalSite.categories.map(category => {
|
|
87
|
-
if (includes(requiredCategories, category.id)) {
|
|
88
|
-
input.push(
|
|
89
|
-
<div className="bu-properties" key={category.id}>
|
|
90
|
-
<strong>{category.name}</strong>
|
|
91
|
-
<ul>
|
|
92
|
-
{category.properties.map(property => (
|
|
93
|
-
<li key={property.id}>
|
|
94
|
-
<label htmlFor={property.id}>
|
|
95
|
-
<input
|
|
96
|
-
type="checkbox"
|
|
97
|
-
id={property.id}
|
|
98
|
-
value={property.id}
|
|
99
|
-
checked={includes(properties, property.id)}
|
|
100
|
-
onChange={this.handlePropertyChange}
|
|
101
|
-
/>
|
|
102
|
-
{property.name}
|
|
103
|
-
</label>
|
|
104
|
-
</li>
|
|
105
|
-
))}
|
|
106
|
-
</ul>
|
|
107
|
-
</div>
|
|
108
|
-
);
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
} else if (field.type === 'select') {
|
|
112
|
-
console.log({ countries });
|
|
113
|
-
if (options && includes(['countries', 'cities', 'regions'], field.id)) {
|
|
114
|
-
input = (
|
|
115
|
-
<select
|
|
116
|
-
name={field.id}
|
|
117
|
-
onBlur={this.handleChange}
|
|
118
|
-
onChange={this.handleChange}
|
|
119
|
-
value={value}
|
|
120
|
-
>
|
|
121
|
-
<option value="" />
|
|
122
|
-
{options.map(opt => {
|
|
123
|
-
let hidden = false;
|
|
124
|
-
if (includes(['cities', 'regions'], field.id)) {
|
|
125
|
-
if (countries && !includes(countries, opt.country_id)) {
|
|
126
|
-
hidden = true;
|
|
127
|
-
}
|
|
128
|
-
if (field.id === 'cities') {
|
|
129
|
-
if (regions && !includes(regions, opt.region)) {
|
|
130
|
-
hidden = true;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
return (
|
|
136
|
-
<option
|
|
137
|
-
key={opt.id}
|
|
138
|
-
value={opt.id}
|
|
139
|
-
id={opt.region}
|
|
140
|
-
disabled={hidden}
|
|
141
|
-
hidden={hidden}
|
|
142
|
-
>
|
|
143
|
-
{opt.name}
|
|
144
|
-
</option>
|
|
145
|
-
);
|
|
146
|
-
})}
|
|
147
|
-
</select>
|
|
148
|
-
);
|
|
149
|
-
} else {
|
|
150
|
-
input = (
|
|
151
|
-
<select
|
|
152
|
-
name={field.id}
|
|
153
|
-
onBlur={this.handleChange}
|
|
154
|
-
onChange={this.handleChange}
|
|
155
|
-
value={value}
|
|
156
|
-
>
|
|
157
|
-
<option value="" />
|
|
158
|
-
{options.map(opt => {
|
|
159
|
-
let hidden = false;
|
|
160
|
-
|
|
161
|
-
return (
|
|
162
|
-
<option key={opt} value={opt} disabled={hidden} hidden={hidden}>
|
|
163
|
-
{opt}
|
|
164
|
-
</option>
|
|
165
|
-
);
|
|
166
|
-
})}
|
|
167
|
-
</select>
|
|
168
|
-
);
|
|
169
|
-
}
|
|
170
|
-
} else if (field.type === 'list') {
|
|
171
|
-
input = <List countries={countries} field={field} options={options} handleCheckboxChange={this.handleCheckboxChange} value={value} />
|
|
172
|
-
} else if (field.type === 'radio') {
|
|
173
|
-
input = (
|
|
174
|
-
<ul className="radioList">
|
|
175
|
-
{options.map(opt => (
|
|
176
|
-
<li
|
|
177
|
-
key={opt.id || opt}
|
|
178
|
-
className={`bu-list-item ${countries && !includes(countries, opt.country_id) ? 'bu-disabled' : ''}`}
|
|
179
|
-
>
|
|
180
|
-
<input
|
|
181
|
-
name={field.id}
|
|
182
|
-
type="radio"
|
|
183
|
-
id={opt.id || opt}
|
|
184
|
-
value={opt.id || opt}
|
|
185
|
-
disabled={
|
|
186
|
-
countries ? !includes(countries, opt.country_id) : false
|
|
187
|
-
}
|
|
188
|
-
// checked={value === opt.id || opt}
|
|
189
|
-
onBlur={this.handleChange}
|
|
190
|
-
onChange={this.handleChange}
|
|
191
|
-
/>
|
|
192
|
-
<label htmlFor={opt.id || opt}>{opt.name || opt}</label>
|
|
193
|
-
</li>
|
|
194
|
-
))}
|
|
195
|
-
</ul>
|
|
196
|
-
);
|
|
197
|
-
} else if (field.type === 'number') {
|
|
198
|
-
input = (
|
|
199
|
-
<input
|
|
200
|
-
value={value}
|
|
201
|
-
type="number"
|
|
202
|
-
min="0"
|
|
203
|
-
max={
|
|
204
|
-
field.id === 'persons_min'
|
|
205
|
-
? PortalSite.max_persons
|
|
206
|
-
: PortalSite[field.id]
|
|
207
|
-
}
|
|
208
|
-
onBlur={this.handleChange}
|
|
209
|
-
/>
|
|
210
|
-
);
|
|
211
|
-
} else if (field.type === 'date') {
|
|
212
|
-
let tempval;
|
|
213
|
-
if (value === '' || !value) {
|
|
214
|
-
tempval = null;
|
|
215
|
-
} else {
|
|
216
|
-
tempval = new Date(value);
|
|
217
|
-
}
|
|
218
|
-
input = (
|
|
219
|
-
<DatePicker
|
|
220
|
-
id={field.id}
|
|
221
|
-
onChange={this.handleDateChange}
|
|
222
|
-
value={tempval}
|
|
223
|
-
format='dd-MM-y'
|
|
224
|
-
/>
|
|
225
|
-
);
|
|
226
|
-
} else {
|
|
227
|
-
input = <input value={value} onBlur={this.handleChange} />;
|
|
228
|
-
}
|
|
229
|
-
return input;
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
Field.propTypes = {
|
|
234
|
-
field: PropTypes.object.isRequired,
|
|
235
|
-
PortalSite: PropTypes.object.isRequired,
|
|
236
|
-
value: PropTypes.oneOfType([PropTypes.string, PropTypes.array]),
|
|
237
|
-
filters: PropTypes.object.isRequired,
|
|
238
|
-
onFilterChange: PropTypes.func.isRequired,
|
|
239
|
-
};
|
|
240
|
-
|
|
241
|
-
export default Field;
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import React, { Component } from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
|
-
import Field from './Field';
|
|
4
|
-
import Reload from '../icons/Reload.svg';
|
|
5
|
-
import { FormattedMessage } from 'react-intl';
|
|
6
|
-
|
|
7
|
-
class Filters extends Component {
|
|
8
|
-
constructor(props) {
|
|
9
|
-
super(props);
|
|
10
|
-
this.saveFilters = this.saveFilters.bind(this);
|
|
11
|
-
this.toggle = this.toggle.bind(this);
|
|
12
|
-
this.state = {
|
|
13
|
-
show: false,
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
saveFilters(field, input) {
|
|
18
|
-
let newFilters = this.props.filters;
|
|
19
|
-
newFilters[field] = input;
|
|
20
|
-
this.props.onFilterChange(newFilters);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
toggle() {
|
|
24
|
-
const { show } = this.state;
|
|
25
|
-
let newShow = !show;
|
|
26
|
-
this.setState({
|
|
27
|
-
show: newShow,
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
render() {
|
|
32
|
-
const { PortalSite, filters, options } = this.props;
|
|
33
|
-
const searchFields = PortalSite.options.searchFields || [
|
|
34
|
-
{
|
|
35
|
-
label: 'Land',
|
|
36
|
-
id: 'countries',
|
|
37
|
-
type: 'select',
|
|
38
|
-
required: false,
|
|
39
|
-
mandatory: true,
|
|
40
|
-
options: ['select', 'list', 'radio', 'text'],
|
|
41
|
-
},
|
|
42
|
-
];
|
|
43
|
-
let fixed = options.filtersForm
|
|
44
|
-
? options.filtersForm.fixedMobile
|
|
45
|
-
? 'fixed-mobile'
|
|
46
|
-
: null
|
|
47
|
-
: null;
|
|
48
|
-
|
|
49
|
-
let filterClass = options.filtersForm
|
|
50
|
-
? options.filtersForm.show
|
|
51
|
-
? `filters filters-${options.filtersForm.location}`
|
|
52
|
-
: 'filters-hidden'
|
|
53
|
-
: 'filters';
|
|
54
|
-
|
|
55
|
-
let show = this.state.show && 'showOnMobile';
|
|
56
|
-
|
|
57
|
-
return (
|
|
58
|
-
<React.Fragment>
|
|
59
|
-
<button className={`filters-button ${fixed}`} onClick={this.toggle}>
|
|
60
|
-
<FormattedMessage id="filters" />
|
|
61
|
-
</button>
|
|
62
|
-
<div className={`${filterClass} ${fixed} ${show}`}>
|
|
63
|
-
<button
|
|
64
|
-
onClick={() => {
|
|
65
|
-
let filters = {};
|
|
66
|
-
for (var property in this.props.filters) {
|
|
67
|
-
filters[property] = '';
|
|
68
|
-
}
|
|
69
|
-
this.props.onFilterChange(filters);
|
|
70
|
-
}}
|
|
71
|
-
className="filters-reload"
|
|
72
|
-
>
|
|
73
|
-
<Reload />
|
|
74
|
-
</button>
|
|
75
|
-
{searchFields.map(field => (
|
|
76
|
-
<div key={field.id} className="bu-field" id={field.id}>
|
|
77
|
-
<label
|
|
78
|
-
style={{
|
|
79
|
-
width: '100%',
|
|
80
|
-
display: 'block',
|
|
81
|
-
}}
|
|
82
|
-
htmlFor={field.id}
|
|
83
|
-
>
|
|
84
|
-
{PortalSite[`${field.id}_label`]}
|
|
85
|
-
</label>
|
|
86
|
-
<Field
|
|
87
|
-
field={field}
|
|
88
|
-
PortalSite={PortalSite}
|
|
89
|
-
filters={filters}
|
|
90
|
-
value={filters[field.id]}
|
|
91
|
-
onFilterChange={this.saveFilters}
|
|
92
|
-
/>
|
|
93
|
-
</div>
|
|
94
|
-
))}
|
|
95
|
-
</div>
|
|
96
|
-
</React.Fragment>
|
|
97
|
-
);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
Filters.propTypes = {
|
|
102
|
-
PortalSite: PropTypes.object.isRequired,
|
|
103
|
-
filters: PropTypes.object.isRequired,
|
|
104
|
-
options: PropTypes.object.isRequired,
|
|
105
|
-
onFilterChange: PropTypes.func.isRequired,
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
export default Filters;
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { Query } from '@apollo/client/react/components';
|
|
3
|
-
import Pagination from 'react-js-pagination';
|
|
4
|
-
import { FormattedMessage } from 'react-intl';
|
|
5
|
-
import PropTypes from 'prop-types';
|
|
6
|
-
// import { Container } from './Pagination.css';
|
|
7
|
-
import { HOUSE_COUNT_QUERY } from '../../_lib/SearchQueries';
|
|
8
|
-
import Loading from '../icons/loading.svg';
|
|
9
|
-
|
|
10
|
-
function Paginator({ onPageChange, variables, activePage, limit }) {
|
|
11
|
-
return (
|
|
12
|
-
<Query query={HOUSE_COUNT_QUERY} variables={variables}>
|
|
13
|
-
{({ loading, error, data }) => {
|
|
14
|
-
if (loading)
|
|
15
|
-
return (
|
|
16
|
-
<div
|
|
17
|
-
style={{
|
|
18
|
-
width: '100%',
|
|
19
|
-
display: 'flex',
|
|
20
|
-
justifyContent: 'center',
|
|
21
|
-
}}
|
|
22
|
-
>
|
|
23
|
-
<Loading />
|
|
24
|
-
</div>
|
|
25
|
-
);
|
|
26
|
-
if (error) {
|
|
27
|
-
return <div>Error</div>;
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
const results = data.PortalSite.houses;
|
|
31
|
-
return (
|
|
32
|
-
<div className="bu-paginator">
|
|
33
|
-
<div>
|
|
34
|
-
{results.length} <FormattedMessage id="results" />
|
|
35
|
-
</div>
|
|
36
|
-
<Pagination
|
|
37
|
-
activePage={activePage}
|
|
38
|
-
itemsCountPerPage={limit}
|
|
39
|
-
totalItemsCount={results.length}
|
|
40
|
-
pageRangeDisplayed={5}
|
|
41
|
-
onChange={e => { onPageChange(e) }}
|
|
42
|
-
innerClass="bu-pagination"
|
|
43
|
-
/>
|
|
44
|
-
</div>
|
|
45
|
-
);
|
|
46
|
-
}}
|
|
47
|
-
</Query>
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
Paginator.propTypes = {
|
|
53
|
-
activePage: PropTypes.number.isRequired,
|
|
54
|
-
limit: PropTypes.number.isRequired,
|
|
55
|
-
onPageChange: PropTypes.func.isRequired,
|
|
56
|
-
variables: PropTypes.object.isRequired,
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
export default Paginator;
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
|
-
import { Query } from '@apollo/client/react/components';
|
|
4
|
-
import { FormattedMessage } from 'react-intl';
|
|
5
|
-
import differenceInCalendarDays from 'date-fns/difference_in_calendar_days';
|
|
6
|
-
import Loading from '../icons/loading.svg';
|
|
7
|
-
import SingleResult from './SingleResult';
|
|
8
|
-
import Paginator from './Paginator';
|
|
9
|
-
|
|
10
|
-
import { HOUSES_PRICE_QUERY, HOUSES_QUERY } from '../../_lib/SearchQueries';
|
|
11
|
-
import { ApiError } from '../Error';
|
|
12
|
-
|
|
13
|
-
function Results({
|
|
14
|
-
filters,
|
|
15
|
-
PortalSite,
|
|
16
|
-
limit,
|
|
17
|
-
skip,
|
|
18
|
-
locale,
|
|
19
|
-
onPageChange,
|
|
20
|
-
activePage,
|
|
21
|
-
}) {
|
|
22
|
-
let min_nights = null;
|
|
23
|
-
let requestPrices = false
|
|
24
|
-
if (filters.departure_date && filters.arrival_date) {
|
|
25
|
-
min_nights = differenceInCalendarDays(
|
|
26
|
-
filters.departure_date,
|
|
27
|
-
filters.arrival_date
|
|
28
|
-
);
|
|
29
|
-
requestPrices = true
|
|
30
|
-
} else if (filters.arrival_date) {
|
|
31
|
-
min_nights = 1;
|
|
32
|
-
}
|
|
33
|
-
let filterProperties = filters.properties || [];
|
|
34
|
-
filterProperties = filterProperties.map((e) => {
|
|
35
|
-
return JSON.stringify(e);
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
let properties = filterProperties.join(',');
|
|
39
|
-
|
|
40
|
-
let variables = {
|
|
41
|
-
id: PortalSite.portal_code,
|
|
42
|
-
country_id: filters.countries || null,
|
|
43
|
-
region_id: filters.regions || null,
|
|
44
|
-
city_id: filters.cities,
|
|
45
|
-
persons_min: Number(filters.persons_min) || null,
|
|
46
|
-
persons_max: Number(filters.persons_max) || null,
|
|
47
|
-
bedrooms_min: Number(filters.bedrooms_min),
|
|
48
|
-
bathrooms_min: Number(filters.bathrooms_min),
|
|
49
|
-
arrival_date: filters.arrival_date,
|
|
50
|
-
starts_at: filters.arrival_date,
|
|
51
|
-
ends_at: filters.departure_date,
|
|
52
|
-
no_nights: Number(min_nights) || null,
|
|
53
|
-
extra_search: filters.extra_search,
|
|
54
|
-
properties,
|
|
55
|
-
weekprice_max: Number(filters.weekprice_max) || null,
|
|
56
|
-
limit,
|
|
57
|
-
skip,
|
|
58
|
-
locale,
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
return (
|
|
62
|
-
<Query query={requestPrices ? HOUSES_PRICE_QUERY : HOUSES_QUERY} variables={variables}>
|
|
63
|
-
{({ loading, error, data }) => {
|
|
64
|
-
if (loading)
|
|
65
|
-
return (
|
|
66
|
-
<div>
|
|
67
|
-
<Loading />
|
|
68
|
-
</div>
|
|
69
|
-
);
|
|
70
|
-
if (error) {
|
|
71
|
-
return (
|
|
72
|
-
<div>
|
|
73
|
-
<ApiError errors={error}></ApiError>
|
|
74
|
-
</div>
|
|
75
|
-
);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const Results = data.PortalSite.houses;
|
|
79
|
-
|
|
80
|
-
return (
|
|
81
|
-
<div
|
|
82
|
-
id="results"
|
|
83
|
-
className={
|
|
84
|
-
PortalSite.options.filtersForm
|
|
85
|
-
? PortalSite.options.filtersForm.mode
|
|
86
|
-
: null
|
|
87
|
-
}
|
|
88
|
-
>
|
|
89
|
-
<Paginator
|
|
90
|
-
variables={variables}
|
|
91
|
-
activePage={activePage}
|
|
92
|
-
limit={limit}
|
|
93
|
-
onPageChange={onPageChange}
|
|
94
|
-
/>{' '}
|
|
95
|
-
{Results.length === 0 ? (
|
|
96
|
-
<div className="bu-noresults">
|
|
97
|
-
<FormattedMessage id="no_results" />
|
|
98
|
-
</div>
|
|
99
|
-
) : null}
|
|
100
|
-
{Results.map((result) => (
|
|
101
|
-
<SingleResult
|
|
102
|
-
key={result.id}
|
|
103
|
-
result={result}
|
|
104
|
-
options={PortalSite.options.filtersForm}
|
|
105
|
-
/>
|
|
106
|
-
))}
|
|
107
|
-
<Paginator
|
|
108
|
-
variables={variables}
|
|
109
|
-
activePage={activePage}
|
|
110
|
-
limit={limit}
|
|
111
|
-
onPageChange={onPageChange}
|
|
112
|
-
/>
|
|
113
|
-
</div>
|
|
114
|
-
);
|
|
115
|
-
}}
|
|
116
|
-
</Query>
|
|
117
|
-
);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
Results.propTypes = {
|
|
121
|
-
PortalSite: PropTypes.object.isRequired,
|
|
122
|
-
filters: PropTypes.object.isRequired,
|
|
123
|
-
activePage: PropTypes.number.isRequired,
|
|
124
|
-
locale: PropTypes.string.isRequired,
|
|
125
|
-
limit: PropTypes.number.isRequired,
|
|
126
|
-
skip: PropTypes.number.isRequired,
|
|
127
|
-
onPageChange: PropTypes.func.isRequired,
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
export default Results;
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import includes from 'array-includes'
|
|
3
|
-
|
|
4
|
-
export default function List({ countries, field, options, handleCheckboxChange, value }) {
|
|
5
|
-
const updateList = (e) => {
|
|
6
|
-
if (value === e.target.value) {
|
|
7
|
-
handleCheckboxChange(null)
|
|
8
|
-
} else {
|
|
9
|
-
handleCheckboxChange(e.target.value)
|
|
10
|
-
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
if (includes(['cities', 'regions'], field.id)) {
|
|
15
|
-
|
|
16
|
-
return (
|
|
17
|
-
<ul className="radioList">
|
|
18
|
-
{options.map(opt => (
|
|
19
|
-
<li
|
|
20
|
-
key={opt.id}
|
|
21
|
-
className={`bu-list-item ${countries && !includes(countries, opt.country_id) ? 'bu-disabled' : 'bu-open'}`}
|
|
22
|
-
>
|
|
23
|
-
<input
|
|
24
|
-
name={field.id}
|
|
25
|
-
type="checkbox"
|
|
26
|
-
id={opt.id}
|
|
27
|
-
value={opt.id}
|
|
28
|
-
disabled={
|
|
29
|
-
countries ? !includes(countries, opt.country_id) : false
|
|
30
|
-
}
|
|
31
|
-
checked={value === opt.id}
|
|
32
|
-
onBlur={handleCheckboxChange}
|
|
33
|
-
onChange={handleCheckboxChange}
|
|
34
|
-
/>
|
|
35
|
-
<label htmlFor={opt.id}>{opt.name}</label>
|
|
36
|
-
</li>
|
|
37
|
-
))}
|
|
38
|
-
</ul>
|
|
39
|
-
);
|
|
40
|
-
} else {
|
|
41
|
-
return (
|
|
42
|
-
<ul className="radioList">
|
|
43
|
-
{options.map(opt => (
|
|
44
|
-
<li
|
|
45
|
-
key={opt.id}
|
|
46
|
-
className={`bu-list-item bu-open`}
|
|
47
|
-
>
|
|
48
|
-
<input
|
|
49
|
-
name={field.id}
|
|
50
|
-
type="checkbox"
|
|
51
|
-
id={opt.id}
|
|
52
|
-
value={opt.id}
|
|
53
|
-
checked={value === opt.id}
|
|
54
|
-
onBlur={handleCheckboxChange}
|
|
55
|
-
onChange={updateList}
|
|
56
|
-
/>
|
|
57
|
-
<label htmlFor={opt.id}>{opt.name}</label>
|
|
58
|
-
</li>
|
|
59
|
-
))}
|
|
60
|
-
</ul>
|
|
61
|
-
);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
|
|
3
|
-
const ArrowRight = () => (
|
|
4
|
-
<svg
|
|
5
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
6
|
-
xmlnsXlink="http://www.w3.org/1999/xlink"
|
|
7
|
-
version="1.1"
|
|
8
|
-
x="0px"
|
|
9
|
-
y="0px"
|
|
10
|
-
viewBox="0 0 100 125"
|
|
11
|
-
style={{ enableBackground: 'new 0 0 100 100' }}
|
|
12
|
-
xmlSpace="preserve"
|
|
13
|
-
>
|
|
14
|
-
<path d="M2.4,44.1l32.9-32.9c3.1-3.1,8.2-3.1,11.4,0c1.6,1.6,2.4,3.6,2.4,5.7c0,2.1-0.8,4.1-2.4,5.7L27.2,42h64.7 c2.2,0,4.2,0.9,5.7,2.4c1.5,1.5,2.4,3.5,2.4,5.7c0,4.4-3.6,8.1-8.1,8.1H27.4l19.3,19.3c1.6,1.6,2.4,3.6,2.4,5.7s-0.8,4.1-2.4,5.7 c-3.1,3.1-8.3,3.1-11.4,0L2.4,55.9C0.8,54.3,0,52.3,0,50.2c0-0.1,0-0.1,0-0.2c0-0.1,0-0.1,0-0.2C0,47.7,0.8,45.7,2.4,44.1z" />
|
|
15
|
-
</svg>
|
|
16
|
-
);
|
|
17
|
-
|
|
18
|
-
export default ArrowRight;
|
package/src/index.js
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import App from "./components/App";
|
|
3
|
-
import { IntlProvider } from "react-intl";
|
|
4
|
-
// import registerServiceWorker from './registerServiceWorker';
|
|
5
|
-
|
|
6
|
-
import {
|
|
7
|
-
ApolloClient,
|
|
8
|
-
InMemoryCache,
|
|
9
|
-
ApolloProvider,
|
|
10
|
-
} from "@apollo/client";
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
import en from "./locales/en.json";
|
|
14
|
-
import nl from "./locales/nl.json";
|
|
15
|
-
import de from "./locales/de.json";
|
|
16
|
-
import fr from "./locales/fr.json";
|
|
17
|
-
import es from "./locales/es.json";
|
|
18
|
-
import it from "./locales/it.json";
|
|
19
|
-
|
|
20
|
-
import "./styles/main.css";
|
|
21
|
-
import { IntegrationError } from "./components/Error";
|
|
22
|
-
|
|
23
|
-
function Portal({ portalCode, objectCode, pageType, locale, filters, api_url } ) {
|
|
24
|
-
const errors = IntegrationError({ portalCode, pageType, locale, filters })
|
|
25
|
-
if (errors) {
|
|
26
|
-
return errors
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
if (!locale) {
|
|
30
|
-
locale = 'en'
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const client = new ApolloClient({
|
|
34
|
-
uri: api_url,
|
|
35
|
-
cache: new InMemoryCache(),
|
|
36
|
-
headers: {
|
|
37
|
-
locale,
|
|
38
|
-
},
|
|
39
|
-
defaultOptions: {
|
|
40
|
-
watchQuery: {
|
|
41
|
-
fetchPolicy: "cache-and-network",
|
|
42
|
-
},
|
|
43
|
-
},
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
const messages = { en, nl, de, fr, es, it };
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
window.__localeId__ = locale;
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
return (
|
|
55
|
-
<ApolloProvider client={client}>
|
|
56
|
-
<IntlProvider locale={locale} messages={messages[locale]}>
|
|
57
|
-
<App
|
|
58
|
-
portalCode={portalCode}
|
|
59
|
-
objectCode={objectCode}
|
|
60
|
-
pageType={pageType}
|
|
61
|
-
locale={locale}
|
|
62
|
-
filters={filters}
|
|
63
|
-
/>
|
|
64
|
-
</IntlProvider>
|
|
65
|
-
</ApolloProvider>
|
|
66
|
-
);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
Portal.defaultProps = {
|
|
70
|
-
pageType: null,
|
|
71
|
-
api_url: "https://api.bukazu.com/graphql"
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
export default Portal;
|