@bytebrand/fe-ui-core 4.2.177 → 4.2.178
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/__tests__/components/UserDasboardPage/sections/CheckoutSection/CheckoutSection.test.tsx +16 -19
- package/package.json +1 -1
- package/source/components/Checkout/CheckoutStepper/CheckoutStepper.tsx +16 -15
- package/source/components/UserDashboardPage/sections/CheckoutSection/CheckoutSection.tsx +63 -50
- package/source/components/containers/SearchPage/FiltersContainer/FiltersContainer.tsx +3 -3
package/__tests__/components/UserDasboardPage/sections/CheckoutSection/CheckoutSection.test.tsx
CHANGED
|
@@ -15,8 +15,6 @@ interface IWithRouter {
|
|
|
15
15
|
children?: JSX.Element;
|
|
16
16
|
link?: string;
|
|
17
17
|
}
|
|
18
|
-
const getCheckoutCarListMock = jest.fn();
|
|
19
|
-
|
|
20
18
|
const checkoutCars = [
|
|
21
19
|
{
|
|
22
20
|
parkedFor: 'N/A',
|
|
@@ -543,7 +541,7 @@ const checkoutCars = [
|
|
|
543
541
|
seoText: ''
|
|
544
542
|
}
|
|
545
543
|
];
|
|
546
|
-
const
|
|
544
|
+
const getCarList = () => {
|
|
547
545
|
return new Promise((resolve) => {
|
|
548
546
|
resolve(checkoutCars);
|
|
549
547
|
});
|
|
@@ -582,35 +580,34 @@ const mockProps = {
|
|
|
582
580
|
appStore: { language:'en' },
|
|
583
581
|
carsStore: { aggStatsData },
|
|
584
582
|
imagesStore: { getSupportedImageFormat: jest.fn() },
|
|
585
|
-
|
|
583
|
+
UserActionsAPI:{ getCheckoutCarList:getCarList }
|
|
586
584
|
};
|
|
587
585
|
|
|
588
586
|
describe('CheckoutSection', () => {
|
|
589
587
|
it('renders correctly', () => {
|
|
590
588
|
const { container } = render(<CheckoutSection {...mockProps as any} />);
|
|
591
|
-
expect(mockProps.checkoutStore.getCheckoutCarList).toHaveBeenCalledTimes(1);
|
|
592
589
|
expect(container).toBeInTheDocument();
|
|
593
590
|
});
|
|
594
591
|
it('should display correct car data', () => {
|
|
595
592
|
const { container } = render(<CheckoutSection {...mockProps as any} />);
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
593
|
+
let checkoutCarList:[] = [];
|
|
594
|
+
mockProps.UserActionsAPI.getCheckoutCarList()
|
|
595
|
+
.then((savedCheckoutDataList: any) => {
|
|
596
|
+
checkoutCarList = savedCheckoutDataList;
|
|
597
|
+
checkoutCarList.forEach((element:any) => {
|
|
598
|
+
expect(container).toHaveTextContent(element.title.make);
|
|
599
|
+
});
|
|
602
600
|
});
|
|
603
|
-
// });
|
|
604
601
|
});
|
|
605
602
|
it('should open checkout page with correct URL on car select', () => {
|
|
606
603
|
const { getAllByRole } = render(<CheckoutSection {...mockProps as any} />);
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
604
|
+
mockProps.UserActionsAPI.getCheckoutCarList()
|
|
605
|
+
.then((savedCheckoutDataList: any) => {
|
|
606
|
+
const checkoutButton = getAllByRole('link')[0];
|
|
607
|
+
fireEvent.click(checkoutButton);
|
|
608
|
+
const expectedUrl = `/checkout/contact-information?carId=${savedCheckoutDataList[0].id}&isSavedCheckout=true&mainImageId=${savedCheckoutDataList[0].mainImageId}&model=${savedCheckoutDataList[0].title.model}&subModel=${savedCheckoutDataList[0].title.subModel}&make=${savedCheckoutDataList[0].title.make}`;
|
|
609
|
+
waitFor(() => expect(window.open).toHaveBeenCalledWith(expectedUrl, '_blank'));
|
|
610
|
+
});
|
|
614
611
|
});
|
|
615
612
|
|
|
616
613
|
});
|
package/package.json
CHANGED
|
@@ -4,16 +4,17 @@ import { useStyles } from './CheckoutStepperClasses';
|
|
|
4
4
|
import styles from './CheckoutStepper.styl';
|
|
5
5
|
import { Hidden } from 'react-grid-system';
|
|
6
6
|
import { Stepper, Step, StepButton, IconSVG } from '../../../../common';
|
|
7
|
-
import { toJS } from 'mobx';
|
|
8
7
|
|
|
9
8
|
interface ICheckoutStepper {
|
|
10
|
-
|
|
9
|
+
steps: [];
|
|
10
|
+
activeStep?: number;
|
|
11
|
+
handleStep?: (index: number) => () => void;
|
|
12
|
+
completed?: any;
|
|
11
13
|
t?: (phrase: string) => {};
|
|
12
14
|
}
|
|
13
15
|
|
|
14
|
-
const CheckoutStepper: FunctionComponent<ICheckoutStepper> = ({
|
|
16
|
+
const CheckoutStepper: FunctionComponent<ICheckoutStepper> = ({ steps, activeStep, completed, handleStep, t }) => {
|
|
15
17
|
const classes = useStyles();
|
|
16
|
-
const steps = toJS(checkoutStore.steps);
|
|
17
18
|
return (
|
|
18
19
|
<div className={`${classes.root} ${styles.stepperWrapper}`}>
|
|
19
20
|
<Stepper
|
|
@@ -21,34 +22,34 @@ const CheckoutStepper: FunctionComponent<ICheckoutStepper> = ({ checkoutStore, t
|
|
|
21
22
|
nonLinear
|
|
22
23
|
orientation={isMobileOnly ? 'horizontal' : 'vertical'}
|
|
23
24
|
alternativeLabel={isMobileOnly}
|
|
24
|
-
activeStep={
|
|
25
|
+
activeStep={activeStep}>
|
|
25
26
|
{steps.map(({ title, pathname }, index) => {
|
|
26
27
|
const labelRep = !!title && !isMobileOnly ? title.replace('-', '') : title;
|
|
27
28
|
return (
|
|
28
29
|
<Step key={pathname}
|
|
29
|
-
className={`${
|
|
30
|
-
${
|
|
31
|
-
${
|
|
30
|
+
className={`${completed.has(steps[index].pathname) ? classes.isCompleted : ''}
|
|
31
|
+
${completed.has(steps[index].pathname) ? classes.completeLine : ''}
|
|
32
|
+
${activeStep === index && classes.activeLine}
|
|
32
33
|
`}
|
|
33
|
-
|
|
34
|
+
>
|
|
34
35
|
<StepButton
|
|
35
|
-
onClick={
|
|
36
|
+
onClick={handleStep(index)}
|
|
36
37
|
classes={{
|
|
37
38
|
root: classes.buttonItem,
|
|
38
39
|
horizontal: classes.labelWrap,
|
|
39
40
|
vertical: classes.verticalWrap
|
|
40
41
|
}}
|
|
41
42
|
className={`
|
|
42
|
-
${
|
|
43
|
-
${
|
|
43
|
+
${activeStep === index ? classes.active : classes.default}
|
|
44
|
+
${completed.has(steps[index].pathname) && activeStep !== index && classes.completeStep}`}>
|
|
44
45
|
<span>{labelRep}</span>
|
|
45
46
|
<Hidden xs sm md>
|
|
46
|
-
{
|
|
47
|
-
{!
|
|
47
|
+
{activeStep !== index && <IconSVG name='menuArrow' className={styles.menuArrow} customDimensions={false}/>}
|
|
48
|
+
{!completed.has(steps[index].pathname) &&
|
|
48
49
|
<span
|
|
49
50
|
className={`
|
|
50
51
|
${classes.minutes}
|
|
51
|
-
${
|
|
52
|
+
${completed.has(steps[index].pathname) && activeStep !== index && classes.completeStep}`}
|
|
52
53
|
>
|
|
53
54
|
{steps[index].minutes}
|
|
54
55
|
|
|
@@ -5,7 +5,7 @@ import styles from './CheckoutSection.styl';
|
|
|
5
5
|
import { isMobileOnly } from 'react-device-detect';
|
|
6
6
|
import Slider from 'react-slick';
|
|
7
7
|
import { VehicleSmallCard } from '../../../../../common';
|
|
8
|
-
|
|
8
|
+
|
|
9
9
|
|
|
10
10
|
interface ITFunction {
|
|
11
11
|
<T = string>(key: string, options?: object): T;
|
|
@@ -20,70 +20,83 @@ interface ICheckoutSectionProps {
|
|
|
20
20
|
LinkRouter: any;
|
|
21
21
|
PLACEHOLDER_IMAGE_SMALL_URL:string;
|
|
22
22
|
UserActionsAPI:any;
|
|
23
|
-
checkoutStore:any;
|
|
24
23
|
}
|
|
25
24
|
|
|
26
25
|
class CheckoutSection extends React.Component<ICheckoutSectionProps, {}> {
|
|
26
|
+
state: {
|
|
27
|
+
checkoutCars: any[];
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
constructor(props: ICheckoutSectionProps) {
|
|
31
|
+
super(props);
|
|
32
|
+
this.state = {
|
|
33
|
+
checkoutCars: []
|
|
34
|
+
};
|
|
35
|
+
}
|
|
27
36
|
componentDidMount() {
|
|
28
|
-
|
|
29
|
-
|
|
37
|
+
try {
|
|
38
|
+
const { UserActionsAPI } = this.props;
|
|
39
|
+
UserActionsAPI.getCheckoutCarList()
|
|
40
|
+
.then((savedCheckoutDataList: any) => {
|
|
41
|
+
this.setState({ checkoutCars: Object.values(savedCheckoutDataList) });
|
|
42
|
+
});
|
|
43
|
+
} catch (err) {
|
|
44
|
+
console.log('[CheckoutSection] err = ', err);
|
|
45
|
+
}
|
|
30
46
|
}
|
|
31
47
|
|
|
32
48
|
onCarSelectCheckout = (carId?: string) => {
|
|
33
|
-
|
|
34
|
-
const checkoutCars = toJS(this.props.checkoutStore.checkoutCars);
|
|
35
|
-
const car = checkoutCars.find((item: any) => item.id === carId);
|
|
49
|
+
const car = this.state.checkoutCars.find((item: any) => item.id === carId);
|
|
36
50
|
const { mainImageId, title: { model, subModel, make } } = car;
|
|
37
51
|
window.open(`/checkout/contact-information?carId=${carId}&isSavedCheckout=true&mainImageId=${mainImageId}&model=${model}&subModel=${subModel}&make=${make}`, '_blank');
|
|
38
52
|
};
|
|
39
53
|
|
|
40
54
|
private renderCheckouts = () => {
|
|
41
|
-
const {
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
};
|
|
55
|
+
const { checkoutCars } = this.state;
|
|
56
|
+
const { t, appStore: { language }, carsStore, imagesStore , PLACEHOLDER_IMAGE_SMALL_URL } = this.props;
|
|
57
|
+
return checkoutCars.map((car: any) => {
|
|
58
|
+
const carId = _get(car, 'id');
|
|
59
|
+
const { mainImageId, title: { model, subModel, make } } = car;
|
|
60
|
+
const src = !!mainImageId && !!car.imagesCount
|
|
61
|
+
? imagesStore.getSupportedImageFormat(carId, mainImageId, 'small')
|
|
62
|
+
: PLACEHOLDER_IMAGE_SMALL_URL;
|
|
63
|
+
const vehicleProps = {
|
|
64
|
+
...car,
|
|
65
|
+
t,
|
|
66
|
+
language,
|
|
67
|
+
url: `/checkout/contact-information?carId=${carId}&isSavedCheckout=true&mainImageId=${mainImageId}&model=${model}&subModel=${subModel}&make=${make}`,
|
|
68
|
+
id: carId,
|
|
69
|
+
target: '_blank',
|
|
70
|
+
rel: 'noopener noreferrer',
|
|
71
|
+
showSlider: false,
|
|
72
|
+
showOfferBtn: true,
|
|
73
|
+
showFavoriteStar: false,
|
|
74
|
+
mainImageId,
|
|
75
|
+
priceSubMtl: !isMobileOnly ? t('vehicleProps:value.priceSub') : null,
|
|
76
|
+
src,
|
|
77
|
+
stats: {
|
|
78
|
+
imagesCount: _get(car, 'imagesCount'),
|
|
79
|
+
statsData: carsStore.aggStatsData.get(car.id)
|
|
80
|
+
},
|
|
81
|
+
dashboardButtonText: t('vehicleProps:title.toCheckoutCar'),
|
|
82
|
+
i18nPrefixForPriceRating: 'common:',
|
|
83
|
+
className: styles.wrapFavorites,
|
|
84
|
+
classButton: styles.favoriteBtn,
|
|
85
|
+
onDetailsClick: this.onCarSelectCheckout,
|
|
86
|
+
vehicleComponentName: 'favorite'
|
|
87
|
+
};
|
|
75
88
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}
|
|
89
|
+
return (
|
|
90
|
+
<div key={`checkoutCar${carId}`} className={styles.checkoutWrapItem}>
|
|
91
|
+
<VehicleSmallCard {...vehicleProps} />
|
|
92
|
+
</div>
|
|
93
|
+
);
|
|
94
|
+
});
|
|
83
95
|
};
|
|
84
96
|
|
|
85
97
|
render(): JSX.Element {
|
|
86
|
-
const { t
|
|
98
|
+
const { t } = this.props;
|
|
99
|
+
const { checkoutCars } = this.state;
|
|
87
100
|
const sliderProps = {
|
|
88
101
|
slidesToShow: 3,
|
|
89
102
|
slidesToScroll: 1,
|
|
@@ -109,7 +122,7 @@ class CheckoutSection extends React.Component<ICheckoutSectionProps, {}> {
|
|
|
109
122
|
|
|
110
123
|
return (
|
|
111
124
|
<>
|
|
112
|
-
{
|
|
125
|
+
{Array.isArray(checkoutCars) && checkoutCars.length ?
|
|
113
126
|
<DashboardSection className={styles.checkoutSection} title={t('DashboardPage:checkoutTitle')}>
|
|
114
127
|
{!isMobileOnly ?
|
|
115
128
|
this.renderCheckouts()
|
|
@@ -390,8 +390,8 @@ class FiltersContainer extends React.Component<IFiltersContainerProps, {}> {
|
|
|
390
390
|
|
|
391
391
|
onVehicleIdChange = (value: string) => {
|
|
392
392
|
const { filters, changeFilterValue, search } = this.props;
|
|
393
|
-
const upperCaseValue = value.toLocaleUpperCase();
|
|
394
|
-
if (
|
|
393
|
+
const upperCaseValue = value.toLocaleUpperCase().trim();
|
|
394
|
+
if (upperCaseValue.length === 6 || !value) {
|
|
395
395
|
this.onFilterChange('VEHICLE_ID', upperCaseValue);
|
|
396
396
|
changeFilterValue('VEHICLE_ID', upperCaseValue);
|
|
397
397
|
search(filters, 1, true);
|
|
@@ -434,7 +434,7 @@ class FiltersContainer extends React.Component<IFiltersContainerProps, {}> {
|
|
|
434
434
|
value={VEHICLE_ID.value}
|
|
435
435
|
onChange={this.onVehicleIdChange}
|
|
436
436
|
size='custom'
|
|
437
|
-
placeholder='
|
|
437
|
+
placeholder={t('SearchPage:vehicleIdexample')}
|
|
438
438
|
/>
|
|
439
439
|
</div>
|
|
440
440
|
{this.renderFilters()}
|