@bytebrand/fe-ui-core 4.2.58 → 4.2.60

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.
@@ -0,0 +1,88 @@
1
+ import React from 'react';
2
+ import { fireEvent, render } from '@testing-library/react';
3
+ import VehicleInfo from '../../../source/components/VehicleSmallCard/VehicleData/VehicleInfo/VehicleInfo';
4
+ import { IVehicleInfo } from '../../../source/framework/types/types';
5
+
6
+ const defaultProps: IVehicleInfo = {
7
+ t: jest.fn(), // mock translation function
8
+ mlCurrentSalesPricePredicted: 30000,
9
+ i18nPrefixForPriceRating: 'common:',
10
+ vehicleComponentName: 'search',
11
+ combineRefAlternative: false,
12
+ language: 'en',
13
+ url: '/vehicle',
14
+ target: '_self',
15
+ rel: 'noopener noreferrer',
16
+ regDate: 20210101,
17
+ linkTag: 'a',
18
+ routeObj: {},
19
+ gearbox: 'Automatic',
20
+ numberOfPreviousOwners: 2,
21
+ usageType: 'Used',
22
+ condition: 'Good',
23
+ damaged: false,
24
+ driveType: 'AWD',
25
+ environmentEmissions: { co2: 123 },
26
+ common: {
27
+ currentSalesPrice: 235,
28
+ mileage: '7.5'
29
+ },
30
+ consumption: {
31
+ fuel: 'Gasoline',
32
+ consumptionCombined: 7.5,
33
+ consumptionPowerCombined: 9.1,
34
+ },
35
+ location: {
36
+ city: 'Lviv',
37
+ street: 'street',
38
+ zipCode: 55555
39
+ },
40
+ offer: 'Offer',
41
+ engineData: {
42
+ power: '200hp',
43
+ cylinder: '8',
44
+ fuelType: 'Gasoline',
45
+ }
46
+ };
47
+
48
+ describe('VehicleInfo', () => {
49
+ beforeEach(() => {
50
+ jest.clearAllMocks();
51
+ });
52
+
53
+ it('renders without crashing with default props', () => {
54
+ render(<VehicleInfo {...defaultProps} />);
55
+ });
56
+
57
+ it('renders the link with the correct href', () => {
58
+ const { getByRole } = render(<VehicleInfo {...defaultProps} url="/vehicles/123" />);
59
+ expect(getByRole('link')).toHaveAttribute('href', '/vehicles/123');
60
+ });
61
+
62
+ // it('renders the correct main properties for comparable cars', () => {
63
+ // const { getByText } = render(<VehicleInfo {...defaultProps} vehicleComponentName="comparable" />);
64
+ // expect(getByText('Fuel Type')).toBeInTheDocument();
65
+ // expect(getByText('Consumption Combined (l/100km)')).toBeInTheDocument();
66
+ // expect(getByText('Power')).toBeInTheDocument();
67
+ // });
68
+
69
+ // it('renders the correct main properties for landing cars', () => {
70
+ // const { getByText } = render(<VehicleInfo {...defaultProps} vehicleComponentName="landing" />);
71
+ // expect(getByText('Mileage')).toBeInTheDocument();
72
+ // expect(getByText('First Registration')).toBeInTheDocument();
73
+ // expect(getByText('Fuel Type')).toBeInTheDocument();
74
+ // });
75
+
76
+ // it('renders the correct main properties for SRL', () => {
77
+ // const { getByText } = render(<VehicleInfo {...defaultProps} vehicleComponentName="myVehicles" />);
78
+ // expect(getByText('Mileage')).toBeInTheDocument();
79
+ // expect(getByText('First Registration')).toBeInTheDocument();
80
+ // expect(getByText('Drive type')).toBeInTheDocument();
81
+ // });
82
+
83
+ // it('renders the correct PriceRating component', () => {
84
+ // const { getByTestId } = render(<VehicleInfo {...defaultProps} />);
85
+ // expect(getByTestId('price-rating')).toBeInTheDocument();
86
+ // });
87
+
88
+ });
@@ -0,0 +1,91 @@
1
+ import React from 'react';
2
+ import { fireEvent, render } from '@testing-library/react';
3
+ import VehicleTitle from '../../../source/components/VehicleSmallCard/VehicleData/VehicleTitle/VehicleTitle';
4
+ import { IVehicleTitleProps } from '../../../source/framework/types/types';
5
+
6
+ const props: IVehicleTitleProps = {
7
+ onFavoriteClick: jest.fn(),
8
+ isCarInFavorite: false,
9
+ id: '123',
10
+ make: 'Toyota',
11
+ model: 'Camry',
12
+ subModel: 'subModelText',
13
+ option: 'option',
14
+ isSponsored: true,
15
+ combineRefAlternative: true,
16
+ vehicleComponentName: 'search',
17
+ };
18
+
19
+ describe('VehicleTitle', () => {
20
+ beforeEach(() => {
21
+ jest.clearAllMocks();
22
+ });
23
+
24
+ it('should render VehicleTitle component with correct texts and styles', () => {
25
+ const { container, getByText } = render(<VehicleTitle {...props} />);
26
+
27
+ const infoSectionElement = container.querySelector('.infoSection');
28
+ const wrapTitlesElement = container.querySelector('.wrapTitles');
29
+ const optionTitleElement = container.querySelector('.optionTitle');
30
+
31
+ switch (props.vehicleComponentName) {
32
+ case 'search':
33
+ expect(infoSectionElement).toHaveClass('infoSectionSearch');
34
+ expect(wrapTitlesElement).toHaveClass('wrapTitlesSearch');
35
+ expect(optionTitleElement).toHaveClass('optionTitleSearch');
36
+ break;
37
+ case 'recently':
38
+ expect(infoSectionElement).toHaveClass('infoSectionRecently');
39
+ expect(wrapTitlesElement).toHaveClass('wrapTitlesRecently');
40
+ expect(optionTitleElement).toHaveClass('optionTitleRecently');
41
+ break;
42
+ case 'favorite':
43
+ expect(infoSectionElement).toHaveClass('infoSectionRecently');
44
+ expect(wrapTitlesElement).toHaveClass('wrapTitlesFavorite');
45
+ break;
46
+ case 'landing':
47
+ expect(infoSectionElement).toHaveClass('infoSectionRecently');
48
+ expect(wrapTitlesElement).toHaveClass('wrapTitlesRecently');
49
+ expect(optionTitleElement).toHaveClass('optionTitleRecently');
50
+ break;
51
+ case 'myVehicles':
52
+ expect(infoSectionElement).toHaveClass('infoSectionMyVehicles');
53
+ expect(wrapTitlesElement).toHaveClass('wrapTitlesSearch');
54
+ expect(optionTitleElement).toHaveClass('optionTitleSearch');
55
+ break;
56
+ case 'main':
57
+ expect(infoSectionElement).toHaveClass('infoSectionRecently');
58
+ expect(wrapTitlesElement).toHaveClass('wrapTitlesRecently');
59
+ expect(optionTitleElement).toHaveClass('optionTitleRecently');
60
+ break;
61
+ default:
62
+ break;
63
+ }
64
+
65
+ if (props.combineRefAlternative) {
66
+ expect(optionTitleElement).toHaveClass('optionTitleIsAlternative');
67
+ }
68
+
69
+ expect(getByText('Toyota Camry')).toBeInTheDocument();
70
+ expect(getByText('subModelText')).toBeInTheDocument();
71
+ expect(getByText('option')).toBeInTheDocument();
72
+
73
+ });
74
+
75
+ it('render StarButton when combineRefAlternative is false', () => {
76
+ const { container } = render(<VehicleTitle {...props} combineRefAlternative={false} showFavoriteStar={true} />);
77
+ expect(container.querySelector('.starButton')).toBeInTheDocument();
78
+ });
79
+
80
+ it('should call onFavoriteClick handler when clicking on StarButton', () => {
81
+
82
+ const { container } = render(<VehicleTitle {...props} combineRefAlternative={false} showFavoriteStar={true} />);
83
+
84
+ fireEvent.click(container.querySelector('svg'));
85
+ expect(props.onFavoriteClick).toHaveBeenCalledTimes(1);
86
+ expect(props.onFavoriteClick).toHaveBeenCalledWith(
87
+ expect.objectContaining({ type: 'click' }),
88
+ props.id
89
+ );
90
+ });
91
+ });
@@ -0,0 +1,23 @@
1
+ import React from 'react';
2
+ import { render } from '@testing-library/react';
3
+ import IconSVG from '../../../../source/components/_common/IconSVG/IconSVG';
4
+
5
+ describe('IconSVG component', () => {
6
+ it('should render the SVG icon when a valid name prop is passed', () => {
7
+ const { container } = render(<IconSVG name='Search' />);
8
+ const svgIcon = container.querySelector('svg');
9
+ expect(svgIcon).toBeDefined();
10
+ });
11
+
12
+ it('should not render anything when an invalid name prop is passed', () => {
13
+ const { container } = render(<IconSVG name='nonexistenticon' />);
14
+ const svgIcon = container.querySelector('svg');
15
+ expect(svgIcon).toBeNull();
16
+ });
17
+
18
+ it('should apply custom dimensions when customDimensions prop is false', () => {
19
+ const { container } = render(<IconSVG name="search" customDimensions={false} />);
20
+ const svgIcon = container.querySelector('svg');
21
+ expect(svgIcon).toHaveAttribute('style', 'width: 1.5rem; height: auto;');
22
+ });
23
+ });
@@ -0,0 +1,46 @@
1
+ import React from 'react';
2
+ import { render, fireEvent } from '@testing-library/react';
3
+ import StarButton from '../../../../source/components/_common/StarButton/StarButton';
4
+
5
+
6
+ describe('StarButton', () => {
7
+ const defaultProps = {
8
+ onClick: jest.fn(),
9
+ isFavorite: true,
10
+ amountOfFavorite: 5
11
+ }
12
+
13
+ it('render StarButton component', () => {
14
+ const { container } = render(<StarButton {...defaultProps} />);
15
+ const svgIcon = container.querySelector('svg');
16
+ expect(svgIcon.firstChild).toBeTruthy();
17
+ });
18
+
19
+ it('should trigger the onClick function when clicked', () => {
20
+ const { container } = render(<StarButton {...defaultProps} />);
21
+ fireEvent.click(container.querySelector('svg'));
22
+ expect(defaultProps.onClick).toHaveBeenCalled();
23
+ });
24
+
25
+ it('render amount of favorite if is amountOfFavorite are true', () => {
26
+ const { container, queryByTitle } = render(<StarButton {...defaultProps} amountOfFavorite={5} />);
27
+ expect(container.querySelector('span')).toBeInTheDocument();
28
+ expect(queryByTitle(`${defaultProps.amountOfFavorite}`));
29
+ });
30
+
31
+ it('removes amount of favorite if no favorites are present', () => {
32
+ const { queryByTitle } = render(<StarButton {...defaultProps} amountOfFavorite={0} />);
33
+ expect(queryByTitle(`${defaultProps.amountOfFavorite}`)).toBeFalsy();
34
+ });
35
+
36
+ it('renders custom container class when custom container prop exists', () => {
37
+ const customContainerClass = 'custom-container-class';
38
+ const { container } = render(<StarButton {...defaultProps} customContainer={customContainerClass} />);
39
+ expect(container.firstChild).toHaveClass(customContainerClass);
40
+ });
41
+
42
+ it('adds "active" className when isFavorite is true', () => {
43
+ const { container } = render(<StarButton isFavorite />);
44
+ expect(container.querySelector('svg')).toHaveClass('active');
45
+ });
46
+ });
package/common.ts CHANGED
@@ -85,6 +85,9 @@ export { default as Breadcrumbs } from './source/components/Breadcrumbs/Breadcru
85
85
  export { default as FirstInfoBlock } from './source/components/Breadcrumbs/FirstInfoBlock/FirstInfoBlock';
