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.
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
@@ -0,0 +1,59 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { FormattedMessage } from 'react-intl';
4
+ import {
5
+ FormatIntl,
6
+ LONG_DATE_FORMAT,
7
+ Parse_EN_US
8
+ } from '../../../_lib/date_helper';
9
+ import { HouseType } from '../../../types';
10
+ import { PossibleValues } from '../formParts/form_types';
11
+
12
+ interface Props {
13
+ house: HouseType;
14
+ values: PossibleValues;
15
+ }
16
+
17
+ export const Object = ({ house, values }: Props): React.ReactNode => {
18
+ const { arrivalDate, departureDate } = values;
19
+ return (
20
+ <React.Fragment>
21
+ <h2>
22
+ <FormattedMessage id="booking_details" />
23
+ </h2>
24
+ <div className="house-details">
25
+ <div>{house.name}</div>
26
+ <img src={house.image_url} alt="" />
27
+ <table>
28
+ <tbody>
29
+ <tr>
30
+ <th>
31
+ <FormattedMessage id={`${house.house_type}.arrival`} />
32
+ </th>
33
+ <td className="price">
34
+ {FormatIntl(Parse_EN_US(arrivalDate.date), LONG_DATE_FORMAT)}
35
+ </td>
36
+ <td>
37
+ {arrivalDate.arrival_time_from} - {arrivalDate.arrival_time_to}
38
+ </td>
39
+ </tr>
40
+ <tr>
41
+ <th>
42
+ <FormattedMessage id={`${house.house_type}.departure`} />
43
+ </th>
44
+ <td className="price">
45
+ {FormatIntl(Parse_EN_US(departureDate.date), LONG_DATE_FORMAT)}
46
+ </td>
47
+ <td>{departureDate.departure_time}</td>
48
+ </tr>
49
+ </tbody>
50
+ </table>
51
+ </div>
52
+ </React.Fragment>
53
+ );
54
+ };
55
+
56
+ Object.propTypes = {
57
+ house: PropTypes.object.isRequired,
58
+ values: PropTypes.object.isRequired
59
+ };
@@ -2,8 +2,13 @@ import React from 'react';
2
2
  import CostRow from './CostRow';
3
3
  import OptionalOnSite from './OptionalOnSite';
4
4
  import { FormattedMessage } from 'react-intl';
5
+ import { PricesType } from './cost_types';
5
6
 
