@bytebrand/fe-ui-core 4.3.0 → 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.
Files changed (125) hide show
  1. package/__tests__/components/UserDasboardPage/sections/CheckoutSection/CheckoutSection.test.tsx +613 -0
  2. package/__tests__/components/UserDasboardPage/sections/FavoriteSection/FavoriteSection.test.tsx +335 -0
  3. package/__tests__/utils/CommonUtils/getOfferSliders.test.ts +4 -2
  4. package/common.ts +6 -2
  5. package/package.json +19 -28
  6. package/source/components/AccordionWidget/AccordionWidget.tsx +1 -3
  7. package/source/components/Breadcrumbs/Breadcrumbs.tsx +3 -3
  8. package/source/components/Checkout/CheckoutStepper/CheckoutStepper.styl +2 -190
  9. package/source/components/Checkout/CheckoutStepper/CheckoutStepper.tsx +15 -16
  10. package/source/components/Checkout/OrderOverviewItem/OrderOverviewItem.styl +2 -2
  11. package/source/components/Checkout/OrderOverviewItem/OrderOverviewItem.tsx +3 -3
  12. package/source/components/FormattedNumber/FormattedNumber.tsx +2 -3
  13. package/source/components/InfoBlocks/FirstInfoBlock/FirstInfoBlockItem/FirstInfoBlockItem.styl +4 -6
  14. package/source/components/OfferDetailedSection/partials/PanelConfig.tsx +0 -3
  15. package/source/components/OfferPanel/MuiOfferPeriod/{MuiOfferPeriod.theme.js → MuiOfferPeriod.theme.tsx} +8 -13
  16. package/source/components/OfferPanel/MuiOfferPeriod/MuiOfferPeriod.tsx +28 -4
  17. package/source/components/OfferPanel/OfferCheckboxGroup/CheckboxContainer.tsx +6 -12
  18. package/source/components/OfferPanel/OfferCheckboxGroup/OfferCheckboxGroup.tsx +1 -1
  19. package/source/components/OfferPanel/OfferPanel.tsx +1 -1
  20. package/source/components/OfferPanel/OfferPeriod/OfferPeriod.tsx +0 -4
  21. package/source/components/OfferPanel/RangeGroup/RangeGroup.tsx +6 -4
  22. package/source/components/PriceRatingDetailed/PriceRatingDetailed.tsx +6 -2
  23. package/source/components/SearchFilters/filters/AlternativeID.tsx +42 -53
  24. package/source/components/SearchFilters/filters/DriveType.tsx +1 -1
  25. package/source/components/SearchFilters/filters/EmissionSticker.tsx +1 -1
  26. package/source/components/SearchFilters/filters/FirstRegistration.tsx +0 -1
  27. package/source/components/SearchFilters/filters/InteriorColor.tsx +1 -1
  28. package/source/components/SearchFilters/filters/InteriorMaterial.tsx +2 -1
  29. package/source/components/SearchFilters/filters/Mileage.tsx +1 -1
  30. package/source/components/SearchFilters/filters/Power.tsx +36 -17
  31. package/source/components/SearchFilters/filters/StateOptions.tsx +0 -1
  32. package/source/components/SearchFilters/filters/Transmission.tsx +1 -1
  33. package/source/components/SearchPage/SearchChips/SearchChips.tsx +1 -1
  34. package/source/components/SearchPageMobile/FiltersDetailed/BodyType.tsx +3 -3
  35. package/source/components/SearchPageMobile/FiltersDetailed/Consumption.tsx +2 -2
  36. package/source/components/SearchPageMobile/FiltersDetailed/Doors.tsx +1 -1
  37. package/source/components/SearchPageMobile/FiltersDetailed/MakeModel.tsx +1 -1
  38. package/source/components/SearchWidget/ColorWidget/BodyColorWidget.tsx +3 -3
  39. package/source/components/SearchWidget/EnvironmentWidget/EnvironmentWidget.tsx +3 -3
  40. package/source/components/SearchWidget/HighlightsWidget/HighlightsWidget.tsx +2 -2
  41. package/source/components/SearchWidget/StateWidget/StateWidget.tsx +1 -2
  42. package/source/components/SearchWidgetsMobile/BasicDataWidgetMobile/BasicDataWidgetMobile.tsx +4 -4
  43. package/source/components/SearchWidgetsMobile/EquipmentsWidget/EquipmentsWidget.tsx +16 -16
  44. package/source/components/SearchWidgetsMobile/HighlightsWidgetMobile/HighlightsWidgetMobile.tsx +1 -1
  45. package/source/components/SearchWidgetsMobile/InteriorWidget/InteriorWidget.tsx +1 -1
  46. package/source/components/SearchWidgetsMobile/SafetyWidget/SafetyWidget.tsx +6 -6
  47. package/source/components/Stepper/Stepper.tsx +4 -3
  48. package/source/components/UserDashboardPage/sections/CheckoutSection/CheckoutSection.styl +38 -0
  49. package/source/components/UserDashboardPage/sections/CheckoutSection/CheckoutSection.tsx +120 -0
  50. package/source/components/UserDashboardPage/sections/FavoriteSection/FavoriteSection.styl +22 -0
  51. package/source/components/UserDashboardPage/sections/FavoriteSection/FavoriteSection.tsx +84 -0
  52. package/source/components/UserDashboardPage/sections/OrderStatusSection/AdditionalOrderInfo.styl +11 -2
  53. package/source/components/UserDashboardPage/sections/OrderStatusSection/AdditionalOrderInfo.tsx +5 -5
  54. package/source/components/UserDashboardPage/sections/OrderStatusSection/OrderStatusCar.tsx +57 -38
  55. package/source/components/UserDashboardPage/sections/OrderStatusSection/OrderStatusCard.tsx +2 -2
  56. package/source/components/UserDashboardPage/sections/OrderStatusSection/OrderStatusSection.tsx +183 -101
  57. package/source/components/UserDashboardPage/sections/RequestedCarsSection/RequestedCarsSection.tsx +5 -7
  58. package/source/components/Vehicle/VehicleFormattedPrice/VehicleFormattedPrice.tsx +33 -7
  59. package/source/components/VehicleDetailedSidebar/VehicleDetailedSidebar.styl +10 -2
  60. package/source/components/VehicleDetailedSidebar/VehicleDetailedSidebar.tsx +54 -14
  61. package/source/components/VehicleDetailedSidebar/partials/Price.styl +5 -1
  62. package/source/components/VehicleDetailedSidebar/partials/Price.tsx +2 -1
  63. package/source/components/VehicleDetailedSidebar/partials/PriceContent.styl +16 -5
  64. package/source/components/VehicleDetailedSidebar/partials/PriceContent.tsx +9 -4
  65. package/source/components/VehicleDetailedSidebar/partials/Properties.tsx +1 -1
  66. package/source/components/VehicleDetailedSlider/VehicleDetailedSlider.styl +45 -0
  67. package/source/components/VehicleDetailedSlider/VehicleDetailedSlider.tsx +121 -42
  68. package/source/components/VehicleDetailedSlider/partials/PriceData.styl +4 -1
  69. package/source/components/VehicleDetailedSlider/partials/PriceData.tsx +8 -1
  70. package/source/components/VehicleDetailedSlider/partials/Stats.tsx +2 -2
  71. package/source/components/VehicleSmallCard/VehicleData/VechiclePriceItem/VechiclePriceItem.tsx +9 -7
  72. package/source/components/VehicleSmallCard/VehicleData/VehiclePrice/VehiclePrice.styl +35 -1
  73. package/source/components/VehicleSmallCard/VehicleData/VehiclePrice/VehiclePrice.tsx +9 -3
  74. package/source/components/VehicleSmallCard/VehicleData/VehicleTitle/VehicleTitle.styl +11 -2
  75. package/source/components/VehicleSmallCard/VehicleData/VehicleTitle/VehicleTitle.tsx +2 -1
  76. package/source/components/VehicleSmallCard/VehicleSmallCard.styl +3 -1
  77. package/source/components/VehicleSmallCard/VehicleSmallCard.tsx +3 -7
  78. package/source/components/_common/Badge/Badge.styl +3 -0
  79. package/source/components/_common/Badge/Badge.tsx +1 -1
  80. package/source/components/_common/Button/Button.tsx +5 -4
  81. package/source/components/_common/Checkbox/FormCheckbox.tsx +4 -4
  82. package/source/components/_common/CheckboxMaterial/CheckboxMaterial.tsx +1 -1
  83. package/source/components/_common/Chip/Chip.tsx +1 -3
  84. package/source/components/_common/ExpansionPanel/ExpansionPanel.tsx +3 -3
  85. package/source/components/_common/IconSVG/IconSVGConfig.tsx +2 -0
  86. package/source/components/_common/IconSVG/SVG/flags/SK.tsx +0 -1
  87. package/source/components/_common/IconSVG/SVG/slider/360New.tsx +1 -1
  88. package/source/components/_common/IconSVG/SVG/slider/YoutubeButton.tsx +26 -0
  89. package/source/components/_common/MaterialAccordion/MaterialAccordion.tsx +22 -30
  90. package/source/components/_common/MaterialAutocomplete/MaterialAutocomplete.styled.tsx +8 -8
  91. package/source/components/_common/MaterialDatePicker/MaterialDatePicker.styled.tsx +0 -1
  92. package/source/components/_common/MaterialSelect/MaterialSelect.styled.tsx +12 -15
  93. package/source/components/_common/MaterialSelect/MaterialSelect.tsx +3 -3
  94. package/source/components/_common/MaterialSwitch/MaterialSwitch.tsx +3 -1
  95. package/source/components/_common/MaterialTooltip/MaterialTooltip.styled.tsx +1 -1
  96. package/source/components/_common/MaterialTooltip/MaterialTooltip.tsx +3 -3
  97. package/source/components/_common/Modal/CookieModal.tsx +1 -3
  98. package/source/components/_common/Modal/Modal.styled.tsx +2 -1
  99. package/source/components/_common/Modal/Modal.tsx +1 -5
  100. package/source/components/_common/Modal/ModalsConfig.tsx +5 -1
  101. package/source/components/_common/Modal/modals/ManageCookieModal/ManageCookieModal.styl +23 -7
  102. package/source/components/_common/Modal/modals/ManageCookieModal/ManageCookieModal.tsx +84 -36
  103. package/source/components/_common/Modal/modals/PreviewCookieModal/PreviewCookieModal.styl +29 -14
  104. package/source/components/_common/Modal/modals/PreviewCookieModal/PreviewCookieModal.tsx +17 -10
  105. package/source/components/_common/OfferRequestButtonWrapper/OfferRequestButtonWrapper.tsx +12 -4
  106. package/source/components/_common/Range/Range.tsx +27 -14
  107. package/source/components/_common/UserMenu/MaterialMenu.styled.tsx +0 -1
  108. package/source/components/_common/UserMenu/MaterialMenu.tsx +3 -3
  109. package/source/components/_common/UserMenu/MaterialMenuItem.tsx +42 -20
  110. package/source/components/_common/UserMenu/NestedMenu.tsx +1 -1
  111. package/source/components/_common/withStats/withStats.styl +3 -0
  112. package/source/components/_common/withStats/withStats.tsx +19 -16
  113. package/source/components/containers/SearchPage/FiltersContainer/FiltersContainer.styl +14 -1
  114. package/source/components/containers/SearchPage/FiltersContainer/FiltersContainer.tsx +78 -42
  115. package/source/framework/constants/common.ts +89 -60
  116. package/source/framework/constants/highlights.ts +1 -1
  117. package/source/framework/constants.ts +1 -1
  118. package/source/framework/types/types.ts +9 -4
  119. package/source/framework/utils/CommonUtils.ts +73 -62
  120. package/source/framework/utils/DateUtils.ts +10 -2
  121. package/source/framework/vehiclesProps/decoratedLightProps.tsx +1 -2
  122. package/source/framework/vehiclesProps/decoratedProps.tsx +1 -2
  123. package/source/locales/data.ts +2 -2
  124. package/tslint.json +1 -2
  125. package/utils.ts +2 -0