86
86
  export { default as InfoBlockWrapper } from './source/components/InfoBlocks/InfoBlockWrapper/InfoBlockWrapper';
87
87
 
88
+ // USER DASHBOARD
89
+ export { default as OrderStatusSection } from './source/components/UserDashboardPage/sections/OrderStatusSection/OrderStatusSection';
90
+
88
91
  // Filters
89
92
  export { default as FilterBlock } from './source/components/SearchFilters/common/FilterBlock/FilterBlock';
90
93
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bytebrand/fe-ui-core",
3
- "version": "4.2.58",
3
+ "version": "4.2.60",
4
4
  "description": "UI components for the auto.de project",
5
5
  "main": "index.ts",
6
6
  "module": "dist/common.js",
@@ -1,5 +1,5 @@
1
- @import '../../../../theme/theme.styl'
2
- @import '../../../../theme/mixins.styl'
1
+ @import '../../../../../theme/theme.styl'
2
+ @import '../../../../../theme/mixins.styl'
3
3
 
4
4
  .container
5
5
  padding: 8px 8px 16px
@@ -7,6 +7,9 @@
7
7
  +media-tablet-landscape-up()
8
8
  padding: 12px 16px
9
9
  display: grid
10
+ grid-template-areas:
11
+ 'addresses orderPrice'\
12
+ 'customerSuport orderPrice'
10
13
  grid-template-columns: 1fr 1fr
