@bytebrand/fe-ui-core 4.2.48 → 4.2.50
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/VehicleSmallCard/VehicleData/VehiclePrice/VehiclePrice.tsx +183 -205
- package/source/components/VehicleSmallCard/VehicleSmallCard.tsx +73 -70
- package/source/components/_common/VehicleSlider/VehicleSliderForSRL.tsx +56 -58
- package/source/components/_common/withStats/withStats.tsx +140 -146
- package/source/framework/types/types.ts +3 -1
- package/source/framework/vehiclesProps/decoratedProps.tsx +4 -4
package/package.json
CHANGED
|
@@ -49,10 +49,6 @@ export interface IVehiclePriceSectionProps {
|
|
|
49
49
|
typeAlternative?: string;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
export interface IPriceItemsProps {
|
|
53
|
-
priceItemsProp: IVehiclePriceSectionProps[];
|
|
54
|
-
}
|
|
55
|
-
|
|
56
52
|
interface IPriceData {
|
|
57
53
|
tooltipDescription?: string;
|
|
58
54
|
perMonthOld?: any;
|
|
@@ -71,235 +67,217 @@ interface IPriceData {
|
|
|
71
67
|
totalCurrent: number;
|
|
72
68
|
}
|
|
73
69
|
|
|
74
|
-
|
|
70
|
+
const VehiclePrice: React.FC<IVehiclePriceSectionProps> = (props: IVehiclePriceSectionProps) => {
|
|
75
71
|
|
|
76
|
-
onAddOfferClick = (event: any) => {
|
|
77
|
-
const { id, mainImageId, buy: { currentSalesPriceExtra } } =
|
|
72
|
+
const onAddOfferClick = (event: any) => {
|
|
73
|
+
const { id, mainImageId, buy: { currentSalesPriceExtra } } = props;
|
|
78
74
|
event.stopPropagation();
|
|
79
75
|
event.preventDefault();
|
|
80
|
-
|
|
76
|
+
props.onAddOfferToMainSlideClick(id, mainImageId, currentSalesPriceExtra, props);
|
|
81
77
|
};
|
|
82
78
|
|
|
83
|
-
onDetailsClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
|
84
|
-
const { id, onDetailsClick } =
|
|
79
|
+
const onDetailsClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
|
80
|
+
const { id, onDetailsClick } = props;
|
|
85
81
|
event.preventDefault();
|
|
86
82
|
event.stopPropagation();
|
|
87
83
|
onDetailsClick(id);
|
|
88
84
|
};
|
|
89
85
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
86
|
+
const {
|
|
87
|
+
t,
|
|
88
|
+
combineRefAlternative,
|
|
89
|
+
url,
|
|
90
|
+
target,
|
|
91
|
+
rel,
|
|
92
|
+
isDealerSuperAdmin,
|
|
93
|
+
linkTag,
|
|
94
|
+
showOfferBtn,
|
|
95
|
+
routeObj,
|
|
96
|
+
toggleCarToCompare,
|
|
97
|
+
toCompare,
|
|
98
|
+
priceSubMtl,
|
|
99
|
+
classButton,
|
|
100
|
+
onRemoveClick,
|
|
101
|
+
showCompareCheckboxes,
|
|
102
|
+
vatRate,
|
|
103
|
+
iconName,
|
|
104
|
+
vehicleComponentName,
|
|
105
|
+
financing: { monthlyInstallment, oldMonthlyInstallment },
|
|
106
|
+
leasing: {
|
|
107
|
+
monthlyInstallment: lMonthlyInstallment,
|
|
108
|
+
oldMonthlyInstallment: lOldMonthlyInstallment,
|
|
109
|
+
isActive: isLeasingActive
|
|
110
|
+
},
|
|
111
|
+
buy: {
|
|
112
|
+
currentSalesPriceExtra = 0,
|
|
113
|
+
highestPriceExtra = 0
|
|
114
|
+
} = {},
|
|
115
|
+
common: { isStrikeShown },
|
|
116
|
+
typeAlternative,
|
|
117
|
+
margin
|
|
118
|
+
} = props;
|
|
119
|
+
|
|
120
|
+
const vehiclePriceSectionClassName = classnames(
|
|
121
|
+
styles.vehiclePriceSection,
|
|
122
|
+
{ [styles.vehiclePriceSectionSearch]: vehicleComponentName === 'search' || vehicleComponentName === 'myVehicles' },
|
|
123
|
+
{ [styles.vehiclePriceSectionFavorite]: vehicleComponentName === 'favorite' },
|
|
124
|
+
{ [styles.vehiclePriceSectionRecently]: vehicleComponentName === 'recently' || vehicleComponentName === 'landing' },
|
|
125
|
+
{ [styles.vehiclePriceTitleMain]: vehicleComponentName === 'main' }
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
const vehiclePriceTitleClassName = classnames(
|
|
129
|
+
styles.vehiclePriceTitle,
|
|
130
|
+
{ [styles.vehiclePriceTitleFavorite]: vehicleComponentName === 'favorite' },
|
|
131
|
+
{ [styles.vehiclePriceTitleRecently]: vehicleComponentName === 'recently' },
|
|
132
|
+
{ [styles.vehiclePriceTitleLanding]: vehicleComponentName === 'landing' || vehicleComponentName === 'main' },
|
|
133
|
+
{ [styles.vehiclePriceTitleSearch]: vehicleComponentName === 'search' || vehicleComponentName === 'myVehicles' }
|
|
134
|
+
);
|
|
124
135
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
{ [styles.vehiclePriceTitleMain]: vehicleComponentName === 'main' }
|
|
131
|
-
);
|
|
136
|
+
const buttonClassNames = classnames(
|
|
137
|
+
classButton,
|
|
138
|
+
styles.buttonDetails,
|
|
139
|
+
{ [styles.isAlternativeButton]: typeAlternative }
|
|
140
|
+
);
|
|
132
141
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
{ [styles.vehiclePriceTitleRecently]: vehicleComponentName === 'recently' },
|
|
137
|
-
{ [styles.vehiclePriceTitleLanding]: vehicleComponentName === 'landing' || vehicleComponentName === 'main' },
|
|
138
|
-
{ [styles.vehiclePriceTitleSearch]: vehicleComponentName === 'search' || vehicleComponentName === 'myVehicles' }
|
|
139
|
-
);
|
|
142
|
+
const offerBtnVariantCondition = vehicleComponentName === 'recently' ||
|
|
143
|
+
vehicleComponentName === 'landing' ||
|
|
144
|
+
vehicleComponentName === 'main' ? 'outlined' : 'contained';
|
|
140
145
|
|
|
141
|
-
const priceItemsGlobal = [
|
|
142
|
-
{
|
|
143
|
-
perMonthOld: oldMonthlyInstallment,
|
|
144
|
-
perMonthCurrent: monthlyInstallment,
|
|
145
|
-
title: t('vehicleProps:title.financing'),
|
|
146
|
-
prefixOldPrice: vehicleComponentName === 'search' && !isMobileOnly && t('vehicleProps:value.prefixOldPrice'),
|
|
147
|
-
postfix: '3',
|
|
148
|
-
priceSub: priceSubMtl,
|
|
149
|
-
tooltipDescription: !combineRefAlternative && t('vehicleProps:title.financingDescription')
|
|
150
|
-
},
|
|
151
|
-
{
|
|
152
|
-
perMonthOld: lOldMonthlyInstallment,
|
|
153
|
-
perMonthCurrent: lMonthlyInstallment,
|
|
154
|
-
prefixOldPrice: vehicleComponentName === 'search' && !isMobileOnly && t('vehicleProps:value.prefixOldPrice'),
|
|
155
|
-
postfix: '1,3',
|
|
156
|
-
isPriceDisable: !isLeasingActive,
|
|
157
|
-
title: t('vehicleProps:title.leasing'),
|
|
158
|
-
priceSub: priceSubMtl,
|
|
159
|
-
tooltipDescription: !combineRefAlternative && t('vehicleProps:title.leasingDescription')
|
|
160
|
-
}
|
|
161
|
-
];
|
|
162
146
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
147
|
+
const priceItemsGlobal = [
|
|
148
|
+
{
|
|
149
|
+
perMonthOld: oldMonthlyInstallment,
|
|
150
|
+
perMonthCurrent: monthlyInstallment,
|
|
151
|
+
title: t('vehicleProps:title.financing'),
|
|
152
|
+
prefixOldPrice: vehicleComponentName === 'search' && !isMobileOnly && t('vehicleProps:value.prefixOldPrice'),
|
|
153
|
+
postfix: '3',
|
|
154
|
+
priceSub: priceSubMtl,
|
|
155
|
+
tooltipDescription: !combineRefAlternative && t('vehicleProps:title.financingDescription')
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
perMonthOld: lOldMonthlyInstallment,
|
|
159
|
+
perMonthCurrent: lMonthlyInstallment,
|
|
160
|
+
prefixOldPrice: vehicleComponentName === 'search' && !isMobileOnly && t('vehicleProps:value.prefixOldPrice'),
|
|
161
|
+
postfix: '1,3',
|
|
162
|
+
isPriceDisable: !isLeasingActive,
|
|
163
|
+
title: t('vehicleProps:title.leasing'),
|
|
164
|
+
priceSub: priceSubMtl,
|
|
165
|
+
tooltipDescription: !combineRefAlternative && t('vehicleProps:title.leasingDescription')
|
|
166
|
+
}
|
|
167
|
+
];
|
|
167
168
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
isNewPriceCategory: true,
|
|
173
|
-
showAboIcon: true,
|
|
174
|
-
isPriceDisable: true,
|
|
175
|
-
positionY: 'top',
|
|
176
|
-
title: t('vehicleProps:title.abo'),
|
|
177
|
-
tooltipDescription: t('vehicleProps:title.aboDescription')
|
|
178
|
-
}
|
|
179
|
-
] : '';
|
|
169
|
+
// const showAboCondition = vehicleComponentName !== 'favorite' &&
|
|
170
|
+
// vehicleComponentName !== 'recently' &&
|
|
171
|
+
// vehicleComponentName !== 'search';
|
|
172
|
+
const showAboCondition = false;
|
|
180
173
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
title: t('vehicleProps:title.marge')
|
|
194
|
-
}
|
|
195
|
-
] : [
|
|
196
|
-
...priceItemsGlobal,
|
|
197
|
-
...Abo,
|
|
198
|
-
{
|
|
199
|
-
isTotal: true,
|
|
200
|
-
totalCurrent: currentSalesPriceExtra,
|
|
201
|
-
positionY: 'top',
|
|
202
|
-
postfix: !!vatRate ? '1' : '',
|
|
203
|
-
title: t('vehicleProps:title.buy'),
|
|
204
|
-
tooltipDescription: t('vehicleProps:title.buyDescription')
|
|
205
|
-
}
|
|
206
|
-
];
|
|
174
|
+
const Abo = showAboCondition ? [
|
|
175
|
+
{
|
|
176
|
+
perMonthOld: oldMonthlyInstallment,
|
|
177
|
+
perMonthCurrent: monthlyInstallment,
|
|
178
|
+
isNewPriceCategory: true,
|
|
179
|
+
showAboIcon: true,
|
|
180
|
+
isPriceDisable: true,
|
|
181
|
+
positionY: 'top',
|
|
182
|
+
title: t('vehicleProps:title.abo'),
|
|
183
|
+
tooltipDescription: t('vehicleProps:title.aboDescription')
|
|
184
|
+
}
|
|
185
|
+
] : '';
|
|
207
186
|
|
|
208
|
-
|
|
187
|
+
const priceData = combineRefAlternative ? [
|
|
188
|
+
...priceItemsGlobal,
|
|
189
|
+
{
|
|
190
|
+
isTotal: true,
|
|
191
|
+
totalCurrent: currentSalesPriceExtra,
|
|
192
|
+
postfix: !!vatRate ? '1' : '',
|
|
193
|
+
title: t('vehicleProps:title.buy'),
|
|
194
|
+
isAlternativeText: t('vehicleProps:title.margeInkl')
|
|
195
|
+
},
|
|
209
196
|
{
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
}
|
|
225
|
-
|
|
197
|
+
isTotal: true,
|
|
198
|
+
totalCurrent: margin ? margin : currentSalesPriceExtra,
|
|
199
|
+
title: t('vehicleProps:title.marge')
|
|
200
|
+
}
|
|
201
|
+
] : [
|
|
202
|
+
...priceItemsGlobal,
|
|
203
|
+
...Abo,
|
|
204
|
+
{
|
|
205
|
+
isTotal: true,
|
|
206
|
+
totalCurrent: currentSalesPriceExtra,
|
|
207
|
+
|
|
208
|
+
postfix: !!vatRate ? '1' : '',
|
|
209
|
+
title: t('vehicleProps:title.buy'),
|
|
210
|
+
tooltipDescription: t('vehicleProps:title.buyDescription')
|
|
211
|
+
}
|
|
212
|
+
];
|
|
213
|
+
|
|
214
|
+
return (
|
|
215
|
+
<section className={vehiclePriceSectionClassName}>
|
|
216
|
+
{vehicleComponentName === 'favorite' && showCompareCheckboxes && (
|
|
217
|
+
<CheckboxMaterial
|
|
218
|
+
checked={toCompare}
|
|
219
|
+
onChange={toggleCarToCompare}
|
|
220
|
+
labelPlacement='start'
|
|
221
|
+
label={t('FavoritesPage:toCompare')}
|
|
222
|
+
formControlClassName={styles.wrapCheckbox}
|
|
223
|
+
/>
|
|
224
|
+
)}
|
|
225
|
+
{vehicleComponentName !== 'favorite' && vehicleComponentName !== 'search' && !isMobileOnly && (
|
|
226
|
+
<span className={vehiclePriceTitleClassName}>{t('vehicleProps:title.monthlyFrom')}</span>
|
|
227
|
+
)}
|
|
228
|
+
{isMobileOnly && !showCompareCheckboxes && (
|
|
229
|
+
<span className={vehiclePriceTitleClassName}>{t('vehicleProps:title.monthlyFrom')}</span>
|
|
230
|
+
)}
|
|
231
|
+
{priceData.map((props: any) => (
|
|
226
232
|
<VehiclePriceItem
|
|
227
|
-
tooltipDescription={tooltipDescription}
|
|
228
|
-
key={title}
|
|
229
|
-
priceTitle={title}
|
|
230
|
-
isPriceDisable={isPriceDisable}
|
|
231
|
-
perMonthOld={perMonthOld}
|
|
232
|
-
perMonthCurrent={perMonthCurrent}
|
|
233
|
-
isNewPriceCategory={isNewPriceCategory}
|
|
234
|
-
isAlternativeText={isAlternativeText}
|
|
235
|
-
showAboIcon={showAboIcon}
|
|
233
|
+
tooltipDescription={props.tooltipDescription}
|
|
234
|
+
key={props.title}
|
|
235
|
+
priceTitle={props.title}
|
|
236
|
+
isPriceDisable={props.isPriceDisable}
|
|
237
|
+
perMonthOld={props.perMonthOld}
|
|
238
|
+
perMonthCurrent={props.perMonthCurrent}
|
|
239
|
+
isNewPriceCategory={props.isNewPriceCategory}
|
|
240
|
+
isAlternativeText={props.isAlternativeText}
|
|
241
|
+
showAboIcon={props.showAboIcon}
|
|
236
242
|
totalOld={highestPriceExtra}
|
|
237
|
-
isTotal={isTotal}
|
|
238
|
-
priceSub={priceSub}
|
|
239
|
-
positionY={positionY}
|
|
243
|
+
isTotal={props.isTotal}
|
|
244
|
+
priceSub={props.priceSub}
|
|
245
|
+
positionY={props.positionY}
|
|
240
246
|
url={url}
|
|
241
247
|
target={target}
|
|
242
248
|
rel={rel}
|
|
243
249
|
isStrikeShown={isStrikeShown}
|
|
244
250
|
iconName={iconName}
|
|
245
|
-
prefixOldPrice={prefixOldPrice}
|
|
246
|
-
totalCurrent={totalCurrent}
|
|
247
|
-
postfix={postfix}
|
|
251
|
+
prefixOldPrice={props.prefixOldPrice}
|
|
252
|
+
totalCurrent={props.totalCurrent}
|
|
253
|
+
postfix={props.postfix}
|
|
248
254
|
linkTag={linkTag}
|
|
249
255
|
routeObj={routeObj}
|
|
250
256
|
vehicleComponentName={vehicleComponentName}
|
|
251
257
|
combineRefAlternative={combineRefAlternative}
|
|
252
258
|
/>
|
|
253
|
-
)
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
{ [styles.isAlternativeButton]: typeAlternative }
|
|
259
|
-
);
|
|
260
|
-
|
|
261
|
-
const offerBtnVariantCondition = vehicleComponentName === 'recently' ||
|
|
262
|
-
vehicleComponentName === 'landing' ||
|
|
263
|
-
vehicleComponentName === 'main' ? 'outlined' : 'contained';
|
|
264
|
-
return (
|
|
265
|
-
<section className={vehiclePriceSectionClassName}>
|
|
266
|
-
{vehicleComponentName === 'favorite' && showCompareCheckboxes && (
|
|
267
|
-
<CheckboxMaterial
|
|
268
|
-
checked={toCompare}
|
|
269
|
-
onChange={toggleCarToCompare}
|
|
270
|
-
labelPlacement='start'
|
|
271
|
-
label={t('FavoritesPage:toCompare')}
|
|
272
|
-
formControlClassName={styles.wrapCheckbox}
|
|
273
|
-
/>
|
|
274
|
-
)}
|
|
275
|
-
{vehicleComponentName !== 'favorite' && vehicleComponentName !== 'search' && !isMobileOnly && (
|
|
276
|
-
<span className={vehiclePriceTitleClassName}>{t('vehicleProps:title.monthlyFrom')}</span>
|
|
277
|
-
)}
|
|
278
|
-
{isMobileOnly && !showCompareCheckboxes && (
|
|
279
|
-
<span className={vehiclePriceTitleClassName}>{t('vehicleProps:title.monthlyFrom')}</span>
|
|
280
|
-
)}
|
|
281
|
-
{ListPrices}
|
|
282
|
-
{vehicleComponentName === 'favorite' && showCompareCheckboxes && (
|
|
283
|
-
<div className={styles.wrapHandleCompare}>
|
|
284
|
-
<Button variant='outlined' onClick={onRemoveClick} className={styles.btnCompareRemove} color='error'>
|
|
285
|
-
<IconSVG className={styles.removeIcon} name='trashRed' customDimensions />
|
|
286
|
-
</Button>
|
|
287
|
-
<Button className={styles.btnCarToCompare} variant='outlined' onClick={toggleCarToCompare}>
|
|
288
|
-
<span className={styles.btnPlusIcon}>{!toCompare ? '+' : '-'}</span>
|
|
289
|
-
{t('FavoritesPage:compare')}
|
|
290
|
-
</Button>
|
|
291
|
-
</div>
|
|
292
|
-
)}
|
|
293
|
-
{isDealerSuperAdmin && !typeAlternative ? (
|
|
294
|
-
<Button className={styles.addOfferButton} onClick={this.onAddOfferClick}>
|
|
295
|
-
{t('vehicleProps:title.addOfferToMainSlide')}
|
|
259
|
+
))}
|
|
260
|
+
{vehicleComponentName === 'favorite' && showCompareCheckboxes && (
|
|
261
|
+
<div className={styles.wrapHandleCompare}>
|
|
262
|
+
<Button variant='outlined' onClick={onRemoveClick} className={styles.btnCompareRemove} color='error'>
|
|
263
|
+
<IconSVG className={styles.removeIcon} name='trashRed' customDimensions />
|
|
296
264
|
</Button>
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
}
|
|
305
|
-
|
|
265
|
+
<Button className={styles.btnCarToCompare} variant='outlined' onClick={toggleCarToCompare}>
|
|
266
|
+
<span className={styles.btnPlusIcon}>{!toCompare ? '+' : '-'}</span>
|
|
267
|
+
{t('FavoritesPage:compare')}
|
|
268
|
+
</Button>
|
|
269
|
+
</div>
|
|
270
|
+
)}
|
|
271
|
+
{isDealerSuperAdmin && !typeAlternative ? (
|
|
272
|
+
<Button className={styles.addOfferButton} onClick={onAddOfferClick}>
|
|
273
|
+
{t('vehicleProps:title.addOfferToMainSlide')}
|
|
274
|
+
</Button>
|
|
275
|
+
) : null}
|
|
276
|
+
{showOfferBtn ? (
|
|
277
|
+
<Button variant={offerBtnVariantCondition} className={buttonClassNames} onClick={onDetailsClick}>{t('vehicleProps:title.toOffer')}</Button>
|
|
278
|
+
) : ''}
|
|
279
|
+
</section>
|
|
280
|
+
);
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
export default VehiclePrice;
|
|
@@ -55,6 +55,8 @@ interface IVehicleSmallCardProps {
|
|
|
55
55
|
seoText?: string;
|
|
56
56
|
classButton?: string;
|
|
57
57
|
mainImageId?: string;
|
|
58
|
+
target?: string;
|
|
59
|
+
rel?: string;
|
|
58
60
|
crawledAt?: string;
|
|
59
61
|
modificationDate?: string;
|
|
60
62
|
baseUrl?: string;
|
|
@@ -62,7 +64,6 @@ interface IVehicleSmallCardProps {
|
|
|
62
64
|
priceSubMtl?: string | null;
|
|
63
65
|
ownerName?: string;
|
|
64
66
|
className?: string;
|
|
65
|
-
percentage?: number;
|
|
66
67
|
id?: string;
|
|
67
68
|
linkTag?: string;
|
|
68
69
|
src?: string;
|
|
@@ -136,7 +137,6 @@ const VehicleSmallCard: FunctionComponent<IVehicleSmallCardProps> = (props) => {
|
|
|
136
137
|
children,
|
|
137
138
|
iconName,
|
|
138
139
|
showSlider,
|
|
139
|
-
percentage,
|
|
140
140
|
classButton,
|
|
141
141
|
hasInteriorExteriorPhoto,
|
|
142
142
|
dashboardButtonText,
|
|
@@ -180,12 +180,12 @@ const VehicleSmallCard: FunctionComponent<IVehicleSmallCardProps> = (props) => {
|
|
|
180
180
|
...slider,
|
|
181
181
|
price,
|
|
182
182
|
showNewLabel,
|
|
183
|
-
percentage,
|
|
184
183
|
CircularProgressbar,
|
|
185
184
|
isReferenceSearch,
|
|
186
185
|
isAlternative,
|
|
187
186
|
typeAlternative
|
|
188
187
|
};
|
|
188
|
+
|
|
189
189
|
const favoriteProps = {
|
|
190
190
|
...title,
|
|
191
191
|
id,
|
|
@@ -276,77 +276,79 @@ const VehicleSmallCard: FunctionComponent<IVehicleSmallCardProps> = (props) => {
|
|
|
276
276
|
vehicleComponentName === 'recently';
|
|
277
277
|
return (
|
|
278
278
|
<section className={wrapperClassName} onClick={onContainerClick} id={id}>
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
279
|
+
<>
|
|
280
|
+
{createElement(linkTag, {
|
|
281
|
+
children: <VehicleTitle {...favoriteProps} />,
|
|
282
|
+
...routeObj,
|
|
283
|
+
target,
|
|
284
|
+
rel,
|
|
285
|
+
className: `${styles.redirectClassLink} ${styles.gridAreaTitle}`,
|
|
286
|
+
onClick: () => localStorage.setItem('activeTabCDP', t('vehicleProps:title.financing')),
|
|
287
|
+
href: url
|
|
288
|
+
})}
|
|
288
289
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
290
|
+
{createElement(linkTag, {
|
|
291
|
+
children: (
|
|
292
|
+
<>
|
|
293
|
+
{showSlider ? (
|
|
294
|
+
<>
|
|
295
|
+
{showComponentLikeSlider ? (
|
|
296
|
+
<>
|
|
297
|
+
<DecoratedSliderForSRL {...decoratedSliderProps} />
|
|
298
|
+
{renderIDInfo && isDealer ? renderIDInfo() : null}
|
|
299
|
+
{combineRefAlternative && (
|
|
300
|
+
<div className={styles.wrapAlternativeData}>
|
|
301
|
+
<div>
|
|
302
|
+
{offerSource || ownerName ? (
|
|
303
|
+
<>
|
|
304
|
+
<IconSVG className={styles.svgIcon} name='linkAlternative' />
|
|
305
|
+
<span onClick={(e: MouseEvent<HTMLImageElement>) => linkBaseUrl(e)}>
|
|
306
|
+
{!typeAlternative ? ownerName : t(`cbd:${offerSource}`)}
|
|
307
|
+
</span>
|
|
308
|
+
</>
|
|
309
|
+
) : ''}
|
|
310
|
+
</div>
|
|
311
|
+
{crawledAt || modificationDate ? (
|
|
312
|
+
<div>
|
|
313
|
+
<IconSVG className={styles.svgIcon} name='lastCrawledAt' />
|
|
314
|
+
<span>
|
|
315
|
+
{!typeAlternative ? modificationDate : crawledAt}
|
|
306
316
|
</span>
|
|
307
|
-
|
|
317
|
+
</div>
|
|
308
318
|
) : ''}
|
|
309
319
|
</div>
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
<VehiclePrice {...vehiclePriceProps} />
|
|
343
|
-
{seoText ? (
|
|
344
|
-
<a className={`${styles.redirectClassLink} ${styles.gridAreaSeoText}`} href={url}>
|
|
345
|
-
<SeoText seoText={seoText} />
|
|
346
|
-
</a>
|
|
347
|
-
) : null
|
|
348
|
-
}
|
|
349
|
-
{children}
|
|
320
|
+
)}
|
|
321
|
+
</>
|
|
322
|
+
) : (
|
|
323
|
+
<figure className={styles.figure}>
|
|
324
|
+
<DecoratedSlider {...decoratedSliderProps} />
|
|
325
|
+
</figure>
|
|
326
|
+
)}
|
|
327
|
+
</>
|
|
328
|
+
) : (
|
|
329
|
+
<LazyLoad {...lazyLoadProps}>
|
|
330
|
+
<ImageWithStats {...imageProps} {...statsProps} />
|
|
331
|
+
</LazyLoad>
|
|
332
|
+
)}
|
|
333
|
+
</>
|
|
334
|
+
),
|
|
335
|
+
...routeObj,
|
|
336
|
+
target,
|
|
337
|
+
rel,
|
|
338
|
+
className: `${styles.redirectClassLink} ${styles.gridAreaImage}`,
|
|
339
|
+
onClick: () => localStorage.setItem('activeTabCDP', t('vehicleProps:title.financing')),
|
|
340
|
+
href: url
|
|
341
|
+
})}
|
|
342
|
+
<VehicleInfo {...vehicleInfoProps} />
|
|
343
|
+
<VehiclePrice {...vehiclePriceProps} />
|
|
344
|
+
{seoText ? (
|
|
345
|
+
<a className={`${styles.redirectClassLink} ${styles.gridAreaSeoText}`} href={url}>
|
|
346
|
+
<SeoText seoText={seoText} />
|
|
347
|
+
</a>
|
|
348
|
+
) : null
|
|
349
|
+
}
|
|
350
|
+
{children}
|
|
351
|
+
</>
|
|
350
352
|
</section>
|
|
351
353
|
);
|
|
352
354
|
};
|
|
@@ -364,6 +366,7 @@ VehicleSmallCard.defaultProps = {
|
|
|
364
366
|
info: {},
|
|
365
367
|
crawledAt: 'N/A',
|
|
366
368
|
baseUrl: '',
|
|
369
|
+
typeAlternative: '',
|
|
367
370
|
offerSource: '',
|
|
368
371
|
src: 'https://images.auto.de/noimage/small',
|
|
369
372
|
environmentEmissions: null,
|
|
@@ -11,61 +11,53 @@ import { preloadNearbyImages } from '../../../framework/utils/CommonUtils';
|
|
|
11
11
|
import { IVehicleSliderForSRLProps } from '../../../framework/types/types';
|
|
12
12
|
import styles from './VehicleSlider.styl';
|
|
13
13
|
|
|
14
|
-
interface IVehicleSliderForSRLState {
|
|
15
|
-
noImagesLoaded: boolean;
|
|
16
|
-
activeSlide: number;
|
|
17
|
-
}
|
|
18
14
|
|
|
19
|
-
const SlickButtonFix: React.
|
|
15
|
+
const SlickButtonFix: React.FC = ({ currentSlide, slideCount, children, ...props }: any) => (
|
|
20
16
|
<div {...props} tabIndex={-1}>{children}</div>
|
|
21
17
|
);
|
|
22
18
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
19
|
+
const VehicleSliderForSRL: React.FC<IVehicleSliderForSRLProps> = ({
|
|
20
|
+
id,
|
|
21
|
+
src,
|
|
22
|
+
className,
|
|
23
|
+
images,
|
|
24
|
+
imagesCount,
|
|
25
|
+
imageSize,
|
|
26
|
+
mainImageId,
|
|
27
|
+
getCarImagesData,
|
|
28
|
+
type,
|
|
29
|
+
isAlternative,
|
|
30
|
+
typeAlternative,
|
|
31
|
+
isReferenceSearch,
|
|
32
|
+
CircularProgressbar,
|
|
33
|
+
onSlideChange
|
|
34
|
+
}: IVehicleSliderForSRLProps) => {
|
|
35
|
+
const [ noImagesLoaded, setNoImagesLoaded ] = React.useState<boolean>(false);
|
|
36
|
+
const [ activeSlide, setActiveSlide ] = React.useState<number>(0);
|
|
37
|
+
|
|
38
|
+
const beforeChange = () => {
|
|
42
39
|
|
|
43
40
|
const isMyVehicle: boolean = type === 'myVehicle';
|
|
44
41
|
|
|
45
42
|
if (_isLength(images)) return false;
|
|
46
|
-
getCarImagesData(
|
|
43
|
+
getCarImagesData(id, true, isMyVehicle, type, typeAlternative).then((data) => {
|
|
47
44
|
// a case when all images are in_postprocessing
|
|
48
45
|
|
|
49
46
|
if (!data || data.length === 0) {
|
|
50
|
-
|
|
47
|
+
setNoImagesLoaded(true);
|
|
51
48
|
}
|
|
52
49
|
|
|
53
50
|
preloadNearbyImages(data, activeSlide, 'imageUrlSmall');
|
|
54
51
|
});
|
|
55
52
|
};
|
|
56
53
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
this.setState({ activeSlide: index });
|
|
61
|
-
|
|
62
|
-
this.props.onSlideChange(index);
|
|
54
|
+
const onHandleSlideChange = (index: number): void => {
|
|
55
|
+
setActiveSlide(index);
|
|
56
|
+
onSlideChange(index);
|
|
63
57
|
preloadNearbyImages(images, index, 'imageUrlSmall');
|
|
64
58
|
};
|
|
65
59
|
|
|
66
|
-
renderSliderImages = () => {
|
|
67
|
-
const { carId, mainImageId, images, imagesCount, imageSize, src, isAlternative } = this.props;
|
|
68
|
-
const { activeSlide } = this.state;
|
|
60
|
+
const renderSliderImages = () => {
|
|
69
61
|
|
|
70
62
|
const imageProps = {
|
|
71
63
|
isAlternative,
|
|
@@ -106,11 +98,11 @@ class VehicleSliderForSRL extends React.Component<IVehicleSliderForSRLProps, IVe
|
|
|
106
98
|
|
|
107
99
|
if (mainImageId && !!imagesCount) {
|
|
108
100
|
const mainImage = (
|
|
109
|
-
<LazyLoad {...lazyLoadProps} key={
|
|
101
|
+
<LazyLoad {...lazyLoadProps} key={id}>
|
|
110
102
|
<Image src={src} {...imageProps} />
|
|
111
103
|
</LazyLoad>
|
|
112
104
|
);
|
|
113
|
-
const spinner = !
|
|
105
|
+
const spinner = !noImagesLoaded ? (
|
|
114
106
|
<div className={styles.spinnerWrap} key='spinnerWrap'>
|
|
115
107
|
<Loader className={styles.spinner} size='medium' key='small_slider_loader' />
|
|
116
108
|
</div>
|
|
@@ -121,18 +113,18 @@ class VehicleSliderForSRL extends React.Component<IVehicleSliderForSRLProps, IVe
|
|
|
121
113
|
|
|
122
114
|
return (
|
|
123
115
|
<LazyLoad {...lazyLoadProps}>
|
|
124
|
-
<Image src={`${PLACEHOLDER_IMAGE}${imageSize}`} key={
|
|
116
|
+
<Image src={`${PLACEHOLDER_IMAGE}${imageSize}`} key={id} {...imageProps} />
|
|
125
117
|
</LazyLoad>
|
|
126
118
|
);
|
|
127
119
|
};
|
|
128
120
|
|
|
129
|
-
renderSlider = () => {
|
|
121
|
+
const renderSlider = () => {
|
|
130
122
|
const settings = {
|
|
123
|
+
beforeChange,
|
|
131
124
|
autoPlay: false,
|
|
132
125
|
speed: 300,
|
|
133
126
|
infinite: true,
|
|
134
127
|
dots: false,
|
|
135
|
-
beforeChange: this.beforeChange,
|
|
136
128
|
className: styles.slider,
|
|
137
129
|
accessibility: false,
|
|
138
130
|
draggable: true,
|
|
@@ -140,31 +132,37 @@ class VehicleSliderForSRL extends React.Component<IVehicleSliderForSRLProps, IVe
|
|
|
140
132
|
prevArrow: <SlickButtonFix />,
|
|
141
133
|
swipeToSlide: true,
|
|
142
134
|
focusOnSelect: true,
|
|
143
|
-
afterChange:
|
|
144
|
-
key: `${
|
|
135
|
+
afterChange: onHandleSlideChange,
|
|
136
|
+
key: `${noImagesLoaded}`
|
|
145
137
|
};
|
|
146
138
|
|
|
147
139
|
return (
|
|
148
|
-
<div className={styles.wrapper} onMouseEnter={
|
|
149
|
-
<Slider {...settings}>{
|
|
140
|
+
<div className={styles.wrapper} onMouseEnter={beforeChange}>
|
|
141
|
+
<Slider {...settings}>{renderSliderImages()}</Slider>
|
|
150
142
|
</div>
|
|
151
143
|
);
|
|
152
144
|
};
|
|
153
145
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
146
|
+
const containerClassName = classnames(styles.imageContainer, className, {
|
|
147
|
+
[styles[type]]: !!type
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
return (
|
|
151
|
+
<div className={containerClassName}>
|
|
152
|
+
{isReferenceSearch && <CircularProgressbar />}
|
|
153
|
+
{images ? renderSlider() : false}
|
|
154
|
+
</div>
|
|
155
|
+
);
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
VehicleSliderForSRL.defaultProps = {
|
|
159
|
+
mainImageId: '',
|
|
160
|
+
imagesCount: 0,
|
|
161
|
+
imageSize: 'small',
|
|
162
|
+
isAlternative: false,
|
|
163
|
+
typeAlternative: '',
|
|
164
|
+
images: [],
|
|
165
|
+
getCarImagesData: () => null
|
|
168
166
|
}
|
|
169
167
|
|
|
170
168
|
export default VehicleSliderForSRL;
|
|
@@ -32,154 +32,148 @@ export interface IStatsWrapperProps {
|
|
|
32
32
|
imagesCount?: number;
|
|
33
33
|
showNewLabel?: boolean;
|
|
34
34
|
onFavoriteClick?: (event: any) => void;
|
|
35
|
-
|
|
35
|
+
getCarImagesData?: (carId: string, force?: boolean, includeAll?: boolean, type?: any, typeAlternative?: string) => Promise<any>;
|
|
36
36
|
[key: string]: any;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
if (typeof this.props.onSlideChange === 'function') {
|
|
66
|
-
this.props.onSlideChange(activeSlide);
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
renderImagesData = (): JSX.Element => {
|
|
71
|
-
const { imagesCount, statsSize } = this.props;
|
|
72
|
-
if (!Number.isFinite(imagesCount)) return null;
|
|
73
|
-
|
|
74
|
-
const { activeSlide } = this.state;
|
|
75
|
-
const delimiters = { xs: '|', sm: '|', md: 'von' };
|
|
76
|
-
|
|
77
|
-
return (
|
|
78
|
-
<div className={styles.section}>
|
|
79
|
-
{statsSize === 'md' ? <IconSVG name='common_camera' customDimensions className={styles.cameraIcon} /> : null}
|
|
80
|
-
{!!imagesCount && <span>{`${activeSlide + 1} ${delimiters[statsSize]} ${imagesCount}`}</span>}
|
|
81
|
-
</div>
|
|
82
|
-
);
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
renderRotateSvg = (): JSX.Element => {
|
|
86
|
-
const { hasInteriorExteriorPhoto, images } = this.props;
|
|
87
|
-
const hasExteriorPhotos = hasInteriorExteriorPhoto && Array.isArray(images) && images.length > 0;
|
|
88
|
-
if (!hasExteriorPhotos) return null;
|
|
89
|
-
return (
|
|
90
|
-
<div className={styles.section}>
|
|
91
|
-
{hasExteriorPhotos ? (
|
|
92
|
-
<IconSVG name='rotate360New' customDimensions className={styles.statsEyeIcon} />
|
|
93
|
-
) : null}
|
|
94
|
-
</div>
|
|
95
|
-
);
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
renderStarButton = () => {
|
|
99
|
-
const { isFavoured, onFavoriteClick } = this.props;
|
|
100
|
-
if (!onFavoriteClick) return null;
|
|
101
|
-
|
|
102
|
-
return (
|
|
103
|
-
<IconSVG
|
|
104
|
-
name='common_StarRoundedCorners'
|
|
105
|
-
customDimensions
|
|
106
|
-
className={classnames(styles.starButton, { [styles.starButtonFavored]: isFavoured })}
|
|
107
|
-
onClick={onFavoriteClick}
|
|
108
|
-
/>
|
|
109
|
-
);
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
renderStatsData = (): JSX.Element => {
|
|
113
|
-
const { statsData, isFavoured, onFavoriteClick } = this.props;
|
|
114
|
-
if (!statsData) return null;
|
|
115
|
-
const { totalCarImpCount, totalFavCount } = statsData;
|
|
116
|
-
const favoritesClassName = classnames(
|
|
117
|
-
styles.statsFavoritesCount,
|
|
118
|
-
{
|
|
119
|
-
[styles.accented]: isFavoured,
|
|
120
|
-
[styles.clickable]: typeof onFavoriteClick === 'function'
|
|
121
|
-
});
|
|
122
|
-
const favoritesIconClassName = classnames(styles.statsStarIcon, { [styles.accented]: isFavoured });
|
|
123
|
-
|
|
124
|
-
return (
|
|
125
|
-
<div className={styles.section}>
|
|
126
|
-
{!!totalCarImpCount ? <div className={styles.statsViewsCount}>
|
|
127
|
-
<IconSVG name='common_SliderEye' customDimensions className={styles.statsEyeIcon} />
|
|
128
|
-
<span>
|
|
129
|
-
{totalCarImpCount}
|
|
130
|
-
</span>
|
|
131
|
-
</div> : null}
|
|
132
|
-
{!!totalFavCount ? <div className={favoritesClassName} onClick={onFavoriteClick}>
|
|
133
|
-
<IconSVG name='star' customDimensions className={favoritesIconClassName} />
|
|
134
|
-
<span>
|
|
135
|
-
{totalFavCount}
|
|
136
|
-
</span>
|
|
137
|
-
</div> : null}
|
|
138
|
-
</div>
|
|
139
|
-
);
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
renderPriceData = () => {
|
|
143
|
-
const { price: { historyPriceDifference, historyPriceDifferencePerCent }, showNewLabel, classWrapPrice, t } = this.props;
|
|
144
|
-
|
|
145
|
-
const newText = !!t ? t('vehicleProps:promoSlider.new') : 'neu';
|
|
146
|
-
const EUR = `\u20AC`;
|
|
147
|
-
|
|
148
|
-
return (
|
|
149
|
-
<div className={classnames(styles.topWrapper, classWrapPrice)}>
|
|
150
|
-
{showNewLabel && <Badge type='blue' className={styles.new}>{newText}</Badge>}
|
|
151
|
-
{!!historyPriceDifference && historyPriceDifference >= MIN_PRICE_DIFFERENCE && (
|
|
152
|
-
<Badge type='green'>
|
|
153
|
-
{`-`}
|
|
154
|
-
<FormattedNumber value={historyPriceDifference} numbersAfterDot={0} />
|
|
155
|
-
{` ${EUR}`}
|
|
156
|
-
</Badge>
|
|
157
|
-
)}
|
|
158
|
-
{!!historyPriceDifferencePerCent && historyPriceDifferencePerCent >= MIN_PERCENT && (
|
|
159
|
-
<Badge type='red' className={styles.priceDifferencePerCent}>-{historyPriceDifferencePerCent}%</Badge>
|
|
160
|
-
)}
|
|
161
|
-
</div>
|
|
162
|
-
);
|
|
163
|
-
};
|
|
164
|
-
|
|
165
|
-
render() {
|
|
166
|
-
const {
|
|
167
|
-
statsSize, isFavoured, onFavoriteClick, statsData, isReferenceSearch,
|
|
168
|
-
...wrappedComponentProps
|
|
169
|
-
} = this.props;
|
|
170
|
-
|
|
171
|
-
return (
|
|
172
|
-
<div className={styles.wrapper}>
|
|
173
|
-
{!isReferenceSearch && this.renderPriceData()}
|
|
174
|
-
<WrappedComponent {...wrappedComponentProps} onSlideChange={this.onSlideChange} isReferenceSearch={isReferenceSearch} />
|
|
175
|
-
<div className={classnames(styles.controls, styles[statsSize])}>
|
|
176
|
-
{this.renderImagesData()}
|
|
177
|
-
{this.renderRotateSvg()}
|
|
178
|
-
{this.renderStarButton()}
|
|
179
|
-
{this.renderStatsData()}
|
|
180
|
-
</div>
|
|
181
|
-
</div>
|
|
182
|
-
);
|
|
39
|
+
const withStats = (WrappedComponent: any) => ({
|
|
40
|
+
t,
|
|
41
|
+
images,
|
|
42
|
+
hasInteriorExteriorPhoto,
|
|
43
|
+
imagesCount,
|
|
44
|
+
statsData,
|
|
45
|
+
isFavoured,
|
|
46
|
+
onFavoriteClick,
|
|
47
|
+
isReferenceSearch,
|
|
48
|
+
onSlideChange,
|
|
49
|
+
classWrapPrice = '',
|
|
50
|
+
showNewLabel = false,
|
|
51
|
+
statsSize = 'xs',
|
|
52
|
+
price: { historyPriceDifference = 0, historyPriceDifferencePerCent = 0 },
|
|
53
|
+
...props
|
|
54
|
+
}: IStatsWrapperProps) => {
|
|
55
|
+
const [ activeSlide, setActiveSlide ] = React.useState<number>(0);
|
|
56
|
+
|
|
57
|
+
const MIN_PERCENT = 5;
|
|
58
|
+
const MIN_PRICE_DIFFERENCE = 500;
|
|
59
|
+
|
|
60
|
+
const onHandleSlideChange = (activeSlide: number) => {
|
|
61
|
+
setActiveSlide(activeSlide);
|
|
62
|
+
|
|
63
|
+
if (typeof onSlideChange === 'function') {
|
|
64
|
+
onSlideChange(activeSlide);
|
|
183
65
|
}
|
|
184
66
|
};
|
|
185
|
-
|
|
67
|
+
|
|
68
|
+
const renderImagesData = (): JSX.Element => {
|
|
69
|
+
if (!Number.isFinite(imagesCount)) return null;
|
|
70
|
+
|
|
71
|
+
const delimiters = { xs: '|', sm: '|', md: 'von' };
|
|
72
|
+
|
|
73
|
+
return (
|
|
74
|
+
<div className={styles.section}>
|
|
75
|
+
{statsSize === 'md' ? <IconSVG name='common_camera' customDimensions className={styles.cameraIcon} /> : null}
|
|
76
|
+
{!!imagesCount && <span>{`${activeSlide + 1} ${delimiters[statsSize]} ${imagesCount}`}</span>}
|
|
77
|
+
</div>
|
|
78
|
+
);
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const renderRotateSvg = (): JSX.Element => {
|
|
82
|
+
const hasExteriorPhotos = hasInteriorExteriorPhoto && Array.isArray(images) && images.length > 0;
|
|
83
|
+
if (!hasExteriorPhotos) return null;
|
|
84
|
+
return (
|
|
85
|
+
<div className={styles.section}>
|
|
86
|
+
{hasExteriorPhotos ? (
|
|
87
|
+
<IconSVG name='rotate360New' customDimensions className={styles.statsEyeIcon} />
|
|
88
|
+
) : null}
|
|
89
|
+
</div>
|
|
90
|
+
);
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const renderStarButton = () => {
|
|
94
|
+
if (!onFavoriteClick) return null;
|
|
95
|
+
|
|
96
|
+
return (
|
|
97
|
+
<IconSVG
|
|
98
|
+
name='common_StarRoundedCorners'
|
|
99
|
+
customDimensions
|
|
100
|
+
className={classnames(styles.starButton, { [styles.starButtonFavored]: isFavoured })}
|
|
101
|
+
onClick={onFavoriteClick}
|
|
102
|
+
/>
|
|
103
|
+
);
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const renderStatsData = (): JSX.Element => {
|
|
107
|
+
if (!statsData) return null;
|
|
108
|
+
const { totalCarImpCount, totalFavCount } = statsData;
|
|
109
|
+
const favoritesClassName = classnames(
|
|
110
|
+
styles.statsFavoritesCount,
|
|
111
|
+
{
|
|
112
|
+
[styles.accented]: isFavoured,
|
|
113
|
+
[styles.clickable]: typeof onFavoriteClick === 'function'
|
|
114
|
+
});
|
|
115
|
+
const favoritesIconClassName = classnames(styles.statsStarIcon, { [styles.accented]: isFavoured });
|
|
116
|
+
|
|
117
|
+
return (
|
|
118
|
+
<div className={styles.section}>
|
|
119
|
+
{!!totalCarImpCount ? <div className={styles.statsViewsCount}>
|
|
120
|
+
<IconSVG name='common_SliderEye' customDimensions className={styles.statsEyeIcon} />
|
|
121
|
+
<span>
|
|
122
|
+
{totalCarImpCount}
|
|
123
|
+
</span>
|
|
124
|
+
</div> : null}
|
|
125
|
+
{!!totalFavCount ? <div className={favoritesClassName} onClick={onFavoriteClick}>
|
|
126
|
+
<IconSVG name='star' customDimensions className={favoritesIconClassName} />
|
|
127
|
+
<span>
|
|
128
|
+
{totalFavCount}
|
|
129
|
+
</span>
|
|
130
|
+
</div> : null}
|
|
131
|
+
</div>
|
|
132
|
+
);
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
const renderPriceData = () => {
|
|
136
|
+
const newText = !!t ? t('vehicleProps:promoSlider.new') : 'neu';
|
|
137
|
+
const EUR = `\u20AC`;
|
|
138
|
+
|
|
139
|
+
return (
|
|
140
|
+
<div className={classnames(styles.topWrapper, classWrapPrice)}>
|
|
141
|
+
{showNewLabel && <Badge type='blue' className={styles.new}>{newText}</Badge>}
|
|
142
|
+
{!!historyPriceDifference && historyPriceDifference >= MIN_PRICE_DIFFERENCE && (
|
|
143
|
+
<Badge type='green'>
|
|
144
|
+
{`-`}
|
|
145
|
+
<FormattedNumber value={historyPriceDifference} numbersAfterDot={0} />
|
|
146
|
+
{` ${EUR}`}
|
|
147
|
+
</Badge>
|
|
148
|
+
)}
|
|
149
|
+
{!!historyPriceDifferencePerCent && historyPriceDifferencePerCent >= MIN_PERCENT && (
|
|
150
|
+
<Badge type='red' className={styles.priceDifferencePerCent}>-{historyPriceDifferencePerCent}%</Badge>
|
|
151
|
+
)}
|
|
152
|
+
</div>
|
|
153
|
+
);
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
const wrappedComponentProps = {
|
|
157
|
+
t,
|
|
158
|
+
images,
|
|
159
|
+
hasInteriorExteriorPhoto,
|
|
160
|
+
imagesCount,
|
|
161
|
+
classWrapPrice,
|
|
162
|
+
...props
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return (
|
|
166
|
+
<div className={styles.wrapper}>
|
|
167
|
+
{!isReferenceSearch && renderPriceData()}
|
|
168
|
+
<WrappedComponent onSlideChange={onHandleSlideChange} isReferenceSearch={isReferenceSearch} {...wrappedComponentProps} />
|
|
169
|
+
<div className={classnames(styles.controls, styles[statsSize])}>
|
|
170
|
+
{renderImagesData()}
|
|
171
|
+
{renderRotateSvg()}
|
|
172
|
+
{renderStarButton()}
|
|
173
|
+
{renderStatsData()}
|
|
174
|
+
</div>
|
|
175
|
+
</div>
|
|
176
|
+
);
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
export default withStats;
|
|
@@ -141,8 +141,10 @@ export interface IVehicleSliderProps extends Settings {
|
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
export interface IVehicleSliderForSRLProps {
|
|
144
|
-
|
|
144
|
+
t?: (key: string, options?: object) => string;
|
|
145
|
+
id?: string;
|
|
145
146
|
mainImageId?: string;
|
|
147
|
+
hasInteriorExteriorPhoto?: boolean;
|
|
146
148
|
imageSize?: 'small' | 'medium' | 'large';
|
|
147
149
|
imagesCount?: number;
|
|
148
150
|
images?: ICarImage[];
|
|
@@ -688,7 +688,7 @@ const getDecoratedProps = (
|
|
|
688
688
|
? t('vehicleProps:value.co2Combined', { co2: co2.toLocaleString(language) })
|
|
689
689
|
: t('vehicleProps:value.na');
|
|
690
690
|
|
|
691
|
-
return <>{consumptionValue} <br /> {co2Value}</>;
|
|
691
|
+
return <>{wrapValue(consumptionValue)} <br /> {wrapValue(co2Value)}</>;
|
|
692
692
|
}
|
|
693
693
|
},
|
|
694
694
|
consumptionPowerCombinedAlternateView: {
|
|
@@ -708,7 +708,7 @@ const getDecoratedProps = (
|
|
|
708
708
|
? t('vehicleProps:value.co2Combined', { co2: co2.toLocaleString(language) })
|
|
709
709
|
: t('vehicleProps:value.na');
|
|
710
710
|
|
|
711
|
-
return <>{consumptionValue} <br /> {co2Value}</>;
|
|
711
|
+
return <>{wrapValue(consumptionValue)} <br /> {wrapValue(co2Value)}</>;
|
|
712
712
|
}
|
|
713
713
|
},
|
|
714
714
|
consumptionHydrogenCombinedAlternateView: {
|
|
@@ -728,7 +728,7 @@ const getDecoratedProps = (
|
|
|
728
728
|
? t('vehicleProps:value.co2Combined', { co2: co2.toLocaleString(language) })
|
|
729
729
|
: t('vehicleProps:value.na');
|
|
730
730
|
|
|
731
|
-
return <>{consumptionValue} <br /> {co2Value}</>;
|
|
731
|
+
return <>{wrapValue(consumptionValue)} <br /> {wrapValue(co2Value)}</>;
|
|
732
732
|
}
|
|
733
733
|
},
|
|
734
734
|
consumptionGasCombinedAlternateView: {
|
|
@@ -749,7 +749,7 @@ const getDecoratedProps = (
|
|
|
749
749
|
? t('vehicleProps:value.co2Combined', { co2: co2.toLocaleString(language) })
|
|
750
750
|
: t('vehicleProps:value.na');
|
|
751
751
|
|
|
752
|
-
return <>{consumptionValue} <br /> {co2Value}</>;
|
|
752
|
+
return <>{wrapValue(consumptionValue)} <br /> {wrapValue(co2Value)}</>;
|
|
753
753
|
}
|
|
754
754
|
},
|
|
755
755
|
|