@bytebrand/fe-ui-core 4.2.242 → 4.2.244
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/package.json +1 -1
- package/source/components/Checkout/CheckoutStepper/CheckoutStepper.styl +2 -190
- package/source/components/Checkout/OrderOverviewItem/OrderOverviewItem.styl +2 -2
- package/source/components/Checkout/OrderOverviewItem/OrderOverviewItem.tsx +3 -3
- package/source/components/InfoBlocks/FirstInfoBlock/FirstInfoBlockItem/FirstInfoBlockItem.styl +4 -6
- package/source/components/UserDashboardPage/sections/OrderStatusSection/AdditionalOrderInfo.styl +5 -1
- package/source/components/UserDashboardPage/sections/OrderStatusSection/AdditionalOrderInfo.tsx +1 -1
- package/source/components/UserDashboardPage/sections/OrderStatusSection/OrderStatusCar.tsx +43 -27
- package/source/components/UserDashboardPage/sections/OrderStatusSection/OrderStatusSection.tsx +62 -27
- package/source/components/VehicleDetailedSidebar/VehicleDetailedSidebar.styl +9 -1
- package/source/components/VehicleDetailedSidebar/VehicleDetailedSidebar.tsx +36 -32
- package/source/components/VehicleDetailedSidebar/partials/PriceContent.tsx +1 -1
- package/source/components/VehicleDetailedSlider/VehicleDetailedSlider.styl +45 -0
- package/source/components/VehicleDetailedSlider/VehicleDetailedSlider.tsx +112 -42
- package/source/components/VehicleDetailedSlider/partials/Stats.tsx +2 -2
- package/source/components/VehicleSmallCard/VehicleData/VechiclePriceItem/VechiclePriceItem.tsx +4 -2
- package/source/components/VehicleSmallCard/VehicleData/VehiclePrice/VehiclePrice.styl +35 -1
- package/source/components/VehicleSmallCard/VehicleData/VehiclePrice/VehiclePrice.tsx +8 -2
- 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.tsx +0 -1
- package/source/components/_common/Button/Button.tsx +4 -2
- package/source/components/_common/IconSVG/IconSVGConfig.tsx +2 -0
- package/source/components/_common/IconSVG/SVG/slider/YoutubeButton.tsx +26 -0
- package/source/components/_common/MaterialAutocomplete/MaterialAutocomplete.styled.tsx +8 -8
- package/source/components/_common/MaterialSelect/MaterialSelect.styled.tsx +4 -4
- package/source/components/_common/OfferRequestButtonWrapper/OfferRequestButtonWrapper.tsx +12 -4
- package/source/components/_common/withStats/withStats.styl +3 -0
- package/source/components/_common/withStats/withStats.tsx +18 -15
- package/source/components/containers/SearchPage/FiltersContainer/FiltersContainer.styl +3 -1
- package/source/components/containers/SearchPage/FiltersContainer/FiltersContainer.tsx +7 -7
- package/source/framework/types/types.ts +2 -0
- package/source/framework/utils/CommonUtils.ts +1 -0
- package/source/framework/utils/DateUtils.ts +8 -0
- package/source/locales/cbd.ts +1 -1
|
@@ -10,6 +10,7 @@ import styles from './VehicleDetailedSidebar.styl';
|
|
|
10
10
|
import { vehicleProps } from '../../locales/data';
|
|
11
11
|
import { IVehicleDetailedSidebarProps } from '../../framework/types/types';
|
|
12
12
|
import DealerInfo from '../Alternative/DealerInfo';
|
|
13
|
+
import { Skeleton } from '@mui/material';
|
|
13
14
|
|
|
14
15
|
declare global {
|
|
15
16
|
interface Window {
|
|
@@ -35,7 +36,8 @@ const VehicleDetailedSidebar: FunctionComponent<IVehicleDetailedSidebarProps> =
|
|
|
35
36
|
originUrl,
|
|
36
37
|
// isAlternative,
|
|
37
38
|
infoSections,
|
|
38
|
-
onCurrentSalesPriceChange
|
|
39
|
+
onCurrentSalesPriceChange,
|
|
40
|
+
isFetching
|
|
39
41
|
} = props;
|
|
40
42
|
const ref = useRef(null);
|
|
41
43
|
const [offerBlockOpen, setOfferBlockOpen] = useState(false);
|
|
@@ -145,34 +147,34 @@ const VehicleDetailedSidebar: FunctionComponent<IVehicleDetailedSidebarProps> =
|
|
|
145
147
|
|
|
146
148
|
return (
|
|
147
149
|
<>
|
|
148
|
-
<div className={styles.detailedInfo}>
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
>
|
|
163
|
-
<a
|
|
164
|
-
href='https://de.trustpilot.com/review/www.auto.de'
|
|
165
|
-
target='_blank'
|
|
166
|
-
rel='noopener noreferrer'
|
|
150
|
+
{!isFetching ? <div className={styles.detailedInfo}>
|
|
151
|
+
<Title {...titleProps} />
|
|
152
|
+
<Price {...priceProps} />
|
|
153
|
+
<Price {...priceProps} isSticky={true} />
|
|
154
|
+
{isMobileOnly && (
|
|
155
|
+
<div
|
|
156
|
+
ref={ref}
|
|
157
|
+
data-locale='de-DE'
|
|
158
|
+
data-template-id='5419b6a8b0d04a076446a9ad'
|
|
159
|
+
data-businessunit-id='46edfd1c0000640005017f22'
|
|
160
|
+
data-style-height='32px'
|
|
161
|
+
data-style-width='100%'
|
|
162
|
+
data-theme='light'
|
|
163
|
+
data-style-alignment='center'
|
|
167
164
|
>
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
165
|
+
<a
|
|
166
|
+
href='https://de.trustpilot.com/review/www.auto.de'
|
|
167
|
+
target='_blank'
|
|
168
|
+
rel='noopener noreferrer'
|
|
169
|
+
>
|
|
170
|
+
Trustpilot
|
|
171
|
+
</a>
|
|
172
|
+
</div>
|
|
173
|
+
)}
|
|
174
|
+
{props.children}
|
|
175
|
+
</div> : <div className={styles.skeletonInfoContainer}><Skeleton /></div>
|
|
176
|
+
}
|
|
177
|
+
{!isFetching ? <div>{isAlternativeType &&
|
|
176
178
|
<DealerInfo
|
|
177
179
|
t={t}
|
|
178
180
|
infoSections={infoSections}
|
|
@@ -182,10 +184,12 @@ const VehicleDetailedSidebar: FunctionComponent<IVehicleDetailedSidebarProps> =
|
|
|
182
184
|
currentSalesPrice={currentSalesPrice}
|
|
183
185
|
onCurrentSalesPriceChange={onCurrentSalesPriceChange}
|
|
184
186
|
/>}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
187
|
+
</div> : <div className={styles.skeletonInfoContainer}><Skeleton /></div>
|
|
188
|
+
}
|
|
189
|
+
{!isFetching ? <Hidden xs sm md>
|
|
190
|
+
<div className={`${styles.detailedInfo} ${styles.highlights}`}>{carLoaded && <Properties {...propertiesProps} />}</div>
|
|
191
|
+
</Hidden> : <div className={styles.skeletonInfoContainer}><Skeleton /></div>
|
|
192
|
+
}
|
|
189
193
|
</>
|
|
190
194
|
);
|
|
191
195
|
};
|
|
@@ -108,7 +108,7 @@ const PriceContent: React.FunctionComponent<IPriceContentProps> = ({
|
|
|
108
108
|
className={styles.infoIcon}
|
|
109
109
|
customDimensions
|
|
110
110
|
/>
|
|
111
|
-
<span>{t('sidebar.adjustRate')}</span>
|
|
111
|
+
<span>{priceTabActiveIndex === 2 ? t('sidebar.serviceProducts') : t('sidebar.adjustRate')}</span>
|
|
112
112
|
<IconSVG name='menuArrow' className={`${styles.arrowDownIcon} ${offerBlockOpen ? styles.arrowUpIcon : ''}`} customDimensions />
|
|
113
113
|
</span>
|
|
114
114
|
</span>
|
|
@@ -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,31 +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;
|
|
30
|
-
activeTab:number;
|
|
35
|
+
activeTab: number;
|
|
31
36
|
make: string;
|
|
32
37
|
model: string;
|
|
33
38
|
subModel: string;
|
|
34
39
|
powerKW: number;
|
|
35
40
|
powerPS: number;
|
|
36
|
-
financingConfig:any;
|
|
41
|
+
financingConfig: any;
|
|
42
|
+
youtubeId: string;
|
|
37
43
|
showModal?: (id: string, props?: any) => void;
|
|
38
44
|
hideModal: (id: string) => void;
|
|
39
45
|
onCarFavorite: (event: MouseEvent<HTMLElement>) => void;
|
|
40
|
-
showDownPayment:boolean;
|
|
46
|
+
showDownPayment: boolean;
|
|
47
|
+
handleSentryInit?: () => void;
|
|
41
48
|
}
|
|
42
49
|
|
|
43
50
|
interface IState {
|
|
@@ -46,6 +53,8 @@ interface IState {
|
|
|
46
53
|
smallLoaded: boolean;
|
|
47
54
|
largeLoaded1: boolean;
|
|
48
55
|
largeLoaded01: boolean;
|
|
56
|
+
videoSrc: string;
|
|
57
|
+
showYoutube: boolean;
|
|
49
58
|
}
|
|
50
59
|
|
|
51
60
|
const MagnifyGlassImage = withMagnifyGlassImage(Image);
|
|
@@ -62,17 +71,21 @@ class VehicleDetailedSlider extends Component<IProps, IState> {
|
|
|
62
71
|
};
|
|
63
72
|
|
|
64
73
|
private slider: any;
|
|
74
|
+
|
|
65
75
|
private imagesCache: string[] = [];
|
|
66
76
|
|
|
67
77
|
constructor(props: IProps) {
|
|
68
78
|
super(props);
|
|
69
|
-
|
|
79
|
+
const cookieConfig = JSON.parse(localStorage.getItem('cookieConfig')) || {};
|
|
80
|
+
const youtubeConfig = !cookieConfig?.marketing?.includes('youtube');
|
|
70
81
|
this.state = {
|
|
71
82
|
activeSlide: 0,
|
|
72
83
|
largeLoaded: false,
|
|
73
84
|
smallLoaded: false,
|
|
74
85
|
largeLoaded1: false,
|
|
75
|
-
largeLoaded01: false
|
|
86
|
+
largeLoaded01: false,
|
|
87
|
+
videoSrc: '',
|
|
88
|
+
showYoutube: youtubeConfig
|
|
76
89
|
};
|
|
77
90
|
}
|
|
78
91
|
|
|
@@ -80,7 +93,11 @@ class VehicleDetailedSlider extends Component<IProps, IState> {
|
|
|
80
93
|
this.slider.slickGoTo(0);
|
|
81
94
|
};
|
|
82
95
|
|
|
83
|
-
|
|
96
|
+
|
|
97
|
+
componentDidUpdate(prevProps: IProps, prevState: IState) {
|
|
98
|
+
const cookieConfig = JSON.parse(localStorage.getItem('cookieConfig')) || {};
|
|
99
|
+
const showYoutube = !cookieConfig?.marketing?.includes('youtube');
|
|
100
|
+
console.log('showYoutube', showYoutube);
|
|
84
101
|
if (prevProps.photos.length !== this.props.photos.length && this.props.photos.length === 0) {
|
|
85
102
|
this.setState(() => ({
|
|
86
103
|
largeLoaded: false,
|
|
@@ -89,10 +106,15 @@ class VehicleDetailedSlider extends Component<IProps, IState> {
|
|
|
89
106
|
largeLoaded01: false
|
|
90
107
|
}));
|
|
91
108
|
}
|
|
109
|
+
if (showYoutube !== prevState.showYoutube) {
|
|
110
|
+
this.setState(() => ({
|
|
111
|
+
showYoutube: showYoutube
|
|
112
|
+
}));
|
|
113
|
+
}
|
|
92
114
|
}
|
|
93
115
|
|
|
94
116
|
handleOpenSliderModal = (sliderType: SliderType) => {
|
|
95
|
-
const { t = (phrase: string) => _get(VehicleDetailedSliderTranslate(statsData), phrase, phrase), photos, exteriorPhotos, interiorPhoto, showModal, hideModal, statsData } = this.props;
|
|
117
|
+
const { t = (phrase: string) => _get(VehicleDetailedSliderTranslate(statsData), phrase, phrase), photos, exteriorPhotos, interiorPhoto, showModal, hideModal, statsData, handleSentryInit } = this.props;
|
|
96
118
|
const { activeSlide } = this.state;
|
|
97
119
|
|
|
98
120
|
showModal('VEHICLE_DETAILED_SLIDER_MODAL', {
|
|
@@ -108,12 +130,22 @@ class VehicleDetailedSlider extends Component<IProps, IState> {
|
|
|
108
130
|
onClose: (index: number) => {
|
|
109
131
|
this.slider.slickGoTo(index, true);
|
|
110
132
|
hideModal('VEHICLE_DETAILED_SLIDER_MODAL');
|
|
111
|
-
}
|
|
133
|
+
},
|
|
134
|
+
handleSentryInit: handleSentryInit
|
|
112
135
|
});
|
|
113
136
|
};
|
|
114
137
|
|
|
138
|
+
handleSlideChange = (_currentSlide: any, nextSlide: number) => {
|
|
139
|
+
const { photos } = this.props;
|
|
140
|
+
if (photos[nextSlide].videoUrl) {
|
|
141
|
+
this.setState({ videoSrc: `https://www.youtube.com/embed/${photos[nextSlide].videoUrl}` })
|
|
142
|
+
} else {
|
|
143
|
+
this.setState({ videoSrc: null })
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
115
147
|
getImages = () => {
|
|
116
|
-
const { photos, mainImageUrl, mainImageBlur } = this.props;
|
|
148
|
+
const { photos, mainImageUrl, mainImageBlur, t, handleSentryInit } = this.props;
|
|
117
149
|
const { activeSlide, largeLoaded, smallLoaded, largeLoaded1, largeLoaded01 } = this.state;
|
|
118
150
|
|
|
119
151
|
const imageProps = {
|
|
@@ -123,6 +155,7 @@ class VehicleDetailedSlider extends Component<IProps, IState> {
|
|
|
123
155
|
className: styles.image,
|
|
124
156
|
withLoader: false
|
|
125
157
|
};
|
|
158
|
+
|
|
126
159
|
if (Array.isArray(photos) && photos.length > 0 && largeLoaded && smallLoaded && largeLoaded1 && largeLoaded01) {
|
|
127
160
|
let isMouseDown = false;
|
|
128
161
|
let isDragging = false;
|
|
@@ -147,11 +180,24 @@ class VehicleDetailedSlider extends Component<IProps, IState> {
|
|
|
147
180
|
isDragging = false;
|
|
148
181
|
};
|
|
149
182
|
|
|
183
|
+
const updateCookies = () => {
|
|
184
|
+
const cookieConfig = localStorage.getItem('cookieConfig');
|
|
185
|
+
const conf = JSON.parse(cookieConfig);
|
|
186
|
+
const indexToRemove = conf.marketing.indexOf('youtube');
|
|
187
|
+
if (indexToRemove !== -1) {
|
|
188
|
+
conf.marketing.splice(indexToRemove, 1);
|
|
189
|
+
}
|
|
190
|
+
const showYoutube = !conf?.marketing?.includes('youtube');
|
|
191
|
+
this.setState({ showYoutube: showYoutube })
|
|
192
|
+
localStorage.setItem('cookieConfig', JSON.stringify(conf));
|
|
193
|
+
updateCookieList(handleSentryInit);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
|
|
150
197
|
const imagesCount = photos.length;
|
|
151
198
|
const currentSlide = activeSlide;
|
|
152
199
|
const prevSlide = (activeSlide - 1 % imagesCount + imagesCount) % imagesCount;
|
|
153
200
|
const nextSlide = (activeSlide + 1 % imagesCount + imagesCount) % imagesCount;
|
|
154
|
-
|
|
155
201
|
return photos.map((item: IImage, index: number) => {
|
|
156
202
|
const showImage = index === currentSlide || index === prevSlide || index === nextSlide || this.imagesCache[index] !== undefined;
|
|
157
203
|
const imageUrlSmall = _get(item, 'imageUrlSmall', null);
|
|
@@ -160,16 +206,15 @@ class VehicleDetailedSlider extends Component<IProps, IState> {
|
|
|
160
206
|
this.imagesCache[currentSlide] = imageUrlLarge;
|
|
161
207
|
this.imagesCache[prevSlide] = imageUrlLarge;
|
|
162
208
|
this.imagesCache[nextSlide] = imageUrlLarge;
|
|
163
|
-
|
|
164
209
|
return (
|
|
165
210
|
<div
|
|
166
211
|
className={styles.photo}
|
|
167
212
|
key={imageUrlLarge}
|
|
168
213
|
onMouseDown={handleMouseDown}
|
|
169
214
|
onMouseMove={handleMouseMove}
|
|
170
|
-
onMouseUp={handleMouseUp}
|
|
215
|
+
onMouseUp={this.state.showYoutube ? handleMouseUp : null}
|
|
171
216
|
>
|
|
172
|
-
{showImage && (
|
|
217
|
+
{showImage && !item.videoUrl && (
|
|
173
218
|
<MagnifyGlassImage
|
|
174
219
|
src={index !== 0 ? imageUrlLarge : null}
|
|
175
220
|
srcSmall={index === 0 ? imageUrlSmall : null}
|
|
@@ -177,54 +222,77 @@ class VehicleDetailedSlider extends Component<IProps, IState> {
|
|
|
177
222
|
{...imageProps}
|
|
178
223
|
/>
|
|
179
224
|
)}
|
|
225
|
+
{showImage && item.videoUrl && this.state.showYoutube && (
|
|
226
|
+
<iframe
|
|
227
|
+
width='100%'
|
|
228
|
+
height='441'
|
|
229
|
+
src={this.state.videoSrc}
|
|
230
|
+
title='YouTube Video'
|
|
231
|
+
className={styles.frame}
|
|
232
|
+
></iframe>
|
|
233
|
+
)}
|
|
234
|
+
{showImage && item.videoUrl && !this.state.showYoutube && this.state.videoSrc && (
|
|
235
|
+
<div className={styles.noYoutubeWrapper}>
|
|
236
|
+
<SvgYoutubeButton></SvgYoutubeButton>
|
|
237
|
+
<span className={styles.youtubeCookiesText}>{t('youtube.acceptCookiesText')}</span>
|
|
238
|
+
<div>
|
|
239
|
+
<Button variant='text' className={styles.btn} onClick={() => window.open('https://www.youtube.com/howyoutubeworks/our-commitments/protecting-user-data/', '_blank')}>
|
|
240
|
+
{t('youtube.dataProtection')}
|
|
241
|
+
</Button>
|
|
242
|
+
<Button color='primary' className={styles.btn} onClick={updateCookies}>{t('youtube.allow')}</Button>
|
|
243
|
+
</div>
|
|
244
|
+
</div>
|
|
245
|
+
)}
|
|
180
246
|
</div>
|
|
181
247
|
);
|
|
182
248
|
});
|
|
183
249
|
}
|
|
184
|
-
|
|
185
250
|
if (mainImageUrl) {
|
|
186
251
|
const imagesCount = Array.isArray(photos) && photos.length > 0 ? photos.length : 0;
|
|
187
252
|
const prevSlide = (activeSlide - 1 % imagesCount + imagesCount) % imagesCount;
|
|
188
253
|
const nextSlide = (activeSlide + 1 % imagesCount + imagesCount) % imagesCount;
|
|
189
254
|
return (
|
|
190
255
|
// preload cached photos from props
|
|
256
|
+
|
|
191
257
|
<div className={classnames(styles.photo, { [styles.blurred]: (mainImageBlur && mainImageUrl !== PLACEHOLDER_IMAGE_SMALL_URL) })} key={mainImageUrl}>
|
|
192
|
-
{(!largeLoaded || !smallLoaded || !largeLoaded1 || !largeLoaded01) && <Image src={mainImageUrl} {...imageProps} />
|
|
258
|
+
{(!largeLoaded || !smallLoaded || !largeLoaded1 || !largeLoaded01) && <Image src={mainImageUrl} {...imageProps} />}
|
|
193
259
|
|
|
194
|
-
{
|
|
195
|
-
style={
|
|
196
|
-
src={
|
|
197
|
-
onLoad={
|
|
260
|
+
{Array.isArray(photos) && photos.length > 0 && <Image
|
|
261
|
+
style={{ display: 'none' }}
|
|
262
|
+
src={photos[activeSlide]?.imageUrlSmall}
|
|
263
|
+
onLoad={() => this.setState({ smallLoaded: true })}
|
|
198
264
|
{...imageProps}
|
|
199
|
-
|
|
265
|
+
/>
|
|
200
266
|
}
|
|
201
|
-
{
|
|
202
|
-
style={
|
|
203
|
-
src={
|
|
204
|
-
onLoad={
|
|
267
|
+
{Array.isArray(photos) && photos.length > 0 && <Image
|
|
268
|
+
style={{ display: 'none' }}
|
|
269
|
+
src={photos[activeSlide]?.imageUrlLarge}
|
|
270
|
+
onLoad={() => this.setState({ largeLoaded: true })}
|
|
205
271
|
{...imageProps}
|
|
206
|
-
|
|
272
|
+
/>
|
|
207
273
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
274
|
+
|
|
275
|
+
{Array.isArray(photos) && photos.length > 0 && <Image
|
|
276
|
+
style={{ display: 'none' }}
|
|
277
|
+
src={photos[nextSlide]?.imageUrlLarge}
|
|
278
|
+
onLoad={() => this.setState({ largeLoaded1: true })}
|
|
212
279
|
{...imageProps}
|
|
213
|
-
|
|
280
|
+
/>
|
|
214
281
|
}
|
|
215
|
-
{
|
|
216
|
-
style={
|
|
217
|
-
src={
|
|
218
|
-
onLoad={
|
|
282
|
+
{Array.isArray(photos) && photos.length > 0 && <Image
|
|
283
|
+
style={{ display: 'none' }}
|
|
284
|
+
src={photos[prevSlide]?.imageUrlLarge}
|
|
285
|
+
onLoad={() => this.setState({ largeLoaded01: true })}
|
|
219
286
|
{...imageProps}
|
|
220
|
-
|
|
287
|
+
/>
|
|
221
288
|
}
|
|
222
289
|
</div>
|
|
223
290
|
);
|
|
291
|
+
|
|
224
292
|
}
|
|
225
293
|
|
|
226
294
|
return (
|
|
227
|
-
<div className={styles.noPhoto}/>
|
|
295
|
+
<div className={styles.noPhoto} />
|
|
228
296
|
);
|
|
229
297
|
};
|
|
230
298
|
|
|
@@ -249,7 +317,6 @@ class VehicleDetailedSlider extends Component<IProps, IState> {
|
|
|
249
317
|
onCarFavorite
|
|
250
318
|
} = this.props;
|
|
251
319
|
const { activeSlide } = this.state;
|
|
252
|
-
|
|
253
320
|
const sliderProps = {
|
|
254
321
|
autoPlay: false,
|
|
255
322
|
speed: 300,
|
|
@@ -258,6 +325,7 @@ class VehicleDetailedSlider extends Component<IProps, IState> {
|
|
|
258
325
|
arrows: Array.isArray(photos) && photos.length > 0,
|
|
259
326
|
slidesToShow: 1,
|
|
260
327
|
slidesToScroll: 1,
|
|
328
|
+
beforeChange: this.handleSlideChange,
|
|
261
329
|
afterChange: (index: number) => {
|
|
262
330
|
this.setState({
|
|
263
331
|
activeSlide: index
|
|
@@ -290,14 +358,16 @@ class VehicleDetailedSlider extends Component<IProps, IState> {
|
|
|
290
358
|
return (
|
|
291
359
|
<div className={styles.sliderWrap}>
|
|
292
360
|
{isMobileOnly &&
|
|
293
|
-
<Title {...{ t, make, model, subModel, powerKW, powerPS, onCarFavorite, isFavorite }}/>
|
|
361
|
+
<Title {...{ t, make, model, subModel, powerKW, powerPS, onCarFavorite, isFavorite }} />
|
|
294
362
|
}
|
|
295
363
|
<div className={styles.slider}>
|
|
296
|
-
<PriceData {...priceProps}/>
|
|
364
|
+
{!photos[activeSlide]?.videoUrl && <PriceData {...priceProps} />}
|
|
297
365
|
<Slider ref={slider => (this.slider = slider)} {...sliderProps}>
|
|
298
366
|
{this.getImages()}
|
|
299
367
|
</Slider>
|
|
300
|
-
{
|
|
368
|
+
{!photos[activeSlide]?.videoUrl ? (
|
|
369
|
+
isMobileOnly ? <MobileStats {...statsProps} /> : <Stats {...statsProps} />
|
|
370
|
+
) : null}
|
|
301
371
|
</div>
|
|
302
372
|
</div>
|
|
303
373
|
);
|
|
@@ -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 = () => {
|
|
@@ -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;
|
|
@@ -136,6 +136,7 @@ const VehiclePrice: React.FC<IVehiclePriceSectionProps> = (props: IVehiclePriceS
|
|
|
136
136
|
const buttonClassNames = classnames(
|
|
137
137
|
classButton,
|
|
138
138
|
styles.buttonDetails,
|
|
139
|
+
{ [styles.landingButton]: vehicleComponentName === 'landing' },
|
|
139
140
|
{ [styles.isAlternativeButton]: typeAlternative }
|
|
140
141
|
);
|
|
141
142
|
|
|
@@ -195,7 +196,8 @@ const VehiclePrice: React.FC<IVehiclePriceSectionProps> = (props: IVehiclePriceS
|
|
|
195
196
|
{
|
|
196
197
|
isTotal: true,
|
|
197
198
|
totalCurrent: margin ? margin : currentSalesPriceExtra,
|
|
198
|
-
title: t('vehicleProps:title.marge')
|
|
199
|
+
title: t('vehicleProps:title.marge'),
|
|
200
|
+
isMarge: true
|
|
199
201
|
}
|
|
200
202
|
] : [
|
|
201
203
|
...priceItemsGlobal,
|
|
@@ -254,6 +256,7 @@ const VehiclePrice: React.FC<IVehiclePriceSectionProps> = (props: IVehiclePriceS
|
|
|
254
256
|
routeObj={routeObj}
|
|
255
257
|
vehicleComponentName={vehicleComponentName}
|
|
256
258
|
combineRefAlternative={combineRefAlternative}
|
|
259
|
+
isMarge={props.isMarge}
|
|
257
260
|
/>
|
|
258
261
|
))}
|
|
259
262
|
{vehicleComponentName === 'favorite' && showCompareCheckboxes && (
|
|
@@ -273,7 +276,10 @@ const VehiclePrice: React.FC<IVehiclePriceSectionProps> = (props: IVehiclePriceS
|
|
|
273
276
|
</Button>
|
|
274
277
|
) : null}
|
|
275
278
|
{showOfferBtn ? (
|
|
276
|
-
|
|
279
|
+
vehicleComponentName === 'landing' ? (
|
|
280
|
+
<button className={buttonClassNames} onClick={onDetailsClick}>{t('vehicleProps:title.toOffer')}</button>
|
|
281
|
+
) :
|
|
282
|
+
<Button variant={offerBtnVariantCondition} className={buttonClassNames} onClick={onDetailsClick}>{t('vehicleProps:title.toOffer')}</Button>
|
|
277
283
|
) : ''}
|
|
278
284
|
</section>
|
|
279
285
|
);
|
|
@@ -28,6 +28,9 @@
|
|
|
28
28
|
display block
|
|
29
29
|
+media-tablet-landscape-up()
|
|
30
30
|
display flex
|
|
31
|
+
&.wrapTitlesAlternative
|
|
32
|
+
+media-tablet-landscape-up()
|
|
33
|
+
flex-wrap: wrap
|
|
31
34
|
&.wrapTitlesFavorite
|
|
32
35
|
display: flex;
|
|
33
36
|
+media-tablet-landscape-up()
|
|
@@ -57,7 +60,7 @@
|
|
|
57
60
|
|
|
58
61
|
+media-tablet-landscape-up()
|
|
59
62
|
margin: 0 0 -1px 3px
|
|
60
|
-
|
|
63
|
+
overflow: hidden
|
|
61
64
|
|
|
62
65
|
.optionTitle
|
|
63
66
|
display: flex
|
|
@@ -72,6 +75,7 @@
|
|
|
72
75
|
margin-top: 3px;
|
|
73
76
|
+media-tablet-landscape-up()
|
|
74
77
|
margin-left: 8px;
|
|
78
|
+
width: 100%
|
|
75
79
|
margin-top: 0;
|
|
76
80
|
&.optionTitleFavorite
|
|
77
81
|
font-size: 12px;
|
|
@@ -83,7 +87,12 @@
|
|
|
83
87
|
margin-left: 8px;
|
|
84
88
|
&.optionTitleIsAlternative
|
|
85
89
|
overflow: hidden;
|
|
86
|
-
|
|
90
|
+
.subModel
|
|
91
|
+
margin: 5px 0 0 0
|
|
92
|
+
+media-tablet-landscape-up()
|
|
93
|
+
max-width: 260px;
|
|
94
|
+
+media-tablet-landscape-up()
|
|
95
|
+
margin-left: 0
|
|
87
96
|
|
|
88
97
|
.sponsored
|
|
89
98
|
font-weight: 700
|
|
@@ -33,7 +33,8 @@ const VehicleTitle: React.FC<IVehicleTitleProps> = ({
|
|
|
33
33
|
styles.wrapTitles,
|
|
34
34
|
{ [styles.wrapTitlesFavorite]: vehicleComponentName === 'favorite' },
|
|
35
35
|
{ [styles.wrapTitlesRecently]: vehicleComponentName === 'recently' || vehicleComponentName === 'landing' || vehicleComponentName === 'main' },
|
|
36
|
-
{ [styles.wrapTitlesSearch]: vehicleComponentName === 'search' || vehicleComponentName === 'myVehicles' }
|
|
36
|
+
{ [styles.wrapTitlesSearch]: vehicleComponentName === 'search' || vehicleComponentName === 'myVehicles' },
|
|
37
|
+
{ [styles.wrapTitlesAlternative]: combineRefAlternative }
|
|
37
38
|
);
|
|
38
39
|
const optionTitleClassName = classnames(
|
|
39
40
|
styles.optionTitle,
|
|
@@ -34,7 +34,6 @@ interface IVehicleSmallCardProps {
|
|
|
34
34
|
language?: string;
|
|
35
35
|
vehicleComponentName?: 'comparable' | 'landing' | 'search' | 'main' | 'myVehicles' | 'favorite' | 'recently';
|
|
36
36
|
isTop?: boolean;
|
|
37
|
-
isDealer?: boolean;
|
|
38
37
|
isDealerSuperAdmin?: boolean;
|
|
39
38
|
isReferenceSearch?: boolean;
|
|
40
39
|
dashboardButtonText?: string;
|