@bytebrand/fe-ui-core-autobahn 1.0.1 → 1.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/assets/autode-logo.svg +6 -6
- package/cards/CarCard.tsx +174 -174
- package/cards/CarRow.tsx +186 -182
- package/cards/cardParts.tsx +529 -489
- package/cards/index.ts +37 -35
- package/cards/types.ts +124 -114
- package/chrome/Footer.tsx +189 -189
- package/chrome/TopBar.tsx +405 -405
- package/chrome/index.ts +20 -20
- package/chrome/svg.d.ts +11 -11
- package/compat/AccardionSection/AccardionSection.styl +45 -45
- package/compat/AccardionSection/AccardionSection.tsx +56 -56
- package/compat/AccordionWidget/AccordionWidget.styl +220 -220
- package/compat/AccordionWidget/AccordionWidget.tsx +257 -257
- package/compat/AccordionWrapper/AccordionItem/AccordionItem.styl +34 -34
- package/compat/AccordionWrapper/AccordionItem/AccordionItem.tsx +64 -64
- package/compat/AccordionWrapper/AccordionWrapper.tsx +34 -34
- package/compat/AdvantageItem/AdvantageItem.styl +47 -47
- package/compat/AdvantageItem/AdvantageItem.tsx +26 -26
- package/compat/Alternative/DealerInfo.styl +116 -116
- package/compat/Alternative/DealerInfo.tsx +171 -171
- package/compat/Badge/Badge.styl +44 -44
- package/compat/Badge/Badge.tsx +25 -25
- package/compat/BodyTypeIcons/Audi.tsx +9 -9
- package/compat/BodyTypeIcons/Bmw.tsx +860 -860
- package/compat/BodyTypeIcons/Ford.tsx +31 -31
- package/compat/BodyTypeIcons/IconsConfig.tsx +44 -44
- package/compat/BodyTypeIcons/IconsConfigCompact.tsx +30 -30
- package/compat/BodyTypeIcons/Mazda.tsx +44 -44
- package/compat/BodyTypeIcons/MercedesBenz.tsx +38 -38
- package/compat/BodyTypeIcons/Opel.tsx +19 -19
- package/compat/BodyTypeIcons/Search.tsx +19 -19
- package/compat/BodyTypeIcons/SelectorCategoryCombi.tsx +68 -68
- package/compat/BodyTypeIcons/SelectorCategoryCompact.tsx +20 -20
- package/compat/BodyTypeIcons/SelectorCategoryConvertible.tsx +68 -68
- package/compat/BodyTypeIcons/SelectorCategoryCoupe.tsx +60 -60
- package/compat/BodyTypeIcons/SelectorCategoryMinibus.tsx +64 -64
- package/compat/BodyTypeIcons/SelectorCategorySedan.tsx +69 -69
- package/compat/BodyTypeIcons/SelectorCategorySuv.tsx +77 -77
- package/compat/BodyTypeIcons/SelectorCategoryTransporter.tsx +68 -68
- package/compat/BodyTypeIcons/SelectorCategoryVan.tsx +72 -72
- package/compat/BodyTypeIcons/Volkswagen.tsx +330 -330
- package/compat/BodyTypeIcons/index.ts +17 -17
- package/compat/Button/Button.tsx +65 -65
- package/compat/ButtonOld/Button.styl +65 -65
- package/compat/ButtonOld/Button.tsx +84 -84
- package/compat/Checkbox/Checkbox.styl +119 -119
- package/compat/Checkbox/Checkbox.tsx +151 -151
- package/compat/Checkbox/FormCheckbox.styl +22 -22
- package/compat/Checkbox/FormCheckbox.tsx +86 -86
- package/compat/Co2Widget/CO2Efficiency.styl +219 -219
- package/compat/Co2Widget/CO2Efficiency.tsx +93 -93
- package/compat/ContactInfo/ContactInfo.styl +22 -22
- package/compat/ContactInfo/ContactInfo.tsx +161 -161
- package/compat/ContactInfo/TemporaryTranslation.ts +11 -11
- package/compat/CookieModal/CookieModal.tsx +49 -49
- package/compat/CookieModal/Modal.tsx +43 -43
- package/compat/CookieModal/ModalsConfig.tsx +23 -23
- package/compat/CookieModal/modals/ManageCookieModal/ManageCookieModal.styl +86 -86
- package/compat/CookieModal/modals/ManageCookieModal/ManageCookieModal.tsx +184 -184
- package/compat/CookieModal/modals/PreviewCookieModal/PreviewCookieModal.styl +66 -66
- package/compat/CookieModal/modals/PreviewCookieModal/PreviewCookieModal.tsx +51 -51
- package/compat/CookieModal/modals/TestModal.tsx +7 -7
- package/compat/CookieModal/useModal.ts +13 -13
- package/compat/CustomerQuote/CustomerQuote.styl +79 -79
- package/compat/CustomerQuote/CustomerQuote.tsx +68 -68
- package/compat/CustomerQuotesSlider/CustomerQuotesSlider.styl +46 -46
- package/compat/CustomerQuotesSlider/CustomerQuotesSlider.tsx +79 -79
- package/compat/CustomerQuotesSlider/SliderArrow.tsx +20 -20
- package/compat/CustomerQuotesSlider/slider.global.styl +2 -2
- package/compat/ExpansionPanel/ExpansionPanel.tsx +68 -68
- package/compat/FirstInfoBlock/FirstInfoBlock.styl +33 -33
- package/compat/FirstInfoBlock/FirstInfoBlock.tsx +49 -49
- package/compat/FirstInfoBlock/FirstInfoBlockItem/FirstInfoBlockItem.styl +66 -66
- package/compat/FirstInfoBlock/FirstInfoBlockItem/FirstInfoBlockItem.tsx +21 -21
- package/compat/FormattedNumber/FormattedNumber.styl +1 -1
- package/compat/FormattedNumber/FormattedNumber.tsx +90 -90
- package/compat/IconContainer/IconContainer.styl +23 -23
- package/compat/IconContainer/IconContainer.tsx +34 -34
- package/compat/Image/Image.styl +109 -109
- package/compat/Image/Image.tsx +302 -302
- package/compat/ImageSettings/EditableOptionsTable/CustomCheckbox/CustomCheckbox.styl +7 -7
- package/compat/ImageSettings/EditableOptionsTable/CustomCheckbox/CustomCheckbox.tsx +30 -30
- package/compat/ImageSettings/EditableOptionsTable/EditableOptionsTable.styl +122 -122
- package/compat/ImageSettings/EditableOptionsTable/EditableOptionsTable.tsx +199 -199
- package/compat/ImageSettings/EditableOptionsTable/ImageIcon/ImageIcon.styl +3 -3
- package/compat/ImageSettings/EditableOptionsTable/ImageIcon/ImageIcon.tsx +15 -15
- package/compat/ImageSettings/OptionsTable/OptionsTable.styl +47 -47
- package/compat/ImageSettings/OptionsTable/OptionsTable.tsx +122 -122
- package/compat/ImageSettings/PricePlan/PricePlan.styl +63 -63
- package/compat/ImageSettings/PricePlan/PricePlan.tsx +32 -32
- package/compat/ImageSettings/index.ts +42 -42
- package/compat/ImagesSet/ImagesSet.styl +27 -27
- package/compat/ImagesSet/ImagesSet.tsx +76 -76
- package/compat/InfoBlockWrapper/InfoBlockWrapper.styl +41 -41
- package/compat/InfoBlockWrapper/InfoBlockWrapper.tsx +46 -46
- package/compat/Loader/Loader.styl +39 -39
- package/compat/Loader/Loader.tsx +32 -32
- package/compat/MagnifyGlass/MagnifyGlass.styl +33 -33
- package/compat/MagnifyGlass/MagnifyGlass.tsx +213 -213
- package/compat/MdAccordionGroup/MdAccordionGroup.tsx +53 -53
- package/compat/MdCheckbox/MdCheckbox.tsx +69 -69
- package/compat/MdField/MdField.tsx +100 -100
- package/compat/MdSelect/MdSelect.tsx +103 -103
- package/compat/MdSwitch/MdSwitch.tsx +29 -29
- package/compat/MdTabs/MdTabs.tsx +47 -47
- package/compat/MdTooltip/MdTooltip.tsx +31 -31
- package/compat/OfferDetailedSection/OfferDetailedSection.styl +31 -31
- package/compat/OfferDetailedSection/OfferDetailedSection.tsx +100 -100
- package/compat/OfferDetailedSection/partials/PanelConfig.styl +131 -131
- package/compat/OfferDetailedSection/partials/PanelConfig.tsx +121 -121
- package/compat/OfferPanel/AboAccordion/AboAccordion.styl +24 -24
- package/compat/OfferPanel/AboAccordion/AboAccordion.tsx +128 -128
- package/compat/OfferPanel/AboAccordion/AboColorOptions/AboColorOptions.styl +11 -11
- package/compat/OfferPanel/AboAccordion/AboColorOptions/AboColorOptions.tsx +35 -35
- package/compat/OfferPanel/AboAccordion/AboFaq/AboFaq.styl +20 -20
- package/compat/OfferPanel/AboAccordion/AboFaq/AboFaq.tsx +25 -25
- package/compat/OfferPanel/AboAccordion/AboIncludedServices/AboIncludedServices.styl +13 -13
- package/compat/OfferPanel/AboAccordion/AboIncludedServices/AboIncludedServices.tsx +39 -39
- package/compat/OfferPanel/MuiOfferPeriod/MuiOfferPeriod.tsx +42 -42
- package/compat/OfferPanel/OfferCheckboxGroup/CheckboxContainer.tsx +140 -140
- package/compat/OfferPanel/OfferCheckboxGroup/OfferCheckboxGroup.styl +144 -144
- package/compat/OfferPanel/OfferCheckboxGroup/OfferCheckboxGroup.tsx +23 -23
- package/compat/OfferPanel/OfferPanel.styl +193 -193
- package/compat/OfferPanel/OfferPanel.tsx +81 -81
- package/compat/OfferPanel/OfferPeriod/OfferPeriod.styl +24 -24
- package/compat/OfferPanel/OfferPeriod/OfferPeriod.tsx +45 -45
- package/compat/OfferPanel/RangeGroup/RangeGroup.tsx +39 -39
- package/compat/OfferRequestButtonWrapper/OfferRequestButtonWrapper.styl +119 -119
- package/compat/OfferRequestButtonWrapper/OfferRequestButtonWrapper.styled.tsx +33 -33
- package/compat/OfferRequestButtonWrapper/OfferRequestButtonWrapper.tsx +122 -122
- package/compat/PriceRating/PriceRating.styl +47 -47
- package/compat/PriceRating/PriceRating.tsx +64 -64
- package/compat/PriceRatingDetailed/PriceRatingDetailed.styl +120 -120
- package/compat/PriceRatingDetailed/PriceRatingDetailed.tsx +191 -191
- package/compat/PricingToolBlock/PricingTool.styl +6 -6
- package/compat/PricingToolBlock/PricingTool.tsx +29 -29
- package/compat/Radio/Radio.styl +115 -115
- package/compat/Radio/Radio.tsx +141 -141
- package/compat/Radio/RadioGroup.styl +5 -5
- package/compat/Radio/RadioGroup.tsx +65 -65
- package/compat/Range/Range.tsx +79 -79
- package/compat/RateSearchValue/RateSearchValue.styl +22 -22
- package/compat/RateSearchValue/RateSearchValue.tsx +55 -55
- package/compat/RateSearchWidget/RateSearchWidget.styl +106 -106
- package/compat/RateSearchWidget/RateSearchWidget.tsx +163 -163
- package/compat/ServiceBlockItem/ServiceBlockItem.styl +47 -47
- package/compat/ServiceBlockItem/ServiceBlockItem.tsx +25 -25
- package/compat/SkeletonItem/SkeletonItem.styl +80 -80
- package/compat/SkeletonItem/SkeletonItem.tsx +80 -80
- package/compat/StarButton/StarButton.styl +39 -39
- package/compat/StarButton/StarButton.tsx +31 -31
- package/compat/TabPanel/TabPanel.tsx +28 -28
- package/compat/TimePicker/TimePicker.styl +22 -22
- package/compat/TimePicker/TimePicker.tsx +156 -156
- package/compat/Tooltip/Tooltip.styl +117 -117
- package/compat/Tooltip/Tooltip.tsx +63 -63
- package/compat/Usp/Usp.styl +78 -78
- package/compat/Usp/Usp.tsx +30 -30
- package/compat/Usp/uspTranslate.ts +12 -12
- package/compat/VehicleDetailedSidebar/VehicleDetailedSidebar.styl +36 -36
- package/compat/VehicleDetailedSidebar/VehicleDetailedSidebar.tsx +178 -178
- package/compat/VehicleDetailedSidebar/partials/Price.styl +27 -27
- package/compat/VehicleDetailedSidebar/partials/Price.tsx +41 -41
- package/compat/VehicleDetailedSidebar/partials/PriceContent.styl +123 -123
- package/compat/VehicleDetailedSidebar/partials/PriceContent.tsx +128 -128
- package/compat/VehicleDetailedSidebar/partials/Properties.styl +58 -58
- package/compat/VehicleDetailedSidebar/partials/Properties.tsx +155 -155
- package/compat/VehicleDetailedSidebar/partials/Title.styl +35 -35
- package/compat/VehicleDetailedSidebar/partials/Title.tsx +33 -33
- package/compat/VehicleDetailedSlider/VehicleDetailedSlider.styl +146 -146
- package/compat/VehicleDetailedSlider/VehicleDetailedSlider.tsx +382 -382
- package/compat/VehicleDetailedSlider/partials/MobileStast.tsx +61 -61
- package/compat/VehicleDetailedSlider/partials/MobileStats.styl +71 -71
- package/compat/VehicleDetailedSlider/partials/PriceData.styl +50 -50
- package/compat/VehicleDetailedSlider/partials/PriceData.tsx +67 -67
- package/compat/VehicleDetailedSlider/partials/Stats.styl +80 -80
- package/compat/VehicleDetailedSlider/partials/Stats.tsx +62 -62
- package/compat/VehicleDetailedSlider/partials/Title.styl +44 -44
- package/compat/VehicleDetailedSlider/partials/Title.tsx +36 -36
- package/compat/VehicleFormattedPrice/VehicleFormattedPrice.styl +148 -148
- package/compat/VehicleFormattedPrice/VehicleFormattedPrice.tsx +163 -163
- package/compat/VehicleSlider/VehicleSlider.styl +62 -62
- package/compat/VehicleSlider/VehicleSlider.tsx +125 -125
- package/compat/VehicleSlider/VehicleSliderForSRL.tsx +175 -175
- package/compat/VehicleSmallCard/SeoText/SeoText.styl +8 -8
- package/compat/VehicleSmallCard/SeoText/SeoText.tsx +16 -16
- package/compat/VehicleSmallCard/VehicleData/VechiclePriceItem/VechiclePriceItem.styl +204 -204
- package/compat/VehicleSmallCard/VehicleData/VechiclePriceItem/VechiclePriceItem.tsx +199 -199
- package/compat/VehicleSmallCard/VehicleData/VehicleInfo/VehicleInfo.styl +273 -273
- package/compat/VehicleSmallCard/VehicleData/VehicleInfo/VehicleInfo.tsx +179 -179
- package/compat/VehicleSmallCard/VehicleData/VehiclePrice/VehiclePrice.styl +165 -165
- package/compat/VehicleSmallCard/VehicleData/VehiclePrice/VehiclePrice.tsx +299 -299
- package/compat/VehicleSmallCard/VehicleData/VehicleProperty/VehicleProperty.styl +32 -32
- package/compat/VehicleSmallCard/VehicleData/VehicleProperty/VehicleProperty.tsx +35 -35
- package/compat/VehicleSmallCard/VehicleData/VehicleTitle/VehicleTitle.styl +135 -135
- package/compat/VehicleSmallCard/VehicleData/VehicleTitle/VehicleTitle.tsx +91 -91
- package/compat/VehicleSmallCard/VehicleSmallCard.styl +309 -309
- package/compat/VehicleSmallCard/VehicleSmallCard.tsx +448 -448
- package/compat/index.ts +77 -77
- package/compat/legacy-theme/mixins.styl +93 -93
- package/compat/legacy-theme/priceReviewColors.styl +12 -12
- package/compat/legacy-theme/slider.global.styl +5 -5
- package/compat/legacy-theme/theme.styl +136 -136
- package/compat/withLabel/withLabel.styl +33 -33
- package/compat/withLabel/withLabel.tsx +44 -44
- package/compat/withStats/withStats.styl +174 -174
- package/compat/withStats/withStats.tsx +238 -238
- package/constants/RateSearchWidget.ts +15 -15
- package/constants/Search.ts +290 -290
- package/constants/SearchWidget.ts +108 -108
- package/constants/app.ts +223 -223
- package/constants/common.ts +127 -127
- package/constants/core.ts +131 -131
- package/constants/highlights.ts +165 -165
- package/constants/price.ts +9 -9
- package/constants/selectors.ts +38 -38
- package/constants.ts +91 -91
- package/data/DataTransformers.ts +88 -88
- package/data/fieldMapping.ts +364 -342
- package/data/toAutobahnCar.ts +455 -442
- package/iconsvg/IconSVG.tsx +30 -30
- package/iconsvg/IconSVGConfig.tsx +768 -768
- package/iconsvg/SVG/AboPartner.tsx +16 -16
- package/iconsvg/SVG/ArrowQuotes.tsx +22 -22
- package/iconsvg/SVG/CloseIcon.tsx +17 -17
- package/iconsvg/SVG/CloseIconSelect.tsx +18 -18
- package/iconsvg/SVG/ClosedLockIcon.tsx +18 -18
- package/iconsvg/SVG/DealerCheckIcon.tsx +18 -18
- package/iconsvg/SVG/DealerPopoverMail.tsx +21 -21
- package/iconsvg/SVG/DealerPopoverPhone.tsx +21 -21
- package/iconsvg/SVG/GrayPhoneIcon.tsx +22 -22
- package/iconsvg/SVG/InternetIcon.tsx +18 -18
- package/iconsvg/SVG/WhiteEnvelopeIcon.tsx +21 -21
- package/iconsvg/SVG/bodyType/Cabrio.tsx +23 -23
- package/iconsvg/SVG/bodyType/Coupe.tsx +22 -22
- package/iconsvg/SVG/bodyType/Minibus.tsx +22 -22
- package/iconsvg/SVG/bodyType/Other.tsx +25 -25
- package/iconsvg/SVG/bodyType/Sedan.tsx +22 -22
- package/iconsvg/SVG/bodyType/SelectorCategoryCombi.tsx +68 -68
- package/iconsvg/SVG/bodyType/SelectorCategoryCompact.tsx +20 -20
- package/iconsvg/SVG/bodyType/SelectorCategoryConvertible.tsx +68 -68
- package/iconsvg/SVG/bodyType/SelectorCategoryCoupe.tsx +60 -60
- package/iconsvg/SVG/bodyType/SelectorCategoryMinibus.tsx +64 -64
- package/iconsvg/SVG/bodyType/SelectorCategoryOther.tsx +60 -60
- package/iconsvg/SVG/bodyType/SelectorCategorySedan.tsx +69 -69
- package/iconsvg/SVG/bodyType/SelectorCategorySuv.tsx +77 -77
- package/iconsvg/SVG/bodyType/SelectorCategoryTransporter.tsx +68 -68
- package/iconsvg/SVG/bodyType/SelectorCategoryVan.tsx +72 -72
- package/iconsvg/SVG/bodyType/Small.tsx +23 -23
- package/iconsvg/SVG/bodyType/Suv.tsx +23 -23
- package/iconsvg/SVG/bodyType/Van.tsx +23 -23
- package/iconsvg/SVG/bodyType/Wagon.tsx +23 -23
- package/iconsvg/SVG/common/AddIcon.tsx +16 -16
- package/iconsvg/SVG/common/AddPlus.tsx +16 -16
- package/iconsvg/SVG/common/AddressDashboard.tsx +29 -29
- package/iconsvg/SVG/common/AddressIcon.tsx +20 -20
- package/iconsvg/SVG/common/ArrowDetailedAccordionBlue.tsx +26 -26
- package/iconsvg/SVG/common/ArrowDownBlue.tsx +21 -21
- package/iconsvg/SVG/common/ArrowSelect.tsx +23 -23
- package/iconsvg/SVG/common/ArrowStepDown.tsx +18 -18
- package/iconsvg/SVG/common/Autocheck.tsx +19 -19
- package/iconsvg/SVG/common/AutodeLogo.tsx +36 -36
- package/iconsvg/SVG/common/Avatar.tsx +17 -17
- package/iconsvg/SVG/common/BellGray.tsx +19 -19
- package/iconsvg/SVG/common/BigInfoTransparent.tsx +13 -13
- package/iconsvg/SVG/common/Browse.tsx +20 -20
- package/iconsvg/SVG/common/Calendar.tsx +24 -24
- package/iconsvg/SVG/common/CallbackDashboard.tsx +30 -30
- package/iconsvg/SVG/common/Camera.tsx +17 -17
- package/iconsvg/SVG/common/Car.tsx +16 -16
- package/iconsvg/SVG/common/CarBody.tsx +19 -19
- package/iconsvg/SVG/common/CarFront.tsx +43 -43
- package/iconsvg/SVG/common/CarInspectionCheck.tsx +21 -21
- package/iconsvg/SVG/common/CarInspectionScheme0.tsx +32 -32
- package/iconsvg/SVG/common/CarInspectionScheme1.tsx +53 -53
- package/iconsvg/SVG/common/CarInspectionScheme2.tsx +52 -52
- package/iconsvg/SVG/common/CarInspectionScheme3.tsx +32 -32
- package/iconsvg/SVG/common/CarInspectionScheme4.tsx +32 -32
- package/iconsvg/SVG/common/CarInspectionScheme5.tsx +32 -32
- package/iconsvg/SVG/common/CarInspectionScheme6.tsx +32 -32
- package/iconsvg/SVG/common/CarInspectionSchemeGeneral copy.tsx +24 -24
- package/iconsvg/SVG/common/CarInspectionSchemeGeneral.tsx +24 -24
- package/iconsvg/SVG/common/CheckBlue.tsx +18 -18
- package/iconsvg/SVG/common/CheckGreen.tsx +22 -22
- package/iconsvg/SVG/common/CheckMark.tsx +16 -16
- package/iconsvg/SVG/common/CheckWhite.tsx +19 -19
- package/iconsvg/SVG/common/Chevron.tsx +17 -17
- package/iconsvg/SVG/common/CircledCheckmark.tsx +25 -25
- package/iconsvg/SVG/common/Clock.tsx +18 -18
- package/iconsvg/SVG/common/Close.tsx +19 -19
- package/iconsvg/SVG/common/CloseGrey.tsx +22 -22
- package/iconsvg/SVG/common/ContactEmail.tsx +21 -21
- package/iconsvg/SVG/common/ContactPhone.tsx +28 -28
- package/iconsvg/SVG/common/CopyIcon copy.tsx +22 -22
- package/iconsvg/SVG/common/CopyIcon.tsx +22 -22
- package/iconsvg/SVG/common/CopyIconForDealer.tsx +21 -21
- package/iconsvg/SVG/common/DashboardIcon.tsx +20 -20
- package/iconsvg/SVG/common/DashboardQuestionMark.tsx +20 -20
- package/iconsvg/SVG/common/DealersIcon.tsx +20 -20
- package/iconsvg/SVG/common/DeleteCircle.tsx +31 -31
- package/iconsvg/SVG/common/DeleteV1Icon.tsx +18 -18
- package/iconsvg/SVG/common/DeliveryDashboard.tsx +25 -25
- package/iconsvg/SVG/common/DeliveryMail.tsx +24 -24
- package/iconsvg/SVG/common/Discount100De.tsx +18 -18
- package/iconsvg/SVG/common/Discount100En.tsx +19 -19
- package/iconsvg/SVG/common/Discount66De.tsx +28 -28
- package/iconsvg/SVG/common/Discount66En.tsx +20 -20
- package/iconsvg/SVG/common/DoneIcon.tsx +18 -18
- package/iconsvg/SVG/common/EditCircle.tsx +32 -32
- package/iconsvg/SVG/common/EditPriceIcon.tsx +20 -20
- package/iconsvg/SVG/common/EuroCurrency.tsx +18 -18
- package/iconsvg/SVG/common/Export.tsx +20 -20
- package/iconsvg/SVG/common/Eye.tsx +17 -17
- package/iconsvg/SVG/common/EyeCatch.tsx +19 -19
- package/iconsvg/SVG/common/FavoritesIcon.tsx +20 -20
- package/iconsvg/SVG/common/FilterRange.tsx +16 -16
- package/iconsvg/SVG/common/FilterToolBlack.tsx +23 -23
- package/iconsvg/SVG/common/FlagDe.tsx +21 -21
- package/iconsvg/SVG/common/FlagEn.tsx +43 -43
- package/iconsvg/SVG/common/GrayEnvelopeIcon.tsx +19 -19
- package/iconsvg/SVG/common/HamburgerMenuIcon.tsx +18 -18
- package/iconsvg/SVG/common/HandingOverDashboard.tsx +32 -32
- package/iconsvg/SVG/common/ImageSettingsIcon.tsx +20 -20
- package/iconsvg/SVG/common/Info.tsx +16 -16
- package/iconsvg/SVG/common/InfoIcon.tsx +17 -17
- package/iconsvg/SVG/common/InfoTransparent.tsx +18 -18
- package/iconsvg/SVG/common/LogoutIcon.tsx +20 -20
- package/iconsvg/SVG/common/MagnifyingGlass.tsx +31 -31
- package/iconsvg/SVG/common/MenuArrow.tsx +16 -16
- package/iconsvg/SVG/common/MenuGrey.tsx +22 -22
- package/iconsvg/SVG/common/MobileDeLogo.tsx +108 -108
- package/iconsvg/SVG/common/MyOrderIcon.tsx +20 -20
- package/iconsvg/SVG/common/MyVehiclesIcon.tsx +20 -20
- package/iconsvg/SVG/common/NewFlagDe.tsx +25 -25
- package/iconsvg/SVG/common/NewFlagEn.tsx +34 -34
- package/iconsvg/SVG/common/OrderReceivedDashboard.tsx +27 -27
- package/iconsvg/SVG/common/Package.tsx +30 -30
- package/iconsvg/SVG/common/Phone.tsx +18 -18
- package/iconsvg/SVG/common/PhoneGrey.tsx +22 -22
- package/iconsvg/SVG/common/PickupDashboard.tsx +30 -30
- package/iconsvg/SVG/common/Picture.tsx +24 -24
- package/iconsvg/SVG/common/Pictures.tsx +32 -32
- package/iconsvg/SVG/common/Plus.tsx +16 -16
- package/iconsvg/SVG/common/PlusNew.tsx +16 -16
- package/iconsvg/SVG/common/PreparationDashboard.tsx +29 -29
- package/iconsvg/SVG/common/ProfileDashboard.tsx +24 -24
- package/iconsvg/SVG/common/ProfileIcon.tsx +17 -17
- package/iconsvg/SVG/common/Question.tsx +19 -19
- package/iconsvg/SVG/common/QuestionBold.tsx +25 -25
- package/iconsvg/SVG/common/RegistrationDashboard.tsx +31 -31
- package/iconsvg/SVG/common/SavedSearchsIcon.tsx +20 -20
- package/iconsvg/SVG/common/Search.tsx +19 -19
- package/iconsvg/SVG/common/SearchGrey.tsx +22 -22
- package/iconsvg/SVG/common/SettingPenIcon.tsx +20 -20
- package/iconsvg/SVG/common/Share.tsx +16 -16
- package/iconsvg/SVG/common/ShoppingCart.tsx +18 -18
- package/iconsvg/SVG/common/SliderArrow.tsx +21 -21
- package/iconsvg/SVG/common/SliderEye.tsx +17 -17
- package/iconsvg/SVG/common/SortUpDownArrows.tsx +18 -18
- package/iconsvg/SVG/common/Speedometer.tsx +23 -23
- package/iconsvg/SVG/common/Star.tsx +20 -20
- package/iconsvg/SVG/common/StarNew.tsx +16 -16
- package/iconsvg/SVG/common/StarOutline.tsx +20 -20
- package/iconsvg/SVG/common/StarRoundedCorners.tsx +18 -18
- package/iconsvg/SVG/common/Stats.tsx +17 -17
- package/iconsvg/SVG/common/Step1.tsx +21 -21
- package/iconsvg/SVG/common/Step2.tsx +20 -20
- package/iconsvg/SVG/common/Step3.tsx +21 -21
- package/iconsvg/SVG/common/SupportCallbackIcon.tsx +20 -20
- package/iconsvg/SVG/common/Telephone.tsx +22 -22
- package/iconsvg/SVG/common/Time.tsx +17 -17
- package/iconsvg/SVG/common/Timetable.tsx +18 -18
- package/iconsvg/SVG/common/Trash.tsx +22 -22
- package/iconsvg/SVG/common/TrashRed.tsx +23 -23
- package/iconsvg/SVG/common/Upload.tsx +17 -17
- package/iconsvg/SVG/common/UserGrey.tsx +22 -22
- package/iconsvg/SVG/common/UserProfileIcon.tsx +20 -20
- package/iconsvg/SVG/common/ValidateFailure.tsx +21 -21
- package/iconsvg/SVG/common/ValidateSuccess.tsx +21 -21
- package/iconsvg/SVG/common/WarningTriangle.tsx +20 -20
- package/iconsvg/SVG/common/WhiteArrowUp.tsx +21 -21
- package/iconsvg/SVG/common/WhiteKey.tsx +21 -21
- package/iconsvg/SVG/common/WhitePeople.tsx +23 -23
- package/iconsvg/SVG/common/WhiteTick.tsx +19 -19
- package/iconsvg/SVG/flags/AT.tsx +19 -19
- package/iconsvg/SVG/flags/BE.tsx +20 -20
- package/iconsvg/SVG/flags/BG.tsx +20 -20
- package/iconsvg/SVG/flags/CH.tsx +22 -22
- package/iconsvg/SVG/flags/CZ.tsx +18 -18
- package/iconsvg/SVG/flags/DE.tsx +18 -18
- package/iconsvg/SVG/flags/DK.tsx +18 -18
- package/iconsvg/SVG/flags/ES.tsx +2585 -2585
- package/iconsvg/SVG/flags/FI.tsx +18 -18
- package/iconsvg/SVG/flags/FR.tsx +20 -20
- package/iconsvg/SVG/flags/GB.tsx +26 -26
- package/iconsvg/SVG/flags/HR.tsx +135 -135
- package/iconsvg/SVG/flags/HU.tsx +20 -20
- package/iconsvg/SVG/flags/IT.tsx +20 -20
- package/iconsvg/SVG/flags/LI.tsx +106 -106
- package/iconsvg/SVG/flags/LU.tsx +18 -18
- package/iconsvg/SVG/flags/NL.tsx +18 -18
- package/iconsvg/SVG/flags/NO.tsx +20 -20
- package/iconsvg/SVG/flags/PL.tsx +19 -19
- package/iconsvg/SVG/flags/RO.tsx +20 -20
- package/iconsvg/SVG/flags/RU.tsx +20 -20
- package/iconsvg/SVG/flags/SE.tsx +20 -20
- package/iconsvg/SVG/flags/SI.tsx +54 -54
- package/iconsvg/SVG/flags/SK.tsx +34 -34
- package/iconsvg/SVG/flags/UA.tsx +19 -19
- package/iconsvg/SVG/infoBlocks/14DaysReturnPolicy.tsx +18 -18
- package/iconsvg/SVG/infoBlocks/AlertInfo.tsx +19 -19
- package/iconsvg/SVG/infoBlocks/Autocheck.tsx +19 -19
- package/iconsvg/SVG/infoBlocks/CheckTheStory.tsx +22 -22
- package/iconsvg/SVG/infoBlocks/CustomerServiceWhite.tsx +16 -16
- package/iconsvg/SVG/infoBlocks/Guarantee.tsx +16 -16
- package/iconsvg/SVG/infoBlocks/OrderWhite.tsx +13 -13
- package/iconsvg/SVG/infoBlocks/PriceGuarantee.tsx +19 -19
- package/iconsvg/SVG/infoBlocks/PriceGuaranteeWhite.tsx +17 -17
- package/iconsvg/SVG/infoBlocks/TransportAndDelivery.tsx +21 -21
- package/iconsvg/SVG/infoBlocks/Warranty.tsx +23 -23
- package/iconsvg/SVG/popower/Mail.tsx +18 -18
- package/iconsvg/SVG/popower/Phone.tsx +19 -19
- package/iconsvg/SVG/popower/Schedule.tsx +18 -18
- package/iconsvg/SVG/searchWidgets/drive/AAllWheelDrive.tsx +26 -26
- package/iconsvg/SVG/searchWidgets/drive/AllWheelDrive.tsx +26 -26
- package/iconsvg/SVG/searchWidgets/drive/FrontWheelDrive.tsx +25 -25
- package/iconsvg/SVG/searchWidgets/drive/OtherWheelDrive.tsx +26 -26
- package/iconsvg/SVG/searchWidgets/drive/RearWheelDrive.tsx +25 -25
- package/iconsvg/SVG/searchWidgets/fuel/FuelDiesel.tsx +18 -18
- package/iconsvg/SVG/searchWidgets/fuel/FuelElectrical.tsx +19 -19
- package/iconsvg/SVG/searchWidgets/fuel/FuelElectricalDiesel.tsx +34 -34
- package/iconsvg/SVG/searchWidgets/fuel/FuelElectricalPetrol.tsx +20 -20
- package/iconsvg/SVG/searchWidgets/fuel/FuelEthanol.tsx +53 -53
- package/iconsvg/SVG/searchWidgets/fuel/FuelHydrogen.tsx +24 -24
- package/iconsvg/SVG/searchWidgets/fuel/FuelLpg.tsx +24 -24
- package/iconsvg/SVG/searchWidgets/fuel/FuelNaturalGas.tsx +23 -23
- package/iconsvg/SVG/searchWidgets/fuel/FuelOther.tsx +28 -28
- package/iconsvg/SVG/searchWidgets/fuel/FuelPetrol.tsx +18 -18
- package/iconsvg/SVG/settings/Account.tsx +17 -17
- package/iconsvg/SVG/settings/DataUsage.tsx +17 -17
- package/iconsvg/SVG/settings/MarketResearch.tsx +17 -17
- package/iconsvg/SVG/settings/Newsletter.tsx +17 -17
- package/iconsvg/SVG/settings/RemoveEye.tsx +17 -17
- package/iconsvg/SVG/settings/RemoveEyeOff.tsx +17 -17
- package/iconsvg/SVG/settings/Security.tsx +17 -17
- package/iconsvg/SVG/settings/Warning.tsx +17 -17
- package/iconsvg/SVG/slider/360.tsx +23 -23
- package/iconsvg/SVG/slider/360New.tsx +20 -20
- package/iconsvg/SVG/slider/Checked.tsx +19 -19
- package/iconsvg/SVG/slider/DiscountRibbon.tsx +51 -51
- package/iconsvg/SVG/slider/DiscountRibbonMobile.tsx +47 -47
- package/iconsvg/SVG/slider/DiscountRibbonNew.tsx +29 -29
- package/iconsvg/SVG/slider/Easy.tsx +19 -19
- package/iconsvg/SVG/slider/Fullscreen.tsx +16 -16
- package/iconsvg/SVG/slider/FullscreenWindow.tsx +23 -23
- package/iconsvg/SVG/slider/Safe.tsx +19 -19
- package/iconsvg/SVG/slider/ToBuy.tsx +19 -19
- package/iconsvg/SVG/slider/YoutubeButton.tsx +26 -26
- package/iconsvg/SVG/slider/ZoomIn.tsx +21 -21
- package/iconsvg/SVG/slider/ZoomOut.tsx +21 -21
- package/iconsvg/SVG/social/AndroidLogo.tsx +18 -18
- package/iconsvg/SVG/social/Apple.tsx +19 -19
- package/iconsvg/SVG/social/FacebookF.tsx +19 -19
- package/iconsvg/SVG/social/GooglePlusG.tsx +19 -19
- package/iconsvg/SVG/social/Instagram.tsx +17 -17
- package/iconsvg/SVG/social/Pinterest.tsx +19 -19
- package/iconsvg/SVG/social/SharingInterface.tsx +21 -21
- package/iconsvg/SVG/social/Twitter.tsx +19 -19
- package/iconsvg/SVG/social/Youtube.tsx +19 -19
- package/iconsvg/SVG/vehicle/AboIcon.tsx +11 -11
- package/iconsvg/SVG/vehicle/Abs.tsx +24 -24
- package/iconsvg/SVG/vehicle/AirCond.tsx +34 -34
- package/iconsvg/SVG/vehicle/Airbag.tsx +21 -21
- package/iconsvg/SVG/vehicle/AuxiliaryHeating.tsx +23 -23
- package/iconsvg/SVG/vehicle/Bluetooth.tsx +22 -22
- package/iconsvg/SVG/vehicle/BuyIcon.tsx +15 -15
- package/iconsvg/SVG/vehicle/CarAvailability.tsx +22 -22
- package/iconsvg/SVG/vehicle/CarInspectionCheck.tsx +21 -21
- package/iconsvg/SVG/vehicle/CarInspectionCross.tsx +21 -21
- package/iconsvg/SVG/vehicle/CheckoutChecked.tsx +15 -15
- package/iconsvg/SVG/vehicle/Co2.tsx +24 -24
- package/iconsvg/SVG/vehicle/CruiseControl.tsx +25 -25
- package/iconsvg/SVG/vehicle/Date.tsx +21 -21
- package/iconsvg/SVG/vehicle/Delivery.tsx +12 -12
- package/iconsvg/SVG/vehicle/Diesel.tsx +28 -28
- package/iconsvg/SVG/vehicle/Display.tsx +25 -25
- package/iconsvg/SVG/vehicle/Done.tsx +11 -11
- package/iconsvg/SVG/vehicle/Door.tsx +19 -19
- package/iconsvg/SVG/vehicle/DoubleDone.tsx +18 -18
- package/iconsvg/SVG/vehicle/EditIcon.tsx +11 -11
- package/iconsvg/SVG/vehicle/EmergencyBrakeAssistant.tsx +27 -27
- package/iconsvg/SVG/vehicle/Eps.tsx +24 -24
- package/iconsvg/SVG/vehicle/Esp.tsx +24 -24
- package/iconsvg/SVG/vehicle/FinancingIcon.tsx +20 -20
- package/iconsvg/SVG/vehicle/FuelConsumption.tsx +20 -20
- package/iconsvg/SVG/vehicle/Fueling.tsx +22 -22
- package/iconsvg/SVG/vehicle/FullDrive.tsx +24 -24
- package/iconsvg/SVG/vehicle/GasElectric.tsx +28 -28
- package/iconsvg/SVG/vehicle/HandsFreePhoneSystem.tsx +24 -24
- package/iconsvg/SVG/vehicle/Kw.tsx +23 -23
- package/iconsvg/SVG/vehicle/LastCrawledAt.tsx +22 -22
- package/iconsvg/SVG/vehicle/LeasingIcon.tsx +14 -14
- package/iconsvg/SVG/vehicle/Led.tsx +24 -24
- package/iconsvg/SVG/vehicle/LightSensor.tsx +22 -22
- package/iconsvg/SVG/vehicle/LinkAlternative.tsx +15 -15
- package/iconsvg/SVG/vehicle/Location.tsx +17 -17
- package/iconsvg/SVG/vehicle/MinusIcon.tsx +11 -11
- package/iconsvg/SVG/vehicle/Mirror.tsx +19 -19
- package/iconsvg/SVG/vehicle/Navigation.tsx +27 -27
- package/iconsvg/SVG/vehicle/NewCar.tsx +21 -21
- package/iconsvg/SVG/vehicle/NoImage.tsx +17 -17
- package/iconsvg/SVG/vehicle/Owner.tsx +18 -18
- package/iconsvg/SVG/vehicle/PanoramicRoof.tsx +23 -23
- package/iconsvg/SVG/vehicle/ParkingAssistants.tsx +24 -24
- package/iconsvg/SVG/vehicle/PickYourself.tsx +18 -18
- package/iconsvg/SVG/vehicle/PlusIcon.tsx +11 -11
- package/iconsvg/SVG/vehicle/Power.tsx +21 -21
- package/iconsvg/SVG/vehicle/Ps.tsx +19 -19
- package/iconsvg/SVG/vehicle/Question.tsx +24 -24
- package/iconsvg/SVG/vehicle/Seats.tsx +21 -21
- package/iconsvg/SVG/vehicle/SeatsHeating.tsx +26 -26
- package/iconsvg/SVG/vehicle/SelectorGearboxAutomatic.tsx +24 -24
- package/iconsvg/SVG/vehicle/SelectorGearboxManualShift.tsx +19 -19
- package/iconsvg/SVG/vehicle/SelectorGearboxOther.tsx +24 -24
- package/iconsvg/SVG/vehicle/SelectorGearboxSemiAutomatic.tsx +30 -30
- package/iconsvg/SVG/vehicle/SelectorInteriorTypeAlcantara.tsx +225 -225
- package/iconsvg/SVG/vehicle/SelectorInteriorTypeFabric.tsx +29 -29
- package/iconsvg/SVG/vehicle/SelectorInteriorTypeFullLeather.tsx +29 -29
- package/iconsvg/SVG/vehicle/SelectorInteriorTypeOther.tsx +26 -26
- package/iconsvg/SVG/vehicle/SelectorInteriorTypePartLeather.tsx +142 -142
- package/iconsvg/SVG/vehicle/SelectorInteriorTypeSyntheticLeather.tsx +27 -27
- package/iconsvg/SVG/vehicle/SelectorInteriorTypeVelours.tsx +39 -39
- package/iconsvg/SVG/vehicle/Shield.tsx +39 -39
- package/iconsvg/SVG/vehicle/Speedometer.tsx +17 -17
- package/iconsvg/SVG/vehicle/StartStopSystem.tsx +30 -30
- package/iconsvg/SVG/vehicle/Stop.tsx +25 -25
- package/iconsvg/SVG/vehicle/TickMark.tsx +21 -21
- package/iconsvg/SVG/vehicle/TrafficSignRecognition.tsx +29 -29
- package/iconsvg/SVG/vehicle/TrailerCoupling.tsx +24 -24
- package/iconsvg/SVG/vehicle/Transmission.tsx +27 -27
- package/iconsvg/SVG/vehicle/Wheel.tsx +43 -43
- package/iconsvg/SVG/vehicle/Wipers.tsx +22 -22
- package/iconsvg/SVG/vehicle/Wrench.tsx +17 -17
- package/iconsvg/index.ts +7 -7
- package/index.ts +18 -18
- package/locales/de/autobahn.json +676 -671
- package/locales/en/autobahn.json +676 -671
- package/locales/legacy/SearchDetailedPage.ts +205 -205
- package/locales/legacy/cbd.ts +719 -719
- package/locales/legacy/common.ts +109 -109
- package/locales/legacy/data.ts +1118 -1118
- package/locales/legacy/priceRating.ts +10 -10
- package/locales/legacy/sortingOptions.ts +21 -21
- package/media/images/raiting-stars-min.svg +7 -7
- package/media/images/refresh-button.svg +49 -49
- package/media/images/user-icon.svg +16 -16
- package/media/svg/infoBlocks/whyAutodeIconSet-F.svg +9 -9
- package/media/svg/infoBlocks/whyAutodeIconSet-G.svg +8 -8
- package/media/svg/infoBlocks/whyAutodeIconSet-Q.svg +6 -6
- package/media/svg/infoBlocks/whyAutodeIconSet-R.svg +9 -9
- package/media/svg/usp/icon1.svg +16 -16
- package/media/svg/usp/icon2.svg +13 -13
- package/media/svg/usp/icon3.svg +10 -10
- package/media/svg/usp/icon4.svg +14 -14
- package/package.json +30 -30
- package/schemes/AggregationScheme.ts +73 -73
- package/searchFilters/filterOptions.ts +119 -119
- package/searchFilters/filterProps.ts +35 -35
- package/searchFilters/index.ts +15 -15
- package/theme/autobahn.css +25 -25
- package/theme/colors_and_type.css +113 -113
- package/theme/md3.css +2045 -2034
- package/types/types.ts +373 -373
- package/types.ts +8 -8
- package/ui/Accordion.tsx +134 -134
- package/ui/Button.tsx +62 -62
- package/ui/CardCarousel.tsx +133 -133
- package/ui/Chip.tsx +29 -29
- package/ui/DatePicker.tsx +145 -145
- package/ui/Dropdown.tsx +205 -205
- package/ui/FileUpload.tsx +154 -154
- package/ui/FormCheckbox.tsx +79 -79
- package/ui/FormDropdown.tsx +327 -327
- package/ui/FormField.tsx +88 -88
- package/ui/FormRadio.tsx +93 -93
- package/ui/FormRadioGroup.tsx +106 -106
- package/ui/Icon.tsx +391 -391
- package/ui/IconButton.tsx +44 -44
- package/ui/Modal.tsx +187 -187
- package/ui/Pagination.tsx +140 -140
- package/ui/Price.tsx +25 -25
- package/ui/PriceEvalBar.tsx +48 -48
- package/ui/SaveChip.tsx +34 -34
- package/ui/Segmented.tsx +48 -48
- package/ui/Skeleton.tsx +75 -75
- package/ui/Spec.tsx +24 -24
- package/ui/Stars.tsx +29 -29
- package/ui/StatChip.tsx +21 -21
- package/ui/Stepper.tsx +106 -106
- package/ui/Switch.tsx +65 -65
- package/ui/Table.tsx +156 -156
- package/ui/Textarea.tsx +58 -58
- package/ui/index.ts +88 -88
- package/utils/CommonUtils.ts +648 -648
- package/utils/DateUtils.ts +101 -101
- package/utils/index.ts +74 -74
- package/utils/power.ts +11 -11
- package/utils/query.ts +21 -21
- package/vdp/FinanceCalculator.tsx +465 -465
- package/vdp/VdpModules.tsx +1490 -1490
- package/vdp/VdpViewer.tsx +209 -209
- package/vdp/index.ts +75 -75
- package/vdp/types.ts +197 -197
- package/vehiclesProps/cbdSelectors.ts +117 -117
- package/vehiclesProps/decoratedLightProps.tsx +572 -572
- package/vehiclesProps/decoratedProps.tsx +1746 -1746
- package/vehiclesProps/equipment.ts +129 -129
- package/vehiclesProps/vehicleDetails.ts +428 -428
- package/widgets/SearchBox.tsx +256 -256
- package/widgets/index.ts +5 -5
|
@@ -1,465 +1,465 @@
|
|
|
1
|
-
// Autobahn (auto.de redesign) — VDP offer / finance card (Finanzierung / Leasing /
|
|
2
|
-
// Barzahlung).
|
|
3
|
-
//
|
|
4
|
-
// Structure (desktop rethink, tabs-on-top): payment-type TABS at the top (MD3 underline tabs),
|
|
5
|
-
// then the rate (with any discount), then the "Rate anpassen" rate-editor, then the primary
|
|
6
|
-
// "Angebot sichern" request CTA, and finally the Finanzierungs-/Leasingdetails info + popup link
|
|
7
|
-
// at the foot. Laufzeit is chosen via chips (discrete terms), not a slider.
|
|
8
|
-
//
|
|
9
|
-
// CONTROLLED / PRESENTATIONAL — computes NOTHING financial: `mode`, `monthly`, `down`, `term` and
|
|
10
|
-
// the slider/chip bounds all arrive as props; segment/slider/chip changes are reported back via
|
|
11
|
-
// `onModeChange` / `onDownChange` / `onTermChange`. The real numbers come from `financingStore`.
|
|
12
|
-
// The only local state is the `adjust` expander (pure view state).
|
|
13
|
-
//
|
|
14
|
-
// Renders correctly only inside a `<div className="md3">` subtree.
|
|
15
|
-
|
|
16
|
-
import React, { useState } from 'react';
|
|
17
|
-
import { TranslationFunction } from '../types';
|
|
18
|
-
|
|
19
|
-
import { Button, Icon } from '../ui';
|
|
20
|
-
import { TIER_LABELS, TIER_KEYS, TIER_COLORS } from '../constants';
|
|
21
|
-
|
|
22
|
-
/** Payment mode segment keys. Mirrors the design's ['fin','leasing','cash']. */
|
|
23
|
-
export type FinanceMode = 'fin' | 'leasing' | 'cash';
|
|
24
|
-
|
|
25
|
-
export interface SliderProps {
|
|
26
|
-
min: number;
|
|
27
|
-
max: number;
|
|
28
|
-
step?: number;
|
|
29
|
-
value: number;
|
|
30
|
-
onChange: (value: number) => void;
|
|
31
|
-
/** formats the min/max end labels (and is reused by callers for the value). */
|
|
32
|
-
fmt?: (v: number) => React.ReactNode;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Range slider with a filled track and min/max end labels. The track fill is a
|
|
37
|
-
* linear-gradient driven by the value's position; the design's `.mslider` class
|
|
38
|
-
* styles the thumb/rail.
|
|
39
|
-
*/
|
|
40
|
-
export const Slider: React.FunctionComponent<SliderProps> = ({ min, max, step = 1, value, onChange, fmt = (v) => v }) => {
|
|
41
|
-
const span = max - min;
|
|
42
|
-
const pct = span > 0 ? ((value - min) / span) * 100 : 0;
|
|
43
|
-
return (
|
|
44
|
-
<div>
|
|
45
|
-
<input
|
|
46
|
-
type="range"
|
|
47
|
-
className="mslider"
|
|
48
|
-
min={min}
|
|
49
|
-
max={max}
|
|
50
|
-
step={step}
|
|
51
|
-
value={value}
|
|
52
|
-
onChange={(e) => onChange(Number(e.target.value))}
|
|
53
|
-
style={{ background: `linear-gradient(90deg, var(--md-primary) ${pct}%, var(--md-sc-highest) ${pct}%)` }}
|
|
54
|
-
/>
|
|
55
|
-
<div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 4 }}>
|
|
56
|
-
<span className="md-label-sm">{fmt(min)}</span>
|
|
57
|
-
<span className="md-label-sm">{fmt(max)}</span>
|
|
58
|
-
</div>
|
|
59
|
-
</div>
|
|
60
|
-
);
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
export interface TermChipsProps {
|
|
64
|
-
/** the selectable term values (months), e.g. [12,24,36,48,60,72]. */
|
|
65
|
-
options: number[];
|
|
66
|
-
value: number;
|
|
67
|
-
onChange: (term: number) => void;
|
|
68
|
-
/** i18n function (drilled from the page). */
|
|
69
|
-
t: TranslationFunction;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/** Laufzeit selector — discrete term values as tappable chips (replaces the fiddly slider). */
|
|
73
|
-
export const TermChips: React.FunctionComponent<TermChipsProps> = ({ options, value, onChange, t }) => (
|
|
74
|
-
<div className="term-chips" role="group" aria-label={t('autobahn:finance.termSelection')}>
|
|
75
|
-
{options.map((m) => (
|
|
76
|
-
<button
|
|
77
|
-
key={m}
|
|
78
|
-
type="button"
|
|
79
|
-
aria-pressed={m === value}
|
|
80
|
-
className={'term-chip' + (m === value ? ' on' : '')}
|
|
81
|
-
onClick={() => onChange(m)}
|
|
82
|
-
>
|
|
83
|
-
{m}
|
|
84
|
-
<span className="tc-unit">{t('autobahn:finance.monthUnit')}</span>
|
|
85
|
-
</button>
|
|
86
|
-
))}
|
|
87
|
-
</div>
|
|
88
|
-
);
|
|
89
|
-
|
|
90
|
-
export interface CalcRowProps {
|
|
91
|
-
label: React.ReactNode;
|
|
92
|
-
/** when true, drops the bottom hairline (last row). */
|
|
93
|
-
last?: boolean;
|
|
94
|
-
children?: React.ReactNode;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/** One label/value row inside the "Rate anpassen" / "Details" expander. */
|
|
98
|
-
export const CalcRow: React.FunctionComponent<CalcRowProps> = ({ label, last, children }) => (
|
|
99
|
-
<div
|
|
100
|
-
style={{
|
|
101
|
-
display: 'flex',
|
|
102
|
-
justifyContent: 'space-between',
|
|
103
|
-
alignItems: 'baseline',
|
|
104
|
-
gap: 12,
|
|
105
|
-
padding: '8px 0',
|
|
106
|
-
borderBottom: last ? 0 : '1px solid var(--md-outline-variant)',
|
|
107
|
-
}}
|
|
108
|
-
>
|
|
109
|
-
<span className="md-label-sm">{label}</span>
|
|
110
|
-
<span className="num" style={{ fontSize: 13.5, fontWeight: 600 }}>
|
|
111
|
-
{children}
|
|
112
|
-
</span>
|
|
113
|
-
</div>
|
|
114
|
-
);
|
|
115
|
-
|
|
116
|
-
export interface FinanceCalculatorProps {
|
|
117
|
-
/** active payment mode (controlled). */
|
|
118
|
-
mode: FinanceMode;
|
|
119
|
-
/** purchase price in EUR (the cash mode hero). */
|
|
120
|
-
price: number;
|
|
121
|
-
/** previous/list price — when > price, shown struck through as the UVP in cash mode (real discount). */
|
|
122
|
-
listPrice?: number;
|
|
123
|
-
/** auto.de-ID reference code — shown with the financing/leasing condition line. */
|
|
124
|
-
autoDeId?: string;
|
|
125
|
-
/** price-rating label, e.g. 'Guter Preis' — drives the Preisbewertung indicator. */
|
|
126
|
-
ratingLabel?: string;
|
|
127
|
-
/** computed monthly rate in EUR for the current mode — supplied, NOT computed here. */
|
|
128
|
-
monthly: number;
|
|
129
|
-
/** effective annual rate (%) for the current mode — supplied, NOT computed here. */
|
|
130
|
-
apr: number;
|
|
131
|
-
/** current down payment in EUR (controlled). */
|
|
132
|
-
down: number;
|
|
133
|
-
/** current term in months (controlled). */
|
|
134
|
-
term: number;
|
|
135
|
-
/** down-payment slider bounds. */
|
|
136
|
-
downMin: number;
|
|
137
|
-
downMax: number;
|
|
138
|
-
/** down-payment slider step (EUR). */
|
|
139
|
-
downStep?: number;
|
|
140
|
-
/** term slider bounds (months) — used to derive chip options when termOptions is absent. */
|
|
141
|
-
termMin: number;
|
|
142
|
-
termMax: number;
|
|
143
|
-
/** term slider step (months). */
|
|
144
|
-
termStep?: number;
|
|
145
|
-
/** the discrete selectable terms (months) for the Laufzeit chips. */
|
|
146
|
-
termOptions?: number[];
|
|
147
|
-
/** annual mileage in km (controlled) — leasing/financing Laufleistung/Jahr. Omit to hide the slider. */
|
|
148
|
-
annualMileage?: number;
|
|
149
|
-
/** annual-mileage slider bounds + step (km). */
|
|
150
|
-
annualMileageMin?: number;
|
|
151
|
-
annualMileageMax?: number;
|
|
152
|
-
annualMileageStep?: number;
|
|
153
|
-
/** annual-mileage slider changed. */
|
|
154
|
-
onAnnualMileageChange?: (km: number) => void;
|
|
155
|
-
/** phone number shown on the secondary CTA (touch only). */
|
|
156
|
-
phone?: string;
|
|
157
|
-
/** primary CTA click (Angebot sichern). */
|
|
158
|
-
onSecure?: () => void;
|
|
159
|
-
/** secondary CTA click (phone). */
|
|
160
|
-
onCall?: () => void;
|
|
161
|
-
/** open the Finanzierungs-/Leasingdetails popup (full breakdown + legal). Omit to hide the link. */
|
|
162
|
-
onShowDetails?: () => void;
|
|
163
|
-
/** mode segment changed. */
|
|
164
|
-
onModeChange: (mode: FinanceMode) => void;
|
|
165
|
-
/** down-payment slider changed. */
|
|
166
|
-
onDownChange: (down: number) => void;
|
|
167
|
-
/** term changed. */
|
|
168
|
-
onTermChange: (term: number) => void;
|
|
169
|
-
/** i18n function (drilled from the page). */
|
|
170
|
-
t: TranslationFunction;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const eur = (n: number): string => n.toLocaleString('de-DE');
|
|
174
|
-
|
|
175
|
-
/** build a [min..max] step range (fallback term options when none are supplied). */
|
|
176
|
-
const range = (min: number, max: number, step: number): number[] => {
|
|
177
|
-
const out: number[] = [];
|
|
178
|
-
for (let v = min; v <= max; v += step || 12) out.push(v);
|
|
179
|
-
return out.length ? out : [min];
|
|
180
|
-
};
|
|
181
|
-
|
|
182
|
-
/** quiet primary-colored text link (Finanzierungsdetails / Details anzeigen). */
|
|
183
|
-
const DetailsLink: React.FunctionComponent<{ label: string; onClick: () => void }> = ({ label, onClick }) => (
|
|
184
|
-
<button
|
|
185
|
-
type="button"
|
|
186
|
-
onClick={onClick}
|
|
187
|
-
style={{
|
|
188
|
-
display: 'inline-flex',
|
|
189
|
-
alignItems: 'center',
|
|
190
|
-
gap: 5,
|
|
191
|
-
background: 'none',
|
|
192
|
-
border: 0,
|
|
193
|
-
padding: 0,
|
|
194
|
-
cursor: 'pointer',
|
|
195
|
-
color: 'var(--md-primary)',
|
|
196
|
-
font: 'inherit',
|
|
197
|
-
fontSize: 13,
|
|
198
|
-
fontWeight: 600,
|
|
199
|
-
}}
|
|
200
|
-
>
|
|
201
|
-
<Icon name="info" size={15} color="var(--md-primary)" />
|
|
202
|
-
{label}
|
|
203
|
-
</button>
|
|
204
|
-
);
|
|
205
|
-
|
|
206
|
-
/** "Rate anpassen" / "Details anzeigen" expander toggle button. */
|
|
207
|
-
const expanderBtnStyle: React.CSSProperties = {
|
|
208
|
-
width: '100%',
|
|
209
|
-
background: 'none',
|
|
210
|
-
border: 0,
|
|
211
|
-
cursor: 'pointer',
|
|
212
|
-
display: 'flex',
|
|
213
|
-
alignItems: 'center',
|
|
214
|
-
justifyContent: 'space-between',
|
|
215
|
-
padding: '10px 0 2px',
|
|
216
|
-
color: 'var(--md-primary)',
|
|
217
|
-
fontWeight: 600,
|
|
218
|
-
fontSize: 14,
|
|
219
|
-
};
|
|
220
|
-
|
|
221
|
-
const FinanceCalculator: React.FunctionComponent<FinanceCalculatorProps> = ({
|
|
222
|
-
mode,
|
|
223
|
-
price,
|
|
224
|
-
listPrice,
|
|
225
|
-
autoDeId,
|
|
226
|
-
ratingLabel,
|
|
227
|
-
monthly,
|
|
228
|
-
down,
|
|
229
|
-
term,
|
|
230
|
-
downMin,
|
|
231
|
-
downMax,
|
|
232
|
-
downStep = 500,
|
|
233
|
-
termMin,
|
|
234
|
-
termMax,
|
|
235
|
-
termStep = 6,
|
|
236
|
-
termOptions,
|
|
237
|
-
annualMileage,
|
|
238
|
-
annualMileageMin = 5000,
|
|
239
|
-
annualMileageMax = 60000,
|
|
240
|
-
annualMileageStep = 5000,
|
|
241
|
-
onAnnualMileageChange,
|
|
242
|
-
phone = '0800 40 30 182',
|
|
243
|
-
onSecure,
|
|
244
|
-
onCall,
|
|
245
|
-
onShowDetails,
|
|
246
|
-
onModeChange,
|
|
247
|
-
onDownChange,
|
|
248
|
-
onTermChange,
|
|
249
|
-
t,
|
|
250
|
-
}) => {
|
|
251
|
-
// Pure view state only — whether the adjust/details expander is open.
|
|
252
|
-
const [adjust, setAdjust] = useState(false);
|
|
253
|
-
const isCash = mode === 'cash';
|
|
254
|
-
const terms = termOptions && termOptions.length ? termOptions : range(termMin, termMax, termStep);
|
|
255
|
-
const showStrike = listPrice != null && listPrice > price;
|
|
256
|
-
// price-evaluation tier from the rating label (defaults to 'Guter Preis' tier when unmapped).
|
|
257
|
-
const tierIdx = TIER_LABELS.indexOf(ratingLabel as (typeof TIER_LABELS)[number]);
|
|
258
|
-
const evalTier = tierIdx >= 0 ? tierIdx : 1;
|
|
259
|
-
const evalTierLabel = t('autobahn:tier.' + TIER_KEYS[evalTier]);
|
|
260
|
-
// condition summary (current selection) — the auto.de-ID lives with the details link, not here.
|
|
261
|
-
const condParts: string[] = [];
|
|
262
|
-
if (!isCash) {
|
|
263
|
-
condParts.push(
|
|
264
|
-
mode === 'leasing' && annualMileage != null
|
|
265
|
-
? t('autobahn:finance.kmPerYear', { value: eur(annualMileage) })
|
|
266
|
-
: t('autobahn:finance.downPaymentLabel', { value: eur(down) }),
|
|
267
|
-
);
|
|
268
|
-
condParts.push(t('autobahn:finance.monthsLabel', { months: term, count: term }));
|
|
269
|
-
}
|
|
270
|
-
const condLine = condParts.join(' · ');
|
|
271
|
-
|
|
272
|
-
return (
|
|
273
|
-
<div className="mcard mcard--elevated" style={{ padding: 20 }}>
|
|
274
|
-
{/* header */}
|
|
275
|
-
<div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 14 }}>
|
|
276
|
-
<span
|
|
277
|
-
style={{
|
|
278
|
-
width: 34,
|
|
279
|
-
height: 34,
|
|
280
|
-
borderRadius: 'var(--md-r-full)',
|
|
281
|
-
background: 'var(--md-primary-container)',
|
|
282
|
-
display: 'flex',
|
|
283
|
-
alignItems: 'center',
|
|
284
|
-
justifyContent: 'center',
|
|
285
|
-
flex: 'none',
|
|
286
|
-
}}
|
|
287
|
-
>
|
|
288
|
-
<Icon name="tag" size={18} color="var(--md-on-primary-container)" />
|
|
289
|
-
</span>
|
|
290
|
-
<div style={{ fontFamily: 'var(--md-font-display)', fontSize: 18, fontWeight: 700 }}>{t('autobahn:finance.headerTitle')}</div>
|
|
291
|
-
</div>
|
|
292
|
-
|
|
293
|
-
{/* payment-type TABS on top */}
|
|
294
|
-
<div className="fin-tabs" role="tablist">
|
|
295
|
-
{(
|
|
296
|
-
[
|
|
297
|
-
['fin', 'autobahn:finance.mode.financing'],
|
|
298
|
-
['leasing', 'autobahn:finance.mode.leasing'],
|
|
299
|
-
['cash', 'autobahn:finance.mode.cash'],
|
|
300
|
-
] as Array<[FinanceMode, string]>
|
|
301
|
-
).map(([k, labelKey]) => (
|
|
302
|
-
<button
|
|
303
|
-
key={k}
|
|
304
|
-
type="button"
|
|
305
|
-
role="tab"
|
|
306
|
-
aria-selected={mode === k}
|
|
307
|
-
className={'fin-tab' + (mode === k ? ' on' : '')}
|
|
308
|
-
onClick={() => onModeChange(k)}
|
|
309
|
-
>
|
|
310
|
-
{t(labelKey)}
|
|
311
|
-
</button>
|
|
312
|
-
))}
|
|
313
|
-
</div>
|
|
314
|
-
|
|
315
|
-
{/* 2-col grid: rate|pill (row 1) + condLine|bar (row 2) — fixed right column prevents wrapping */}
|
|
316
|
-
<div className="fin-price-grid">
|
|
317
|
-
{/* col 1 row 1: hero rate */}
|
|
318
|
-
<div className="fin-rate-main">
|
|
319
|
-
<div style={{ display: 'flex', alignItems: 'baseline', gap: 5 }}>
|
|
320
|
-
<span
|
|
321
|
-
className="num"
|
|
322
|
-
style={{ fontSize: 48, fontWeight: 800, color: 'var(--md-primary)', letterSpacing: '-2px' }}
|
|
323
|
-
>
|
|
324
|
-
{isCash ? eur(price) : eur(Math.round(monthly))}
|
|
325
|
-
</span>
|
|
326
|
-
<span className="md-body-sm" style={{ fontWeight: 600 }}>
|
|
327
|
-
{isCash ? '€' : `€ ${t('autobahn:finance.perMonth')}`}
|
|
328
|
-
</span>
|
|
329
|
-
</div>
|
|
330
|
-
{isCash && <div className="md-label-sm">{t('autobahn:finance.fixedPrice')}</div>}
|
|
331
|
-
{isCash && showStrike && (
|
|
332
|
-
<div className="fin-kauf">
|
|
333
|
-
{t('autobahn:finance.uvp')} <s>{eur(listPrice as number)} €</s>
|
|
334
|
-
</div>
|
|
335
|
-
)}
|
|
336
|
-
</div>
|
|
337
|
-
{/* col 2 row 1: price-rating pill */}
|
|
338
|
-
<div>
|
|
339
|
-
{ratingLabel && (
|
|
340
|
-
<span
|
|
341
|
-
className="fin-eval-pill"
|
|
342
|
-
style={{ color: TIER_COLORS[evalTier], background: `color-mix(in srgb, ${TIER_COLORS[evalTier]} 16%, transparent)` }}
|
|
343
|
-
aria-label={t('autobahn:finance.priceRatingAria', { rating: evalTierLabel })}
|
|
344
|
-
>
|
|
345
|
-
<Icon
|
|
346
|
-
name={evalTier <= 1 ? 'check' : evalTier === 2 ? 'minus' : 'trending-up'}
|
|
347
|
-
size={14}
|
|
348
|
-
stroke={2.6}
|
|
349
|
-
color={TIER_COLORS[evalTier]}
|
|
350
|
-
/>
|
|
351
|
-
{evalTierLabel}
|
|
352
|
-
</span>
|
|
353
|
-
)}
|
|
354
|
-
</div>
|
|
355
|
-
{/* col 1 row 2: condition line */}
|
|
356
|
-
<div className="fin-cond">{condLine}</div>
|
|
357
|
-
{/* col 2 row 2: gradient evaluation bar */}
|
|
358
|
-
<div>
|
|
359
|
-
{ratingLabel && (
|
|
360
|
-
<div className="fin-eval-bar">
|
|
361
|
-
<div className="fin-eval-thumb" style={{ left: `${(evalTier + 0.5) * 20}%`, borderColor: TIER_COLORS[evalTier] }} />
|
|
362
|
-
</div>
|
|
363
|
-
)}
|
|
364
|
-
</div>
|
|
365
|
-
</div>
|
|
366
|
-
|
|
367
|
-
{/* RATE EDIT (Rate anpassen) — between the rate and the request CTA */}
|
|
368
|
-
<div className="fin-adjust">
|
|
369
|
-
<button onClick={() => setAdjust((a) => !a)} style={expanderBtnStyle}>
|
|
370
|
-
<span style={{ display: 'inline-flex', alignItems: 'center', gap: 7 }}>
|
|
371
|
-
<Icon name={isCash ? 'list' : 'sliders-horizontal'} size={16} color="var(--md-primary)" />
|
|
372
|
-
{isCash ? t('autobahn:finance.detailsShow') : t('autobahn:finance.adjustRate')}
|
|
373
|
-
</span>
|
|
374
|
-
<Icon name={adjust ? 'chevron-up' : 'chevron-down'} size={18} color="var(--md-primary)" />
|
|
375
|
-
</button>
|
|
376
|
-
{adjust &&
|
|
377
|
-
(isCash ? (
|
|
378
|
-
<div style={{ marginTop: 4 }}>
|
|
379
|
-
<CalcRow label={t('autobahn:finance.paymentLabel')}>{t('autobahn:finance.paymentValue')}</CalcRow>
|
|
380
|
-
<CalcRow label={t('autobahn:finance.warrantyLabel')}>{t('autobahn:finance.warrantyValue')}</CalcRow>
|
|
381
|
-
<CalcRow label={t('autobahn:finance.deliveryLabel')} last>
|
|
382
|
-
{t('autobahn:finance.deliveryValue')}
|
|
383
|
-
</CalcRow>
|
|
384
|
-
</div>
|
|
385
|
-
) : (
|
|
386
|
-
<div style={{ display: 'flex', flexDirection: 'column', gap: 16, marginTop: 8 }}>
|
|
387
|
-
<div>
|
|
388
|
-
<div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 6 }}>
|
|
389
|
-
<span className="md-title-sm">{t('autobahn:finance.downPaymentSliderLabel')}</span>
|
|
390
|
-
<span className="num" style={{ fontWeight: 700 }}>
|
|
391
|
-
{eur(down)} €
|
|
392
|
-
</span>
|
|
393
|
-
</div>
|
|
394
|
-
<Slider
|
|
395
|
-
min={downMin}
|
|
396
|
-
max={downMax}
|
|
397
|
-
step={downStep}
|
|
398
|
-
value={down}
|
|
399
|
-
onChange={onDownChange}
|
|
400
|
-
fmt={(v) => `${eur(Number(v))} €`}
|
|
401
|
-
/>
|
|
402
|
-
</div>
|
|
403
|
-
{annualMileage != null && onAnnualMileageChange && (
|
|
404
|
-
<div>
|
|
405
|
-
<div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 6 }}>
|
|
406
|
-
<span className="md-title-sm">{t('autobahn:finance.annualMileageLabel')}</span>
|
|
407
|
-
<span className="num" style={{ fontWeight: 700 }}>
|
|
408
|
-
{eur(annualMileage)} km
|
|
409
|
-
</span>
|
|
410
|
-
</div>
|
|
411
|
-
<Slider
|
|
412
|
-
min={annualMileageMin}
|
|
413
|
-
max={annualMileageMax}
|
|
414
|
-
step={annualMileageStep}
|
|
415
|
-
value={annualMileage}
|
|
416
|
-
onChange={onAnnualMileageChange}
|
|
417
|
-
fmt={(v) => `${eur(Number(v))} km`}
|
|
418
|
-
/>
|
|
419
|
-
</div>
|
|
420
|
-
)}
|
|
421
|
-
<div>
|
|
422
|
-
<div className="md-title-sm" style={{ marginBottom: 8 }}>
|
|
423
|
-
{t('autobahn:finance.termSelection')}
|
|
424
|
-
</div>
|
|
425
|
-
<TermChips options={terms} value={term} onChange={onTermChange} t={t} />
|
|
426
|
-
</div>
|
|
427
|
-
<div>
|
|
428
|
-
<CalcRow label={t('autobahn:finance.purchasePrice')}>{eur(price)} €</CalcRow>
|
|
429
|
-
<CalcRow label={t('autobahn:finance.warrantyLabel')}>{t('autobahn:finance.warrantyValue')}</CalcRow>
|
|
430
|
-
<CalcRow label={t('autobahn:finance.deliveryLabel')} last>
|
|
431
|
-
{t('autobahn:finance.deliveryValue')}
|
|
432
|
-
</CalcRow>
|
|
433
|
-
</div>
|
|
434
|
-
</div>
|
|
435
|
-
))}
|
|
436
|
-
</div>
|
|
437
|
-
|
|
438
|
-
{/* REQUEST CTA */}
|
|
439
|
-
<Button variant="filled" block size="lg" icon="shield-check" style={{ marginTop: 14 }} onClick={onSecure}>
|
|
440
|
-
{t('autobahn:finance.secureOffer')}
|
|
441
|
-
</Button>
|
|
442
|
-
{/* phone CTA — touch only (hidden on desktop via .fin-call) */}
|
|
443
|
-
<div className="fin-call">
|
|
444
|
-
<Button variant="outlined" block icon="phone" onClick={onCall}>
|
|
445
|
-
{phone}
|
|
446
|
-
</Button>
|
|
447
|
-
</div>
|
|
448
|
-
|
|
449
|
-
{/* auto.de-ID in front of the Finanzierungs-/Leasingdetails link — one row, under everything */}
|
|
450
|
-
{(autoDeId || (!isCash && onShowDetails)) && (
|
|
451
|
-
<div className="fin-info">
|
|
452
|
-
{autoDeId && <span className="fin-id">auto.de-ID {autoDeId}</span>}
|
|
453
|
-
{!isCash && onShowDetails && (
|
|
454
|
-
<DetailsLink
|
|
455
|
-
label={mode === 'leasing' ? t('autobahn:finance.leasingDetails') : t('autobahn:finance.financingDetails')}
|
|
456
|
-
onClick={onShowDetails}
|
|
457
|
-
/>
|
|
458
|
-
)}
|
|
459
|
-
</div>
|
|
460
|
-
)}
|
|
461
|
-
</div>
|
|
462
|
-
);
|
|
463
|
-
};
|
|
464
|
-
|
|
465
|
-
export default FinanceCalculator;
|
|
1
|
+
// Autobahn (auto.de redesign) — VDP offer / finance card (Finanzierung / Leasing /
|
|
2
|
+
// Barzahlung).
|
|
3
|
+
//
|
|
4
|
+
// Structure (desktop rethink, tabs-on-top): payment-type TABS at the top (MD3 underline tabs),
|
|
5
|
+
// then the rate (with any discount), then the "Rate anpassen" rate-editor, then the primary
|
|
6
|
+
// "Angebot sichern" request CTA, and finally the Finanzierungs-/Leasingdetails info + popup link
|
|
7
|
+
// at the foot. Laufzeit is chosen via chips (discrete terms), not a slider.
|
|
8
|
+
//
|
|
9
|
+
// CONTROLLED / PRESENTATIONAL — computes NOTHING financial: `mode`, `monthly`, `down`, `term` and
|
|
10
|
+
// the slider/chip bounds all arrive as props; segment/slider/chip changes are reported back via
|
|
11
|
+
// `onModeChange` / `onDownChange` / `onTermChange`. The real numbers come from `financingStore`.
|
|
12
|
+
// The only local state is the `adjust` expander (pure view state).
|
|
13
|
+
//
|
|
14
|
+
// Renders correctly only inside a `<div className="md3">` subtree.
|
|
15
|
+
|
|
16
|
+
import React, { useState } from 'react';
|
|
17
|
+
import { TranslationFunction } from '../types';
|
|
18
|
+
|
|
19
|
+
import { Button, Icon } from '../ui';
|
|
20
|
+
import { TIER_LABELS, TIER_KEYS, TIER_COLORS } from '../constants';
|
|
21
|
+
|
|
22
|
+
/** Payment mode segment keys. Mirrors the design's ['fin','leasing','cash']. */
|
|
23
|
+
export type FinanceMode = 'fin' | 'leasing' | 'cash';
|
|
24
|
+
|
|
25
|
+
export interface SliderProps {
|
|
26
|
+
min: number;
|
|
27
|
+
max: number;
|
|
28
|
+
step?: number;
|
|
29
|
+
value: number;
|
|
30
|
+
onChange: (value: number) => void;
|
|
31
|
+
/** formats the min/max end labels (and is reused by callers for the value). */
|
|
32
|
+
fmt?: (v: number) => React.ReactNode;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Range slider with a filled track and min/max end labels. The track fill is a
|
|
37
|
+
* linear-gradient driven by the value's position; the design's `.mslider` class
|
|
38
|
+
* styles the thumb/rail.
|
|
39
|
+
*/
|
|
40
|
+
export const Slider: React.FunctionComponent<SliderProps> = ({ min, max, step = 1, value, onChange, fmt = (v) => v }) => {
|
|
41
|
+
const span = max - min;
|
|
42
|
+
const pct = span > 0 ? ((value - min) / span) * 100 : 0;
|
|
43
|
+
return (
|
|
44
|
+
<div>
|
|
45
|
+
<input
|
|
46
|
+
type="range"
|
|
47
|
+
className="mslider"
|
|
48
|
+
min={min}
|
|
49
|
+
max={max}
|
|
50
|
+
step={step}
|
|
51
|
+
value={value}
|
|
52
|
+
onChange={(e) => onChange(Number(e.target.value))}
|
|
53
|
+
style={{ background: `linear-gradient(90deg, var(--md-primary) ${pct}%, var(--md-sc-highest) ${pct}%)` }}
|
|
54
|
+
/>
|
|
55
|
+
<div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 4 }}>
|
|
56
|
+
<span className="md-label-sm">{fmt(min)}</span>
|
|
57
|
+
<span className="md-label-sm">{fmt(max)}</span>
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
);
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export interface TermChipsProps {
|
|
64
|
+
/** the selectable term values (months), e.g. [12,24,36,48,60,72]. */
|
|
65
|
+
options: number[];
|
|
66
|
+
value: number;
|
|
67
|
+
onChange: (term: number) => void;
|
|
68
|
+
/** i18n function (drilled from the page). */
|
|
69
|
+
t: TranslationFunction;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Laufzeit selector — discrete term values as tappable chips (replaces the fiddly slider). */
|
|
73
|
+
export const TermChips: React.FunctionComponent<TermChipsProps> = ({ options, value, onChange, t }) => (
|
|
74
|
+
<div className="term-chips" role="group" aria-label={t('autobahn:finance.termSelection')}>
|
|
75
|
+
{options.map((m) => (
|
|
76
|
+
<button
|
|
77
|
+
key={m}
|
|
78
|
+
type="button"
|
|
79
|
+
aria-pressed={m === value}
|
|
80
|
+
className={'term-chip' + (m === value ? ' on' : '')}
|
|
81
|
+
onClick={() => onChange(m)}
|
|
82
|
+
>
|
|
83
|
+
{m}
|
|
84
|
+
<span className="tc-unit">{t('autobahn:finance.monthUnit')}</span>
|
|
85
|
+
</button>
|
|
86
|
+
))}
|
|
87
|
+
</div>
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
export interface CalcRowProps {
|
|
91
|
+
label: React.ReactNode;
|
|
92
|
+
/** when true, drops the bottom hairline (last row). */
|
|
93
|
+
last?: boolean;
|
|
94
|
+
children?: React.ReactNode;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** One label/value row inside the "Rate anpassen" / "Details" expander. */
|
|
98
|
+
export const CalcRow: React.FunctionComponent<CalcRowProps> = ({ label, last, children }) => (
|
|
99
|
+
<div
|
|
100
|
+
style={{
|
|
101
|
+
display: 'flex',
|
|
102
|
+
justifyContent: 'space-between',
|
|
103
|
+
alignItems: 'baseline',
|
|
104
|
+
gap: 12,
|
|
105
|
+
padding: '8px 0',
|
|
106
|
+
borderBottom: last ? 0 : '1px solid var(--md-outline-variant)',
|
|
107
|
+
}}
|
|
108
|
+
>
|
|
109
|
+
<span className="md-label-sm">{label}</span>
|
|
110
|
+
<span className="num" style={{ fontSize: 13.5, fontWeight: 600 }}>
|
|
111
|
+
{children}
|
|
112
|
+
</span>
|
|
113
|
+
</div>
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
export interface FinanceCalculatorProps {
|
|
117
|
+
/** active payment mode (controlled). */
|
|
118
|
+
mode: FinanceMode;
|
|
119
|
+
/** purchase price in EUR (the cash mode hero). */
|
|
120
|
+
price: number;
|
|
121
|
+
/** previous/list price — when > price, shown struck through as the UVP in cash mode (real discount). */
|
|
122
|
+
listPrice?: number;
|
|
123
|
+
/** auto.de-ID reference code — shown with the financing/leasing condition line. */
|
|
124
|
+
autoDeId?: string;
|
|
125
|
+
/** price-rating label, e.g. 'Guter Preis' — drives the Preisbewertung indicator. */
|
|
126
|
+
ratingLabel?: string;
|
|
127
|
+
/** computed monthly rate in EUR for the current mode — supplied, NOT computed here. */
|
|
128
|
+
monthly: number;
|
|
129
|
+
/** effective annual rate (%) for the current mode — supplied, NOT computed here. */
|
|
130
|
+
apr: number;
|
|
131
|
+
/** current down payment in EUR (controlled). */
|
|
132
|
+
down: number;
|
|
133
|
+
/** current term in months (controlled). */
|
|
134
|
+
term: number;
|
|
135
|
+
/** down-payment slider bounds. */
|
|
136
|
+
downMin: number;
|
|
137
|
+
downMax: number;
|
|
138
|
+
/** down-payment slider step (EUR). */
|
|
139
|
+
downStep?: number;
|
|
140
|
+
/** term slider bounds (months) — used to derive chip options when termOptions is absent. */
|
|
141
|
+
termMin: number;
|
|
142
|
+
termMax: number;
|
|
143
|
+
/** term slider step (months). */
|
|
144
|
+
termStep?: number;
|
|
145
|
+
/** the discrete selectable terms (months) for the Laufzeit chips. */
|
|
146
|
+
termOptions?: number[];
|
|
147
|
+
/** annual mileage in km (controlled) — leasing/financing Laufleistung/Jahr. Omit to hide the slider. */
|
|
148
|
+
annualMileage?: number;
|
|
149
|
+
/** annual-mileage slider bounds + step (km). */
|
|
150
|
+
annualMileageMin?: number;
|
|
151
|
+
annualMileageMax?: number;
|
|
152
|
+
annualMileageStep?: number;
|
|
153
|
+
/** annual-mileage slider changed. */
|
|
154
|
+
onAnnualMileageChange?: (km: number) => void;
|
|
155
|
+
/** phone number shown on the secondary CTA (touch only). */
|
|
156
|
+
phone?: string;
|
|
157
|
+
/** primary CTA click (Angebot sichern). */
|
|
158
|
+
onSecure?: () => void;
|
|
159
|
+
/** secondary CTA click (phone). */
|
|
160
|
+
onCall?: () => void;
|
|
161
|
+
/** open the Finanzierungs-/Leasingdetails popup (full breakdown + legal). Omit to hide the link. */
|
|
162
|
+
onShowDetails?: () => void;
|
|
163
|
+
/** mode segment changed. */
|
|
164
|
+
onModeChange: (mode: FinanceMode) => void;
|
|
165
|
+
/** down-payment slider changed. */
|
|
166
|
+
onDownChange: (down: number) => void;
|
|
167
|
+
/** term changed. */
|
|
168
|
+
onTermChange: (term: number) => void;
|
|
169
|
+
/** i18n function (drilled from the page). */
|
|
170
|
+
t: TranslationFunction;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const eur = (n: number): string => n.toLocaleString('de-DE');
|
|
174
|
+
|
|
175
|
+
/** build a [min..max] step range (fallback term options when none are supplied). */
|
|
176
|
+
const range = (min: number, max: number, step: number): number[] => {
|
|
177
|
+
const out: number[] = [];
|
|
178
|
+
for (let v = min; v <= max; v += step || 12) out.push(v);
|
|
179
|
+
return out.length ? out : [min];
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
/** quiet primary-colored text link (Finanzierungsdetails / Details anzeigen). */
|
|
183
|
+
const DetailsLink: React.FunctionComponent<{ label: string; onClick: () => void }> = ({ label, onClick }) => (
|
|
184
|
+
<button
|
|
185
|
+
type="button"
|
|
186
|
+
onClick={onClick}
|
|
187
|
+
style={{
|
|
188
|
+
display: 'inline-flex',
|
|
189
|
+
alignItems: 'center',
|
|
190
|
+
gap: 5,
|
|
191
|
+
background: 'none',
|
|
192
|
+
border: 0,
|
|
193
|
+
padding: 0,
|
|
194
|
+
cursor: 'pointer',
|
|
195
|
+
color: 'var(--md-primary)',
|
|
196
|
+
font: 'inherit',
|
|
197
|
+
fontSize: 13,
|
|
198
|
+
fontWeight: 600,
|
|
199
|
+
}}
|
|
200
|
+
>
|
|
201
|
+
<Icon name="info" size={15} color="var(--md-primary)" />
|
|
202
|
+
{label}
|
|
203
|
+
</button>
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
/** "Rate anpassen" / "Details anzeigen" expander toggle button. */
|
|
207
|
+
const expanderBtnStyle: React.CSSProperties = {
|
|
208
|
+
width: '100%',
|
|
209
|
+
background: 'none',
|
|
210
|
+
border: 0,
|
|
211
|
+
cursor: 'pointer',
|
|
212
|
+
display: 'flex',
|
|
213
|
+
alignItems: 'center',
|
|
214
|
+
justifyContent: 'space-between',
|
|
215
|
+
padding: '10px 0 2px',
|
|
216
|
+
color: 'var(--md-primary)',
|
|
217
|
+
fontWeight: 600,
|
|
218
|
+
fontSize: 14,
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
const FinanceCalculator: React.FunctionComponent<FinanceCalculatorProps> = ({
|
|
222
|
+
mode,
|
|
223
|
+
price,
|
|
224
|
+
listPrice,
|
|
225
|
+
autoDeId,
|
|
226
|
+
ratingLabel,
|
|
227
|
+
monthly,
|
|
228
|
+
down,
|
|
229
|
+
term,
|
|
230
|
+
downMin,
|
|
231
|
+
downMax,
|
|
232
|
+
downStep = 500,
|
|
233
|
+
termMin,
|
|
234
|
+
termMax,
|
|
235
|
+
termStep = 6,
|
|
236
|
+
termOptions,
|
|
237
|
+
annualMileage,
|
|
238
|
+
annualMileageMin = 5000,
|
|
239
|
+
annualMileageMax = 60000,
|
|
240
|
+
annualMileageStep = 5000,
|
|
241
|
+
onAnnualMileageChange,
|
|
242
|
+
phone = '0800 40 30 182',
|
|
243
|
+
onSecure,
|
|
244
|
+
onCall,
|
|
245
|
+
onShowDetails,
|
|
246
|
+
onModeChange,
|
|
247
|
+
onDownChange,
|
|
248
|
+
onTermChange,
|
|
249
|
+
t,
|
|
250
|
+
}) => {
|
|
251
|
+
// Pure view state only — whether the adjust/details expander is open.
|
|
252
|
+
const [adjust, setAdjust] = useState(false);
|
|
253
|
+
const isCash = mode === 'cash';
|
|
254
|
+
const terms = termOptions && termOptions.length ? termOptions : range(termMin, termMax, termStep);
|
|
255
|
+
const showStrike = listPrice != null && listPrice > price;
|
|
256
|
+
// price-evaluation tier from the rating label (defaults to 'Guter Preis' tier when unmapped).
|
|
257
|
+
const tierIdx = TIER_LABELS.indexOf(ratingLabel as (typeof TIER_LABELS)[number]);
|
|
258
|
+
const evalTier = tierIdx >= 0 ? tierIdx : 1;
|
|
259
|
+
const evalTierLabel = t('autobahn:tier.' + TIER_KEYS[evalTier]);
|
|
260
|
+
// condition summary (current selection) — the auto.de-ID lives with the details link, not here.
|
|
261
|
+
const condParts: string[] = [];
|
|
262
|
+
if (!isCash) {
|
|
263
|
+
condParts.push(
|
|
264
|
+
mode === 'leasing' && annualMileage != null
|
|
265
|
+
? t('autobahn:finance.kmPerYear', { value: eur(annualMileage) })
|
|
266
|
+
: t('autobahn:finance.downPaymentLabel', { value: eur(down) }),
|
|
267
|
+
);
|
|
268
|
+
condParts.push(t('autobahn:finance.monthsLabel', { months: term, count: term }));
|
|
269
|
+
}
|
|
270
|
+
const condLine = condParts.join(' · ');
|
|
271
|
+
|
|
272
|
+
return (
|
|
273
|
+
<div className="mcard mcard--elevated" style={{ padding: 20 }}>
|
|
274
|
+
{/* header */}
|
|
275
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 14 }}>
|
|
276
|
+
<span
|
|
277
|
+
style={{
|
|
278
|
+
width: 34,
|
|
279
|
+
height: 34,
|
|
280
|
+
borderRadius: 'var(--md-r-full)',
|
|
281
|
+
background: 'var(--md-primary-container)',
|
|
282
|
+
display: 'flex',
|
|
283
|
+
alignItems: 'center',
|
|
284
|
+
justifyContent: 'center',
|
|
285
|
+
flex: 'none',
|
|
286
|
+
}}
|
|
287
|
+
>
|
|
288
|
+
<Icon name="tag" size={18} color="var(--md-on-primary-container)" />
|
|
289
|
+
</span>
|
|
290
|
+
<div style={{ fontFamily: 'var(--md-font-display)', fontSize: 18, fontWeight: 700 }}>{t('autobahn:finance.headerTitle')}</div>
|
|
291
|
+
</div>
|
|
292
|
+
|
|
293
|
+
{/* payment-type TABS on top */}
|
|
294
|
+
<div className="fin-tabs" role="tablist">
|
|
295
|
+
{(
|
|
296
|
+
[
|
|
297
|
+
['fin', 'autobahn:finance.mode.financing'],
|
|
298
|
+
['leasing', 'autobahn:finance.mode.leasing'],
|
|
299
|
+
['cash', 'autobahn:finance.mode.cash'],
|
|
300
|
+
] as Array<[FinanceMode, string]>
|
|
301
|
+
).map(([k, labelKey]) => (
|
|
302
|
+
<button
|
|
303
|
+
key={k}
|
|
304
|
+
type="button"
|
|
305
|
+
role="tab"
|
|
306
|
+
aria-selected={mode === k}
|
|
307
|
+
className={'fin-tab' + (mode === k ? ' on' : '')}
|
|
308
|
+
onClick={() => onModeChange(k)}
|
|
309
|
+
>
|
|
310
|
+
{t(labelKey)}
|
|
311
|
+
</button>
|
|
312
|
+
))}
|
|
313
|
+
</div>
|
|
314
|
+
|
|
315
|
+
{/* 2-col grid: rate|pill (row 1) + condLine|bar (row 2) — fixed right column prevents wrapping */}
|
|
316
|
+
<div className="fin-price-grid">
|
|
317
|
+
{/* col 1 row 1: hero rate */}
|
|
318
|
+
<div className="fin-rate-main">
|
|
319
|
+
<div style={{ display: 'flex', alignItems: 'baseline', gap: 5 }}>
|
|
320
|
+
<span
|
|
321
|
+
className="num"
|
|
322
|
+
style={{ fontSize: 48, fontWeight: 800, color: 'var(--md-primary)', letterSpacing: '-2px' }}
|
|
323
|
+
>
|
|
324
|
+
{isCash ? eur(price) : eur(Math.round(monthly))}
|
|
325
|
+
</span>
|
|
326
|
+
<span className="md-body-sm" style={{ fontWeight: 600 }}>
|
|
327
|
+
{isCash ? '€' : `€ ${t('autobahn:finance.perMonth')}`}
|
|
328
|
+
</span>
|
|
329
|
+
</div>
|
|
330
|
+
{isCash && <div className="md-label-sm">{t('autobahn:finance.fixedPrice')}</div>}
|
|
331
|
+
{isCash && showStrike && (
|
|
332
|
+
<div className="fin-kauf">
|
|
333
|
+
{t('autobahn:finance.uvp')} <s>{eur(listPrice as number)} €</s>
|
|
334
|
+
</div>
|
|
335
|
+
)}
|
|
336
|
+
</div>
|
|
337
|
+
{/* col 2 row 1: price-rating pill */}
|
|
338
|
+
<div>
|
|
339
|
+
{ratingLabel && (
|
|
340
|
+
<span
|
|
341
|
+
className="fin-eval-pill"
|
|
342
|
+
style={{ color: TIER_COLORS[evalTier], background: `color-mix(in srgb, ${TIER_COLORS[evalTier]} 16%, transparent)` }}
|
|
343
|
+
aria-label={t('autobahn:finance.priceRatingAria', { rating: evalTierLabel })}
|
|
344
|
+
>
|
|
345
|
+
<Icon
|
|
346
|
+
name={evalTier <= 1 ? 'check' : evalTier === 2 ? 'minus' : 'trending-up'}
|
|
347
|
+
size={14}
|
|
348
|
+
stroke={2.6}
|
|
349
|
+
color={TIER_COLORS[evalTier]}
|
|
350
|
+
/>
|
|
351
|
+
{evalTierLabel}
|
|
352
|
+
</span>
|
|
353
|
+
)}
|
|
354
|
+
</div>
|
|
355
|
+
{/* col 1 row 2: condition line */}
|
|
356
|
+
<div className="fin-cond">{condLine}</div>
|
|
357
|
+
{/* col 2 row 2: gradient evaluation bar */}
|
|
358
|
+
<div>
|
|
359
|
+
{ratingLabel && (
|
|
360
|
+
<div className="fin-eval-bar">
|
|
361
|
+
<div className="fin-eval-thumb" style={{ left: `${(evalTier + 0.5) * 20}%`, borderColor: TIER_COLORS[evalTier] }} />
|
|
362
|
+
</div>
|
|
363
|
+
)}
|
|
364
|
+
</div>
|
|
365
|
+
</div>
|
|
366
|
+
|
|
367
|
+
{/* RATE EDIT (Rate anpassen) — between the rate and the request CTA */}
|
|
368
|
+
<div className="fin-adjust">
|
|
369
|
+
<button onClick={() => setAdjust((a) => !a)} style={expanderBtnStyle}>
|
|
370
|
+
<span style={{ display: 'inline-flex', alignItems: 'center', gap: 7 }}>
|
|
371
|
+
<Icon name={isCash ? 'list' : 'sliders-horizontal'} size={16} color="var(--md-primary)" />
|
|
372
|
+
{isCash ? t('autobahn:finance.detailsShow') : t('autobahn:finance.adjustRate')}
|
|
373
|
+
</span>
|
|
374
|
+
<Icon name={adjust ? 'chevron-up' : 'chevron-down'} size={18} color="var(--md-primary)" />
|
|
375
|
+
</button>
|
|
376
|
+
{adjust &&
|
|
377
|
+
(isCash ? (
|
|
378
|
+
<div style={{ marginTop: 4 }}>
|
|
379
|
+
<CalcRow label={t('autobahn:finance.paymentLabel')}>{t('autobahn:finance.paymentValue')}</CalcRow>
|
|
380
|
+
<CalcRow label={t('autobahn:finance.warrantyLabel')}>{t('autobahn:finance.warrantyValue')}</CalcRow>
|
|
381
|
+
<CalcRow label={t('autobahn:finance.deliveryLabel')} last>
|
|
382
|
+
{t('autobahn:finance.deliveryValue')}
|
|
383
|
+
</CalcRow>
|
|
384
|
+
</div>
|
|
385
|
+
) : (
|
|
386
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: 16, marginTop: 8 }}>
|
|
387
|
+
<div>
|
|
388
|
+
<div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 6 }}>
|
|
389
|
+
<span className="md-title-sm">{t('autobahn:finance.downPaymentSliderLabel')}</span>
|
|
390
|
+
<span className="num" style={{ fontWeight: 700 }}>
|
|
391
|
+
{eur(down)} €
|
|
392
|
+
</span>
|
|
393
|
+
</div>
|
|
394
|
+
<Slider
|
|
395
|
+
min={downMin}
|
|
396
|
+
max={downMax}
|
|
397
|
+
step={downStep}
|
|
398
|
+
value={down}
|
|
399
|
+
onChange={onDownChange}
|
|
400
|
+
fmt={(v) => `${eur(Number(v))} €`}
|
|
401
|
+
/>
|
|
402
|
+
</div>
|
|
403
|
+
{annualMileage != null && onAnnualMileageChange && (
|
|
404
|
+
<div>
|
|
405
|
+
<div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 6 }}>
|
|
406
|
+
<span className="md-title-sm">{t('autobahn:finance.annualMileageLabel')}</span>
|
|
407
|
+
<span className="num" style={{ fontWeight: 700 }}>
|
|
408
|
+
{eur(annualMileage)} km
|
|
409
|
+
</span>
|
|
410
|
+
</div>
|
|
411
|
+
<Slider
|
|
412
|
+
min={annualMileageMin}
|
|
413
|
+
max={annualMileageMax}
|
|
414
|
+
step={annualMileageStep}
|
|
415
|
+
value={annualMileage}
|
|
416
|
+
onChange={onAnnualMileageChange}
|
|
417
|
+
fmt={(v) => `${eur(Number(v))} km`}
|
|
418
|
+
/>
|
|
419
|
+
</div>
|
|
420
|
+
)}
|
|
421
|
+
<div>
|
|
422
|
+
<div className="md-title-sm" style={{ marginBottom: 8 }}>
|
|
423
|
+
{t('autobahn:finance.termSelection')}
|
|
424
|
+
</div>
|
|
425
|
+
<TermChips options={terms} value={term} onChange={onTermChange} t={t} />
|
|
426
|
+
</div>
|
|
427
|
+
<div>
|
|
428
|
+
<CalcRow label={t('autobahn:finance.purchasePrice')}>{eur(price)} €</CalcRow>
|
|
429
|
+
<CalcRow label={t('autobahn:finance.warrantyLabel')}>{t('autobahn:finance.warrantyValue')}</CalcRow>
|
|
430
|
+
<CalcRow label={t('autobahn:finance.deliveryLabel')} last>
|
|
431
|
+
{t('autobahn:finance.deliveryValue')}
|
|
432
|
+
</CalcRow>
|
|
433
|
+
</div>
|
|
434
|
+
</div>
|
|
435
|
+
))}
|
|
436
|
+
</div>
|
|
437
|
+
|
|
438
|
+
{/* REQUEST CTA */}
|
|
439
|
+
<Button variant="filled" block size="lg" icon="shield-check" style={{ marginTop: 14 }} onClick={onSecure}>
|
|
440
|
+
{t('autobahn:finance.secureOffer')}
|
|
441
|
+
</Button>
|
|
442
|
+
{/* phone CTA — touch only (hidden on desktop via .fin-call) */}
|
|
443
|
+
<div className="fin-call">
|
|
444
|
+
<Button variant="outlined" block icon="phone" onClick={onCall}>
|
|
445
|
+
{phone}
|
|
446
|
+
</Button>
|
|
447
|
+
</div>
|
|
448
|
+
|
|
449
|
+
{/* auto.de-ID in front of the Finanzierungs-/Leasingdetails link — one row, under everything */}
|
|
450
|
+
{(autoDeId || (!isCash && onShowDetails)) && (
|
|
451
|
+
<div className="fin-info">
|
|
452
|
+
{autoDeId && <span className="fin-id">auto.de-ID {autoDeId}</span>}
|
|
453
|
+
{!isCash && onShowDetails && (
|
|
454
|
+
<DetailsLink
|
|
455
|
+
label={mode === 'leasing' ? t('autobahn:finance.leasingDetails') : t('autobahn:finance.financingDetails')}
|
|
456
|
+
onClick={onShowDetails}
|
|
457
|
+
/>
|
|
458
|
+
)}
|
|
459
|
+
</div>
|
|
460
|
+
)}
|
|
461
|
+
</div>
|
|
462
|
+
);
|
|
463
|
+
};
|
|
464
|
+
|
|
465
|
+
export default FinanceCalculator;
|