bukazu-portal-react 2.1.21 → 3.0.2

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.
Files changed (191) hide show
  1. package/.github/workflows/dependabot.yml +11 -0
  2. package/.github/workflows/node.js.yml +31 -0
  3. package/.prettierrc +3 -6
  4. package/CHANGELOG.MD +5 -0
  5. package/babel.config.json +1 -1
  6. package/build/index.css +1 -2312
  7. package/build/portal.es.js +35483 -0
  8. package/build/portal.umd.js +596 -0
  9. package/{build/calendar.html → calendar.html} +2 -4
  10. package/coverage/clover.xml +28 -0
  11. package/coverage/coverage-final.json +2 -0
  12. package/coverage/lcov-report/base.css +224 -0
  13. package/coverage/lcov-report/block-navigation.js +87 -0
  14. package/coverage/lcov-report/favicon.png +0 -0
  15. package/coverage/lcov-report/helper.ts.html +142 -0
  16. package/coverage/lcov-report/index.html +116 -0
  17. package/coverage/lcov-report/prettify.css +1 -0
  18. package/coverage/lcov-report/prettify.js +2 -0
  19. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  20. package/coverage/lcov-report/sorter.js +196 -0
  21. package/coverage/lcov.info +36 -0
  22. package/cypress/{integration → e2e}/.examples/actions.spec.js +0 -0
  23. package/cypress/{integration → e2e}/.examples/aliasing.spec.js +0 -0
  24. package/cypress/{integration → e2e}/.examples/assertions.spec.js +0 -0
  25. package/cypress/{integration → e2e}/.examples/connectors.spec.js +0 -0
  26. package/cypress/{integration → e2e}/.examples/cookies.spec.js +0 -0
  27. package/cypress/{integration → e2e}/.examples/cypress_api.spec.js +0 -0
  28. package/cypress/{integration → e2e}/.examples/files.spec.js +0 -0
  29. package/cypress/{integration → e2e}/.examples/local_storage.spec.js +0 -0
  30. package/cypress/{integration → e2e}/.examples/location.spec.js +0 -0
  31. package/cypress/{integration → e2e}/.examples/misc.spec.js +0 -0
  32. package/cypress/{integration → e2e}/.examples/navigation.spec.js +0 -0
  33. package/cypress/{integration → e2e}/.examples/network_requests.spec.js +0 -0
  34. package/cypress/{integration → e2e}/.examples/querying.spec.js +0 -0
  35. package/cypress/{integration → e2e}/.examples/spies_stubs_clocks.spec.js +0 -0
  36. package/cypress/{integration → e2e}/.examples/traversal.spec.js +0 -0
  37. package/cypress/{integration → e2e}/.examples/utilities.spec.js +0 -0
  38. package/cypress/{integration → e2e}/.examples/viewport.spec.js +0 -0
  39. package/cypress/{integration → e2e}/.examples/waiting.spec.js +0 -0
  40. package/cypress/{integration → e2e}/.examples/window.spec.js +0 -0
  41. package/cypress/{integration → e2e}/booking.spec.js +0 -0
  42. package/cypress/{integration → e2e}/calendar.spec.js +0 -0
  43. package/cypress/{integration → e2e}/search.spec.js +0 -0
  44. package/cypress/support/commands.ts +37 -0
  45. package/cypress/support/component-index.html +12 -0
  46. package/cypress/support/component.ts +39 -0
  47. package/cypress/support/{index.js → e2e.js} +0 -0
  48. package/cypress.config.ts +15 -0
  49. package/{dev.js → dev.tsx} +1 -1
  50. package/index.html +15 -0
  51. package/{build/invalid-calendar.html → invalid-calendar.html} +0 -0
  52. package/jest.config.js +195 -0
  53. package/package.json +35 -40
  54. package/reviews.html +16 -0
  55. package/src/_lib/{SearchQueries.js → SearchQueries.ts} +8 -2
  56. package/src/_lib/{countries.js → countries.ts} +0 -0
  57. package/src/_lib/date_helper.ts +27 -0
  58. package/src/_lib/{queries.js → queries.ts} +24 -5
  59. package/src/components/App.tsx +132 -0
  60. package/src/components/AppContext.ts +14 -0
  61. package/src/components/CalendarPage/BookingForm.tsx +42 -0
  62. package/src/components/CalendarPage/Calendar.tsx +50 -0
  63. package/src/components/CalendarPage/CalendarPage.tsx +43 -0
  64. package/src/components/CalendarPage/CalendarParts/CalendarContext.tsx +89 -0
  65. package/src/components/CalendarPage/CalendarParts/CalendarHeader.tsx +72 -0
  66. package/src/components/CalendarPage/CalendarParts/DayClasses.ts +111 -0
  67. package/src/components/CalendarPage/CalendarParts/GenerateCalendar.tsx +64 -0
  68. package/src/components/CalendarPage/CalendarParts/Legend.tsx +33 -0
  69. package/src/components/CalendarPage/CalendarParts/MonthHeader.tsx +15 -0
  70. package/src/components/CalendarPage/CalendarParts/Months.tsx +37 -0
  71. package/src/components/CalendarPage/CalendarParts/RenderCells.tsx +94 -0
  72. package/src/components/CalendarPage/CalendarParts/SingleMonth.tsx +72 -0
  73. package/src/components/CalendarPage/CalendarParts/StartBooking.tsx +17 -0
  74. package/src/components/CalendarPage/CalendarParts/WeekDays.tsx +27 -0
  75. package/src/components/CalendarPage/FormCreator.tsx +213 -0
  76. package/src/components/CalendarPage/FormItems/{Date.js → Date.tsx} +10 -2
  77. package/src/components/CalendarPage/FormItems/{NumberSelect.js → NumberSelect.tsx} +1 -1
  78. package/src/components/CalendarPage/FormItems/{Select.js → Select.tsx} +0 -0
  79. package/src/components/CalendarPage/FormItems/{index.js → index.ts} +0 -0
  80. package/src/components/CalendarPage/PriceField/Price.tsx +58 -0
  81. package/src/components/CalendarPage/PriceField/Queries.ts +23 -0
  82. package/src/components/CalendarPage/PriceField/index.tsx +127 -0
  83. package/src/components/CalendarPage/Summary/{CostRow.js → CostRow.tsx} +19 -3
  84. package/src/components/CalendarPage/Summary/{CostSection.js → CostSection.tsx} +5 -1
  85. package/src/components/CalendarPage/Summary/{CostSummary.js → CostSummary.tsx} +19 -10
  86. package/src/components/CalendarPage/Summary/Description.tsx +27 -0
  87. package/src/components/CalendarPage/Summary/{InsurancesAndRequired.js → InsurancesAndRequired.tsx} +21 -2
  88. package/src/components/CalendarPage/Summary/Object.tsx +59 -0
  89. package/src/components/CalendarPage/Summary/{OnSite.js → OnSite.tsx} +9 -9
  90. package/src/components/CalendarPage/Summary/{OptionalNotOnSite.js → OptionalNotOnSite.tsx} +19 -18
  91. package/src/components/CalendarPage/Summary/{OptionalOnSite.js → OptionalOnSite.tsx} +6 -1
  92. package/src/components/CalendarPage/Summary/{Queries.js → Queries.ts} +3 -3
  93. package/src/components/CalendarPage/Summary/RentAndDiscount.tsx +30 -0
  94. package/src/components/CalendarPage/Summary/{Totals.js → Totals.tsx} +8 -3
  95. package/src/components/CalendarPage/Summary/cost_types.d.ts +31 -0
  96. package/src/components/CalendarPage/Summary/index.tsx +24 -0
  97. package/src/components/CalendarPage/calender_types.d.ts +16 -0
  98. package/src/components/CalendarPage/formParts/AssistanceMessage.tsx +60 -0
  99. package/src/components/CalendarPage/formParts/{BookingHelpers.js → BookingHelpers.tsx} +3 -3
  100. package/src/components/CalendarPage/formParts/{BookingOrOption.js → BookingOrOption.tsx} +6 -1
  101. package/src/components/CalendarPage/formParts/CancelInsuranceText.tsx +105 -0
  102. package/src/components/CalendarPage/formParts/{DefaultBookingFields.js → DefaultBookingFields.ts} +3 -1
  103. package/src/components/CalendarPage/formParts/DiscountCode.tsx +62 -0
  104. package/src/components/CalendarPage/formParts/{Guests.js → Guests.tsx} +10 -4
  105. package/src/components/CalendarPage/formParts/{OptionalBookingFields.js → OptionalBookingFields.tsx} +0 -0
  106. package/src/components/CalendarPage/formParts/{OptionalCosts.js → OptionalCosts.tsx} +1 -2
  107. package/src/components/CalendarPage/formParts/{SuccessMessage.js → SuccessMessage.tsx} +0 -0
  108. package/src/components/CalendarPage/formParts/Validations.tsx +78 -0
  109. package/src/components/CalendarPage/formParts/{discount.js → discount.tsx} +11 -2
  110. package/src/components/CalendarPage/formParts/form_types.d.ts +38 -0
  111. package/src/components/CalendarPage/formParts/{insurances.js → insurances.tsx} +14 -10
  112. package/src/components/CalendarPage/formParts/{radioButtons.js → radioButtons.tsx} +0 -0
  113. package/src/components/Error/{ApiError.js → ApiError.tsx} +6 -4
  114. package/src/components/Error/{IntegrationError.js → IntegrationError.tsx} +17 -11
  115. package/src/components/Error/{index.js → index.ts} +0 -0
  116. package/src/components/{ErrorBoundary.js → ErrorBoundary.tsx} +13 -5
  117. package/src/components/Modal/index.tsx +46 -0
  118. package/src/components/ReviewsPage/Queries.ts +26 -0
  119. package/src/components/ReviewsPage/ReviewsPage.tsx +43 -0
  120. package/src/components/ReviewsPage/Score.tsx +25 -0
  121. package/src/components/ReviewsPage/SingleReview.tsx +38 -0
  122. package/src/components/SafeBooking.tsx +97 -0
  123. package/src/components/SearchPage/Field.tsx +75 -0
  124. package/src/components/SearchPage/Filters.tsx +91 -0
  125. package/src/components/SearchPage/Paginator.tsx +63 -0
  126. package/src/components/SearchPage/Results.tsx +129 -0
  127. package/src/components/SearchPage/{SearchPage.js → SearchPage.tsx} +42 -31
  128. package/src/components/SearchPage/{SingleResult.js → SingleResult.tsx} +15 -8
  129. package/src/components/SearchPage/filters/Categories.tsx +57 -0
  130. package/src/components/SearchPage/filters/DateFilter.tsx +34 -0
  131. package/src/components/SearchPage/filters/List.tsx +80 -0
  132. package/src/components/SearchPage/filters/NumberFilter.tsx +37 -0
  133. package/src/components/SearchPage/filters/Radio.tsx +46 -0
  134. package/src/components/SearchPage/filters/Select.tsx +85 -0
  135. package/src/components/SearchPage/filters/__tests__/helper.spec.js +15 -0
  136. package/src/components/SearchPage/filters/filter_types.d.ts +25 -0
  137. package/src/components/SearchPage/filters/helper.ts +19 -0
  138. package/src/components/icons/ArrowLeft.svg.tsx +20 -0
  139. package/src/components/icons/{ArrowRight.svg.js → ArrowRight.svg.tsx} +0 -0
  140. package/src/components/icons/{Reload.svg.js → Reload.svg.tsx} +0 -0
  141. package/src/components/icons/{info.svg.js → info.svg.tsx} +0 -0
  142. package/src/components/icons/{loading.svg.js → loading.svg.tsx} +1 -1
  143. package/src/custom.d.ts +10 -0
  144. package/src/index.tsx +93 -0
  145. package/src/locales/de.json +4 -3
  146. package/src/locales/en.json +4 -3
  147. package/src/locales/es.json +4 -3
  148. package/src/locales/fr.json +4 -3
  149. package/src/locales/it.json +4 -3
  150. package/src/locales/nl.json +4 -3
  151. package/src/styles/main.css +2 -1
  152. package/src/styles/modal.css +1 -1
  153. package/src/styles/pagination.css +25 -23
  154. package/src/styles/result.css +33 -2
  155. package/src/styles/reviews.css +76 -0
  156. package/src/types.d.ts +85 -0
  157. package/tsconfig.json +17 -0
  158. package/vite.config.ts +31 -0
  159. package/build/index.html +0 -16
  160. package/build/index.js +0 -48528
  161. package/cypress.json +0 -9
  162. package/rollup.config.js +0 -30
  163. package/src/_lib/format.js +0 -16
  164. package/src/components/App.js +0 -164
  165. package/src/components/CalendarPage/BookingForm.js +0 -57
  166. package/src/components/CalendarPage/Calendar.js +0 -373
  167. package/src/components/CalendarPage/CalendarHeader.js +0 -58
  168. package/src/components/CalendarPage/CalendarPage.js +0 -158
  169. package/src/components/CalendarPage/FormCreator.js +0 -278
  170. package/src/components/CalendarPage/FormItems/Wrapper.js +0 -0
  171. package/src/components/CalendarPage/PriceField.js +0 -203
  172. package/src/components/CalendarPage/Summary/Description.js +0 -22
  173. package/src/components/CalendarPage/Summary/Object.js +0 -46
  174. package/src/components/CalendarPage/Summary/RentAndDiscount.js +0 -21
  175. package/src/components/CalendarPage/Summary/index.js +0 -19
  176. package/src/components/CalendarPage/formParts/AssistanceMessage.js +0 -47
  177. package/src/components/CalendarPage/formParts/CancelInsuranceText.js +0 -91
  178. package/src/components/CalendarPage/formParts/DiscountCode.js +0 -62
  179. package/src/components/CalendarPage/formParts/summary.js +0 -43
  180. package/src/components/Modal/index.js +0 -58
  181. package/src/components/ReviewsPage/ReviewsPage.js +0 -15
  182. package/src/components/SafeBooking.js +0 -69
  183. package/src/components/SearchPage/Field.js +0 -241
  184. package/src/components/SearchPage/Filters.js +0 -108
  185. package/src/components/SearchPage/Paginator.js +0 -59
  186. package/src/components/SearchPage/Results.js +0 -130
  187. package/src/components/SearchPage/filters/List.js +0 -63
  188. package/src/components/icons/ArrowLeft.svg.js +0 -18
  189. package/src/index.js +0 -74
  190. package/webpack.config.dev.js +0 -53
  191. package/webpack.config.js +0 -67
