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
|
@@ -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
|
-
|
|
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)
|
|
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
|
-
|
|
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
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
-
|
|
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}
|
|
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
|
-
|
|
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
|
-
|
|
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;
|
|
@@ -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
|
-
|
|
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>
|
package/src/components/CalendarPage/formParts/{OptionalBookingFields.js → OptionalBookingFields.tsx}
RENAMED
|
File without changes
|
|
@@ -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
|
-
!
|
|
20
|
+
!['none', 'total'].includes(cost.method) &&
|
|
22
21
|
cost.max_available > 0
|
|
23
22
|
) {
|
|
24
23
|
if (cost.max_available === 1) {
|
|
File without changes
|