@bytebrand/fe-ui-core 4.3.1 → 4.4.0
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/__tests__/components/UserDasboardPage/sections/CheckoutSection/CheckoutSection.test.tsx +613 -0
- package/__tests__/components/UserDasboardPage/sections/FavoriteSection/FavoriteSection.test.tsx +335 -0
- package/__tests__/utils/CommonUtils/getOfferSliders.test.ts +4 -2
- package/common.ts +6 -2
- package/package.json +19 -28
- package/source/components/AccordionWidget/AccordionWidget.tsx +1 -3
- package/source/components/Breadcrumbs/Breadcrumbs.tsx +3 -3
- package/source/components/Checkout/CheckoutStepper/CheckoutStepper.styl +2 -190
- package/source/components/Checkout/CheckoutStepper/CheckoutStepper.tsx +15 -16
- package/source/components/Checkout/OrderOverviewItem/OrderOverviewItem.styl +2 -2
- package/source/components/Checkout/OrderOverviewItem/OrderOverviewItem.tsx +3 -3
- package/source/components/FormattedNumber/FormattedNumber.tsx +2 -3
- package/source/components/InfoBlocks/FirstInfoBlock/FirstInfoBlockItem/FirstInfoBlockItem.styl +4 -6
- package/source/components/OfferDetailedSection/partials/PanelConfig.tsx +0 -3
- package/source/components/OfferPanel/MuiOfferPeriod/{MuiOfferPeriod.theme.js → MuiOfferPeriod.theme.tsx} +8 -13
- package/source/components/OfferPanel/MuiOfferPeriod/MuiOfferPeriod.tsx +28 -4
- package/source/components/OfferPanel/OfferCheckboxGroup/CheckboxContainer.tsx +6 -12
- package/source/components/OfferPanel/OfferCheckboxGroup/OfferCheckboxGroup.tsx +1 -1
- package/source/components/OfferPanel/OfferPanel.tsx +1 -1
- package/source/components/OfferPanel/OfferPeriod/OfferPeriod.tsx +0 -4
- package/source/components/OfferPanel/RangeGroup/RangeGroup.tsx +6 -4
- package/source/components/PriceRatingDetailed/PriceRatingDetailed.tsx +6 -2
- package/source/components/SearchFilters/filters/AlternativeID.tsx +42 -53
- package/source/components/SearchFilters/filters/DriveType.tsx +1 -1
- package/source/components/SearchFilters/filters/EmissionSticker.tsx +1 -1
- package/source/components/SearchFilters/filters/FirstRegistration.tsx +0 -1
- package/source/components/SearchFilters/filters/InteriorColor.tsx +1 -1
- package/source/components/SearchFilters/filters/InteriorMaterial.tsx +2 -1
- package/source/components/SearchFilters/filters/Mileage.tsx +1 -1
- package/source/components/SearchFilters/filters/Power.tsx +36 -17
- package/source/components/SearchFilters/filters/StateOptions.tsx +0 -1
- package/source/components/SearchFilters/filters/Transmission.tsx +1 -1
- package/source/components/SearchPage/SearchChips/SearchChips.tsx +1 -1
- package/source/components/SearchPageMobile/FiltersDetailed/BodyType.tsx +3 -3
- package/source/components/SearchPageMobile/FiltersDetailed/Consumption.tsx +2 -2
- package/source/components/SearchPageMobile/FiltersDetailed/Doors.tsx +1 -1
- package/source/components/SearchPageMobile/FiltersDetailed/MakeModel.tsx +1 -1
- package/source/components/SearchWidget/ColorWidget/BodyColorWidget.tsx +3 -3
- package/source/components/SearchWidget/EnvironmentWidget/EnvironmentWidget.tsx +3 -3
- package/source/components/SearchWidget/HighlightsWidget/HighlightsWidget.tsx +2 -2
- package/source/components/SearchWidget/StateWidget/StateWidget.tsx +1 -2
- package/source/components/SearchWidgetsMobile/BasicDataWidgetMobile/BasicDataWidgetMobile.tsx +4 -4
- package/source/components/SearchWidgetsMobile/EquipmentsWidget/EquipmentsWidget.tsx +16 -16
- package/source/components/SearchWidgetsMobile/HighlightsWidgetMobile/HighlightsWidgetMobile.tsx +1 -1
- package/source/components/SearchWidgetsMobile/InteriorWidget/InteriorWidget.tsx +1 -1
- package/source/components/SearchWidgetsMobile/SafetyWidget/SafetyWidget.tsx +6 -6
- package/source/components/Stepper/Stepper.tsx +4 -3
- package/source/components/UserDashboardPage/sections/CheckoutSection/CheckoutSection.styl +38 -0
- package/source/components/UserDashboardPage/sections/CheckoutSection/CheckoutSection.tsx +120 -0
- package/source/components/UserDashboardPage/sections/FavoriteSection/FavoriteSection.styl +22 -0
- package/source/components/UserDashboardPage/sections/FavoriteSection/FavoriteSection.tsx +84 -0
- package/source/components/UserDashboardPage/sections/OrderStatusSection/AdditionalOrderInfo.styl +11 -2
- package/source/components/UserDashboardPage/sections/OrderStatusSection/AdditionalOrderInfo.tsx +5 -5
- package/source/components/UserDashboardPage/sections/OrderStatusSection/OrderStatusCar.tsx +57 -38
- package/source/components/UserDashboardPage/sections/OrderStatusSection/OrderStatusCard.tsx +2 -2
- package/source/components/UserDashboardPage/sections/OrderStatusSection/OrderStatusSection.tsx +183 -101
- package/source/components/UserDashboardPage/sections/RequestedCarsSection/RequestedCarsSection.tsx +5 -7
- package/source/components/Vehicle/VehicleFormattedPrice/VehicleFormattedPrice.tsx +33 -7
- package/source/components/VehicleDetailedSidebar/VehicleDetailedSidebar.styl +10 -2
- package/source/components/VehicleDetailedSidebar/VehicleDetailedSidebar.tsx +54 -14
- package/source/components/VehicleDetailedSidebar/partials/Price.styl +5 -1
- package/source/components/VehicleDetailedSidebar/partials/Price.tsx +2 -1
- package/source/components/VehicleDetailedSidebar/partials/PriceContent.styl +16 -5
- package/source/components/VehicleDetailedSidebar/partials/PriceContent.tsx +9 -4
- package/source/components/VehicleDetailedSidebar/partials/Properties.tsx +1 -1
- package/source/components/VehicleDetailedSlider/VehicleDetailedSlider.styl +45 -0
- package/source/components/VehicleDetailedSlider/VehicleDetailedSlider.tsx +121 -42
- package/source/components/VehicleDetailedSlider/partials/PriceData.styl +4 -1
- package/source/components/VehicleDetailedSlider/partials/PriceData.tsx +8 -1
- package/source/components/VehicleDetailedSlider/partials/Stats.tsx +2 -2
- package/source/components/VehicleSmallCard/VehicleData/VechiclePriceItem/VechiclePriceItem.tsx +9 -7
- package/source/components/VehicleSmallCard/VehicleData/VehiclePrice/VehiclePrice.styl +35 -1
- package/source/components/VehicleSmallCard/VehicleData/VehiclePrice/VehiclePrice.tsx +9 -3
- package/source/components/VehicleSmallCard/VehicleData/VehicleTitle/VehicleTitle.styl +11 -2
- package/source/components/VehicleSmallCard/VehicleData/VehicleTitle/VehicleTitle.tsx +2 -1
- package/source/components/VehicleSmallCard/VehicleSmallCard.styl +3 -1
- package/source/components/VehicleSmallCard/VehicleSmallCard.tsx +3 -7
- package/source/components/_common/Badge/Badge.styl +3 -0
- package/source/components/_common/Badge/Badge.tsx +1 -1
- package/source/components/_common/Button/Button.tsx +5 -4
- package/source/components/_common/Checkbox/FormCheckbox.tsx +4 -4
- package/source/components/_common/CheckboxMaterial/CheckboxMaterial.tsx +1 -1
- package/source/components/_common/Chip/Chip.tsx +1 -3
- package/source/components/_common/ExpansionPanel/ExpansionPanel.tsx +3 -3
- package/source/components/_common/IconSVG/IconSVGConfig.tsx +2 -0
- package/source/components/_common/IconSVG/SVG/flags/SK.tsx +0 -1
- package/source/components/_common/IconSVG/SVG/slider/360New.tsx +1 -1
- package/source/components/_common/IconSVG/SVG/slider/YoutubeButton.tsx +26 -0
- package/source/components/_common/MaterialAccordion/MaterialAccordion.tsx +22 -30
- package/source/components/_common/MaterialAutocomplete/MaterialAutocomplete.styled.tsx +8 -8
- package/source/components/_common/MaterialDatePicker/MaterialDatePicker.styled.tsx +0 -1
- package/source/components/_common/MaterialSelect/MaterialSelect.styled.tsx +12 -15
- package/source/components/_common/MaterialSelect/MaterialSelect.tsx +3 -3
- package/source/components/_common/MaterialSwitch/MaterialSwitch.tsx +3 -1
- package/source/components/_common/MaterialTooltip/MaterialTooltip.styled.tsx +1 -1
- package/source/components/_common/MaterialTooltip/MaterialTooltip.tsx +3 -3
- package/source/components/_common/Modal/CookieModal.tsx +1 -3
- package/source/components/_common/Modal/Modal.styled.tsx +2 -1
- package/source/components/_common/Modal/Modal.tsx +1 -5
- package/source/components/_common/Modal/ModalsConfig.tsx +5 -1
- package/source/components/_common/Modal/modals/ManageCookieModal/ManageCookieModal.styl +23 -7
- package/source/components/_common/Modal/modals/ManageCookieModal/ManageCookieModal.tsx +84 -36
- package/source/components/_common/Modal/modals/PreviewCookieModal/PreviewCookieModal.styl +29 -14
- package/source/components/_common/Modal/modals/PreviewCookieModal/PreviewCookieModal.tsx +17 -10
- package/source/components/_common/OfferRequestButtonWrapper/OfferRequestButtonWrapper.tsx +12 -4
- package/source/components/_common/Range/Range.tsx +26 -16
- package/source/components/_common/UserMenu/MaterialMenu.styled.tsx +0 -1
- package/source/components/_common/UserMenu/MaterialMenu.tsx +3 -3
- package/source/components/_common/UserMenu/MaterialMenuItem.tsx +42 -20
- package/source/components/_common/UserMenu/NestedMenu.tsx +1 -1
- package/source/components/_common/withStats/withStats.styl +3 -0
- package/source/components/_common/withStats/withStats.tsx +19 -16
- package/source/components/containers/SearchPage/FiltersContainer/FiltersContainer.styl +14 -1
- package/source/components/containers/SearchPage/FiltersContainer/FiltersContainer.tsx +78 -42
- package/source/framework/constants/common.ts +89 -60
- package/source/framework/constants/highlights.ts +1 -1
- package/source/framework/constants.ts +1 -1
- package/source/framework/types/types.ts +9 -4
- package/source/framework/utils/CommonUtils.ts +73 -62
- package/source/framework/utils/DateUtils.ts +10 -2
- package/source/framework/vehiclesProps/decoratedLightProps.tsx +1 -2
- package/source/framework/vehiclesProps/decoratedProps.tsx +1 -2
- package/source/locales/data.ts +2 -2
- package/tslint.json +1 -2
- package/utils.ts +2 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
@import '../../../theme/mixins.styl';
|
|
2
2
|
|
|
3
3
|
.newFinancingPriceWrapper
|
|
4
|
-
width:
|
|
4
|
+
width: 159px
|
|
5
5
|
display: flex
|
|
6
6
|
align-items: flex-start;
|
|
7
7
|
color: $lightGreen;
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
font-size: 60px;
|
|
11
11
|
display flex;
|
|
12
12
|
line-height: .8;
|
|
13
|
-
margin 8px 0 0
|
|
13
|
+
margin 8px 0 0 10px;
|
|
14
14
|
[class^="VehicleFormattedPrice__decimals"], [class^="VehicleFormattedPrice__unit"]
|
|
15
15
|
font-size: 16px !important;
|
|
16
16
|
transform: none !important;
|
|
@@ -18,13 +18,14 @@
|
|
|
18
18
|
.tabContentPaddingForBuy
|
|
19
19
|
.newFinancingPriceWrapper
|
|
20
20
|
[class*="VehicleFormattedPrice__large"]
|
|
21
|
-
font-size: 40px;
|
|
22
21
|
margin-left: 0;
|
|
23
22
|
+media-phone-only()
|
|
24
23
|
[class*="VehicleFormattedPrice__large"]
|
|
25
|
-
font-size: 45px;
|
|
26
24
|
margin-left: 3px;
|
|
27
25
|
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
28
29
|
.tabContentPadding
|
|
29
30
|
padding: 10px 10px 10px 10px;
|
|
30
31
|
flex-direction: row
|
|
@@ -110,4 +111,14 @@
|
|
|
110
111
|
transform: rotate(180deg);
|
|
111
112
|
|
|
112
113
|
.wrapper
|
|
113
|
-
|
|
114
|
+
+media-tablet-landscape-up()
|
|
115
|
+
padding-right: 15px;
|
|
116
|
+
|
|
117
|
+
.priceFontSizeSmall
|
|
118
|
+
.priceInfoLabel
|
|
119
|
+
margin-top:8px!important
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
.tabContentPaddingForBuy.priceFontSizeSmall
|
|
123
|
+
.financingPriceItem
|
|
124
|
+
display: flex;
|
|
@@ -7,6 +7,7 @@ import styles from './PriceContent.styl';
|
|
|
7
7
|
import VehicleFormattedPrice from '../../Vehicle/VehicleFormattedPrice/VehicleFormattedPrice';
|
|
8
8
|
import PriceRating from '../../PriceRating/PriceRating';
|
|
9
9
|
import RequestOffer from '../../_common/OfferRequestButtonWrapper/OfferRequestButtonWrapper';
|
|
10
|
+
import { getFormattedPrice } from '../../../../utils';
|
|
10
11
|
|
|
11
12
|
const PriceContent: React.FunctionComponent<IPriceContentProps> = ({
|
|
12
13
|
t,
|
|
@@ -45,11 +46,14 @@ const PriceContent: React.FunctionComponent<IPriceContentProps> = ({
|
|
|
45
46
|
isAdditionalOption: true,
|
|
46
47
|
onShowOfferDetails: offerBlockProps.onShowOfferDetails
|
|
47
48
|
};
|
|
49
|
+
const priceFontSize: string = monthlyInstallment ? (getFormattedPrice(monthlyInstallment)?.toString().match(/\d/g).length >= 4 ? 'small' : 'large') : '';
|
|
48
50
|
|
|
49
51
|
const tabContentPaddingClassName = classnames(
|
|
50
52
|
styles.tabContentPadding,
|
|
51
|
-
{ [styles.tabContentPaddingForBuy]: isBuy }
|
|
53
|
+
{ [styles.tabContentPaddingForBuy]: isBuy },
|
|
54
|
+
{ [styles.priceFontSizeSmall]: priceFontSize === 'small' }
|
|
52
55
|
);
|
|
56
|
+
|
|
53
57
|
return (
|
|
54
58
|
<>
|
|
55
59
|
<div className={tabContentPaddingClassName}>
|
|
@@ -90,11 +94,12 @@ const PriceContent: React.FunctionComponent<IPriceContentProps> = ({
|
|
|
90
94
|
postfix={postfix}
|
|
91
95
|
numbersAfterDot={0}
|
|
92
96
|
size='large'
|
|
97
|
+
dynamicFontSize={tabContentPaddingClassName.includes('tabContentPaddingForBuy') ? 'large' : 'small'}
|
|
93
98
|
/>
|
|
94
99
|
</div>
|
|
95
100
|
) : null}
|
|
96
101
|
</span>
|
|
97
|
-
<div>
|
|
102
|
+
<div className={styles.wrapper}>
|
|
98
103
|
<PriceRating {...priceRatingProps} />
|
|
99
104
|
<span className={styles.priceInfo}>
|
|
100
105
|
<span className={styles.priceInfoLabel} onClick={onAdjustRateClick}>
|
|
@@ -103,13 +108,13 @@ const PriceContent: React.FunctionComponent<IPriceContentProps> = ({
|
|
|
103
108
|
className={styles.infoIcon}
|
|
104
109
|
customDimensions
|
|
105
110
|
/>
|
|
106
|
-
<span>{t('sidebar.adjustRate')}</span>
|
|
111
|
+
<span>{priceTabActiveIndex === 2 ? t('sidebar.serviceProducts') : t('sidebar.adjustRate')}</span>
|
|
107
112
|
<IconSVG name='menuArrow' className={`${styles.arrowDownIcon} ${offerBlockOpen ? styles.arrowUpIcon : ''}`} customDimensions />
|
|
108
113
|
</span>
|
|
109
114
|
</span>
|
|
110
115
|
</div>
|
|
111
116
|
</div>
|
|
112
|
-
{offerBlockOpen && <OfferBlockComponent {...{ ...offerBlockProps, priceTabIndex: activeTab }} />
|
|
117
|
+
{offerBlockOpen && <OfferBlockComponent {...{ ...offerBlockProps, priceTabIndex: activeTab }} />}
|
|
113
118
|
<RequestOffer {...requestOfferProps} />
|
|
114
119
|
</>
|
|
115
120
|
);
|
|
@@ -82,7 +82,7 @@ const Properties: React.FunctionComponent<IPropertiesProps> = ({ t, car, decorat
|
|
|
82
82
|
|
|
83
83
|
const tabsTitles = [
|
|
84
84
|
{
|
|
85
|
-
title:
|
|
85
|
+
title: `${t(`sidebar.overview`)}`,
|
|
86
86
|
children: (
|
|
87
87
|
<div className={`${styles.tabContentPadding} ${styles.tabContentOverviewPadding}`}>
|
|
88
88
|
{mainProperties.map((property: any, index: number) => (
|
|
@@ -100,3 +100,48 @@
|
|
|
100
100
|
|
|
101
101
|
.blurred
|
|
102
102
|
filter: blur(3px)
|
|
103
|
+
|
|
104
|
+
.frame
|
|
105
|
+
aspect-ratio:4/3
|
|
106
|
+
height: auto;
|
|
107
|
+
border-radius: 10px;
|
|
108
|
+
display: block;
|
|
109
|
+
border: none;
|
|
110
|
+
|
|
111
|
+
.noYoutubeWrapper
|
|
112
|
+
margin: 82px auto 0;
|
|
113
|
+
width: 487px;
|
|
114
|
+
display: flex;
|
|
115
|
+
flex-direction: column;
|
|
116
|
+
align-items: center;
|
|
117
|
+
+media-phone-only()
|
|
118
|
+
margin: 40px auto 0;
|
|
119
|
+
width: 297px;
|
|
120
|
+
|
|
121
|
+
svg
|
|
122
|
+
+media-phone-only()
|
|
123
|
+
width: 79px;
|
|
124
|
+
height: 56px;
|
|
125
|
+
|
|
126
|
+
.youtubeCookiesText
|
|
127
|
+
font-size: 28px;
|
|
128
|
+
font-weight: 400;
|
|
129
|
+
line-height: 36px;
|
|
130
|
+
margin:62px 0px 54px;
|
|
131
|
+
display: block;
|
|
132
|
+
text-align: center;
|
|
133
|
+
+media-phone-only()
|
|
134
|
+
margin: 36px auto 39px;
|
|
135
|
+
font-size:17px;
|
|
136
|
+
line-height: 21px
|
|
137
|
+
|
|
138
|
+
.btn
|
|
139
|
+
height: 38px!important
|
|
140
|
+
+media-phone-only()
|
|
141
|
+
height: 30px!important
|
|
142
|
+
font-size:13px;
|
|
143
|
+
|
|
144
|
+
.btn:first-child
|
|
145
|
+
margin-right:22px!important
|
|
146
|
+
+media-phone-only()
|
|
147
|
+
margin-right:5px!important
|
|
@@ -13,28 +13,38 @@ import withMagnifyGlassImage from '../_common/MagnifyGlass/MagnifyGlass';
|
|
|
13
13
|
import { IImage, IPrice, SliderType } from '../../framework/types/types';
|
|
14
14
|
import { PLACEHOLDER_IMAGE_SMALL_URL } from '../../framework/constants/common';
|
|
15
15
|
import { VehicleDetailedSliderTranslate } from '../../locales/data';
|
|
16
|
+
import SvgYoutubeButton from '../_common/IconSVG/SVG/slider/YoutubeButton';
|
|
17
|
+
import Button from '../_common/Button/Button';
|
|
18
|
+
import { updateCookieList } from '../../framework/utils/CommonUtils';
|
|
19
|
+
|
|
20
|
+
|
|
16
21
|
|
|
17
22
|
import styles from './VehicleDetailedSlider.styl';
|
|
18
23
|
|
|
19
24
|
interface IProps {
|
|
20
25
|
t: (phrase: string, config?: any) => string;
|
|
21
26
|
price: IPrice;
|
|
22
|
-
photos: IImage
|
|
23
|
-
exteriorPhotos: IImage
|
|
27
|
+
photos: IImage[];
|
|
28
|
+
exteriorPhotos: IImage[];
|
|
24
29
|
interiorPhoto: IImage;
|
|
25
30
|
mainImageUrl: string;
|
|
26
31
|
mainImageBlur: boolean;
|
|
27
32
|
statsData: any;
|
|
28
33
|
isFavorite: boolean;
|
|
29
34
|
showNewLabel: boolean;
|
|
35
|
+
activeTab: number;
|
|
30
36
|
make: string;
|
|
31
37
|
model: string;
|
|
32
38
|
subModel: string;
|
|
33
39
|
powerKW: number;
|
|
34
40
|
powerPS: number;
|
|
41
|
+
financingConfig: any;
|
|
42
|
+
youtubeId: string;
|
|
35
43
|
showModal?: (id: string, props?: any) => void;
|
|
36
44
|
hideModal: (id: string) => void;
|
|
37
45
|
onCarFavorite: (event: MouseEvent<HTMLElement>) => void;
|
|
46
|
+
showDownPayment: boolean;
|
|
47
|
+
handleSentryInit?: () => void;
|
|
38
48
|
}
|
|
39
49
|
|
|
40
50
|
interface IState {
|
|
@@ -43,6 +53,8 @@ interface IState {
|
|
|
43
53
|
smallLoaded: boolean;
|
|
44
54
|
largeLoaded1: boolean;
|
|
45
55
|
largeLoaded01: boolean;
|
|
56
|
+
videoSrc: string;
|
|
57
|
+
showYoutube: boolean;
|
|
46
58
|
}
|
|
47
59
|
|
|
48
60
|
const MagnifyGlassImage = withMagnifyGlassImage(Image);
|
|
@@ -59,17 +71,21 @@ class VehicleDetailedSlider extends Component<IProps, IState> {
|
|
|
59
71
|
};
|
|
60
72
|
|
|
61
73
|
private slider: any;
|
|
74
|
+
|
|
62
75
|
private imagesCache: string[] = [];
|
|
63
76
|
|
|
64
77
|
constructor(props: IProps) {
|
|
65
78
|
super(props);
|
|
66
|
-
|
|
79
|
+
const cookieConfig = JSON.parse(localStorage.getItem('cookieConfig')) || {};
|
|
80
|
+
const youtubeConfig = !cookieConfig?.marketing?.includes('youtube');
|
|
67
81
|
this.state = {
|
|
68
82
|
activeSlide: 0,
|
|
69
83
|
largeLoaded: false,
|
|
70
84
|
smallLoaded: false,
|
|
71
85
|
largeLoaded1: false,
|
|
72
|
-
largeLoaded01: false
|
|
86
|
+
largeLoaded01: false,
|
|
87
|
+
videoSrc: '',
|
|
88
|
+
showYoutube: youtubeConfig
|
|
73
89
|
};
|
|
74
90
|
}
|
|
75
91
|
|
|
@@ -77,8 +93,10 @@ class VehicleDetailedSlider extends Component<IProps, IState> {
|
|
|
77
93
|
this.slider.slickGoTo(0);
|
|
78
94
|
};
|
|
79
95
|
|
|
80
|
-
|
|
81
|
-
|
|
96
|
+
|
|
97
|
+
componentDidUpdate(prevProps: IProps, prevState: IState) {
|
|
98
|
+
const cookieConfig = JSON.parse(localStorage.getItem('cookieConfig')) || {};
|
|
99
|
+
const showYoutube = !cookieConfig?.marketing?.includes('youtube');
|
|
82
100
|
if (prevProps.photos.length !== this.props.photos.length && this.props.photos.length === 0) {
|
|
83
101
|
this.setState(() => ({
|
|
84
102
|
largeLoaded: false,
|
|
@@ -87,10 +105,15 @@ class VehicleDetailedSlider extends Component<IProps, IState> {
|
|
|
87
105
|
largeLoaded01: false
|
|
88
106
|
}));
|
|
89
107
|
}
|
|
108
|
+
if (showYoutube !== prevState.showYoutube) {
|
|
109
|
+
this.setState(() => ({
|
|
110
|
+
showYoutube: showYoutube
|
|
111
|
+
}));
|
|
112
|
+
}
|
|
90
113
|
}
|
|
91
114
|
|
|
92
115
|
handleOpenSliderModal = (sliderType: SliderType) => {
|
|
93
|
-
const { t = (phrase: string) => _get(VehicleDetailedSliderTranslate(statsData), phrase, phrase), photos, exteriorPhotos, interiorPhoto, showModal, hideModal, statsData } = this.props;
|
|
116
|
+
const { t = (phrase: string) => _get(VehicleDetailedSliderTranslate(statsData), phrase, phrase), photos, exteriorPhotos, interiorPhoto, showModal, hideModal, statsData, handleSentryInit } = this.props;
|
|
94
117
|
const { activeSlide } = this.state;
|
|
95
118
|
|
|
96
119
|
showModal('VEHICLE_DETAILED_SLIDER_MODAL', {
|
|
@@ -106,12 +129,22 @@ class VehicleDetailedSlider extends Component<IProps, IState> {
|
|
|
106
129
|
onClose: (index: number) => {
|
|
107
130
|
this.slider.slickGoTo(index, true);
|
|
108
131
|
hideModal('VEHICLE_DETAILED_SLIDER_MODAL');
|
|
109
|
-
}
|
|
132
|
+
},
|
|
133
|
+
handleSentryInit: handleSentryInit
|
|
110
134
|
});
|
|
111
135
|
};
|
|
112
136
|
|
|
137
|
+
handleSlideChange = (_currentSlide: any, nextSlide: number) => {
|
|
138
|
+
const { photos } = this.props;
|
|
139
|
+
if (photos[nextSlide].videoUrl) {
|
|
140
|
+
this.setState({ videoSrc: `https://www.youtube.com/embed/${photos[nextSlide].videoUrl}` })
|
|
141
|
+
} else {
|
|
142
|
+
this.setState({ videoSrc: null })
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
113
146
|
getImages = () => {
|
|
114
|
-
const { photos, mainImageUrl, mainImageBlur } = this.props;
|
|
147
|
+
const { photos, mainImageUrl, mainImageBlur, t, handleSentryInit } = this.props;
|
|
115
148
|
const { activeSlide, largeLoaded, smallLoaded, largeLoaded1, largeLoaded01 } = this.state;
|
|
116
149
|
|
|
117
150
|
const imageProps = {
|
|
@@ -121,6 +154,7 @@ class VehicleDetailedSlider extends Component<IProps, IState> {
|
|
|
121
154
|
className: styles.image,
|
|
122
155
|
withLoader: false
|
|
123
156
|
};
|
|
157
|
+
|
|
124
158
|
if (Array.isArray(photos) && photos.length > 0 && largeLoaded && smallLoaded && largeLoaded1 && largeLoaded01) {
|
|
125
159
|
let isMouseDown = false;
|
|
126
160
|
let isDragging = false;
|
|
@@ -145,27 +179,41 @@ class VehicleDetailedSlider extends Component<IProps, IState> {
|
|
|
145
179
|
isDragging = false;
|
|
146
180
|
};
|
|
147
181
|
|
|
182
|
+
const updateCookies = () => {
|
|
183
|
+
const cookieConfig = localStorage.getItem('cookieConfig');
|
|
184
|
+
const conf = JSON.parse(cookieConfig);
|
|
185
|
+
const indexToRemove = conf.marketing.indexOf('youtube');
|
|
186
|
+
if (indexToRemove !== -1) {
|
|
187
|
+
conf.marketing.splice(indexToRemove, 1);
|
|
188
|
+
}
|
|
189
|
+
const showYoutube = !conf?.marketing?.includes('youtube');
|
|
190
|
+
this.setState({ showYoutube: showYoutube })
|
|
191
|
+
localStorage.setItem('cookieConfig', JSON.stringify(conf));
|
|
192
|
+
updateCookieList(handleSentryInit);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
|
|
148
196
|
const imagesCount = photos.length;
|
|
149
197
|
const currentSlide = activeSlide;
|
|
150
198
|
const prevSlide = (activeSlide - 1 % imagesCount + imagesCount) % imagesCount;
|
|
151
199
|
const nextSlide = (activeSlide + 1 % imagesCount + imagesCount) % imagesCount;
|
|
152
|
-
|
|
153
|
-
return photos.map(({ imageUrlLarge, imageUrlSmall }: IImage, index: number) => {
|
|
200
|
+
return photos.map((item: IImage, index: number) => {
|
|
154
201
|
const showImage = index === currentSlide || index === prevSlide || index === nextSlide || this.imagesCache[index] !== undefined;
|
|
202
|
+
const imageUrlSmall = _get(item, 'imageUrlSmall', null);
|
|
203
|
+
const imageUrlLarge = _get(item, 'imageUrlLarge', null);
|
|
155
204
|
|
|
156
205
|
this.imagesCache[currentSlide] = imageUrlLarge;
|
|
157
206
|
this.imagesCache[prevSlide] = imageUrlLarge;
|
|
158
207
|
this.imagesCache[nextSlide] = imageUrlLarge;
|
|
159
|
-
|
|
160
208
|
return (
|
|
161
209
|
<div
|
|
162
210
|
className={styles.photo}
|
|
163
211
|
key={imageUrlLarge}
|
|
164
212
|
onMouseDown={handleMouseDown}
|
|
165
213
|
onMouseMove={handleMouseMove}
|
|
166
|
-
onMouseUp={handleMouseUp}
|
|
214
|
+
onMouseUp={this.state.showYoutube ? handleMouseUp : null}
|
|
167
215
|
>
|
|
168
|
-
{showImage && (
|
|
216
|
+
{showImage && !item.videoUrl && (
|
|
169
217
|
<MagnifyGlassImage
|
|
170
218
|
src={index !== 0 ? imageUrlLarge : null}
|
|
171
219
|
srcSmall={index === 0 ? imageUrlSmall : null}
|
|
@@ -173,54 +221,77 @@ class VehicleDetailedSlider extends Component<IProps, IState> {
|
|
|
173
221
|
{...imageProps}
|
|
174
222
|
/>
|
|
175
223
|
)}
|
|
224
|
+
{showImage && item.videoUrl && this.state.showYoutube && (
|
|
225
|
+
<iframe
|
|
226
|
+
width='100%'
|
|
227
|
+
height='441'
|
|
228
|
+
src={this.state.videoSrc}
|
|
229
|
+
title='YouTube Video'
|
|
230
|
+
className={styles.frame}
|
|
231
|
+
></iframe>
|
|
232
|
+
)}
|
|
233
|
+
{showImage && item.videoUrl && !this.state.showYoutube && this.state.videoSrc && (
|
|
234
|
+
<div className={styles.noYoutubeWrapper}>
|
|
235
|
+
<SvgYoutubeButton></SvgYoutubeButton>
|
|
236
|
+
<span className={styles.youtubeCookiesText}>{t('youtube.acceptCookiesText')}</span>
|
|
237
|
+
<div>
|
|
238
|
+
<Button variant='text' className={styles.btn} onClick={() => window.open('https://www.youtube.com/howyoutubeworks/our-commitments/protecting-user-data/', '_blank')}>
|
|
239
|
+
{t('youtube.dataProtection')}
|
|
240
|
+
</Button>
|
|
241
|
+
<Button color='primary' className={styles.btn} onClick={updateCookies}>{t('youtube.allow')}</Button>
|
|
242
|
+
</div>
|
|
243
|
+
</div>
|
|
244
|
+
)}
|
|
176
245
|
</div>
|
|
177
246
|
);
|
|
178
247
|
});
|
|
179
248
|
}
|
|
180
|
-
|
|
181
249
|
if (mainImageUrl) {
|
|
182
250
|
const imagesCount = Array.isArray(photos) && photos.length > 0 ? photos.length : 0;
|
|
183
251
|
const prevSlide = (activeSlide - 1 % imagesCount + imagesCount) % imagesCount;
|
|
184
252
|
const nextSlide = (activeSlide + 1 % imagesCount + imagesCount) % imagesCount;
|
|
185
253
|
return (
|
|
186
254
|
// preload cached photos from props
|
|
255
|
+
|
|
187
256
|
<div className={classnames(styles.photo, { [styles.blurred]: (mainImageBlur && mainImageUrl !== PLACEHOLDER_IMAGE_SMALL_URL) })} key={mainImageUrl}>
|
|
188
|
-
{(!largeLoaded || !smallLoaded || !largeLoaded1 || !largeLoaded01) && <Image src={mainImageUrl} {...imageProps} />
|
|
257
|
+
{(!largeLoaded || !smallLoaded || !largeLoaded1 || !largeLoaded01) && <Image src={mainImageUrl} {...imageProps} />}
|
|
189
258
|
|
|
190
|
-
{
|
|
191
|
-
style={
|
|
192
|
-
src={
|
|
193
|
-
onLoad={
|
|
259
|
+
{Array.isArray(photos) && photos.length > 0 && <Image
|
|
260
|
+
style={{ display: 'none' }}
|
|
261
|
+
src={photos[activeSlide]?.imageUrlSmall}
|
|
262
|
+
onLoad={() => this.setState({ smallLoaded: true })}
|
|
194
263
|
{...imageProps}
|
|
195
|
-
|
|
264
|
+
/>
|
|
196
265
|
}
|
|
197
|
-
{
|
|
198
|
-
style={
|
|
199
|
-
src={
|
|
200
|
-
onLoad={
|
|
266
|
+
{Array.isArray(photos) && photos.length > 0 && <Image
|
|
267
|
+
style={{ display: 'none' }}
|
|
268
|
+
src={photos[activeSlide]?.imageUrlLarge}
|
|
269
|
+
onLoad={() => this.setState({ largeLoaded: true })}
|
|
201
270
|
{...imageProps}
|
|
202
|
-
|
|
271
|
+
/>
|
|
203
272
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
273
|
+
|
|
274
|
+
{Array.isArray(photos) && photos.length > 0 && <Image
|
|
275
|
+
style={{ display: 'none' }}
|
|
276
|
+
src={photos[nextSlide]?.imageUrlLarge}
|
|
277
|
+
onLoad={() => this.setState({ largeLoaded1: true })}
|
|
208
278
|
{...imageProps}
|
|
209
|
-
|
|
279
|
+
/>
|
|
210
280
|
}
|
|
211
|
-
{
|
|
212
|
-
style={
|
|
213
|
-
src={
|
|
214
|
-
onLoad={
|
|
281
|
+
{Array.isArray(photos) && photos.length > 0 && <Image
|
|
282
|
+
style={{ display: 'none' }}
|
|
283
|
+
src={photos[prevSlide]?.imageUrlLarge}
|
|
284
|
+
onLoad={() => this.setState({ largeLoaded01: true })}
|
|
215
285
|
{...imageProps}
|
|
216
|
-
|
|
286
|
+
/>
|
|
217
287
|
}
|
|
218
288
|
</div>
|
|
219
289
|
);
|
|
290
|
+
|
|
220
291
|
}
|
|
221
292
|
|
|
222
293
|
return (
|
|
223
|
-
<div className={styles.noPhoto}/>
|
|
294
|
+
<div className={styles.noPhoto} />
|
|
224
295
|
);
|
|
225
296
|
};
|
|
226
297
|
|
|
@@ -236,13 +307,15 @@ class VehicleDetailedSlider extends Component<IProps, IState> {
|
|
|
236
307
|
showNewLabel,
|
|
237
308
|
make,
|
|
238
309
|
model,
|
|
310
|
+
showDownPayment,
|
|
239
311
|
subModel,
|
|
240
312
|
powerKW,
|
|
241
313
|
powerPS,
|
|
314
|
+
activeTab,
|
|
315
|
+
financingConfig,
|
|
242
316
|
onCarFavorite
|
|
243
317
|
} = this.props;
|
|
244
318
|
const { activeSlide } = this.state;
|
|
245
|
-
|
|
246
319
|
const sliderProps = {
|
|
247
320
|
autoPlay: false,
|
|
248
321
|
speed: 300,
|
|
@@ -251,6 +324,7 @@ class VehicleDetailedSlider extends Component<IProps, IState> {
|
|
|
251
324
|
arrows: Array.isArray(photos) && photos.length > 0,
|
|
252
325
|
slidesToShow: 1,
|
|
253
326
|
slidesToScroll: 1,
|
|
327
|
+
beforeChange: this.handleSlideChange,
|
|
254
328
|
afterChange: (index: number) => {
|
|
255
329
|
this.setState({
|
|
256
330
|
activeSlide: index
|
|
@@ -260,9 +334,12 @@ class VehicleDetailedSlider extends Component<IProps, IState> {
|
|
|
260
334
|
|
|
261
335
|
const priceProps = {
|
|
262
336
|
t,
|
|
337
|
+
financingConfig,
|
|
263
338
|
showNewLabel,
|
|
339
|
+
showDownPayment,
|
|
264
340
|
historyPriceDifference: price ? price.historyPriceDifference : 0,
|
|
265
|
-
historyPriceDifferencePerCent: price ? price.historyPriceDifferencePerCent : 0
|
|
341
|
+
historyPriceDifferencePerCent: price ? price.historyPriceDifferencePerCent : 0,
|
|
342
|
+
activeTab
|
|
266
343
|
};
|
|
267
344
|
|
|
268
345
|
const statsProps = {
|
|
@@ -280,14 +357,16 @@ class VehicleDetailedSlider extends Component<IProps, IState> {
|
|
|
280
357
|
return (
|
|
281
358
|
<div className={styles.sliderWrap}>
|
|
282
359
|
{isMobileOnly &&
|
|
283
|
-
<Title {...{ t, make, model, subModel, powerKW, powerPS, onCarFavorite, isFavorite }}/>
|
|
360
|
+
<Title {...{ t, make, model, subModel, powerKW, powerPS, onCarFavorite, isFavorite }} />
|
|
284
361
|
}
|
|
285
362
|
<div className={styles.slider}>
|
|
286
|
-
<PriceData {...priceProps}/>
|
|
363
|
+
{!photos[activeSlide]?.videoUrl && <PriceData {...priceProps} />}
|
|
287
364
|
<Slider ref={slider => (this.slider = slider)} {...sliderProps}>
|
|
288
365
|
{this.getImages()}
|
|
289
366
|
</Slider>
|
|
290
|
-
{
|
|
367
|
+
{!photos[activeSlide]?.videoUrl ? (
|
|
368
|
+
isMobileOnly ? <MobileStats {...statsProps} /> : <Stats {...statsProps} />
|
|
369
|
+
) : null}
|
|
291
370
|
</div>
|
|
292
371
|
</div>
|
|
293
372
|
);
|
|
@@ -24,7 +24,6 @@
|
|
|
24
24
|
color: white
|
|
25
25
|
padding: 0 15px
|
|
26
26
|
float: left
|
|
27
|
-
text-transform: uppercase
|
|
28
27
|
border-radius: 33px
|
|
29
28
|
font-weight: 700;
|
|
30
29
|
font-size: 20px;
|
|
@@ -46,3 +45,7 @@
|
|
|
46
45
|
.new
|
|
47
46
|
@extend .priceDifference
|
|
48
47
|
margin-right: 12px
|
|
48
|
+
|
|
49
|
+
.percentageOfFirstInstallment
|
|
50
|
+
@extend .priceDifference
|
|
51
|
+
margin-left: 12px
|
|
@@ -3,19 +3,24 @@ import FormattedNumber from '../../FormattedNumber/FormattedNumber';
|
|
|
3
3
|
import Badge from '../../_common/Badge/Badge';
|
|
4
4
|
|
|
5
5
|
import styles from './PriceData.styl';
|
|
6
|
+
import { isNil } from 'lodash';
|
|
6
7
|
|
|
7
8
|
interface IProps {
|
|
8
9
|
t: (phrase: string, config?: any) => string;
|
|
9
10
|
showNewLabel: boolean;
|
|
10
11
|
historyPriceDifference: number;
|
|
11
12
|
historyPriceDifferencePerCent: number;
|
|
13
|
+
financingConfig?:any;
|
|
14
|
+
activeTab?:number;
|
|
15
|
+
showDownPayment:boolean;
|
|
12
16
|
}
|
|
13
17
|
|
|
14
18
|
const MIN_PERCENT = 5;
|
|
15
19
|
const MIN_PRICE_DIFFERENCE = 500;
|
|
16
20
|
const EUR = `\u20AC`;
|
|
17
21
|
|
|
18
|
-
const PriceData: React.FunctionComponent<IProps> = ({ t, showNewLabel, historyPriceDifference, historyPriceDifferencePerCent }) => {
|
|
22
|
+
const PriceData: React.FunctionComponent<IProps> = ({ t, showDownPayment,showNewLabel, historyPriceDifference, historyPriceDifferencePerCent, financingConfig, activeTab }) => {
|
|
23
|
+
const percentageOfFirstInstallment = activeTab === 0 ? financingConfig!.financing.percentageOfFirstInstallment : financingConfig!.leasing.percentageOfFirstInstallment;
|
|
19
24
|
return (
|
|
20
25
|
<div className={styles.topWrapper}>
|
|
21
26
|
{showNewLabel && <Badge type='blue' className={styles.new}>{t('slider.new')}</Badge>}
|
|
@@ -25,6 +30,8 @@ const PriceData: React.FunctionComponent<IProps> = ({ t, showNewLabel, historyPr
|
|
|
25
30
|
{` ${EUR} ${t('slider.save')}`}
|
|
26
31
|
</Badge>
|
|
27
32
|
)}
|
|
33
|
+
{(!isNil(percentageOfFirstInstallment) && activeTab !== 2 && showDownPayment) &&
|
|
34
|
+
<Badge type='lightBlue' className={styles.percentageOfFirstInstallment}>{`${percentageOfFirstInstallment}${percentageOfFirstInstallment > 0 ? '%' : EUR} ${t('slider.firstInstallment')}`}</Badge>}
|
|
28
35
|
{historyPriceDifferencePerCent >= MIN_PERCENT && (
|
|
29
36
|
<Badge type='red' className={styles.priceDifferencePerCent}>
|
|
30
37
|
-{historyPriceDifferencePerCent}%
|
|
@@ -43,7 +43,7 @@ const Stats: FunctionComponent<IProps> = (props) => {
|
|
|
43
43
|
</div>
|
|
44
44
|
)}
|
|
45
45
|
</div>
|
|
46
|
-
<div className={styles.statsContainer}>
|
|
46
|
+
{(totalCarImpCount > 0 || totalFavCount > 0) && <div className={styles.statsContainer}>
|
|
47
47
|
{totalCarImpCount > 0 && (
|
|
48
48
|
<div className={`${styles.statsBlock} ${styles.saveCarAsFavorites}`}>
|
|
49
49
|
<span>{t('slider.customersLookingTheCar', { count: totalCarImpCount })}</span>
|
|
@@ -54,7 +54,7 @@ const Stats: FunctionComponent<IProps> = (props) => {
|
|
|
54
54
|
<span>{t('slider.saveCarAsFavorites', { count: totalFavCount })}</span>
|
|
55
55
|
</div>
|
|
56
56
|
)}
|
|
57
|
-
</div>
|
|
57
|
+
</div>}
|
|
58
58
|
</div>
|
|
59
59
|
);
|
|
60
60
|
};
|
package/source/components/VehicleSmallCard/VehicleData/VechiclePriceItem/VechiclePriceItem.tsx
CHANGED
|
@@ -36,6 +36,7 @@ export interface IVehiclePriceItemProps {
|
|
|
36
36
|
combineRefAlternative?: boolean;
|
|
37
37
|
postfix?: string;
|
|
38
38
|
margin?: number;
|
|
39
|
+
isMarge?: boolean;
|
|
39
40
|
}
|
|
40
41
|
class VehiclePriceItem extends React.Component<IVehiclePriceItemProps> {
|
|
41
42
|
routeToActiveTab = () => {
|
|
@@ -54,15 +55,15 @@ class VehiclePriceItem extends React.Component<IVehiclePriceItemProps> {
|
|
|
54
55
|
totalOld,
|
|
55
56
|
totalCurrent,
|
|
56
57
|
tooltipDescription,
|
|
57
|
-
positionX,
|
|
58
|
-
positionY,
|
|
59
|
-
iconName,
|
|
58
|
+
// positionX,
|
|
59
|
+
// positionY,
|
|
60
|
+
// iconName,
|
|
60
61
|
postfix,
|
|
61
62
|
linkTag,
|
|
62
63
|
routeObj,
|
|
63
|
-
combineRefAlternative,
|
|
64
|
+
// combineRefAlternative,
|
|
64
65
|
prefixOldPrice,
|
|
65
|
-
margin,
|
|
66
|
+
// margin,
|
|
66
67
|
isAlternativeText,
|
|
67
68
|
vehicleComponentName,
|
|
68
69
|
priceSub,
|
|
@@ -70,7 +71,8 @@ class VehiclePriceItem extends React.Component<IVehiclePriceItemProps> {
|
|
|
70
71
|
showAboIcon = false,
|
|
71
72
|
isPriceDisable = false,
|
|
72
73
|
isNewPriceCategory = false,
|
|
73
|
-
isStrikeShown = false
|
|
74
|
+
isStrikeShown = false,
|
|
75
|
+
isMarge
|
|
74
76
|
} = this.props;
|
|
75
77
|
|
|
76
78
|
const stylesItem = classnames(
|
|
@@ -150,7 +152,7 @@ class VehiclePriceItem extends React.Component<IVehiclePriceItemProps> {
|
|
|
150
152
|
<span className={styles.noPrice}>---</span>
|
|
151
153
|
)}
|
|
152
154
|
|
|
153
|
-
{isStrikeShown && isTotal &&
|
|
155
|
+
{isStrikeShown && isTotal && !isMarge && (
|
|
154
156
|
<VehicleFormattedPrice
|
|
155
157
|
numbersAfterDot={0}
|
|
156
158
|
className={styles.oldPrice}
|
|
@@ -127,4 +127,38 @@
|
|
|
127
127
|
margin-right: 5px;
|
|
128
128
|
|
|
129
129
|
+media-tablet-landscape-up()
|
|
130
|
-
margin-right: 10px;
|
|
130
|
+
margin-right: 10px;
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
.landingButton
|
|
134
|
+
position: relative;
|
|
135
|
+
padding: 0px 10px;
|
|
136
|
+
background-color: transparent;
|
|
137
|
+
border-radius: 4px;
|
|
138
|
+
color: #005ccb;
|
|
139
|
+
border: 1px solid #666CFF80;
|
|
140
|
+
font-size: 16px;
|
|
141
|
+
cursor: pointer;
|
|
142
|
+
overflow: hidden;
|
|
143
|
+
z-index: 0;
|
|
144
|
+
|
|
145
|
+
.landingButton::before
|
|
146
|
+
content: "";
|
|
147
|
+
position: absolute;
|
|
148
|
+
top: 50%;
|
|
149
|
+
left: 50%;
|
|
150
|
+
transform: translate(-50%, -50%);
|
|
151
|
+
width: 30%;
|
|
152
|
+
height: 100%;
|
|
153
|
+
background-color: #82b1ff91;
|
|
154
|
+
border-radius: 20%;
|
|
155
|
+
opacity: 0;
|
|
156
|
+
transition: width 0.7s ease-out, height 0.7s ease-out, opacity 0.7s ease-out;
|
|
157
|
+
z-index: -1;
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
.landingButton:active::before
|
|
161
|
+
width: 200%;
|
|
162
|
+
height: 200%;
|
|
163
|
+
opacity: 1;
|
|
164
|
+
transition: width 0.7s ease-out, height 0.7s ease-out, opacity 0.7s ease-out;
|