@@ -1,158 +0,0 @@
1
- import React, { Component } from 'react';
2
- import PropTypes from 'prop-types';
3
- import { Query } from '@apollo/client/react/components';
4
- import { gql} from "@apollo/client";
5
- import Calendar from './Calendar';
6
- import BookingForm from './BookingForm';
7
- import Loading from '../icons/loading.svg';
8
- import { ApiError } from '../Error';
9
-
10
- export const HOUSE_QUERY = gql`
11
- query PortalSiteHousesQuery($id: ID!, $house_id: String!) {
12
- PortalSite(id: $id) {
13
- id
14
- houses(house_code: $house_id) {
15
- id
16
- name
17
- max_nights
18
- last_minute_days
19
- discounts
20
- discounts_info
21
- house_type
22
- persons
23
- }
24
- }
25
- }
26
- `;
27
-
28
- class CalendarPage extends Component {
29
- constructor(props) {
30
- super(props);
31
-
32
- this.onBooking = this.onBooking.bind(this);
33
- this.onReturn = this.onReturn.bind(this);
34
-
35
- this.state = {
36
- bookingStarted: false,
37
- booking: {
38
- objectCode: '',
39
- portalCode: '',
40
- arrivalDate: {},
41
- departureDate: {},
42
- in_option: false,
43
- },
44
- };
45
- }
46
-
47
- onBooking(booking) {
48
- this.setState({
49
- bookingStarted: true,
50
- booking,
51
- });
52
- }
53
-
54
- onReturn(booking) {
55
- this.setState({
56
- bookingStarted: false,
57
- booking,
58
- });
59
- }
60
-
61
- calendar() {
62
- const { objectCode, PortalSite, locale } = this.props;
63
- const variables = {
64
- id: PortalSite.portal_code,
65
- house_id: objectCode,
66
- locale,
67
- };
68
- return (
69
- <Query query={HOUSE_QUERY} variables={variables}>
70
- {({ loading, error, data }) => {
71
- if (loading)
72
- return (
73
- <div>
74
- <Loading />
75
- </div>
76
- );
77
- if (error) {
78
- return (
79
- <div>
80
- <ApiError errors={error} />
81
- </div>
82
- );
83
- }
84
-
85
- const Results = data.PortalSite.houses;
86
- const numberOfMonths = PortalSite.options.bookingForm
87
- ? PortalSite.options.bookingForm.numberOfMonths
88
- : 4;
89
- const numberOfMonthsInARow = PortalSite.options.bookingForm
90
- ? PortalSite.options.bookingForm.numberOfMonthsInARow
91
- : 4;
92
-
93
- return (
94
- <div id="calendar-container">
95
- {Results.length === 0 && (
96
- <div>
97
- <FormattedMessage id="no_house_found" />
98
- </div>
99
- )}
100
- {Results.map((result) => (
101
- <div key={result.id}>
102
- <div className="house-name">{result.name}</div>
103
- <Calendar
104
- portalCode={variables.id}
105
- objectCode={variables.house_id}
106
- numberOfMonths={numberOfMonths}
107
- numberOfMonthsInARow={numberOfMonthsInARow}
108
- house={result}
109
- locale={locale}
110
- onBooking={this.onBooking}
111
- />
112
- </div>
113
- ))}
114
- </div>
115
- );
116
- }}
117
- </Query>
118
- );
119
- }
120
-
121
- bookingForm() {
122
- return (
123
- <BookingForm
124
- booking={this.state.booking}
125
- locale={this.props.locale}
126
- onReturn={this.onReturn}
127
- />
128
- );
129
- }
130
-
131
- render() {
132
- if (this.state.bookingStarted) {
133
- return this.bookingForm();
134
- } else {
135
- return this.calendar();
136
- }
137
- }
138
- }
139
-
140
- CalendarPage.DefaultProps = {
141
- PortalSite: {
142
- options: {
143
- bookingForm: {
144
- numberOfMonths: 4,
145
- numberOfMonthsInARow: 2,
146
- },
147
- },
148
- },
149
- };
150
-
151
- CalendarPage.propTypes = {
152
- objectCode: PropTypes.string.isRequired,
153
- // portalCode: PropTypes.string.isRequired,
154
- PortalSite: PropTypes.object.isRequired,
155
- locale: PropTypes.string.isRequired,
156
- };
157
-
158
- export default CalendarPage;
@@ -1,278 +0,0 @@
1
- import React from 'react';
2
- import PropTypes from 'prop-types';
3
- import { Formik, Form } from 'formik';
4
- import { FormattedMessage } from 'react-intl';
5
- import { Mutation } from '@apollo/client/react/components';
6
- import { CREATE_BOOKING_MUTATION } from '../../_lib/queries';
7
- import { Insurances } from './formParts/insurances';
8
- import Discount from './formParts/discount';
9
- import Summary from './Summary';
10
- import Modal from '../Modal';
11
- import DefaultBookingFields from './formParts/DefaultBookingFields';
12
- import SuccessMessage from './formParts/SuccessMessage';
13
- import OptionalBookingFields, { isInt } from './formParts/OptionalBookingFields';
14
- import includes from 'array-includes';
15
- import { ApiError } from '../Error';
16
- import {
17
- initializeBookingFields,
18
- byString,
19
- validateAge,
20
- } from './formParts/BookingHelpers';
21
- import OptionalCosts from './formParts/OptionalCosts';
22
- import Guests from './formParts/Guests';
23
- class FormCreator extends React.Component {
24
- state = {
25
- formSubmit: false,
26
- bookingFields: this.props.options.bookingFields || DefaultBookingFields,
27
- };
28
-
29
- validate = (values) => {
30
- const { babies_extra, persons } = this.props.house;
31
-
32
- let errors = {};
33
-
34
- let babies = Number(values.babies) - Number(babies_extra);
35
- if (babies < 0) {
36
- babies = 0;
37
- }
38
- values.persons = Number(values.children) + Number(values.adults) + babies;
39
-
40
- for (let field of this.state.bookingFields) {
41
- if (field.required) {
42
- if (isInt(field.id)) {
43
- const validateValue = byString(values, `extra_fields.booking_field_${field.id}`);
44
-
45
- if (!validateValue || validateValue === '') {
46
- errors[field.id] = <FormattedMessage id="required" />;
47
- }
48
- } else {
49
- const validateValue = byString(values, field.id);
50
-
51
- if (!validateValue || validateValue === '') {
52
- errors[field.id] = <FormattedMessage id="required" />;
53
- }
54
- }
55
- }
56
- }
57
-
58
- if (values.adults < 1) {
59
- errors.adults = <FormattedMessage id="at_least_1_adult" />;
60
- }
61
- if (Number(values.discount) > 0 && !values.discount_reason) {
62
- errors.discount_reason = (
63
- <FormattedMessage id="you_need_to_give_reason" />
64
- );
65
- }
66
- if (values.persons > persons) {
67
- errors.max_persons = <FormattedMessage id="max_persons_reached" />;
68
- }
69
-
70
- if (
71
- values.cancel_insurance !== 0 &&
72
- validateAge(values.extra_fields?.date_of_birth)
73
- ) {
74
- errors['extra_fields.date_of_birth'] = (
75
- <FormattedMessage id="at_least_18y_old" />
76
- );
77
- errors['insurances'] = (
78
- <FormattedMessage id="at_least_18y_old" />
79
- );
80
- }
81
-
82
- if (
83
- values.cancel_insurance !== 0 &&
84
- !includes(['nl', 'de', 'be'], values.country)
85
- ) {
86
- errors['insurances'] = (
87
- <FormattedMessage id="can_only_take_insurance_in_de_be_nl" />
88
- );
89
- errors['country'] = (
90
- <FormattedMessage id="can_only_take_insurance_in_de_be_nl" />
91
- );
92
- }
93
-
94
- return errors;
95
- };
96
-
97
- render() {
98
- const { bookingFields } = this.state;
99
-
100
- const { house, locale, PortalSite, options, booking } = this.props;
101
- const bookingPrice = house.booking_price;
102
-
103
- let costs = {};
104
-
105
- for (const val of bookingPrice.optional_house_costs) {
106
- costs[val.id] = '0';
107
- }
108
-
109
- const optBookingFieldsInitialized = initializeBookingFields(bookingFields);
110
-
111
- return (
112
- <Mutation mutation={CREATE_BOOKING_MUTATION}>
113
- {(createBooking, { loading, error, data }) => (
114
- <Formik
115
- validate={this.validate}
116
- initialValues={{
117
- ...booking,
118
- ...optBookingFieldsInitialized,
119
- costs,
120
- adults: booking.persons,
121
- children: 0,
122
- babies: 0,
123
- persons: 2,
124
- discount: 0,
125
- country: 'nl',
126
- }}
127
- onSubmit={(values, { setSubmitting }) => {
128
- let variables = {
129
- ...values,
130
- is_option: JSON.parse(values.is_option),
131
- house_code: values.objectCode,
132
- portal_code: values.portalCode,
133
- comment: values.comment || '',
134
- language: locale,
135
- locale: locale,
136
- country: values.country.toUpperCase(),
137
- adults: Number(values.adults),
138
- children: Number(values.children) || 0,
139
- babies: Number(values.babies) || 0,
140
- discount: Number(values.discount) || 0,
141
- damage_insurance: Number(values.damage_insurance) || 0,
142
- cancel_insurance: Number(values.cancel_insurance) || 0,
143
- travel_insurance: Number(values.travel_insurance) || 0,
144
- arrival_date: values.arrivalDate.date,
145
- departure_date: values.departureDate.date,
146
- costs: JSON.stringify(values.costs),
147
- extra_fields: JSON.stringify(values.extra_fields),
148
- };
149
-
150
- createBooking({ variables })
151
- .then(() => {
152
- if (
153
- options.bookingForm &&
154
- options.bookingForm.redirectUrl &&
155
- options.bookingForm.redirectUrl !== ''
156
- ) {
157
- window.location = options.bookingForm.redirectUrl;
158
- } else {
159
- setTimeout(() => {
160
- this.props.onReturn();
161
- }, 15000);
162
- }
163
- })
164
- .catch((err) => {});
165
- }}
166
- render={({ errors, touched, values, status, isSubmitting }) => (
167
- <Form className="form">
168
- {loading && <div className="return-message">Loading...</div>}
169
- {error && (
170
- <Modal show={true}>
171
- <ApiError errors={error} modal={true} />
172
- </Modal>
173
- )}
174
- {data && (
175
- <Modal show={true}>
176
- <SuccessMessage />
177
- </Modal>
178
- )}
179
-
180
- <div className="form-content">
181
- <div className="form-section">
182
- <a
183
- className="return-link"
184
- role="link"
185
- tabIndex={0}
186
- onKeyPress={() => {
187
- this.props.onReturn();
188
- }}
189
- onClick={() => {
190
- this.props.onReturn();
191
- }}
192
- >
193
- <FormattedMessage id="return_to_calendar" />
194
- </a>
195
- <h2>
196
- <FormattedMessage id="stay_details" />
197
- </h2>
198
- <Guests options={options} house={house} />
199
-
200
- {errors.max_persons && (
201
- <div className="error-message persons">
202
- {errors.max_persons}
203
- </div>
204
- )}
205
- </div>
206
- <Discount errors={errors} house={house} options={options} values={values} />
207
-
208
- <Insurances house={house} values={values} />
209
-
210
- <OptionalCosts costs={bookingPrice.optional_house_costs} />
211
-
212
- <OptionalBookingFields
213
- bookingFields={bookingFields}
214
- errors={errors}
215
- touched={touched}
216
- PortalSite={PortalSite}
217
- values={values}
218
- />
219
- </div>
220
-
221
- <div className="form-sum">
222
- <Summary house={house} values={values} />
223
- {status && status.msg && <div>{status.msg}</div>}
224
- <div className="terms">
225
- <FormattedMessage id="agree_with" />{' '}
226
- <FormattedMessage id="terms">
227
- {(fm) => (
228
- <Modal buttonText={fm}>
229
- <div
230
- style={{
231
- width: '90vh',
232
- height: '90vh',
233
- }}
234
- >
235
- <iframe
236
- src={house.rental_terms}
237
- width="100%"
238
- height="100%"
239
- title="Terms"
240
- frameBorder="0"
241
- />
242
- </div>
243
- </Modal>
244
- )}
245
- </FormattedMessage>
246
- </div>
247
- {includes([1, 2], Number(values.cancel_insurance)) ? (
248
- <div className="terms">
249
- <FormattedMessage id="comply_insurance_card" />
250
- </div>
251
- ) : null}
252
- <button
253
- className="button"
254
- type="submit"
255
- disabled={isSubmitting}
256
- >
257
- <FormattedMessage id="book" />
258
- </button>
259
- </div>
260
- </Form>
261
- )}
262
- />
263
- )}
264
- </Mutation>
265
- );
266
- }
267
- }
268
-
269
- FormCreator.propTypes = {
270
- house: PropTypes.object.isRequired,
271
- options: PropTypes.object.isRequired,
272
- locale: PropTypes.string.isRequired,
273
- booking: PropTypes.object.isRequired,
274
- PortalSite: PropTypes.object.isRequired,
275
- onReturn: PropTypes.func.isRequired,
276
- };
277
-
278
- export default FormCreator;
File without changes
@@ -1,203 +0,0 @@
1
- import React, { Component } from 'react';
2
- import PropTypes from 'prop-types';
3
- import { Query } from '@apollo/client/react/components';
4
- import { gql} from "@apollo/client";
5
- import Loading from '../icons/loading.svg';
6
- import format from '../../_lib/format';
7
- import { FormattedMessage, FormattedNumber } from 'react-intl';
8
- import { createPeronsArray } from './formParts/BookingHelpers';
9
- import { ApiError } from '../Error';
10
-
11
- const dateFormat = 'dddd DD MMMM YYYY';
12
-
13
- export const CALENDAR_QUERY = gql`
14
- query BookingPriceQuery(
15
- $id: ID!
16
- $house_id: String!
17
- $starts_at: Date!
18
- $ends_at: Date!
19
- $persons: Int
20
- ) {
21
- PortalSite(id: $id) {
22
- houses(house_code: $house_id) {
23
- id
24
- name
25
- booking_price(
26
- starts_at: $starts_at
27
- ends_at: $ends_at
28
- persons: $persons
29
- )
30
- }
31
- }
32
- }
33
- `;
34
- class PriceField extends Component {
35
- state = {
36
- persons: 2,
37
- };
38
-
39
- setPersons(persons) {
40
- this.setState({ persons: persons });
41
- }
42
-
43
- render() {
44
- const {
45
- portalCode,
46
- objectCode,
47
- startsAt,
48
- endsAt,
49
- locale,
50
- house,
51
- disabled,
52
- onStartBooking,
53
- minNights,
54
- } = this.props;
55
- const { persons } = this.state;
56
-
57
- let adults = createPeronsArray(house.persons);
58
-
59
- return (
60
- <div className="calendar--picker">
61
- <div className="calendar--picker--date">
62
- <span className="name">
63
- <FormattedMessage id={`${house.house_type}.arrival`} />
64
- </span>
65
- <span className="detail">
66
- {startsAt ? (
67
- <span>{format(startsAt, dateFormat)}</span>
68
- ) : (
69
- <FormattedMessage
70
- id={`${house.house_type}.pick_your_arrivaldate_in_the_calendar`}
71
- />
72
- )}
73
- </span>
74
- </div>
75
- <div className="calendar--picker--date">
76
- <span className="name">
77
- <FormattedMessage id={`${house.house_type}.departure`} />
78
- </span>
79
- <span className="detail">
80
- {endsAt ? (
81
- <span>{format(endsAt, dateFormat)}</span>
82
- ) : (
83
- <div>
84
- <div>
85
- <FormattedMessage
86
- id={`${house.house_type}.pick_your_departure_in_the_calendar`}
87
- />
88
- </div>
89
- {minNights && (
90
- <FormattedMessage
91
- id="minimum_nights"
92
- defaultMessage="Minimum {minimum} nights"
93
- values={{ minimum: minNights }}
94
- />
95
- )}
96
- </div>
97
- )}
98
- </span>
99
- </div>
100
- <div className="calendar--picker--date">
101
- <span className="detail">
102
- <select
103
- className="calendar--picker--persons"
104
- value={persons}
105
- onChange={(e) => {
106
- this.setPersons(e.target.value);
107
- }}
108
- >
109
- {adults.map((person) => (
110
- <FormattedMessage
111
- id="persons"
112
- key={person}
113
- children={(text) => (
114
- <option value={person} key={person}>
115
- {person} {text}
116
- </option>
117
- )}
118
- />
119
- ))}
120
- </select>
121
- </span>
122
- </div>
123
- <div className="calendar--picker--date">
124
- {startsAt && endsAt && (
125
- <Query
126
- query={CALENDAR_QUERY}
127
- variables={{
128
- id: portalCode,
129
- house_id: objectCode,
130
- starts_at: startsAt,
131
- ends_at: endsAt,
132
- persons: parseInt(persons),
133
- locale: locale,
134
- }}
135
- >
136
- {({ loading, data, error }) => {
137
- if (loading)
138
- return (
139
- <div className="price-overview--build">
140
- <Loading />
141
- </div>
142
- );
143
- if (error) {
144
- return (
145
- <div className="price-overview--build">
146
- <ApiError errors={error}></ApiError>
147
- </div>
148
- );
149
- }
150
- const result = data.PortalSite.houses[0].booking_price;
151
- return (
152
- <>
153
- <div className="price-overview--book">
154
- <div className="price">
155
- €{' '}
156
- <FormattedNumber
157
- value={Math.round(result.total_price)}
158
- minimumFractionDigits={2}
159
- maximumFractionDigits={2}
160
- />
161
- </div>
162
- <div>
163
- <i>
164
- <FormattedMessage
165
- id="based_on_one_person"
166
- values={{ persons }}
167
- />
168
- </i>
169
- </div>
170
- </div>
171
- </>
172
- );
173
- }}
174
- </Query>
175
- )}
176
- </div>
177
- <button
178
- className="button"
179
- disabled={!disabled}
180
- onClick={() => {
181
- if (startsAt && endsAt) {
182
- onStartBooking('false', persons);
183
- }
184
- }}
185
- >
186
- <FormattedMessage id="calculate" />
187
- </button>
188
- </div>
189
- );
190
- }
191
- }
192
-
193
- PriceField.propTypes = {
194
- portalCode: PropTypes.string.isRequired,
195
- objectCode: PropTypes.string.isRequired,
196
- startsAt: PropTypes.string,
197
- endsAt: PropTypes.string,
198
- onStartBooking: PropTypes.func.isRequired,
199
- locale: PropTypes.string.isRequired,
200
- minNights: PropTypes.number,
201
- };
202
-
203
- export default PriceField;
@@ -1,22 +0,0 @@
1
- import React from "react";
2
- import Icon from "../../icons/info.svg";
3
- import Modal from "../../Modal";
4
-
5
- function Description({description}) {
6
- let val = <span />;
7
- if (description) {
8
- val = (
9
- <span style={{
10
- padding: "0 0 0 8px"
11
- }}>
12
- <Modal buttonText={<Icon />}>
13
- <p>{description}</p>
14
- </Modal>
15
- </span>
16
- );
17
- }
18
- return val;
19
- }
20
-
21
-
22
- export default Description;