6
- export default function OnSite({ prices }) {
7
+ interface Props {
8
+ prices: PricesType;
9
+ }
10
+
11
+ export default function OnSite({ prices }: Props): React.ReactNode {
7
12
  const { required_costs } = prices.total_costs;
8
13
  const { on_site } = required_costs;
9
14
  return (
@@ -16,15 +21,10 @@ export default function OnSite({ prices }) {
16
21
  {prices.required_house_costs.map((cost) => {
17
22
  if (cost.on_site && cost.gl !== '0120') {
18
23
  if (cost.method === 'none') {
19
- return (
20
- <CostRow key={cost.id} {...cost} />
21
- );
24
+ return <CostRow key={cost.id} {...cost} />;
22
25
  } else {
23
- let amount = on_site.find((x) => x.id == cost.id).amount
24
- return (
25
- <CostRow key={cost.id} {...cost} amount={amount} />
26
-
27
- );
26
+ let amount = on_site.find((x) => x.id == cost.id)?.amount;
27
+ return <CostRow key={cost.id} {...cost} amount={amount} />;
28
28
  }
29
29
  }
30
30
  })}
@@ -1,37 +1,38 @@
1
1
  import React from 'react';
2
2
  import CostRow from './CostRow';
3
+ import { PricesType } from './cost_types';
3
4
 
4
- export default function OptionalNotOnSite({ prices }) {
5
+ interface Props {
6
+ prices: PricesType;
7
+ }
8
+
9
+ export default function OptionalNotOnSite({ prices }: Props): JSX.Element {
5
10
  const { optional_costs } = prices.total_costs;
6
11
  const { not_on_site } = optional_costs;
7
12
  return (
8
13
  <div className="costs-section">
9
14
  <table>
10
- <tbody>
15
+ <tbody>
11
16
  {prices.optional_house_costs.map((cost) => {
12
17
  if (!cost.on_site && cost.gl !== '0120') {
13
18
  if (cost.method === 'none') {
14
- return (
15
- <CostRow key={cost.id} {...cost} />
16
- );
19
+ return <CostRow key={cost.id} {...cost} />;
17
20
  } else if (cost.method === 'on_site') {
18
21
  if (not_on_site.find((x) => x.id == cost.id).nr_of_items > 0) {
19
- return (
20
- <CostRow key={cost.id} {...cost} amount={cost.amount} forceMethod={true} />
21
- );
22
- }
23
- } else {
24
- let amount = not_on_site.find((x) => x.id == cost.id).amount
25
- if (amount > 0) {
26
-
27
22
  return (
28
23
  <CostRow
29
- key={cost.id}
30
- {...cost}
31
- amount={amount}
24
+ key={cost.id}
25
+ {...cost}
26
+ amount={cost.amount}
27
+ forceMethod={true}
32
28
  />
33
- )
34
- }
29
+ );
30
+ }
31
+ } else {
32
+ let amount = not_on_site.find((x) => x.id == cost.id).amount;
33
+ if (amount > 0) {
34
+ return <CostRow key={cost.id} {...cost} amount={amount} />;
35
+ }
35
36
  }
36
37
  }
37
38
  })}
@@ -1,7 +1,12 @@
1
1
  import React from 'react';
2
2
  import CostRow from './CostRow';
3
+ import { PricesType } from './cost_types';
3
4
 
4
- export default function OptionalOnSite({ prices }) {
5
+ interface Props {
6
+ prices: PricesType;
7
+ }
8
+
9
+ export default function OptionalOnSite({ prices }: Props): JSX.Element {
5
10
  const { optional_costs } = prices.total_costs;
6
11
  const { on_site } = optional_costs;
7
12
  return (
@@ -1,6 +1,6 @@
1
- import { gql} from "@apollo/client";
1
+ import { gql } from '@apollo/client';
2
2
 
3
- export const BOOKING_PRICE_TOTAL_QUERY= gql`
3
+ export const BOOKING_PRICE_TOTAL_QUERY = gql`
4
4
  query BookingPriceTotalQuery(
5
5
  $id: ID!
6
6
  $house_id: String!
@@ -28,4 +28,4 @@ export const BOOKING_PRICE_TOTAL_QUERY= gql`
28
28
  }
29
29
  }
30
30
  }
31
- `
31
+ `;
@@ -0,0 +1,30 @@
1
+ import React from 'react';
2
+ import CostRow from './CostRow';
3
+ import { PricesType } from './cost_types';
4
+
5
+ interface Props {
6
+ prices: PricesType;
7
+ }
8
+
9
+ export default function RentAndDiscount({ prices }: Props): JSX.Element {
10
+ const { rent_price, discount, discounted_price } = prices;
11
+ return (
12
+ <div className="costs-section">
13
+ <table>
14
+ <tbody>
15
+ <CostRow name="rent_price" formatName={true} amount={rent_price} />
16
+ {discount > 0 ? (
17
+ <>
18
+ <CostRow name="discount" formatName={true} amount={discount} />
19
+ <CostRow
20
+ name="price_after_discount"
21
+ formatName={true}
22
+ amount={discounted_price}
23
+ />
24
+ </>
25
+ ) : null}
26
+ </tbody>
27
+ </table>
28
+ </div>
29
+ );
30
+ }
@@ -2,8 +2,13 @@ import React from 'react';
2
2
  import CostRow from './CostRow';
3
3
  import CostSection from './CostSection';
4
4
  import { FormattedMessage, FormattedNumber } from 'react-intl';
5
+ import { PricesType } from './cost_types';
5
6
 
6
- function Totals({ prices }) {
7
+ interface Props {
8
+ prices: PricesType;
9
+ }
10
+
11
+ function Totals({ prices }: Props): JSX.Element {
7
12
  return (
8
13
  <>
9
14
  <CostSection>
@@ -11,7 +16,7 @@ function Totals({ prices }) {
11
16
  <th
12
17
  style={{
13
18
  textAlign: 'left',
14
- testTransform: 'capitalize',
19
+ testTransform: 'capitalize'
15
20
  }}
16
21
  >
17
22
  <FormattedMessage id="total" />
@@ -49,7 +54,7 @@ function Totals({ prices }) {
49
54
  <th
50
55
  style={{
51
56
  textAlign: 'left',
52
- testTransform: 'capitalize',
57
+ testTransform: 'capitalize'
53
58
  }}
54
59
  >
55
60
  <FormattedMessage id="total" />
@@ -0,0 +1,31 @@
1
+ export type CostType = {
2
+ on_site: boolean;
3
+ gl: string;
4
+ method: string;
5
+ id: number;
6
+ amount: number;
7
+ name: string;
8
+ };
9
+
10
+ export type PricesType = {
11
+ total_costs: {
12
+ sub_total: number;
13
+ total_price: number;
14
+ insurances: {
15
+ cancel_insurance: number;
16
+ };
17
+ required_costs: {
18
+ not_on_site: CostType[];
19
+ on_site: CostType[];
20
+ };
21
+ optional_costs: {
22
+ not_on_site: CostType[];
23
+ on_site: CostType[];
24
+ };
25
+ };
26
+ optional_house_costs: CostType[];
27
+ required_house_costs: CostType[];
28
+ rent_price: number;
29
+ discount: number;
30
+ discounted_price: number;
31
+ };
@@ -0,0 +1,24 @@
1
+ import React from 'react';
2
+ import { HouseType } from '../../../types';
3
+
4
+ import BookingOrOption from '../formParts/BookingOrOption';
5
+ import { PossibleValues } from '../formParts/form_types';
6
+ import CostSummary from './CostSummary';
7
+ import { Object } from './Object';
8
+
9
+ interface Props {
10
+ values: PossibleValues;
11
+ house: HouseType;
12
+ }
13
+
14
+ function Summary({ values, house }: Props): React.ReactNode {
15
+ return (
16
+ <div>
17
+ <Object house={house} values={values} />
18
+ <BookingOrOption house={house} />
19
+ <CostSummary values={values} house={house} />
20
+ </div>
21
+ );
22
+ }
23
+
24
+ export default Summary;
@@ -0,0 +1,16 @@
1
+ import { BuDate } from '../../types';
2
+
3
+ export type DatesType = {
4
+ arrivalDate: BuDate;
5
+ selectedDate: Date;
6
+ departureDate: BuDate;
7
+ startBooking: Boolean;
8
+ };
9
+
10
+ export type BookingType = {
11
+ arrivalDate: BuDate | null;
12
+ departureDate: BuDate | null;
13
+ selectedDate: Date | null;
14
+ bookingStarted: boolean;
15
+ persons: number;
16
+ };
@@ -0,0 +1,60 @@
1
+ import React, { useContext } from 'react';
2
+ import { FormattedMessage } from 'react-intl';
3
+ import { HouseType } from '../../../types';
4
+ import {
5
+ FormatIntl,
6
+ LONG_DATE_FORMAT,
7
+ Parse_EN_US
8
+ } from '../../../_lib/date_helper';
9
+ import { CalendarContext } from '../CalendarParts/CalendarContext';
10
+
11
+ interface Props {
12
+ house: HouseType;
13
+ }
14
+
15
+ function AssistanceMessage({ house }: Props): JSX.Element {
16
+ const { departureDate, arrivalDate } = useContext(CalendarContext);
17
+
18
+ if (departureDate?.date) {
19
+ return (
20
+ <div className="assistance">
21
+ <FormattedMessage id={`${house.house_type}.you_picked_arrival_date`} />:{' '}
22
+ {FormatIntl(Parse_EN_US(arrivalDate.date), LONG_DATE_FORMAT)}
23
+ <br />
24
+ <FormattedMessage
25
+ id={`${house.house_type}.you_picked_departure_date`}
26
+ />
27
+ : {FormatIntl(Parse_EN_US(departureDate.date), LONG_DATE_FORMAT)}
28
+ </div>
29
+ );
30
+ }
31
+
32
+ if (arrivalDate?.date) {
33
+ return (
34
+ <div className="assistance">
35
+ <FormattedMessage id={`${house.house_type}.you_picked_arrival_date`} />:{' '}
36
+ {FormatIntl(Parse_EN_US(arrivalDate.date), LONG_DATE_FORMAT)}
37
+ <br />
38
+ <FormattedMessage
39
+ id={`${house.house_type}.pick_your_departure_in_the_calendar`}
40
+ />
41
+ <br />
42
+ <FormattedMessage
43
+ id="minimum_nights"
44
+ values={{ minimum: arrivalDate.min_nights }}
45
+ defaultMessage="Minimum {minimum} nights"
46
+ />
47
+ </div>
48
+ );
49
+ }
50
+
51
+ return (
52
+ <div className="assistance">
53
+ <FormattedMessage
54
+ id={`${house.house_type}.pick_your_arrivaldate_in_the_calendar`}
55
+ />
56
+ </div>
57
+ );
58
+ }
59
+
60
+ export default AssistanceMessage;
@@ -2,11 +2,11 @@ import { subYears, isAfter } from 'date-fns'
2
2
  import React from 'react'
3
3
  import { FormattedMessage } from 'react-intl';
4
4
 
5
- export function createPeronsArray(persons) {
5
+ export function createPeronsArray(persons: number): number[] {
6
6
  return Array.apply(null, { length: persons + 1 }).map(Number.call, Number);
7
7
  }
8
8
 
9
- export function initializeBookingFields(bookingFields) {
9
+ export function initializeBookingFields(bookingFields: any[]) {
10
10
  let obj = {};
11
11
  bookingFields.map((field) => {
12
12
  obj[field.id] = '';
@@ -29,7 +29,7 @@ export function byString(o, s) {
29
29
  return o;
30
30
  }
31
31
 
32
- export function translatedOption(id, value) {
32
+ export function translatedOption(id:string, value: string):JSX.Element {
33
33
  return (
34
34
  <FormattedMessage id={id}>
35
35
  {(formattedMessage) => <option value={value}>{formattedMessage}</option>}
@@ -2,8 +2,13 @@ import React from 'react';
2
2
  import { RadioButtonGroup, RadioButton } from './radioButtons';
3
3
  import { Field } from 'formik';
4
4
  import { FormattedMessage } from 'react-intl';
5
+ import { HouseType } from '../../../types';
5
6
 
6
- export default function BookingOrOption({ house, ...props }) {
7
+ interface Props {
8
+ house: HouseType;
9
+ }
10
+
11
+ export default function BookingOrOption({ house }: Props): JSX.Element {
7
12
  return (
8
13
  <>
9
14
  {house.allow_option && (
@@ -0,0 +1,105 @@
1
+ import React, { useContext } from 'react';
2
+ import { FormattedMessage as FM } from 'react-intl';
3
+ import { AppContext } from '../../AppContext';
4
+
5
+ type localeObject = {
6
+ nl: string;
7
+ de: string;
8
+ en: string;
9
+ es: string;
10
+ it: string;
11
+ fr: string;
12
+ };
13
+
14
+ const LocalizedAttachment: localeObject = {
15
+ nl: 'https://insurances.bukazu.com/nl/Voorwaarden%20Annuleringsverzekering.pdf',
16
+ de: 'https://insurances.bukazu.com/de/Bedingungen%20Reiseruecktrittsversicherung.pdf',
17
+ en: 'https://insurances.bukazu.com/en/Terms%20to%20Cancellation%20Insurance.pdf',
18
+ es: 'https://insurances.bukazu.com/en/Terms%20to%20Cancellation%20Insurance.pdf',
19
+ it: 'https://insurances.bukazu.com/en/Terms%20to%20Cancellation%20Insurance.pdf',
20
+ fr: 'https://insurances.bukazu.com/en/Terms%20to%20Cancellation%20Insurance.pdf'
21
+ };
22
+
23
+ const CancelInsuranceText = () => {
24
+ const { locale } = useContext(AppContext);
25
+
26
+ return (
27
+ <>
28
+ <h2>
29
+ <FM id="cancel_insurance" />
30
+ </h2>
31
+ <hr />
32
+ <p>
33
+ <FM id="cancel_insurance_desc" />
34
+ </p>
35
+ <h3>
36
+ <FM id="cancel_insurance_normal_long" />
37
+ </h3>
38
+ <p>
39
+ <FM id="cancel_insurance_normal_desc" />
40
+ </p>
41
+ <h3>
42
+ <FM id="cancel_insurance_all_risk_long" />
43
+ </h3>
44
+ <p>
45
+ <FM id="cancel_insurance_all_risk_desc" />
46
+ </p>
47
+
48
+ <h3>
49
+ <FM id="terms_and_costs" />
50
+ </h3>
51
+ <h4>
52
+ <FM id="costs_normal_cancel_insurance" />
53
+ </h4>
54
+ <p>
55
+ <FM id="666_costs" />
56
+ </p>
57
+ <h4>
58
+ <FM id="costs_allrisk_cancel_insurance" />
59
+ </h4>
60
+ <p>
61
+ <FM id="847_costs" />
62
+ </p>
63
+ <p>
64
+ <FM id="more_information" />
65
+ </p>
66
+ <a
67
+ href={LocalizedAttachment[locale]}
68
+ target="_blank"
69
+ rel="noopener noreferrer"
70
+ >
71
+ <FM id="show_terms" />
72
+ </a>
73
+ <h3>
74
+ <FM id="terms" />
75
+ </h3>
76
+ <ul>
77
+ <li>
78
+ <FM id="9persons_9addresses" />
79
+ </li>
80
+ <li>
81
+ <strong>
82
+ <FM id="or" />
83
+ </strong>
84
+ </li>
85
+ <li>
86
+ <FM id="9persons_4addresses" />
87
+ </li>
88
+ </ul>
89
+
90
+ <hr />
91
+ <h2>
92
+ <FM id="poliscosts" />
93
+ </h2>
94
+ <p>
95
+ <FM id="poliscosts_are" />
96
+ </p>
97
+
98
+ <p>
99
+ <FM id="youwillrecieve" />
100
+ </p>
101
+ </>
102
+ );
103
+ };
104
+
105
+ export default CancelInsuranceText;
@@ -1,4 +1,6 @@
1
- const DefaultBookingFields = [
1
+ import { BookingFieldsType } from "./form_types";
2
+
3
+ const DefaultBookingFields: BookingFieldsType = [
2
4
  {
3
5
  id: 'first_name',
4
6
  label: 'Voornaam',
@@ -0,0 +1,62 @@
1
+ import React, { ReactNode } from 'react';
2
+ import { Field } from 'formik';
3
+ import { FormattedMessage } from 'react-intl';
4
+ import { gql, useMutation } from '@apollo/client';
5
+ import { HouseType } from '../../../types';
6
+
7
+ function DiscountCode({ house }: { house: HouseType }): ReactNode {
8
+ const [checkCode, { loading, error, data }] =
9
+ useMutation(CHECK_DISCOUNT_CODE);
10
+
11
+ return (
12
+ <div className="form-row inline">
13
+ <label htmlFor="discount_code">
14
+ <FormattedMessage id="discount_code" />
15
+ </label>
16
+ <Field name="discount_code">
17
+ {({ field, form }) => {
18
+ return (
19
+ <input
20
+ {...field}
21
+ onChange={(e) => {
22
+ checkCode({
23
+ variables: { code: e.target.value, house_code: house.code }
24
+ });
25
+ form.setFieldValue(field.name, e.target.value);
26
+ }}
27
+ ></input>
28
+ );
29
+ }}
30
+ </Field>
31
+ {loading && <div className="bu_discount_code">Loading...</div>}
32
+ {error && (
33
+ <div className="bu_discount_code">
34
+ <FormattedMessage id="no_discount_code_found" />
35
+ </div>
36
+ )}
37
+ {data && (
38
+ <div className="bu_discount_code">
39
+ <div>{data.checkDiscountCode.name}</div>
40
+ {data.checkDiscountCode.use_price ? (
41
+ <div>€ {data.checkDiscountCode.price}</div>
42
+ ) : (
43
+ <div>{data.checkDiscountCode.percentage}%</div>
44
+ )}
45
+ </div>
46
+ )}
47
+ </div>
48
+ );
49
+ }
50
+
51
+ const CHECK_DISCOUNT_CODE = gql`
52
+ mutation CheckDiscountCode($code: String!, $house_code: String!) {
53
+ checkDiscountCode(code: $code, house_code: $house_code) {
54
+ name
55
+ use_price
56
+ percentage
57
+ price
58
+ }
59
+ }
60
+ `;
61
+
62
+ export default DiscountCode;
@@ -1,8 +1,14 @@
1
1
  import React from 'react';
2
2
  import { NumberSelect } from '../FormItems';
3
3
  import { FormattedMessage } from 'react-intl';
4
+ import { HouseType, PortalOptions } from '../../../types';
4
5
 
5
- export default function Guests({ options, house }) {
6
+ interface Props {
7
+ options: PortalOptions;
8
+ house: HouseType;
9
+ }
10
+
11
+ export default function Guests({ options, house }: Props): React.ReactNode {
6
12
  return (
7
13
  <>
8
14
  <NumberSelect
@@ -17,7 +23,7 @@ export default function Guests({ options, house }) {
17
23
  values={{
18
24
  age: options.bookingForm
19
25
  ? options.bookingForm.adults_from || '18'
20
- : '18',
26
+ : '18'
21
27
  }}
22
28
  />
23
29
  </div>
@@ -39,7 +45,7 @@ export default function Guests({ options, house }) {
39
45
  : '3',
40
46
  til: options.bookingForm
41
47
  ? options.bookingForm.children_til || '17'
42
- : '17',
48
+ : '17'
43
49
  }}
44
50
  />
45
51
  </div>
@@ -59,7 +65,7 @@ export default function Guests({ options, house }) {
59
65
  values={{
60
66
  babies: options.bookingForm
61
67
  ? options.bookingForm.babies_til || '2'
62
- : '2',
68
+ : '2'
63
69
  }}
64
70
  />
65
71
  </div>
@@ -2,7 +2,6 @@ import React from 'react';
2
2
  import { Field } from 'formik';
3
3
  import {FormattedMessage, FormattedNumber } from 'react-intl'
4
4
  import Modal from '../../Modal'
5
- import includes from "array-includes";
6
5
  import Icon from "../../icons/info.svg";
7
6
  import { createPeronsArray } from './BookingHelpers'
8
7
 
@@ -18,7 +17,7 @@ function OptionalCosts({ costs }) {
18
17
  <div>
19
18
  {costs.map((cost) => {
20
19
  if (
21
- !includes(['none', 'total'], cost.method) &&
20
+ !['none', 'total'].includes(cost.method) &&
22
21
  cost.max_available > 0
23
22
  ) {
24
23
  if (cost.max_available === 1) {