11
14
  column-gap: 32px
12
15
 
@@ -14,7 +17,7 @@
14
17
  .orderInfoSection:first-child
15
18
  position: relative
16
19
 
17
- .orderInfoSection:first-child:after
20
+ .orderPriceSection:before
18
21
  content: ''
19
22
  width: 1px
20
23
  height: 100%
@@ -22,7 +25,7 @@
22
25
  display: block;
23
26
  position: absolute;
24
27
  top: 0;
25
- right: -16px;
28
+ left: -16px;
26
29
 
27
30
  .labelText
28
31
  color: $black50
@@ -31,9 +34,18 @@
31
34
 
32
35
  .orderInfoAddresses
33
36
  padding-bottom: 8px
37
+ grid-area: addresses
38
+ display: grid
39
+
40
+ .orderPriceSection
41
+ grid-area: orderPrice
42
+ +media-tablet-landscape-up()
43
+ position: relative
34
44
 
35
45
  .orderInfoPrice
36
46
  border-top: 1px solid rgba(76,78,100,0.12)
47
+ +media-tablet-landscape-up()
48
+ border: none
37
49
 
38
50
  .overallRateLabel
39
51
  @extend .labelText
@@ -48,9 +60,9 @@
48
60
  .customerSuport
49
61
  @extend .labelText
