@duffel/components 3.1.3--prototype.4 → 3.1.3--prototype.7
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/{react-dist/custom-elements.js → custom-elements.js} +2 -2
- package/{react-dist/custom-elements.js.map → custom-elements.js.map} +1 -1
- package/{react-dist/index.js → index.js} +2 -2
- package/{react-dist/index.js.map → index.js.map} +1 -1
- package/package.json +3 -3
- package/scripts/generate-fixture.d.ts +3 -0
- package/scripts/setup-suggestion-data.d.ts +28 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/.circleci/config.yml +0 -67
- package/.eslintrc.js +0 -47
- package/.github/CODEOWNERS +0 -4
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -29
- package/.github/renovate.json +0 -12
- package/.nvmrc +0 -1
- package/.prettierignore +0 -6
- package/.storybook/main.ts +0 -33
- package/.storybook/preview.tsx +0 -28
- package/.tool-versions +0 -1
- package/.vscode/extensions.json +0 -7
- package/.vscode/settings.json +0 -10
- package/.yarn/releases/yarn-4.0.1.cjs +0 -893
- package/.yarn/sdks/eslint/bin/eslint.js +0 -20
- package/.yarn/sdks/eslint/lib/api.js +0 -20
- package/.yarn/sdks/eslint/lib/unsupported-api.js +0 -20
- package/.yarn/sdks/eslint/package.json +0 -14
- package/.yarn/sdks/integrations.yml +0 -5
- package/.yarn/sdks/prettier/bin-prettier.js +0 -20
- package/.yarn/sdks/prettier/index.js +0 -20
- package/.yarn/sdks/prettier/package.json +0 -7
- package/.yarn/sdks/typescript/bin/tsc +0 -20
- package/.yarn/sdks/typescript/bin/tsserver +0 -20
- package/.yarn/sdks/typescript/lib/tsc.js +0 -20
- package/.yarn/sdks/typescript/lib/tsserver.js +0 -225
- package/.yarn/sdks/typescript/lib/tsserverlibrary.js +0 -225
- package/.yarn/sdks/typescript/lib/typescript.js +0 -20
- package/.yarn/sdks/typescript/package.json +0 -10
- package/.yarnrc.yml +0 -3
- package/CONTRIBUTING.md +0 -83
- package/README.md +0 -68
- package/__mocks__/styleMock.js +0 -6
- package/babel.config.js +0 -20
- package/commitlint.config.js +0 -4
- package/config/esbuild.base.config.js +0 -18
- package/config/esbuild.cdn.config.js +0 -51
- package/config/esbuild.dev.config.js +0 -46
- package/config/esbuild.react.config.js +0 -42
- package/data/airports.csv +0 -9084
- package/data/cities.csv +0 -256
- package/jest.config.ts +0 -14
- package/scripts/build-and-publish.sh +0 -42
- package/scripts/generate-fixture.ts +0 -200
- package/scripts/setup-suggestion-data.ts +0 -100
- package/scripts/upload-to-cdn.sh +0 -34
- package/scripts.tsconfig.json +0 -11
- package/src/components/DuffelAncillaries/Card.tsx +0 -126
- package/src/components/DuffelAncillaries/Counter.tsx +0 -40
- package/src/components/DuffelAncillaries/DuffelAncillaries.tsx +0 -350
- package/src/components/DuffelAncillaries/DuffelAncillariesCustomElement.tsx +0 -124
- package/src/components/DuffelAncillaries/bags/BaggageSelectionCard.tsx +0 -101
- package/src/components/DuffelAncillaries/bags/BaggageSelectionController.tsx +0 -88
- package/src/components/DuffelAncillaries/bags/BaggageSelectionModal.tsx +0 -81
- package/src/components/DuffelAncillaries/bags/BaggageSelectionModalBody.tsx +0 -60
- package/src/components/DuffelAncillaries/bags/BaggageSelectionModalBodyPassenger.tsx +0 -122
- package/src/components/DuffelAncillaries/bags/BaggageSelectionModalFooter.tsx +0 -88
- package/src/components/DuffelAncillaries/bags/BaggageSelectionModalHeader.tsx +0 -82
- package/src/components/DuffelAncillaries/bags/IncludedBaggageBanner.tsx +0 -51
- package/src/components/DuffelAncillaries/cancel_for_any_reason/CfarSelectionCard.tsx +0 -90
- package/src/components/DuffelAncillaries/cancel_for_any_reason/CfarSelectionModal.tsx +0 -63
- package/src/components/DuffelAncillaries/cancel_for_any_reason/CfarSelectionModalBody.tsx +0 -56
- package/src/components/DuffelAncillaries/cancel_for_any_reason/CfarSelectionModalBodyListItem.tsx +0 -11
- package/src/components/DuffelAncillaries/cancel_for_any_reason/CfarSelectionModalFooter.tsx +0 -74
- package/src/components/DuffelAncillaries/cancel_for_any_reason/CfarSelectionModalHeader.tsx +0 -9
- package/src/components/DuffelAncillaries/seats/Amenity.tsx +0 -21
- package/src/components/DuffelAncillaries/seats/DeckSelect.tsx +0 -27
- package/src/components/DuffelAncillaries/seats/Element.tsx +0 -52
- package/src/components/DuffelAncillaries/seats/EmptyElement.tsx +0 -5
- package/src/components/DuffelAncillaries/seats/ExitElement.tsx +0 -17
- package/src/components/DuffelAncillaries/seats/Legend.tsx +0 -60
- package/src/components/DuffelAncillaries/seats/Row.tsx +0 -47
- package/src/components/DuffelAncillaries/seats/RowSection.tsx +0 -78
- package/src/components/DuffelAncillaries/seats/SeatElement.tsx +0 -120
- package/src/components/DuffelAncillaries/seats/SeatInfo.tsx +0 -32
- package/src/components/DuffelAncillaries/seats/SeatMap.tsx +0 -85
- package/src/components/DuffelAncillaries/seats/SeatMapUnavailable.tsx +0 -21
- package/src/components/DuffelAncillaries/seats/SeatSelectionCard.tsx +0 -103
- package/src/components/DuffelAncillaries/seats/SeatSelectionModal.tsx +0 -142
- package/src/components/DuffelAncillaries/seats/SeatSelectionModalBody.tsx +0 -13
- package/src/components/DuffelAncillaries/seats/SeatSelectionModalFooter.tsx +0 -89
- package/src/components/DuffelAncillaries/seats/SeatSelectionModalHeader.tsx +0 -97
- package/src/components/DuffelAncillaries/seats/SeatUnavailable.tsx +0 -14
- package/src/components/DuffelPayments/DuffelPayments.tsx +0 -224
- package/src/components/DuffelPayments/DuffelPaymentsCustomElement.tsx +0 -130
- package/src/components/PlacesLookup/PlacesLookup.tsx +0 -122
- package/src/components/shared/AnimatedLoaderEllipsis.tsx +0 -5
- package/src/components/shared/Button.tsx +0 -63
- package/src/components/shared/ErrorBoundary.tsx +0 -54
- package/src/components/shared/FetchOfferErrorState.tsx +0 -35
- package/src/components/shared/Icon.tsx +0 -151
- package/src/components/shared/IconButton.tsx +0 -42
- package/src/components/shared/Modal.tsx +0 -40
- package/src/components/shared/NonIdealState.tsx +0 -28
- package/src/components/shared/Stamp.tsx +0 -29
- package/src/components/shared/Tabs.tsx +0 -36
- package/src/custom-elements.ts +0 -13
- package/src/examples/client-side/README.md +0 -30
- package/src/examples/client-side/index.html +0 -57
- package/src/examples/full-stack/README.md +0 -34
- package/src/examples/full-stack/index.html +0 -48
- package/src/examples/full-stack/server.mjs +0 -158
- package/src/examples/just-typescript/.yarn/install-state.gz +0 -0
- package/src/examples/just-typescript/README.md +0 -37
- package/src/examples/just-typescript/package.json +0 -16
- package/src/examples/just-typescript/src/index.html +0 -23
- package/src/examples/just-typescript/src/index.ts +0 -36
- package/src/examples/just-typescript/yarn.lock +0 -467
- package/src/examples/next/README.md +0 -28
- package/src/examples/next/next-env.d.ts +0 -5
- package/src/examples/next/next.config.js +0 -4
- package/src/examples/next/package.json +0 -24
- package/src/examples/next/src/app/DuffelComponents.tsx +0 -40
- package/src/examples/next/src/app/layout.tsx +0 -18
- package/src/examples/next/src/app/page.tsx +0 -9
- package/src/examples/next/tsconfig.json +0 -27
- package/src/examples/next/yarn.lock +0 -257
- package/src/examples/payments-custom-element/README.md +0 -17
- package/src/examples/payments-custom-element/index.html +0 -43
- package/src/examples/payments-just-typescript/README.md +0 -37
- package/src/examples/payments-just-typescript/package.json +0 -16
- package/src/examples/payments-just-typescript/src/index.html +0 -23
- package/src/examples/payments-just-typescript/src/index.ts +0 -18
- package/src/examples/payments-just-typescript/yarn.lock +0 -154
- package/src/examples/react-app/README.md +0 -37
- package/src/examples/react-app/package.json +0 -20
- package/src/examples/react-app/src/index.html +0 -19
- package/src/examples/react-app/src/index.tsx +0 -48
- package/src/examples/react-app/yarn.lock +0 -219
- package/src/fixtures/offers/off_0000AUde3KwTztSRK1cznH.json +0 -497
- package/src/fixtures/offers/off_0000AVx4lUFFKW8PsPeQeQ.json +0 -307
- package/src/fixtures/offers/off_1.json +0 -488
- package/src/fixtures/passengers/mock_passengers.ts +0 -26
- package/src/fixtures/seat-maps/off_0000AUde3KwTztSRK1cznH.json +0 -6852
- package/src/fixtures/seat-maps/off_0000AVx4lUFFKW8PsPeQeQ.json +0 -1
- package/src/fixtures/seat-maps/off_1.json +0 -6852
- package/src/index.ts +0 -7
- package/src/lib/captureErrorInSentry.ts +0 -42
- package/src/lib/compileCreateOrderPayload.ts +0 -63
- package/src/lib/createPriceFormatters.ts +0 -73
- package/src/lib/fetchFromDuffelAPI.ts +0 -54
- package/src/lib/fetchFromFixtures.ts +0 -18
- package/src/lib/formatAvailableServices.ts +0 -91
- package/src/lib/formatDate.ts +0 -20
- package/src/lib/formatSeatMaps.ts +0 -81
- package/src/lib/getBaggageServiceDescription.ts +0 -39
- package/src/lib/getCabinsForSegmentAndDeck.ts +0 -4
- package/src/lib/getCurrencyForSeatMaps.ts +0 -22
- package/src/lib/getCurrencyForServices.ts +0 -24
- package/src/lib/getFirstSeatElementMatchingCriteria.ts +0 -22
- package/src/lib/getPassengerBySegmentList.ts +0 -10
- package/src/lib/getPassengerInitials.ts +0 -6
- package/src/lib/getPassengerMapById.ts +0 -17
- package/src/lib/getPassengerName.ts +0 -41
- package/src/lib/getRowNumber.ts +0 -16
- package/src/lib/getSegmentList.ts +0 -7
- package/src/lib/getServicePriceMapById.ts +0 -20
- package/src/lib/getSymbols.ts +0 -22
- package/src/lib/getTotalAmountForServices.ts +0 -72
- package/src/lib/getTotalQuantity.ts +0 -5
- package/src/lib/hasHighLuminance.ts +0 -9
- package/src/lib/hasService.ts +0 -24
- package/src/lib/hasServiceOfSameMetadataTypeAlreadyBeenSelected.ts +0 -35
- package/src/lib/hasWings.ts +0 -8
- package/src/lib/isBaggageService.ts +0 -8
- package/src/lib/isCancelForAnyReasonService.ts +0 -9
- package/src/lib/isFixtureOfferId.ts +0 -4
- package/src/lib/isPayloadComplete.ts +0 -11
- package/src/lib/isSeatElement.ts +0 -10
- package/src/lib/logging.ts +0 -120
- package/src/lib/moneyStringFormatter.ts +0 -34
- package/src/lib/offerIsExpired.ts +0 -5
- package/src/lib/retrieveOffer.ts +0 -56
- package/src/lib/retrieveOfferFromDuffelAPI.ts +0 -13
- package/src/lib/retrieveSeatMaps.ts +0 -55
- package/src/lib/retrieveSeatMapsFromDuffelAPI.ts +0 -13
- package/src/lib/setBodyScrollability.ts +0 -7
- package/src/lib/validateProps.ts +0 -37
- package/src/lib/withPlural.ts +0 -8
- package/src/stories/BaggageSelectionModalHeader.stories.tsx +0 -21
- package/src/stories/Button.stories.tsx +0 -91
- package/src/stories/DuffelAncillaries.stories.tsx +0 -166
- package/src/stories/DuffelPayments.stories.tsx +0 -34
- package/src/stories/Icon.stories.tsx +0 -35
- package/src/stories/IconButton.stories.tsx +0 -25
- package/src/stories/PlacesLookup.stories.tsx +0 -22
- package/src/styles/colors.css +0 -22
- package/src/styles/components/Amenity.css +0 -23
- package/src/styles/components/BaggageDisplay.css +0 -25
- package/src/styles/components/Button.css +0 -169
- package/src/styles/components/Card.css +0 -52
- package/src/styles/components/CfarSelectionModal.css +0 -34
- package/src/styles/components/Counter.css +0 -18
- package/src/styles/components/DuffelPayments.css +0 -42
- package/src/styles/components/IconButton.css +0 -63
- package/src/styles/components/Legend.css +0 -62
- package/src/styles/components/Loader.css +0 -37
- package/src/styles/components/LoadingState.css +0 -87
- package/src/styles/components/Modal.css +0 -84
- package/src/styles/components/PassengerSelect.css +0 -99
- package/src/styles/components/PassengersLayout.css +0 -90
- package/src/styles/components/PlacesLookup.css +0 -36
- package/src/styles/components/Row.css +0 -70
- package/src/styles/components/Seat.css +0 -59
- package/src/styles/components/SeatInfo.css +0 -61
- package/src/styles/components/SeatMap.css +0 -24
- package/src/styles/components/SeatSelect.css +0 -92
- package/src/styles/components/Segment.css +0 -17
- package/src/styles/components/SelectionSegment.css +0 -10
- package/src/styles/components/Summary.css +0 -70
- package/src/styles/components/Tabs.css +0 -52
- package/src/styles/flex.css +0 -5
- package/src/styles/font-families.css +0 -47
- package/src/styles/global.css +0 -52
- package/src/styles/margin.css +0 -3
- package/src/styles/spacing.css +0 -18
- package/src/styles/transitions.css +0 -3
- package/src/styles/typography.css +0 -13
- package/src/tests/components/DuffelAncillaries.test.tsx +0 -342
- package/src/tests/lib/createPriceFormatters.test.tsx +0 -152
- package/src/tests/lib/formatAvailableServices.test.tsx +0 -79
- package/src/tests/lib/formatSeatMaps.test.tsx +0 -49
- package/src/tests/lib/getCurrencyForServices.test.tsx +0 -44
- package/src/tests/lib/hasServiceOfSameMetadataTypeAlreadyBeenSelected.test.ts +0 -86
- package/src/tests/lib/logging.test.tsx +0 -32
- package/src/tests/lib/moneyStringFormatter.test.tsx +0 -12
- package/src/tests/lib/validateProps.test.tsx +0 -57
- package/src/types/Aircraft.ts +0 -16
- package/src/types/Airline.ts +0 -16
- package/src/types/Airport.ts +0 -54
- package/src/types/City.ts +0 -21
- package/src/types/CreateOrderPayload.ts +0 -99
- package/src/types/CurrencyConversion.ts +0 -10
- package/src/types/DuffelAncillariesProps.ts +0 -108
- package/src/types/Offer.ts +0 -851
- package/src/types/Order.ts +0 -6
- package/src/types/Place.ts +0 -6
- package/src/types/SeatMap.ts +0 -231
- package/src/types/index.ts +0 -11
- package/tsconfig.json +0 -58
- /package/{react-dist/components → components}/DuffelAncillaries/Card.d.ts +0 -0
- /package/{react-dist/components → components}/DuffelAncillaries/Counter.d.ts +0 -0
- /package/{react-dist/components → components}/DuffelAncillaries/DuffelAncillaries.d.ts +0 -0
- /package/{react-dist/components → components}/DuffelAncillaries/DuffelAncillariesCustomElement.d.ts +0 -0
- /package/{react-dist/components → components}/DuffelAncillaries/bags/BaggageSelectionCard.d.ts +0 -0
- /package/{react-dist/components → components}/DuffelAncillaries/bags/BaggageSelectionController.d.ts +0 -0
- /package/{react-dist/components → components}/DuffelAncillaries/bags/BaggageSelectionModal.d.ts +0 -0
- /package/{react-dist/components → components}/DuffelAncillaries/bags/BaggageSelectionModalBody.d.ts +0 -0
- /package/{react-dist/components → components}/DuffelAncillaries/bags/BaggageSelectionModalBodyPassenger.d.ts +0 -0
- /package/{react-dist/components → components}/DuffelAncillaries/bags/BaggageSelectionModalFooter.d.ts +0 -0
- /package/{react-dist/components → components}/DuffelAncillaries/bags/BaggageSelectionModalHeader.d.ts +0 -0
- /package/{react-dist/components → components}/DuffelAncillaries/bags/IncludedBaggageBanner.d.ts +0 -0
- /package/{react-dist/components → components}/DuffelAncillaries/cancel_for_any_reason/CfarSelectionCard.d.ts +0 -0
- /package/{react-dist/components → components}/DuffelAncillaries/cancel_for_any_reason/CfarSelectionModal.d.ts +0 -0
- /package/{react-dist/components → components}/DuffelAncillaries/cancel_for_any_reason/CfarSelectionModalBody.d.ts +0 -0
- /package/{react-dist/components → components}/DuffelAncillaries/cancel_for_any_reason/CfarSelectionModalBodyListItem.d.ts +0 -0
- /package/{react-dist/components → components}/DuffelAncillaries/cancel_for_any_reason/CfarSelectionModalFooter.d.ts +0 -0
- /package/{react-dist/components → components}/DuffelAncillaries/cancel_for_any_reason/CfarSelectionModalHeader.d.ts +0 -0
- /package/{react-dist/components → components}/DuffelAncillaries/seats/Amenity.d.ts +0 -0
- /package/{react-dist/components → components}/DuffelAncillaries/seats/DeckSelect.d.ts +0 -0
- /package/{react-dist/components → components}/DuffelAncillaries/seats/Element.d.ts +0 -0
- /package/{react-dist/components → components}/DuffelAncillaries/seats/EmptyElement.d.ts +0 -0
- /package/{react-dist/components → components}/DuffelAncillaries/seats/ExitElement.d.ts +0 -0
- /package/{react-dist/components → components}/DuffelAncillaries/seats/Legend.d.ts +0 -0
- /package/{react-dist/components → components}/DuffelAncillaries/seats/Row.d.ts +0 -0
- /package/{react-dist/components → components}/DuffelAncillaries/seats/RowSection.d.ts +0 -0
- /package/{react-dist/components → components}/DuffelAncillaries/seats/SeatElement.d.ts +0 -0
- /package/{react-dist/components → components}/DuffelAncillaries/seats/SeatInfo.d.ts +0 -0
- /package/{react-dist/components → components}/DuffelAncillaries/seats/SeatMap.d.ts +0 -0
- /package/{react-dist/components → components}/DuffelAncillaries/seats/SeatMapUnavailable.d.ts +0 -0
- /package/{react-dist/components → components}/DuffelAncillaries/seats/SeatSelectionCard.d.ts +0 -0
- /package/{react-dist/components → components}/DuffelAncillaries/seats/SeatSelectionModal.d.ts +0 -0
- /package/{react-dist/components → components}/DuffelAncillaries/seats/SeatSelectionModalBody.d.ts +0 -0
- /package/{react-dist/components → components}/DuffelAncillaries/seats/SeatSelectionModalFooter.d.ts +0 -0
- /package/{react-dist/components → components}/DuffelAncillaries/seats/SeatSelectionModalHeader.d.ts +0 -0
- /package/{react-dist/components → components}/DuffelAncillaries/seats/SeatUnavailable.d.ts +0 -0
- /package/{react-dist/components → components}/DuffelPayments/DuffelPayments.d.ts +0 -0
- /package/{react-dist/components → components}/DuffelPayments/DuffelPaymentsCustomElement.d.ts +0 -0
- /package/{react-dist/components → components}/PlacesLookup/PlacesLookup.d.ts +0 -0
- /package/{react-dist/components → components}/shared/AnimatedLoaderEllipsis.d.ts +0 -0
- /package/{react-dist/components → components}/shared/Button.d.ts +0 -0
- /package/{react-dist/components → components}/shared/ErrorBoundary.d.ts +0 -0
- /package/{react-dist/components → components}/shared/FetchOfferErrorState.d.ts +0 -0
- /package/{react-dist/components → components}/shared/Icon.d.ts +0 -0
- /package/{react-dist/components → components}/shared/IconButton.d.ts +0 -0
- /package/{react-dist/components → components}/shared/Modal.d.ts +0 -0
- /package/{react-dist/components → components}/shared/NonIdealState.d.ts +0 -0
- /package/{react-dist/components → components}/shared/Stamp.d.ts +0 -0
- /package/{react-dist/components → components}/shared/Tabs.d.ts +0 -0
- /package/{react-dist/custom-elements.d.ts → custom-elements.d.ts} +0 -0
- /package/{react-dist/index.d.ts → index.d.ts} +0 -0
- /package/{react-dist/lib → lib}/captureErrorInSentry.d.ts +0 -0
- /package/{react-dist/lib → lib}/compileCreateOrderPayload.d.ts +0 -0
- /package/{react-dist/lib → lib}/createPriceFormatters.d.ts +0 -0
- /package/{react-dist/lib → lib}/fetchFromDuffelAPI.d.ts +0 -0
- /package/{react-dist/lib → lib}/fetchFromFixtures.d.ts +0 -0
- /package/{react-dist/lib → lib}/formatAvailableServices.d.ts +0 -0
- /package/{react-dist/lib → lib}/formatDate.d.ts +0 -0
- /package/{react-dist/lib → lib}/formatSeatMaps.d.ts +0 -0
- /package/{react-dist/lib → lib}/getBaggageServiceDescription.d.ts +0 -0
- /package/{react-dist/lib → lib}/getCabinsForSegmentAndDeck.d.ts +0 -0
- /package/{react-dist/lib → lib}/getCurrencyForSeatMaps.d.ts +0 -0
- /package/{react-dist/lib → lib}/getCurrencyForServices.d.ts +0 -0
- /package/{react-dist/lib → lib}/getFirstSeatElementMatchingCriteria.d.ts +0 -0
- /package/{react-dist/lib → lib}/getPassengerBySegmentList.d.ts +0 -0
- /package/{react-dist/lib → lib}/getPassengerInitials.d.ts +0 -0
- /package/{react-dist/lib → lib}/getPassengerMapById.d.ts +0 -0
- /package/{react-dist/lib → lib}/getPassengerName.d.ts +0 -0
- /package/{react-dist/lib → lib}/getRowNumber.d.ts +0 -0
- /package/{react-dist/lib → lib}/getSegmentList.d.ts +0 -0
- /package/{react-dist/lib → lib}/getServicePriceMapById.d.ts +0 -0
- /package/{react-dist/lib → lib}/getSymbols.d.ts +0 -0
- /package/{react-dist/lib → lib}/getTotalAmountForServices.d.ts +0 -0
- /package/{react-dist/lib → lib}/getTotalQuantity.d.ts +0 -0
- /package/{react-dist/lib → lib}/hasHighLuminance.d.ts +0 -0
- /package/{react-dist/lib → lib}/hasService.d.ts +0 -0
- /package/{react-dist/lib → lib}/hasServiceOfSameMetadataTypeAlreadyBeenSelected.d.ts +0 -0
- /package/{react-dist/lib → lib}/hasWings.d.ts +0 -0
- /package/{react-dist/lib → lib}/isBaggageService.d.ts +0 -0
- /package/{react-dist/lib → lib}/isCancelForAnyReasonService.d.ts +0 -0
- /package/{react-dist/lib → lib}/isFixtureOfferId.d.ts +0 -0
- /package/{react-dist/lib → lib}/isPayloadComplete.d.ts +0 -0
- /package/{react-dist/lib → lib}/isSeatElement.d.ts +0 -0
- /package/{react-dist/lib → lib}/logging.d.ts +0 -0
- /package/{react-dist/lib → lib}/moneyStringFormatter.d.ts +0 -0
- /package/{react-dist/lib → lib}/offerIsExpired.d.ts +0 -0
- /package/{react-dist/lib → lib}/retrieveOffer.d.ts +0 -0
- /package/{react-dist/lib → lib}/retrieveOfferFromDuffelAPI.d.ts +0 -0
- /package/{react-dist/lib → lib}/retrieveSeatMaps.d.ts +0 -0
- /package/{react-dist/lib → lib}/retrieveSeatMapsFromDuffelAPI.d.ts +0 -0
- /package/{react-dist/lib → lib}/setBodyScrollability.d.ts +0 -0
- /package/{react-dist/lib → lib}/validateProps.d.ts +0 -0
- /package/{react-dist/lib → lib}/withPlural.d.ts +0 -0
- /package/{react-dist/types → types}/Aircraft.d.ts +0 -0
- /package/{react-dist/types → types}/Airline.d.ts +0 -0
- /package/{react-dist/types → types}/Airport.d.ts +0 -0
- /package/{react-dist/types → types}/City.d.ts +0 -0
- /package/{react-dist/types → types}/CreateOrderPayload.d.ts +0 -0
- /package/{react-dist/types → types}/CurrencyConversion.d.ts +0 -0
- /package/{react-dist/types → types}/DuffelAncillariesProps.d.ts +0 -0
- /package/{react-dist/types → types}/Offer.d.ts +0 -0
- /package/{react-dist/types → types}/Order.d.ts +0 -0
- /package/{react-dist/types → types}/Place.d.ts +0 -0
- /package/{react-dist/types → types}/SeatMap.d.ts +0 -0
- /package/{react-dist/types → types}/index.d.ts +0 -0
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import { formatDateString } from "@lib/formatDate";
|
|
2
|
-
import React from "react";
|
|
3
|
-
import { OfferSliceSegment } from "../../../types/Offer";
|
|
4
|
-
|
|
5
|
-
export interface SeatSelectionModalHeaderProps {
|
|
6
|
-
segmentAndPassengerPermutationsCount: number;
|
|
7
|
-
currentSegment: OfferSliceSegment;
|
|
8
|
-
currentPassengerName: string;
|
|
9
|
-
|
|
10
|
-
currentSegmentAndPassengerPermutationsIndex: number;
|
|
11
|
-
setCurrentSegmentAndPassengerPermutationsIndex: (index: number) => void;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export const SeatSelectionModalHeader: React.FC<
|
|
15
|
-
SeatSelectionModalHeaderProps
|
|
16
|
-
> = ({
|
|
17
|
-
segmentAndPassengerPermutationsCount,
|
|
18
|
-
currentSegmentAndPassengerPermutationsIndex,
|
|
19
|
-
currentSegment,
|
|
20
|
-
currentPassengerName,
|
|
21
|
-
setCurrentSegmentAndPassengerPermutationsIndex,
|
|
22
|
-
}) => (
|
|
23
|
-
<div style={{ padding: "24px 24px 16px" }}>
|
|
24
|
-
{segmentAndPassengerPermutationsCount > 1 && (
|
|
25
|
-
<div style={{ display: "flex", columnGap: "4px" }}>
|
|
26
|
-
{Array(segmentAndPassengerPermutationsCount)
|
|
27
|
-
.fill(0)
|
|
28
|
-
.map((_, index) =>
|
|
29
|
-
index === currentSegmentAndPassengerPermutationsIndex ? (
|
|
30
|
-
<ActiveSegment key={`segment_${index}`} />
|
|
31
|
-
) : (
|
|
32
|
-
<InactiveSegment
|
|
33
|
-
key={`segment_${index}`}
|
|
34
|
-
onClick={() =>
|
|
35
|
-
setCurrentSegmentAndPassengerPermutationsIndex(index)
|
|
36
|
-
}
|
|
37
|
-
/>
|
|
38
|
-
)
|
|
39
|
-
)}
|
|
40
|
-
</div>
|
|
41
|
-
)}
|
|
42
|
-
<h2
|
|
43
|
-
className="h3--semibold"
|
|
44
|
-
style={
|
|
45
|
-
segmentAndPassengerPermutationsCount > 1
|
|
46
|
-
? { marginBlock: "12px 0px" }
|
|
47
|
-
: {}
|
|
48
|
-
}
|
|
49
|
-
>
|
|
50
|
-
Flight to {currentSegment.destination.iata_code}
|
|
51
|
-
<span
|
|
52
|
-
className="p2--regular"
|
|
53
|
-
style={{
|
|
54
|
-
color: "var(--GREY-600)",
|
|
55
|
-
marginLeft: "8px",
|
|
56
|
-
}}
|
|
57
|
-
>
|
|
58
|
-
{formatDateString(currentSegment.departing_at)}
|
|
59
|
-
</span>
|
|
60
|
-
</h2>
|
|
61
|
-
<p
|
|
62
|
-
className="h3--semibold"
|
|
63
|
-
style={{ color: `var(--GREY-600)`, marginBlock: "0 4px" }}
|
|
64
|
-
>
|
|
65
|
-
{currentPassengerName}
|
|
66
|
-
</p>
|
|
67
|
-
</div>
|
|
68
|
-
);
|
|
69
|
-
|
|
70
|
-
const InactiveSegment: React.FC<{
|
|
71
|
-
style?: React.CSSProperties;
|
|
72
|
-
onClick?: React.MouseEventHandler<HTMLButtonElement>;
|
|
73
|
-
}> = ({ onClick, style }) => (
|
|
74
|
-
<button
|
|
75
|
-
onClick={onClick}
|
|
76
|
-
style={{
|
|
77
|
-
border: "none",
|
|
78
|
-
width: "4px",
|
|
79
|
-
height: "4px",
|
|
80
|
-
padding: "0",
|
|
81
|
-
borderRadius: "4px",
|
|
82
|
-
backgroundColor:
|
|
83
|
-
"var(--TERTIARY, rgba(var(--ACCENT), var(--ACCENT-LIGHT-200)))",
|
|
84
|
-
transition: "background-color 0.3s var(--TRANSITION-CUBIC-BEZIER)",
|
|
85
|
-
...style,
|
|
86
|
-
}}
|
|
87
|
-
/>
|
|
88
|
-
);
|
|
89
|
-
|
|
90
|
-
const ActiveSegment = () => (
|
|
91
|
-
<InactiveSegment
|
|
92
|
-
onClick={undefined}
|
|
93
|
-
style={{
|
|
94
|
-
backgroundColor: "var(--SECONDARY, rgb(var(--ACCENT)))",
|
|
95
|
-
}}
|
|
96
|
-
/>
|
|
97
|
-
);
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { Icon } from "@components/shared/Icon";
|
|
2
|
-
import * as React from "react";
|
|
3
|
-
import { SeatMapCabinRowSectionElementSeat } from "../../../types/SeatMap";
|
|
4
|
-
|
|
5
|
-
export const SeatUnavailable: React.FC<{
|
|
6
|
-
seat: SeatMapCabinRowSectionElementSeat;
|
|
7
|
-
}> = ({ seat }) => (
|
|
8
|
-
<span
|
|
9
|
-
className="map-element map-element__seat"
|
|
10
|
-
aria-label={`${seat.designator} ${seat.name || "Seat"} Unavailable`}
|
|
11
|
-
>
|
|
12
|
-
<Icon name="close" size={14} />
|
|
13
|
-
</span>
|
|
14
|
-
);
|
|
@@ -1,224 +0,0 @@
|
|
|
1
|
-
import { ErrorBoundary } from "@components/shared/ErrorBoundary";
|
|
2
|
-
import { hasHighLuminance } from "@lib/hasHighLuminance";
|
|
3
|
-
import { initializeLogger } from "@lib/logging";
|
|
4
|
-
import {
|
|
5
|
-
CardElement,
|
|
6
|
-
Elements,
|
|
7
|
-
useElements,
|
|
8
|
-
useStripe,
|
|
9
|
-
} from "@stripe/react-stripe-js";
|
|
10
|
-
import { StripeCardElement, StripeError, loadStripe } from "@stripe/stripe-js";
|
|
11
|
-
import * as React from "react";
|
|
12
|
-
import { CustomStyles } from "../../types";
|
|
13
|
-
import { Button } from "../shared/Button";
|
|
14
|
-
|
|
15
|
-
const COMPONENT_CDN = process.env.COMPONENT_CDN || "";
|
|
16
|
-
const hrefToComponentStyles = `${COMPONENT_CDN}/global.css`;
|
|
17
|
-
|
|
18
|
-
const STRIPE_CARD_ELEMENT = "card";
|
|
19
|
-
const COMPONENT_VERSION = process.env.COMPONENT_VERSION;
|
|
20
|
-
|
|
21
|
-
export interface DuffelPaymentsProps {
|
|
22
|
-
paymentIntentClientToken: string;
|
|
23
|
-
onSuccessfulPayment: () => void;
|
|
24
|
-
onFailedPayment: (error: StripeError) => void;
|
|
25
|
-
|
|
26
|
-
styles?: CustomStyles;
|
|
27
|
-
debug?: boolean;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const CARD_ELEMENT_STYLE_BASE = {
|
|
31
|
-
color: "var(--GREY-900)",
|
|
32
|
-
fontFamily:
|
|
33
|
-
'"-apple-system", "BlinkMacSystemFont", "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", "sans-serif"',
|
|
34
|
-
fontSmoothing: "antialiased",
|
|
35
|
-
fontSize: "16px",
|
|
36
|
-
"::placeholder": {
|
|
37
|
-
color: "#ababb4",
|
|
38
|
-
},
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
const CARD_ELEMENT_STYLE_INVALID = {
|
|
42
|
-
color: "#ef4444",
|
|
43
|
-
iconColor: "#ef4444",
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const CardPaymentComponent: React.FC<DuffelPaymentsProps> = ({
|
|
47
|
-
styles,
|
|
48
|
-
paymentIntentClientToken,
|
|
49
|
-
onSuccessfulPayment,
|
|
50
|
-
onFailedPayment,
|
|
51
|
-
}) => {
|
|
52
|
-
const [cardElement, setCardElement] =
|
|
53
|
-
React.useState<StripeCardElement | null>(null);
|
|
54
|
-
const [isComplete, setIsComplete] = React.useState<boolean>(false);
|
|
55
|
-
const [isInvalid, setIsInvalid] = React.useState<boolean>(false);
|
|
56
|
-
const [isProcessing, setIsProcessing] = React.useState<boolean>(false);
|
|
57
|
-
const [errorMessage, setErrorMessage] = React.useState<string>("");
|
|
58
|
-
const stripe = useStripe();
|
|
59
|
-
const elements = useElements();
|
|
60
|
-
|
|
61
|
-
React.useEffect(() => {
|
|
62
|
-
if (elements && !cardElement) {
|
|
63
|
-
const maybeCard = elements?.getElement(STRIPE_CARD_ELEMENT);
|
|
64
|
-
maybeCard && setCardElement(maybeCard as StripeCardElement);
|
|
65
|
-
}
|
|
66
|
-
}, [elements, cardElement]);
|
|
67
|
-
|
|
68
|
-
React.useEffect(() => {
|
|
69
|
-
if (cardElement) {
|
|
70
|
-
cardElement.on("change", (event) => {
|
|
71
|
-
const { error, complete } = event;
|
|
72
|
-
|
|
73
|
-
if (error) {
|
|
74
|
-
setIsInvalid(true);
|
|
75
|
-
setErrorMessage(error.message);
|
|
76
|
-
} else {
|
|
77
|
-
setIsInvalid(false);
|
|
78
|
-
}
|
|
79
|
-
complete ? setIsComplete(true) : setIsComplete(false);
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
}, [cardElement]);
|
|
83
|
-
|
|
84
|
-
// User is responsible for handling outcome of payment.
|
|
85
|
-
const handleSubmit = async (
|
|
86
|
-
e: React.MouseEvent<HTMLFormElement, MouseEvent>
|
|
87
|
-
) => {
|
|
88
|
-
e.preventDefault();
|
|
89
|
-
if (!stripe || !elements) {
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (cardElement) {
|
|
94
|
-
setIsProcessing(true);
|
|
95
|
-
const decodedDuffelPaymentIntentClientToken = atob(
|
|
96
|
-
paymentIntentClientToken
|
|
97
|
-
);
|
|
98
|
-
const parsedDuffelPaymentIntentClientToken = JSON.parse(
|
|
99
|
-
decodedDuffelPaymentIntentClientToken
|
|
100
|
-
);
|
|
101
|
-
const { client_secret: clientSecret } =
|
|
102
|
-
parsedDuffelPaymentIntentClientToken;
|
|
103
|
-
|
|
104
|
-
const result = await stripe.confirmCardPayment(clientSecret, {
|
|
105
|
-
payment_method: {
|
|
106
|
-
card: cardElement,
|
|
107
|
-
metadata: {
|
|
108
|
-
duffel_components_version:
|
|
109
|
-
COMPONENT_VERSION || "failed-to-get-version",
|
|
110
|
-
},
|
|
111
|
-
},
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
setIsProcessing(false);
|
|
115
|
-
if (result.error) {
|
|
116
|
-
const { error } = result;
|
|
117
|
-
onFailedPayment(error);
|
|
118
|
-
} else {
|
|
119
|
-
onSuccessfulPayment();
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
return paymentIntentClientToken ? (
|
|
125
|
-
<div className="card-payment__container">
|
|
126
|
-
<form onSubmit={handleSubmit}>
|
|
127
|
-
{isProcessing && (
|
|
128
|
-
<div
|
|
129
|
-
className="card-payment--in-progress"
|
|
130
|
-
aria-live="polite"
|
|
131
|
-
aria-busy="true"
|
|
132
|
-
/>
|
|
133
|
-
)}
|
|
134
|
-
<CardElement
|
|
135
|
-
className="card-details"
|
|
136
|
-
options={{
|
|
137
|
-
style: {
|
|
138
|
-
base: {
|
|
139
|
-
...CARD_ELEMENT_STYLE_BASE,
|
|
140
|
-
...(styles?.fontFamily && {
|
|
141
|
-
fontFamily: styles.fontFamily,
|
|
142
|
-
}),
|
|
143
|
-
},
|
|
144
|
-
invalid: { ...CARD_ELEMENT_STYLE_INVALID },
|
|
145
|
-
},
|
|
146
|
-
}}
|
|
147
|
-
/>
|
|
148
|
-
<div className="card-payment__container--invalid" role="alert">
|
|
149
|
-
{isInvalid && errorMessage}
|
|
150
|
-
</div>
|
|
151
|
-
<Button
|
|
152
|
-
className="card-payment__pay-button"
|
|
153
|
-
type="submit"
|
|
154
|
-
disabled={!isComplete || isProcessing}
|
|
155
|
-
aria-label="Pay"
|
|
156
|
-
>
|
|
157
|
-
{isProcessing ? "Processing..." : "Pay"}
|
|
158
|
-
</Button>
|
|
159
|
-
</form>
|
|
160
|
-
</div>
|
|
161
|
-
) : null;
|
|
162
|
-
};
|
|
163
|
-
|
|
164
|
-
export const DuffelPayments: React.FC<DuffelPaymentsProps> = (props) => {
|
|
165
|
-
const [stripe, setStripe] = React.useState<Promise<any> | null>(null);
|
|
166
|
-
initializeLogger(props.debug || false);
|
|
167
|
-
|
|
168
|
-
const decodedDuffelPaymentIntentClientToken = atob(
|
|
169
|
-
props.paymentIntentClientToken
|
|
170
|
-
);
|
|
171
|
-
|
|
172
|
-
let parsedDuffelPaymentIntentClientToken;
|
|
173
|
-
|
|
174
|
-
try {
|
|
175
|
-
parsedDuffelPaymentIntentClientToken = JSON.parse(
|
|
176
|
-
decodedDuffelPaymentIntentClientToken
|
|
177
|
-
);
|
|
178
|
-
} catch (error) {
|
|
179
|
-
throw new Error("Invalid Duffel payment intent client token provided");
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
const { publishable_key: duffelPublishableKey } =
|
|
183
|
-
parsedDuffelPaymentIntentClientToken;
|
|
184
|
-
|
|
185
|
-
React.useEffect(() => {
|
|
186
|
-
if (!stripe && duffelPublishableKey) {
|
|
187
|
-
const stripe = loadStripe(duffelPublishableKey);
|
|
188
|
-
stripe && setStripe(stripe);
|
|
189
|
-
}
|
|
190
|
-
}, [stripe, duffelPublishableKey]);
|
|
191
|
-
|
|
192
|
-
const duffelComponentsStyle: React.CSSProperties = {
|
|
193
|
-
...(props.styles?.accentColor && {
|
|
194
|
-
"--ACCENT": props.styles.accentColor,
|
|
195
|
-
}),
|
|
196
|
-
...(props.styles?.accentColor &&
|
|
197
|
-
hasHighLuminance(props.styles.accentColor) && {
|
|
198
|
-
"--SECONDARY": "black",
|
|
199
|
-
"--TERTIARY": "grey",
|
|
200
|
-
}),
|
|
201
|
-
...(props.styles?.fontFamily && {
|
|
202
|
-
"--FONT-FAMILY": props.styles.fontFamily,
|
|
203
|
-
}),
|
|
204
|
-
...(props.styles?.buttonCornerRadius && {
|
|
205
|
-
"--BUTTON-RADIUS": props.styles.buttonCornerRadius,
|
|
206
|
-
}),
|
|
207
|
-
// `as any` is needed here is needed because we want to set css variables
|
|
208
|
-
// that are not part of the css properties type
|
|
209
|
-
} as any;
|
|
210
|
-
|
|
211
|
-
return (
|
|
212
|
-
<>
|
|
213
|
-
<link rel="stylesheet" href={hrefToComponentStyles}></link>
|
|
214
|
-
|
|
215
|
-
<div className="duffel-components" style={duffelComponentsStyle}>
|
|
216
|
-
<ErrorBoundary>
|
|
217
|
-
<Elements stripe={stripe}>
|
|
218
|
-
<CardPaymentComponent {...props} />
|
|
219
|
-
</Elements>
|
|
220
|
-
</ErrorBoundary>
|
|
221
|
-
</div>
|
|
222
|
-
</>
|
|
223
|
-
);
|
|
224
|
-
};
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
import { StripeError } from "@stripe/stripe-js";
|
|
2
|
-
import { createRoot, Root } from "react-dom/client";
|
|
3
|
-
import { DuffelPayments, DuffelPaymentsProps } from "./DuffelPayments";
|
|
4
|
-
|
|
5
|
-
declare global {
|
|
6
|
-
// eslint-disable-next-line @typescript-eslint/no-namespace
|
|
7
|
-
namespace JSX {
|
|
8
|
-
interface IntrinsicElements {
|
|
9
|
-
"duffel-payments": React.DetailedHTMLProps<
|
|
10
|
-
React.HTMLAttributes<HTMLElement>,
|
|
11
|
-
HTMLElement
|
|
12
|
-
>;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const CUSTOM_ELEMENT_TAG = "duffel-payments";
|
|
18
|
-
|
|
19
|
-
type DuffelPaymentsCustomElementRenderArguments = Pick<
|
|
20
|
-
DuffelPaymentsProps,
|
|
21
|
-
"paymentIntentClientToken" | "styles"
|
|
22
|
-
>;
|
|
23
|
-
|
|
24
|
-
class DuffelPaymentsCustomElement extends HTMLElement {
|
|
25
|
-
/**
|
|
26
|
-
* The React root for displaying content inside a browser DOM element.
|
|
27
|
-
*/
|
|
28
|
-
private root!: Root;
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* `connectedCallback` is called to initialise the custom element
|
|
32
|
-
*/
|
|
33
|
-
connectedCallback() {
|
|
34
|
-
const container = document.createElement("div");
|
|
35
|
-
this.appendChild(container);
|
|
36
|
-
|
|
37
|
-
this.root = createRoot(container);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* When this function is called, it will render/re-render
|
|
42
|
-
* the `DuffelPayments` component with the given props.
|
|
43
|
-
*/
|
|
44
|
-
public render(withProps: DuffelPaymentsCustomElementRenderArguments) {
|
|
45
|
-
if (!this.root) {
|
|
46
|
-
throw "It was not possible to render `duffel-payments` because `this.root` is missing.";
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
this.root.render(
|
|
50
|
-
<DuffelPayments
|
|
51
|
-
{...withProps}
|
|
52
|
-
onSuccessfulPayment={() => {
|
|
53
|
-
this.dispatchEvent(
|
|
54
|
-
new CustomEvent("onSuccessfulPayment", {
|
|
55
|
-
composed: true,
|
|
56
|
-
})
|
|
57
|
-
);
|
|
58
|
-
}}
|
|
59
|
-
onFailedPayment={(error: StripeError) => {
|
|
60
|
-
this.dispatchEvent(
|
|
61
|
-
new CustomEvent("onFailedPayment", {
|
|
62
|
-
detail: { error },
|
|
63
|
-
composed: true,
|
|
64
|
-
})
|
|
65
|
-
);
|
|
66
|
-
}}
|
|
67
|
-
/>
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
window.customElements.get(CUSTOM_ELEMENT_TAG) ||
|
|
73
|
-
window.customElements.define(CUSTOM_ELEMENT_TAG, DuffelPaymentsCustomElement);
|
|
74
|
-
|
|
75
|
-
function tryToGetDuffelPaymentsCustomElement(
|
|
76
|
-
caller: string
|
|
77
|
-
): DuffelPaymentsCustomElement {
|
|
78
|
-
const element =
|
|
79
|
-
document.querySelector<DuffelPaymentsCustomElement>(CUSTOM_ELEMENT_TAG);
|
|
80
|
-
if (!element) {
|
|
81
|
-
throw new Error(
|
|
82
|
-
`Could not find duffel-payments element in the DOM. Maybe you need to call ${caller} after 'window.onload'?`
|
|
83
|
-
);
|
|
84
|
-
}
|
|
85
|
-
return element;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
export function renderDuffelPaymentsCustomElement(
|
|
89
|
-
props: DuffelPaymentsCustomElementRenderArguments
|
|
90
|
-
) {
|
|
91
|
-
const element = tryToGetDuffelPaymentsCustomElement(
|
|
92
|
-
"renderDuffelPaymentsCustomElement"
|
|
93
|
-
);
|
|
94
|
-
element.render(props);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export function onDuffelPaymentsSuccessfulPayment(
|
|
98
|
-
onSuccessfulPayment: DuffelPaymentsProps["onSuccessfulPayment"]
|
|
99
|
-
) {
|
|
100
|
-
const element = tryToGetDuffelPaymentsCustomElement(
|
|
101
|
-
"onDuffelPaymentsPayloadReady"
|
|
102
|
-
);
|
|
103
|
-
|
|
104
|
-
// using `as EventListener` here because typescript doesn't know the event type for `onPayloadReady`
|
|
105
|
-
// There's a few different suggestions to resolve this seemed good enough
|
|
106
|
-
// You can learn more here: https://github.com/microsoft/TypeScript/issues/28357
|
|
107
|
-
element.addEventListener(
|
|
108
|
-
"onPayloadReady",
|
|
109
|
-
onSuccessfulPayment as EventListener
|
|
110
|
-
);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
type OnFailedPaymentCustomEvent = CustomEvent<{
|
|
114
|
-
error: StripeError;
|
|
115
|
-
}>;
|
|
116
|
-
export function onDuffelPaymentsFailedPayment(
|
|
117
|
-
onFailedPayment: DuffelPaymentsProps["onFailedPayment"]
|
|
118
|
-
) {
|
|
119
|
-
const element = tryToGetDuffelPaymentsCustomElement(
|
|
120
|
-
"onDuffelPaymentsPayloadReady"
|
|
121
|
-
);
|
|
122
|
-
const eventListener = (event: OnFailedPaymentCustomEvent) => {
|
|
123
|
-
onFailedPayment(event.detail.error);
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
// using `as EventListener` here because typescript doesn't know the event type for `onPayloadReady`
|
|
127
|
-
// There's a few different suggestions to resolve this seemed good enough
|
|
128
|
-
// You can learn more here: https://github.com/microsoft/TypeScript/issues/28357
|
|
129
|
-
element.addEventListener("onPayloadReady", eventListener as EventListener);
|
|
130
|
-
}
|
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
import Fuse from "fuse.js";
|
|
2
|
-
import { debounce } from "lodash";
|
|
3
|
-
import React from "react";
|
|
4
|
-
import { Icon } from "../shared/Icon";
|
|
5
|
-
|
|
6
|
-
const DATA_SOURCE = "https://assets.duffel.com/data/iata-lookup-v2.json";
|
|
7
|
-
|
|
8
|
-
interface City {
|
|
9
|
-
type: "city";
|
|
10
|
-
name: string;
|
|
11
|
-
iata_code: string;
|
|
12
|
-
}
|
|
13
|
-
interface Airport {
|
|
14
|
-
type: "airport";
|
|
15
|
-
name: string;
|
|
16
|
-
iata_code: string;
|
|
17
|
-
latitude: string;
|
|
18
|
-
longitude: string;
|
|
19
|
-
}
|
|
20
|
-
type Place = City | Airport;
|
|
21
|
-
|
|
22
|
-
const mapDataRowsIntoObjects = (data: string[]): Place[] =>
|
|
23
|
-
data.map((row) => {
|
|
24
|
-
const [type, name, iata_code, latitude, longitude] = row.split(",");
|
|
25
|
-
if (type === "C") return { type: "city", name, iata_code } as City;
|
|
26
|
-
else
|
|
27
|
-
return {
|
|
28
|
-
type: "airport",
|
|
29
|
-
name,
|
|
30
|
-
iata_code,
|
|
31
|
-
latitude,
|
|
32
|
-
longitude,
|
|
33
|
-
} as Airport;
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
export interface PlacesLookupProps {
|
|
37
|
-
onPlaceSelected: (selection: Place) => void;
|
|
38
|
-
placeholder?: string;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export const PlacesLookup: React.FC<PlacesLookupProps> = ({
|
|
42
|
-
onPlaceSelected,
|
|
43
|
-
placeholder = "Lookup city or airport",
|
|
44
|
-
}) => {
|
|
45
|
-
const [shouldShowPopover, setShouldShowPopover] =
|
|
46
|
-
React.useState<boolean>(true);
|
|
47
|
-
const [inputValue, setInputValue] = React.useState<string>("");
|
|
48
|
-
const [lookupData, setLookupData] = React.useState<Fuse<Place>>(new Fuse([]));
|
|
49
|
-
const [lookupResults, setLookupResults] = React.useState<
|
|
50
|
-
Fuse.FuseResult<Place>[]
|
|
51
|
-
>([]);
|
|
52
|
-
|
|
53
|
-
const runLookup = debounce((newInputValue: string) => {
|
|
54
|
-
setLookupResults(
|
|
55
|
-
lookupData.search(newInputValue, {
|
|
56
|
-
limit: 10,
|
|
57
|
-
})
|
|
58
|
-
);
|
|
59
|
-
}, 300);
|
|
60
|
-
|
|
61
|
-
React.useEffect(() => {
|
|
62
|
-
fetch(DATA_SOURCE)
|
|
63
|
-
.then((response: Response) => response.json())
|
|
64
|
-
.then((data: string[]) =>
|
|
65
|
-
setLookupData(
|
|
66
|
-
new Fuse<Place>(mapDataRowsIntoObjects(data), {
|
|
67
|
-
threshold: 0.2,
|
|
68
|
-
keys: ["name", "iata_code"],
|
|
69
|
-
})
|
|
70
|
-
)
|
|
71
|
-
);
|
|
72
|
-
}, []);
|
|
73
|
-
|
|
74
|
-
return (
|
|
75
|
-
<div className="places-lookup">
|
|
76
|
-
<input
|
|
77
|
-
className="places-lookup-input"
|
|
78
|
-
placeholder={placeholder}
|
|
79
|
-
type="text"
|
|
80
|
-
value={inputValue}
|
|
81
|
-
onChange={(e) => {
|
|
82
|
-
if (!shouldShowPopover) setShouldShowPopover(true);
|
|
83
|
-
setInputValue(e.target.value);
|
|
84
|
-
runLookup(e.target.value);
|
|
85
|
-
}}
|
|
86
|
-
/>
|
|
87
|
-
{shouldShowPopover &&
|
|
88
|
-
inputValue.length > 0 &&
|
|
89
|
-
lookupResults.length > 0 && (
|
|
90
|
-
<div
|
|
91
|
-
className="places-lookup-popover"
|
|
92
|
-
style={{ display: "flex", flexDirection: "column" }}
|
|
93
|
-
>
|
|
94
|
-
{lookupResults.map(({ item }, index) => (
|
|
95
|
-
<button
|
|
96
|
-
className="places-lookup-popover__item"
|
|
97
|
-
key={item.iata_code + index}
|
|
98
|
-
onClick={() => {
|
|
99
|
-
setShouldShowPopover(false);
|
|
100
|
-
onPlaceSelected(item);
|
|
101
|
-
setInputValue(item.name);
|
|
102
|
-
}}
|
|
103
|
-
>
|
|
104
|
-
<span className="places-lookup-popover__icon-and-name-container">
|
|
105
|
-
<Icon
|
|
106
|
-
style={{ fill: "var(--GREY-400)", marginTop: "-2px" }}
|
|
107
|
-
name={
|
|
108
|
-
item.type === "airport" ? "flight_takeoff" : "apartment"
|
|
109
|
-
}
|
|
110
|
-
/>
|
|
111
|
-
{item.name}
|
|
112
|
-
</span>{" "}
|
|
113
|
-
<span style={{ color: "var(--GREY-600)", fontSize: "12px" }}>
|
|
114
|
-
{item.iata_code}
|
|
115
|
-
</span>
|
|
116
|
-
</button>
|
|
117
|
-
))}
|
|
118
|
-
</div>
|
|
119
|
-
)}
|
|
120
|
-
</div>
|
|
121
|
-
);
|
|
122
|
-
};
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { Icon, IconName } from "@components/shared/Icon";
|
|
2
|
-
import classNames from "classnames";
|
|
3
|
-
import * as React from "react";
|
|
4
|
-
|
|
5
|
-
const BUTTON_VARIANTS = {
|
|
6
|
-
primary: "button--primary",
|
|
7
|
-
outlined: "button--outlined",
|
|
8
|
-
destructive: "button--destructive",
|
|
9
|
-
};
|
|
10
|
-
type ButtonVariants = keyof typeof BUTTON_VARIANTS;
|
|
11
|
-
|
|
12
|
-
const BUTTON_SIZES = {
|
|
13
|
-
32: "button--32",
|
|
14
|
-
40: "button--40",
|
|
15
|
-
48: "button--48",
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
type ButtonSizes = keyof typeof BUTTON_SIZES;
|
|
19
|
-
|
|
20
|
-
type NativeButtonProps = React.DetailedHTMLProps<
|
|
21
|
-
React.ButtonHTMLAttributes<HTMLButtonElement>,
|
|
22
|
-
HTMLButtonElement
|
|
23
|
-
>;
|
|
24
|
-
|
|
25
|
-
export interface ButtonProps
|
|
26
|
-
extends Pick<
|
|
27
|
-
NativeButtonProps,
|
|
28
|
-
"id" | "onClick" | "disabled" | "children" | "className" | "type"
|
|
29
|
-
> {
|
|
30
|
-
"data-testid"?: string;
|
|
31
|
-
iconBefore?: IconName;
|
|
32
|
-
variant?: ButtonVariants;
|
|
33
|
-
size?: ButtonSizes;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export const Button: React.FC<ButtonProps> = ({
|
|
37
|
-
iconBefore,
|
|
38
|
-
variant = "primary",
|
|
39
|
-
size = 40,
|
|
40
|
-
children,
|
|
41
|
-
className,
|
|
42
|
-
type = "button",
|
|
43
|
-
...nativeButtonProps
|
|
44
|
-
}) => (
|
|
45
|
-
<button
|
|
46
|
-
type={type}
|
|
47
|
-
className={classNames(
|
|
48
|
-
"button",
|
|
49
|
-
BUTTON_VARIANTS[variant],
|
|
50
|
-
BUTTON_SIZES[size],
|
|
51
|
-
className
|
|
52
|
-
)}
|
|
53
|
-
{...nativeButtonProps}
|
|
54
|
-
>
|
|
55
|
-
{iconBefore && (
|
|
56
|
-
<Icon
|
|
57
|
-
className="duffel-button__icon duffel-button__icon--before"
|
|
58
|
-
name={iconBefore}
|
|
59
|
-
/>
|
|
60
|
-
)}
|
|
61
|
-
{children}
|
|
62
|
-
</button>
|
|
63
|
-
);
|