@@ -1,7 +1,7 @@
1
1
  @import '../../../theme/mixins.styl';
2
2
 
3
3
  .newFinancingPriceWrapper
4
- width: 100%
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 16px;
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
- padding-right: 15px;
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: 'overview',
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
- componentDidUpdate(prevProps: IProps) {
81
- console.log('VehicleDetailedSlider-works!');
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
- { Array.isArray(photos) && photos.length > 0 && <Image
191
- style={ { display: 'none' } }
192
- src={ photos[activeSlide].imageUrlSmall }
193
- onLoad={ () => this.setState({ smallLoaded: true }) }
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
- { Array.isArray(photos) && photos.length > 0 && <Image
198
- style={ { display: 'none' } }
199
- src={ photos[activeSlide].imageUrlLarge }
200
- onLoad={ () => this.setState({ largeLoaded: true }) }
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
- { Array.isArray(photos) && photos.length > 0 && <Image
205
- style={ { display: 'none' } }
206
- src={ photos[nextSlide].imageUrlLarge }
207
- onLoad={ () => this.setState({ largeLoaded1: true }) }
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
- { Array.isArray(photos) && photos.length > 0 && <Image
212
- style={ { display: 'none' } }
213
- src={ photos[prevSlide].imageUrlLarge }
214
- onLoad={ () => this.setState({ largeLoaded01: true }) }
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
- {isMobileOnly ? <MobileStats {...statsProps} /> : <Stats {...statsProps}/>}
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
  };
@@ -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;