50
62
  text-align: center
51
- margin-top: 8px
52
63
  padding: 16px 24px
53
64
  border-top: 1px solid rgba(76,78,100,0.12)
65
+ grid-area: customerSuport
54
66
 
55
67
  .customerSuportButton
56
68
  margin-top: 8px
@@ -9,8 +9,7 @@ import classNames from 'classnames';
9
9
 
10
10
  interface IAdditionalOrderData {
11
11
  addressData: { label: string, value: string }[];
12
- carPriceData: { label: string, value: string }[];
13
- financingData: { label: string, value: string }[];
12
+ carPriceData: { label: string, value: string | number }[];
14
13
  overallRate: {
15
14
  label: string,
16
15
  value: number
@@ -20,24 +19,30 @@ interface IAdditionalOrderData {
20
19
  interface IAdditionalOrderInfo {
21
20
  t: i18n.TFunction;
22
21
  additionalOrderData: IAdditionalOrderData;
22
+ redirectToUrl: (url: string) => void;
23
23
  }
24
24
 
25
- const AdditionalOrderInfo = ({ t, additionalOrderData }: IAdditionalOrderInfo) => {
26
- const { addressData, carPriceData, financingData, overallRate } = additionalOrderData;
25
+ const AdditionalOrderInfo = ({ t, additionalOrderData, redirectToUrl }: IAdditionalOrderInfo) => {
26
+ const { addressData, carPriceData, overallRate } = additionalOrderData;
27
+
28
+ const redirectToContactPage = () => {
29
+ return redirectToUrl('/account/kontakt');
30
+ };
31
+
27
32
  return (
28
33
  <div className={styles.container}>
29
- <div className={styles.orderInfoSection}>
30
- <div className={styles.orderInfoAddresses}>
31
- {addressData.map((data) => {
32
- const { value, label } = data;
33
- return (
34
- <div key={label}>
35
- <div className={styles.labelText}>{label}</div>
36
- <div className={styles.labelText}>{value}</div>
37
- </div>
38
- );
39
- })}
40
- </div>
34
+ <div className={styles.orderInfoAddresses}>
35
+ {addressData.map((data) => {
36
+ const { value, label } = data;
37
+ return (
38
+ <div key={label}>
39
+ <div className={styles.labelText}>{label}</div>
40
+ <div className={styles.labelText}>{value}</div>
41
+ </div>
42
+ );
43
+ })}
44
+ </div>
45
+ <div className={styles.orderPriceSection}>
41
46
  <div className={styles.orderInfoPrice}>
42
47
  {carPriceData.map((data) => {
43
48
  const { value, label } = data;
@@ -49,18 +54,7 @@ const AdditionalOrderInfo = ({ t, additionalOrderData }: IAdditionalOrderInfo) =
49
54
  );
50
55
  })}
51
56
  </div>
52
- </div>
53
- <div className={styles.orderInfoSection}>
54
57
  <div className={styles.orderInfoFinancing}>
55
- {financingData.map((data) => {
56
- const { value, label } = data;
57
- return (
58
- <div className={styles.flexContainer} key={label}>
59
- <div className={styles.labelText}>{label}</div>
60
- <div className={styles.labelText}>{value}</div>
61
- </div>
62
- );
63
- })}
64
58
  <div className={classNames(styles.flexContainer, styles.overallRate)}>
65
59
  <div className={styles.overallRateLabel}>{overallRate.label}</div>
66
60
  <div>
@@ -77,10 +71,10 @@ const AdditionalOrderInfo = ({ t, additionalOrderData }: IAdditionalOrderInfo) =
77
71
  </div>
78
72
  </div>
79
73
  </div>
80
- <div className={styles.customerSuport}>
81
- <div>{t('customerSupportText')}</div>
82
- <Button className={styles.customerSuportButton} variant='outlined'>{t('customerSupport')}</Button>
83
- </div>
74
+ </div>
75
+ <div className={styles.customerSuport}>
76
+ <div>{t('customerSupportText')}</div>
77
+ <Button onClick={redirectToContactPage} className={styles.customerSuportButton} variant='outlined'>{t('customerSupport')}</Button>
84
78
  </div>
85
79
  </div>
86
80
  );
@@ -1,17 +1,19 @@
1
1
  import React from 'react';
2
2
 
3
3
  import DashboardSection from '../../../containers/DasboardSection/DashboardSection';
4
- // import AdditionalOrderInfo from './AdditionalOrderInfo';
4
+ import AdditionalOrderInfo from './AdditionalOrderInfo';
5
5
  import OrderStatusCar from './OrderStatusCar';
6
6
  import styles from './OrderStatusSection.styl';
7
- // import { history } from '../../../../../AppRouter';
8
7
  import { Skeleton } from '@mui/material';
9
- import i18next from 'i18next';
8
+
9
+ import { getFormattedPrice } from '../../../../framework/utils/CommonUtils';
10
+
11
+ import i18n from 'i18next';
10
12
 
11
13
  interface IOrderStatusSection {
12
- redirectToCar: (id: string) => void;
13
14
  getSupportedImageFormat: (id: string, mainImageId: string, size: 'small' | 'medium' | 'large') => string;
14
- t: i18next.TFunction;
15
+ redirectToUrl: (url: string) => void;
16
+ t: i18n.TFunction;
15
17
  isFetching: boolean;
16
18
  withAdditionalInfo?: boolean; // for using on /account/my-order.
17
19
  orderedCars: any[]; // TODO: create interface for orderedCars, when the object is formatted by the backend
@@ -20,13 +22,14 @@ interface IOrderStatusSection {
20
22
  const OrderStatusSection = ({
21
23
  getSupportedImageFormat,
22
24
  t,
25
+ redirectToUrl,
23
26
  orderedCars,
24
27
  isFetching,
25
- withAdditionalInfo = false,
26
- redirectToCar
28
+ withAdditionalInfo = false
27
29
  }: IOrderStatusSection) => {
30
+
28
31
  const onDetailsClick = (carId: string) => {
29
- redirectToCar(carId);
32
+ return redirectToUrl(`/search/vehicle/${carId}`);
30
33
  };
31
34
 
32
35
  const renderRequestedCars = () => {
@@ -35,7 +38,7 @@ const OrderStatusSection = ({
35
38
  {!!orderedCars && orderedCars.map((orderedCar, index) => {
36
39
  const { car: { _id } } = orderedCar;
37
40
  const { car: { mainData: { make, model, subModel } } } = orderedCar;
38
- const { car: { metaData: { mainImageId } } } = orderedCar;
41
+ const { car: { metaData: { mainImageId } }} = orderedCar;
39
42
  const {
40
43
  buyingType,
41
44
  selfPickup,
@@ -44,39 +47,44 @@ const OrderStatusSection = ({
44
47
  status,
45
48
  request,
46
49
  registration,
47
- currentSalesPrice
50
+ currentSalesPrice,
51
+ deposit,
52
+ preparationCost,
53
+ licensePlateCost,
54
+ registrationCost,
55
+ transportationCost,
56
+ customerAddress: {
57
+ customerFirstname,
58
+ customerLastname
59
+ }
48
60
  } = orderedCar;
49
61
 
50
- // ---- data for testing additionalInfo ----
51
-
52
- // const additionalOrderData = {
53
- // addressData: [
54
- // { label: 'Billing address:', value: 'Hannes Käther, Wittenberger Str. 81, 04129 Leipzig' },
55
- // { label: 'Vehicle delivery:', value: 'Hannes Käther, Wittenberger Str. 81, 04129 Leipzig' }
56
- // ],
57
- // carPriceData: [
58
- // { label: 'Car price', value: '22.799,00 €' },
59
- // { label: 'Preparation cost', value: '799,00 €' },
60
- // { label: 'vehicle registration', value: '399,00 €' },
61
- // { label: 'Silver Guarantee Pack (2 years)', value: '1.099,00 €' },
62
- // { label: 'license plates', value: '140,66 €' },
63
- // { label: 'Delivery', value: '799,36 €' }
64
- // ],
65
- // financingData: [
66
- // { label: 'Leasing rate', value: '€194.00 per month' },
67
- // { label: 'Running time (months)', value: '72 months' },
68
- // { label: 'Deposit', value: '1.000,99 €' }
69
- // ],
70
- // overallRate: {
71
- // label: 'Your overall rate',
72
- // value: 599
73
- // }
74
- // };
62
+ const additionalOrderData = {
63
+ addressData: [
64
+ { label: 'Billing address:', value: `${customerFirstname} ${customerLastname}` },
65
+ { label: 'Vehicle delivery:', value: 'Hannes Käther, Wittenberger Str. 81, 04129 Leipzig' }
66
+ ],
67
+ carPriceData: [
68
+ { label: 'Car price', value: getFormattedPrice(currentSalesPrice, '$,.2f', ' €') },
69
+ { label: 'Preparation cost', value: getFormattedPrice(preparationCost, '$,.2f', ' €')},
70
+ { label: 'vehicle registration', value: getFormattedPrice(registrationCost, '$,.2f', ' €') },
71
+ { label: 'license plates', value: getFormattedPrice(licensePlateCost, '$,.2f', ' €') },
72
+ { label: 'Delivery', value: getFormattedPrice(transportationCost, '$,.2f', ' €') },
73
+ { label: `${buyingType} rate`, value: buyingType !== 'buy' ? `${getFormattedPrice(monthlyInstallment, '$,.2f', '', '€')} per month` : getFormattedPrice(monthlyInstallment, '$,.2f', ' €') },
74
+ { label: 'Running time (months)', value: `${paybackPeriod} months` },
75
+ { label: 'Deposit', value: getFormattedPrice(deposit, '$,.2f', ' €') }
76
+ ],
77
+ overallRate: {
78
+ label: 'Your overall rate',
79
+ value: monthlyInstallment
80
+ }
81
+ };
75
82
 
76
- // const additionalOrderInfoProps = {
77
- // t,
78
- // additionalOrderData
79
- // };
83
+ const additionalOrderInfoProps = {
84
+ t,
85
+ additionalOrderData,
86
+ redirectToUrl
87
+ };
80
88
 
81
89
  const imageUrl = getSupportedImageFormat(_id, mainImageId, 'small');
82
90
 
@@ -105,7 +113,7 @@ const OrderStatusSection = ({
105
113
  return (
106
114
  <DashboardSection key={index} title={title}>
107
115
  <OrderStatusCar { ...orderStatusCarProps } />
108
- {/* {withAdditionalInfo ? <AdditionalOrderInfo { ...additionalOrderInfoProps } /> : null} */}
116
+ {withAdditionalInfo ? <AdditionalOrderInfo { ...additionalOrderInfoProps } /> : null}
109
117
  </DashboardSection>
110
118
  );
111
119
  })}
@@ -115,7 +123,7 @@ const OrderStatusSection = ({
115
123
 
116
124
  return (
117
125
  <>
118
- {isFetching ?
126
+ {isFetching ?
119
127
  <div className={styles.skeletonBlock}>
120
128
  <Skeleton animation='wave' variant='rectangular' width='100%' />
121
129
  </div>
@@ -59,6 +59,13 @@ const BreadcrumbsFactory: IBreadcrumbsFactoryConfig = {
59
59
  className: 'breadcrumbsUserDashboard'
60
60
  }),
61
61
 
62
+ MY_ORDER: (props: any) => ({
63
+ list: [
64
+ { link: '/account/dashboard', title: props.t('common:breadcrumbs.DashboardNew') },
65
+ { link: '', title: props.t('common:breadcrumbs.myOrder') }
66
+ ]
67
+ }),
68
+
62
69
  DEALER_EMPLOYEES_SET: (props: any) => ({
63
70
  list: [
64
71
  { link: '/account/position/employees', title: props.t('common:breadcrumbs.Employees') },
@@ -95,9 +95,11 @@ export interface IVehicleInfo {
95
95
  routeObj?: any;
96
96
  linkTag?: string;
97
97
  mlCurrentSalesPricePredicted?: number;
98
- currentSalesPrice?: number;
99
- mileage?: string;
100
98
  location?: IVehicleLocation;
99
+ common: {
100
+ currentSalesPrice?: number;
101
+ mileage?: string;
102
+ };
101
103
  environmentEmissions?: any;
102
104
  engineData?: any;
103
105
  offer?: any;
@@ -311,13 +311,13 @@ export const sliceMoreThan = (array: number[], from: any): number[] => {
311
311
  : array;
312
312
  };
313
313
 
314
- export const getFormattedPrice = (price: number, format = '$,.0f', currency = ''): string => {
314
+ export const getFormattedPrice = (price: number, format = '$,.0f', currency = '', currencyPrefix = ''): string => {
315
315
  if (!Number.isFinite(price)) return '-';
316
316
  const groupingNum = 3;
317
317
  return d3formatLocale({
318
318
  decimal: ',',
319
319
  thousands: '.',
320
- currency: ['', currency],
320
+ currency: [currencyPrefix, currency],
321
321
  grouping: [groupingNum]
322
322
  }).format(format)(price);
323
323
  };
@@ -1,27 +0,0 @@
1
- import React from 'react';
2
-
3
- import { storiesOf } from '@storybook/react';
4
- import { action } from '@storybook/addon-actions';
5
-
6
- import VehicleTitle from './VehicleTitle';
7
-
8
- const container = {
9
- maxWidth: 200
10
- };
11
-
12
- const titleProps = {
13
- manufacturer: 'BMW',
14
- model: '320',
15
- subModel: 'Touring Edition Fleet +PDC +Navi',
16
- option: '135 (184) KW (PS)',
17
-
18
- isSponsored: false,
19
- onClick: action('click')
20
- };
21
-
22
- storiesOf('Vehicle title', module)
23
- .add('default', () => (
24
- <div style={container}>
25
- <VehicleTitle {...titleProps} />
26
- </div>
27
- ));
@@ -1,48 +0,0 @@
1
- .text
2
- margin-right: 5px
3
- white-space: nowrap
4
-
5
- .title
6
- width: 100%
7
- overflow: hidden
8
- text-overflow: ellipsis
9
- font-size: 14px
10
- cursor: pointer
11
- line-height: 20px
12
- font-family: 'Arial Standard', 'Arial'
13
- font-weight: 400
14
- font-style: normal
15
-
16
- .mainTitle, .optionTitle
17
- display: flex
18
- flex-direction: row
19
- align-items: center
20
- flex-wrap: nowrap
21
-
22
- .brand
23
- font-weight: 700
24
- text-transform: capitalize
25
-
26
- .sponsored
27
- font-family: 'Arial Fett', 'Arial Standard', 'Arial'
28
- font-weight: 700
29
- font-style: normal
30
- font-size: 10px
31
- border 1px solid #CCC
32
- padding: 2px 5px
33
- box-sizing: border-box
34
- border-radius 3px
35
- line-height: 12px
36
- text-transform: uppercase
37
-
38
- .model
39
- text-transform: capitalize
40
-
41
- .subModel
42
- font-weight normal
43
- overflow: hidden
44
- text-overflow: ellipsis
45
-
46
- .option
47
- margin-right: 5px
48
- line-height: 20px
@@ -1,44 +0,0 @@
1
- import * as React from 'react';
2
- import classnames from 'classnames';
3
-
4
- import styles from './VehicleTitle.styl';
5
-
6
- interface IVehicleTitleProps {
7
- manufacturer?: string;
8
- model?: string;
9
- subModel?: string;
10
- option?: string;
11
-
12
- isSponsored?: boolean;
13
- onClick?: (event: React.MouseEvent<HTMLElement>) => void;
14
- }
15
-
16
- const VehicleTitle: React.FC<IVehicleTitleProps> = (props) => {
17
- const { manufacturer, model, subModel, option, isSponsored, onClick } = props;
18
-
19
- return (
20
- <div className={styles.title} onClick={onClick}>
21
- <div className={styles.mainTitle}>
22
- <span className={classnames(styles.text, styles.brand)}>{manufacturer}</span>
23
- <span className={classnames(styles.text, styles.model)}>{model}</span>
24
- <span className={classnames(styles.text, styles.subModel)}>{subModel}</span>
25
- </div>
26
- <div className={styles.optionTitle}>
27
- <span className={styles.option}>{option}</span>
28
- {isSponsored && <span className={styles.sponsored}>Sponsored</span>}
29
- </div>
30
- </div>
31
- );
32
- };
33
-
34
- VehicleTitle.defaultProps = {
35
- manufacturer: '',
36
- model: '',
37
- subModel: '',
38
- option: '',
39
-
40
- isSponsored: false,
41
- onClick: () => { }
42
- };
43
-
44
- export default VehicleTitle;