@bytebrand/fe-ui-core 4.2.66 → 4.2.68

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.
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { render, fireEvent } from '@testing-library/react'
2
+ import { render, fireEvent } from '@testing-library/react';
3
3
  import OrderStatusCar from '../../../../../source/components/UserDashboardPage/sections/OrderStatusSection/OrderStatusCar';
4
4
 
5
5
  const t = (phrase: string | string[], options: object) => {
@@ -8,7 +8,7 @@ const t = (phrase: string | string[], options: object) => {
8
8
  return `${phrase} ${value}`;
9
9
  }
10
10
  return phrase;
11
- }
11
+ };
12
12
 
13
13
  const mockProps = {
14
14
  t,
@@ -25,7 +25,7 @@ const mockProps = {
25
25
  registration: false,
26
26
  currentSalesPrice: 30000,
27
27
  onClick: jest.fn()
28
- }
28
+ };
29
29
 
30
30
  describe('OrderStatusCar', () => {
31
31
  it('renders OrderStatusCar component without error', () => {
@@ -45,7 +45,7 @@ describe('OrderStatusCar', () => {
45
45
 
46
46
  it('should display correct car image', () => {
47
47
  const { getByTestId } = render(<OrderStatusCar {...mockProps}/>);
48
- const carImage = getByTestId('car-image')
48
+ const carImage = getByTestId('car-image');
49
49
  expect(carImage).toHaveAttribute('src', mockProps.imageUrl);
50
50
  });
51
51
 
@@ -0,0 +1,117 @@
1
+ import { fireEvent, getByTestId, render, screen } from '@testing-library/react';
2
+ // import userEvent from '@testing-library/user-event';
3
+ import React from 'react';
4
+ import RequestedCarsSection from '../../../../../source/components/UserDashboardPage/sections/RequestedCarsSection/RequestedCarsSection';
5
+
6
+ const t = (phrase: string | string[], options: object) => {
7
+ if (options) {
8
+ const value = Object.values(options).map((option) => option);
9
+ return `${phrase} ${value}`;
10
+ }
11
+ return phrase;
12
+ };
13
+ interface IWithRouter {
14
+ children?: JSX.Element;
15
+ link?: string;
16
+ }
17
+ const LinkRouter = ({ children, link } :IWithRouter) => {
18
+ return (
19
+ <a href={link} >
20
+ { children }
21
+ </a>
22
+ );
23
+ };
24
+
25
+ const requestedCars = [
26
+ {
27
+ car: {
28
+ _id: '28121b1a-398c-4e9c-9097-51be545817c5',
29
+ mainData: {
30
+ make: 'Volvo',
31
+ model: 'CX95',
32
+ subModel: 'Test123'
33
+ },
34
+ metaData: {
35
+ mainImageId: 'RQ_mHNek5hIk'
36
+ }
37
+ },
38
+ buyingType: 'leasing',
39
+ selfPickup: true,
40
+ paybackPeriod: 24,
41
+ monthlyInstallment: 2000,
42
+ request: '010203555',
43
+ currentSalesPrice: 50000
44
+ },
45
+ {
46
+ car: {
47
+ _id: '1234567890',
48
+ mainData: {
49
+ make: 'Volvo',
50
+ model: 'CX90',
51
+ subModel: 'Test155'
52
+ },
53
+ metaData: {
54
+ mainImageId: 'main image id'
55
+ }
56
+ },
57
+ buyingType: 'financing',
58
+ selfPickup: false,
59
+ paybackPeriod: 24,
60
+ monthlyInstallment: 1000,
61
+ request: '010203123',
62
+ currentSalesPrice: 20000
63
+ }
64
+ ];
65
+
66
+ const mockProps = {
67
+ t,
68
+ requestedCars,
69
+ getSupportedImageFormat: jest.fn(),
70
+ redirectToCar: jest.fn(),
71
+ initHotjar: jest.fn(),
72
+ // tslint:disable-next-line:object-shorthand-properties-first
73
+ LinkRouter
74
+ };
75
+
76
+ describe('RequestedCarsSection', () => {
77
+ it('renders correctly', () => {
78
+ const { container } = render(<RequestedCarsSection {...mockProps} />);
79
+ expect(container).toBeInTheDocument();
80
+ });
81
+
82
+ it('should display correct car data', () => {
83
+ const { container } = render(<RequestedCarsSection {...mockProps} />);
84
+ const requestedCars = mockProps.requestedCars;
85
+ requestedCars.forEach((element) => {
86
+ expect(container).toHaveTextContent(element.buyingType);
87
+ });
88
+ });
89
+ it('should display correct car make and model', () => {
90
+ const { getByText } = render(<RequestedCarsSection {...mockProps} />);
91
+ const requestedCars = mockProps.requestedCars;
92
+ requestedCars.forEach((element) => {
93
+ expect(getByText(`${element.car.mainData.make} ${element.car.mainData.model}`)).toBeInTheDocument();
94
+ });
95
+ });
96
+ it('should display correct car subModel', () => {
97
+ const { getByText } = render(<RequestedCarsSection {...mockProps} />);
98
+ const requestedCars = mockProps.requestedCars;
99
+ requestedCars.forEach((element) => {
100
+ expect(getByText(`${element.car.mainData.subModel}`)).toBeInTheDocument();
101
+ });
102
+ });
103
+ it('should display correct car request number', () => {
104
+ const { getByText } = render(<RequestedCarsSection {...mockProps} />);
105
+ const requestedCars = mockProps.requestedCars;
106
+ requestedCars.forEach((element) => {
107
+ expect(getByText(`${element.request}`)).toBeInTheDocument();
108
+ });
109
+ });
110
+ it('calls redirectToCar with car ID on button click', () => {
111
+ const { getByTestId } = render(<RequestedCarsSection {...mockProps} />);
112
+ const carWrapper = getByTestId(mockProps.requestedCars[0].car._id);
113
+ fireEvent.click(carWrapper);
114
+ expect(mockProps.redirectToCar).toHaveBeenCalledTimes(1);
115
+ expect(mockProps.redirectToCar).toHaveBeenCalledWith(mockProps.requestedCars[0].car._id); // assert the correct car ID
116
+ });
117
+ });
@@ -0,0 +1,49 @@
1
+ import React from "react";
2
+ import { render, fireEvent } from "@testing-library/react";
3
+ import MaterialAutocomplete from "../../../../source/components/_common/MaterialAutocomplete/MaterialAutocomplete";
4
+ let value: any = null;
5
+ const setValue = jest.fn();
6
+ const materialAutocompleteProps = {
7
+ onChange: setValue,
8
+ label: 'test label',
9
+ value: value,
10
+ error: false,
11
+ required: true,
12
+ items: [
13
+ { value: '+49', label: '+49', icon: 'de' },
14
+ { value: '+43', label: '+43', icon: 'at' }
15
+ ],
16
+ listWithImage: 'true'
17
+ }
18
+ describe('MaterialAutocomplete', () => {
19
+ it('renders component without errors', () => {
20
+ const { container, getByRole, getByText } = render(<MaterialAutocomplete {...materialAutocompleteProps} />)
21
+ expect(container).toBeInTheDocument();
22
+ const input = getByRole('combobox');
23
+ const button = getByRole('button');
24
+ fireEvent.click(button);
25
+ const listItem = getByText('+43');
26
+ fireEvent.click(listItem);
27
+ expect(input).toHaveAttribute('value', '+43');
28
+ })
29
+
30
+ it('renders component, open list and choose any option from list', () => {
31
+ const { getByRole, getByText } = render(<MaterialAutocomplete {...materialAutocompleteProps} />)
32
+ const input = getByRole('combobox');
33
+ const button = getByRole('button');
34
+ fireEvent.click(button);
35
+ const listItem = getByText('+43');
36
+ fireEvent.click(listItem);
37
+ expect(input).toHaveAttribute('value', '+43');
38
+ })
39
+
40
+ it('renders component, open list and check if we have icons in list, when "listWithImage: true"', () => {
41
+ const { getByRole, container } = render(<MaterialAutocomplete {...materialAutocompleteProps} />)
42
+ const button = getByRole('button');
43
+ fireEvent.click(button);
44
+ const iconDe = container.querySelector('[id="flag-icons-de"]');
45
+ const iconAt = container.querySelector('[id="flag-icons-at"]');
46
+ expect(iconDe).toBeInTheDocument();
47
+ expect(iconAt).toBeInTheDocument();
48
+ })
49
+ })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bytebrand/fe-ui-core",
3
- "version": "4.2.66",
3
+ "version": "4.2.68",
4
4
  "description": "UI components for the auto.de project",
5
5
  "main": "index.ts",
6
6
  "module": "dist/common.js",
package/setupTests.js CHANGED
@@ -1 +1,8 @@
1
- import '@testing-library/jest-dom/extend-expect';
1
+ import '@testing-library/jest-dom/extend-expect';
2
+ global.matchMedia = global.matchMedia || function() {
3
+ return {
4
+ matches : false,
5
+ addListener : function() {},
6
+ removeListener: function() {}
7
+ }
8
+ }
@@ -4,10 +4,12 @@ import OrderStatusCard from './OrderStatusCard';
4
4
  import Image from '../../../_common/Image/Image';
5
5
  import { getFormattedPrice } from '../../../../framework/utils/CommonUtils';
6
6
 
7
+ // tslint:disable-next-line:interface-name
7
8
  interface TFunction {
8
9
  <T = string>(key: string, options?: object): T;
9
10
  <T = string>(keys: string[], options?: object): T;
10
11
  }
12
+ // tslint:disable-next-line:interface-name
11
13
  interface IOrderStatusCar {
12
14
  make?: string;
13
15
  model?: string;
@@ -0,0 +1,97 @@
1
+ import React from 'react';
2
+ import { storiesOf } from '@storybook/react';
3
+
4
+ import RequestedCarsSection from './RequestedCarsSection';
5
+
6
+ const requestedCars = [
7
+ {
8
+ car: {
9
+ _id: '1234567892',
10
+ mainData: {
11
+ make: 'Volvo',
12
+ model: 'CX90',
13
+ subModel: 'sub model',
14
+ },
15
+ metaData: {
16
+ mainImageId: 'main image id'
17
+ }
18
+ },
19
+ buyingType: 'leasing',
20
+ selfPickup: true,
21
+ paybackPeriod: 24,
22
+ monthlyInstallment: 1000,
23
+ status: 'selector_status_preparation',
24
+ request: '010203',
25
+ registration: true,
26
+ currentSalesPrice: 20000
27
+ },
28
+ {
29
+ car: {
30
+ _id: '1234567890',
31
+ mainData: {
32
+ make: 'Volvo',
33
+ model: 'CX90',
34
+ subModel: 'sub model',
35
+ },
36
+ metaData: {
37
+ mainImageId: 'main image id'
38
+ }
39
+ },
40
+ buyingType: 'financing',
41
+ selfPickup: false,
42
+ paybackPeriod: 24,
43
+ monthlyInstallment: 1000,
44
+ status: 'selector_status_registration',
45
+ request: '010203',
46
+ registration: false,
47
+ currentSalesPrice: 20000
48
+ }
49
+ ];
50
+
51
+ const translates = {
52
+ 'DealerDashboardPage:buyingType.buy': 'buy',
53
+ 'DealerDashboardPage:buyingType.leasing': 'leasing',
54
+ 'DealerDashboardPage:buyingType.financing': 'financing',
55
+ 'DealerDashboardPage:paybackPeriod': 'payback period',
56
+ 'DealerDashboardPage:currentSalesPrice': 'current sales price',
57
+ 'DealerDashboardPage:monthlyInstallment': 'monthly installment',
58
+ 'DealerDashboardPage:requestedCars.requestedCarsTitle':'Requested cars',
59
+ 'DealerDashboardPage:requestedCars.toOffer': 'To offer',
60
+ 'DealerDashboardPage:requestedCars.customerService':'Support',
61
+ 'DealerDashboardPage:requestedCars.customerServiceText':'Do you have questions about your desired vehicle or about car financing, delivery or registration? Please use the contact form and let us know your question. We will get back to you as soon as possible. Thank you very much.',
62
+ 'DealerDashboardPage:requestedCars.contact':'Contact'
63
+ }
64
+
65
+ const t = (phrase, options) => {
66
+ if (options) {
67
+ console.log('qqqq options ====', options);
68
+ const value = Object.values(options).map((option) => option)
69
+ return `${translates[phrase]} ${value}`;
70
+ }
71
+ return translates[phrase];
72
+ }
73
+ const LinkRouter = ({ children, link }) => {
74
+ return (
75
+ <a href={link} >
76
+ { children }
77
+ </a>
78
+ );
79
+ };
80
+ const initHotjar = () => {
81
+ console.log('Hotjar works')
82
+ };
83
+
84
+ const props = {
85
+ t,
86
+ redirectToCar: (id) => console.log(`redirect to car with id: ${id}`),
87
+ getSupportedImageFormat: (id, mainImageId, size) => 'https://images.autode-dev.de/carimage/28121b1a-398c-4e9c-9097-51be545817c5/RQ_mHNek5hIk/small-cached.webp',
88
+ requestedCars,
89
+ LinkRouter,
90
+ initHotjar
91
+ };
92
+
93
+
94
+ storiesOf('userDashboard', module)
95
+ .add('RequestedCarsSection', () => (
96
+ <RequestedCarsSection {...props} />
97
+ ));
@@ -0,0 +1,147 @@
1
+ @import '../../../../theme/mixins.styl'
2
+
3
+ .requestedCarsSectionWrapper
4
+ border-right: 1px solid rgba(76, 78, 100, 0.12)
5
+ width: 219px!important
6
+ padding: 28px 10px 21px
7
+ cursor: pointer
8
+ display: flex!important;
9
+ flex-direction: column;
10
+ height: 305px;
11
+ justify-content: space-between;
12
+ +media-tablet-landscape-down()
13
+ width: 100% !important;
14
+ padding: 28px 10px 21px;
15
+
16
+ .carsContainer
17
+ display: flex;
18
+ +media-tablet-landscape-down()
19
+ width: 93vw;
20
+ overflow-x: scroll;
21
+
22
+
23
+ .model
24
+ font-style: normal;
25
+ font-weight: 500;
26
+ font-size: 20px;
27
+ line-height: 24px;
28
+ text-align: center;
29
+ letter-spacing: 0.15px;
30
+ color: rgba(76, 78, 100, 0.87);
31
+ max-height: 48px
32
+ display: flex
33
+ justify-content: center
34
+ -webkit-line-clamp: 1;
35
+ display: -webkit-box;
36
+ -webkit-box-orient: vertical;
37
+ overflow: hidden;
38
+ height: 26px;
39
+
40
+ .subModel
41
+ font-style: normal;
42
+ font-weight: 500;
43
+ font-size: 12px;
44
+ line-height: 16px;
45
+ text-align: center;
46
+ letter-spacing: 0.15px;
47
+ color: rgba(76, 78, 100, 0.87);
48
+ width: 100%;
49
+ -webkit-line-clamp: 1;
50
+ display: -webkit-box;
51
+ -webkit-box-orient: vertical;
52
+ overflow: hidden;
53
+ height: 16px;
54
+
55
+ .payment
56
+ height: 20px;
57
+ font-style: normal;
58
+ font-weight: 400;
59
+ font-size: 12px;
60
+ line-height: 20px;
61
+ text-align: center;
62
+ letter-spacing: 0.15px;
63
+ color: rgba(76, 78, 100, 0.87);
64
+ +media-tablet-landscape-down()
65
+ height: 40px;
66
+
67
+ .req
68
+ font-style: normal;
69
+ font-weight: 400;
70
+ font-size: 12px;
71
+ line-height: 16px;
72
+ text-align: center;
73
+ letter-spacing: 0.4px;
74
+ color: rgba(76, 78, 100, 0.87);
75
+
76
+ .offerButton
77
+ display: flex;
78
+ justify-content: center;
79
+ margin-top: 8px;
80
+ [class*='MuiButtonBase-root']
81
+ width: 187px
82
+
83
+ .container
84
+ display: flex
85
+ flex-direction: row
86
+
87
+ .defaultLayout
88
+ display: flex
89
+ flex-direction: row
90
+ justify-content: space-around
91
+ +media-tablet-landscape-down()
92
+ width: 100% !important;
93
+
94
+ .image
95
+ max-height: 164px;
96
+ overflow: hidden;
97
+
98
+ .sliderContainer
99
+ width: 720px;
100
+ +media-tablet-landscape-down()
101
+ width: 90vw;
102
+ :global
103
+ .slick-slider
104
+ overflow: hidden
105
+ +media-tablet-landscape-down()
106
+ padding 0;
107
+ .slick-arrow,
108
+ .slick-arrow:focus,
109
+ .slick-arrow:hover
110
+ display: inline-block
111
+ width: 25px
112
+ height: 50px
113
+ z-index: 1
114
+ transition: all 0.2s ease-in-out
115
+ .slick-arrow::before
116
+ display: none
117
+ .click-arrow::before:hover
118
+ background-color: black
119
+
120
+ .slick-arrow::after
121
+ position: absolute
122
+ content: ''
123
+ display: inline-block
124
+ width: inherit
125
+ height: inherit
126
+ top: 50%
127
+ transform: translateY(-50%)
128
+ transform-origin: top center
129
+ background-image: url('../../../../../media/images/slider-arrow-new.svg')
130
+ background-size: cover
131
+
132
+ .slick-next::after
133
+ left: 10px
134
+
135
+ .slick-prev::after
136
+ transform: rotate(180deg) translateY(-50%)
137
+ right: 0
138
+
139
+ .slick-prev
140
+ left: -5px!important
141
+ top:50%!important
142
+
143
+ .slick-next
144
+ right: -5px!important
145
+ top:50%!important
146
+
147
+
@@ -0,0 +1,131 @@
1
+ import React, { useEffect } from 'react';
2
+ import styles from './RequestedCarsSection.styl';
3
+
4
+ import Slider from 'react-slick';
5
+ import DashboardSection from '../../../containers/DasboardSection/DashboardSection';
6
+ import SupportSection from './SupportSection';
7
+ import i18next from 'i18next';
8
+ import { translate } from 'react-i18next';
9
+ import Image from '../../../_common/Image/Image';
10
+ import { Hidden, Visible } from 'react-grid-system';
11
+ import { getFormattedPrice } from '../../../../framework/utils/CommonUtils';
12
+ // import { history } from '../../../../../AppRouter';
13
+ import Button from '../../../_common/Button/Button';
14
+
15
+ interface IWithRouter {
16
+ children?: JSX.Element;
17
+ }
18
+ // tslint:disable-next-line:interface-name
19
+ interface TFunction {
20
+ <T = string>(key: string, options?: object): T;
21
+ <T = string>(keys: string[], options?: object): T;
22
+ }
23
+
24
+ interface IRequestedCarsSection {
25
+ redirectToCar: (id: string) => void;
26
+ getSupportedImageFormat: (id: string, mainImageId: string, size: 'small' | 'medium' | 'large') => string;
27
+ requestedCars: any[];
28
+ t: TFunction;
29
+ LinkRouter:any;
30
+ initHotjar:() => void;
31
+ }
32
+
33
+ const RequestedCarsSection = ({ t, getSupportedImageFormat, requestedCars, redirectToCar, LinkRouter, initHotjar }: IRequestedCarsSection) => {
34
+ useEffect(() => {
35
+ initHotjar();
36
+ }, []);
37
+ const onDetailsClick = (event: React.MouseEvent, carId: string) => {
38
+ redirectToCar(carId);
39
+ event.preventDefault();
40
+ event.stopPropagation();
41
+ // history.push(`/search/vehicle/${carId}`);
42
+ };
43
+
44
+ const renderItems = () => {
45
+ if (requestedCars && requestedCars.length > 0) {
46
+ const carsCard = requestedCars.map((car) => {
47
+ if (car && car.car) {
48
+ const { car: { mainData: { make, model, subModel } } } = car;
49
+ const { car: { _id, metaData: { mainImageId } } } = car;
50
+ const { buyingType, paybackPeriod, monthlyInstallment, request, currentSalesPrice } = car;
51
+ const imageUrl = getSupportedImageFormat(_id, mainImageId, 'small');
52
+ return (
53
+ <div key={_id} className={styles.requestedCarsSectionWrapper} data-testid={_id} onClick={(e: React.MouseEvent<HTMLDivElement>) => onDetailsClick(e, _id)}>
54
+ <div className={styles.model}>{make} {model}</div>
55
+ <div className={styles.subModel}>{subModel}</div>
56
+ <Image className={styles.image} width='100%' ratioW={4} ratioH={3} data-testid='car-image' src={imageUrl} />
57
+ <div className={styles.req}>{request}</div>
58
+ {
59
+ (buyingType !== 'buy')
60
+ ? (<div className={styles.payment}> {t(`DealerDashboardPage:buyingType.${buyingType}`)}, {t('DealerDashboardPage:paybackPeriod', { paybackPeriod })}, {t('DealerDashboardPage:monthlyInstallment', { monthlyInstallment: getFormattedPrice(monthlyInstallment, '$,.2f') })}</div>)
61
+ : (<div className={styles.payment}>
62
+ {t(`DealerDashboardPage:buyingType.${buyingType}`)}, {t('DealerDashboardPage:currentSalesPrice', { currentSalesPrice: getFormattedPrice(currentSalesPrice) })}
63
+ </div>)
64
+ }
65
+ <div></div>
66
+ <div className={styles.offerButton}>
67
+ <Button variant='outlined' size='small' onClick={(e: React.MouseEvent<HTMLButtonElement>) => { onDetailsClick(e, _id); }}>{t('DealerDashboardPage:requestedCars.toOffer')}</Button>
68
+ </div>
69
+ </div>
70
+ );
71
+ }
72
+ });
73
+ return carsCard.reverse();
74
+ }
75
+ };
76
+
77
+ const renderSlider = () => {
78
+ const sliderProps = {
79
+ className: 'react-slider-container',
80
+ slidesToShow: 3,
81
+ slidesToScroll: 1,
82
+ dots: false,
83
+ arrow: false,
84
+ rows: 1,
85
+ infinity: false
86
+ };
87
+ return (
88
+ <>
89
+ <Visible xs sm md>
90
+ <div className={styles.defaultLayout}>
91
+ {renderItems()}
92
+ </div>
93
+ </Visible>
94
+ <Hidden xs sm md>
95
+ {(requestedCars.length >= 3) ? (
96
+ <div className={styles.sliderContainer}>
97
+ <Slider {...sliderProps}>
98
+ {renderItems()}
99
+ </Slider>
100
+ </div>) :
101
+ (<div className={styles.defaultLayout}>
102
+ {renderItems()}
103
+ </div>)
104
+ }
105
+ </Hidden>
106
+ </>
107
+ );
108
+ };
109
+ const SupportSectionProps = {
110
+ t,
111
+ Link:LinkRouter
112
+ };
113
+
114
+ return (
115
+ <>
116
+ {requestedCars.length > 0 ? (
117
+ <DashboardSection title={t('DealerDashboardPage:requestedCars.requestedCarsTitle')}>
118
+ <div className={styles.carsContainer}>
119
+ <div className={styles.wrapper}>
120
+ {renderSlider()}
121
+ </div>
122
+ <SupportSection {...SupportSectionProps} />
123
+ </div>
124
+ </DashboardSection>
125
+ ) : (
126
+ null
127
+ )}
128
+ </>
129
+ );
130
+ };
131
+ export default RequestedCarsSection;
@@ -0,0 +1,47 @@
1
+ @import '../../../../theme/mixins.styl'
2
+ .supportSection
3
+ padding: 22px 20px
4
+ display: flex;
5
+ flex-direction: column;
6
+ justify-content: space-between;
7
+ +media-tablet-landscape-down()
8
+ padding: 22px 10px;
9
+
10
+ .circle
11
+ width: 56px;
12
+ height: 56px;
13
+ background: linear-gradient(0deg, rgba(255, 255, 255, 0.88), rgba(255, 255, 255, 0.88)), #666CFF;
14
+ border-radius: 56px;
15
+ display: flex;
16
+ justify-content: center;
17
+ align-items: center;
18
+ margin: 0px auto;
19
+ .title
20
+ font-style: normal;
21
+ font-weight: 500;
22
+ font-size: 20px;
23
+ line-height: 32px;
24
+ text-align: center;
25
+ letter-spacing: 0.15px;
26
+ color: rgba(76, 78, 100, 0.87);
27
+
28
+ .text
29
+ font-style: normal;
30
+ font-weight: 400;
31
+ font-size: 14px;
32
+ line-height: 20px;
33
+ text-align: center;
34
+ letter-spacing: 0.15px;
35
+ color: rgba(76, 78, 100, 0.68);
36
+ +media-tablet-landscape-down()
37
+ width: 88vw
38
+
39
+
40
+ .contactButton
41
+ display: flex;
42
+ justify-content: center;
43
+ margin-top: 8px;
44
+ [class*='MuiButtonBase-root']
45
+ background-color: rgba(0, 184, 0, 1);
46
+ width: 111px;
47
+ height: 42px;
@@ -0,0 +1,32 @@
1
+ // import { Button, IconSVG } from '@bytebrand/fe-ui-core/common';
2
+ import i18next from 'i18next';
3
+ import IconSVG from '../../../_common/IconSVG/IconSVG';
4
+ import Button from '../../../_common/Button/Button';
5
+ import React from 'react';
6
+ import styles from './SupportSection.styl';
7
+
8
+ export interface IProps {
9
+ t: i18next.TFunction;
10
+ Link?: any;
11
+ }
12
+ const SupportSection: React.FunctionComponent<IProps> = ({ t , Link }) => {
13
+ return (
14
+ <div className={styles.supportSection}>
15
+ <div className={styles.circle}>
16
+ <IconSVG className={styles.icon} name='dashboardQuestionMark' customDimensions />
17
+ </div>
18
+ <div className={styles.title}>
19
+ {t('DealerDashboardPage:requestedCars.customerService')}
20
+ </div>
21
+ <div className={styles.text}>
22
+ {t('DealerDashboardPage:requestedCars.customerServiceText')}</div>
23
+ <div className={styles.contactButton}>
24
+ <Link link='/account/kontakt'>
25
+ <Button size='small' color='success' variant='contained'>{t('DealerDashboardPage:requestedCars.contact')}</Button>
26
+ </Link>
27
+ </div>
28
+ </div>
29
+ );
30
+ };
31
+
32
+ export default SupportSection;
@@ -114,9 +114,9 @@ export const Theme = createTheme({
114
114
  },
115
115
  MuiInputLabel: {
116
116
  styleOverrides: {
117
- root: ({ ownerState }) => ({
117
+ root: ({ ownerState: { size } }: { ownerState: { size?: string } }) => ({
118
118
  maxWidth: 'calc(100% - 28px)',
119
- ...(ownerState.size === 'custom' && { // tslint:disable-line
119
+ ...(size === 'custom' && {
120
120
  marginTop: isMobileOnly ? '0px' :'-4px',
121
121
  ['&.MuiInputLabel-shrink, &.Mui-focused']: {
122
122
  marginTop: 0
@@ -127,8 +127,8 @@ export const Theme = createTheme({
127
127
  },
128
128
  MuiOutlinedInput: {
129
129
  styleOverrides: {
130
- root: ({ ownerState }) => ({
131
- ...(ownerState.size === 'small' && {
130
+ root: ({ ownerState: { size, name } }: { ownerState: { size?: string, name?: string } }) => ({
131
+ ...(size === 'small' && {
132
132
  paddingRight: '0 !important',
133
133
  flexWrap: 'nowrap !important',
134
134
  backgroundColor: '#fff',
@@ -150,11 +150,11 @@ export const Theme = createTheme({
150
150
  opacity:'0.38'
151
151
  },
152
152
  ['& .MuiAutocomplete-input']: {
153
- ...(ownerState.name === 'mobileSearch' && {
153
+ ...(name === 'mobileSearch' && {
154
154
  textAlign: isMobileOnly ? 'right !important' : 'left'
155
155
  })
156
156
  },
157
- ...(ownerState.size === 'custom' && {
157
+ ...(size === 'custom' && {
158
158
  height: isMobileOnly ? 56 : 48,
159
159
  boxSizing: 'border-box',
160
160
  backgroundColor: '#fff',
@@ -164,7 +164,7 @@ export const Theme = createTheme({
164
164
  padding: '5.5px 4px 7.5px 6px !important'
165
165
  }
166
166
  }),
167
- ...(ownerState.name === 'mobileSearch' && {
167
+ ...(name === 'mobileSearch' && {
168
168
  color: isMobileOnly ? '#005ccb' : 'rgba(0, 0, 0, 0.87)',
169
169
  backgroundColor: isMobileOnly ? 'transparent' : '#fff',
170
170
  paddingRight: isMobileOnly ? '33px !important' : '42px !important',
@@ -181,7 +181,7 @@ export const Theme = createTheme({
181
181
  borderWidth: isMobileOnly ? 0 : 1
182
182
  }
183
183
  })
184
- })
184
+ } as any)
185
185
  }
186
186
  }
187
187
  }
@@ -11,6 +11,7 @@ import Autocomplete, { createFilterOptions } from '@mui/material/Autocomplete';
11
11
  import { Theme, ArrowSelect, CheckboxLabel } from './MaterialAutocomplete.styled';
12
12
  import isEqual from 'lodash/isEqual';
13
13
  import IconSVG from '../IconSVG/IconSVG';
14
+ import { isMobileOnly } from 'react-device-detect';
14
15
 
15
16
  export interface IItems {
16
17
  value: string | number;
@@ -100,11 +101,8 @@ const MaterialAutocomplete: React.FC<IMaterialAutocompleteProps> = ({
100
101
  multiple={multiple}
101
102
  handleHomeEndKeys
102
103
  value={value}
103
- name={name}
104
- error={error ? error.toString() : ''}
105
104
  readOnly={readOnly}
106
- listwithimage={listWithImage}
107
- onChange={(e, newValue, reason: string, details?: { option: any }) => {
105
+ onChange={(e, newValue, _: string, details?: { option: any }) => {
108
106
  e.persist();
109
107
  if (typeof newValue === 'string') {
110
108
  onChange(newValue);
@@ -150,17 +148,16 @@ const MaterialAutocomplete: React.FC<IMaterialAutocompleteProps> = ({
150
148
  }}
151
149
  options={multiple ? items.map(option => option.label) : items}
152
150
  ListboxProps={{
153
- sx: {
154
- maxHeight: {
155
- xs: MOBILE_ITEM_HEIGHT * MENU_ITEMS,
156
- sm: ITEM_HEIGHT * MENU_ITEMS
157
- }
151
+ style: {
152
+ maxHeight: isMobileOnly ?
153
+ MOBILE_ITEM_HEIGHT * MENU_ITEMS
154
+ : ITEM_HEIGHT * MENU_ITEMS
158
155
  }
159
156
  }}
160
157
  forcePopupIcon
161
158
  popupIcon={disableIcon ? '' : <ArrowSelect name='arrowSelect' customDimensions />}
162
159
  isOptionEqualToValue={(option, value) => option.value === value}
163
- renderOption={(props, option) => {
160
+ renderOption={(props: any, option) => {
164
161
  if (multiple) {
165
162
  return (
166
163
  <li {...props}>
@@ -218,8 +215,7 @@ const MaterialAutocomplete: React.FC<IMaterialAutocompleteProps> = ({
218
215
  InputProps={{ ...params.InputProps, readOnly }}
219
216
  />
220
217
  )}
221
- >
222
- </Autocomplete>
218
+ />
223
219
  </ThemeProvider>
224
220
  );
225
221
  };
@@ -12,7 +12,7 @@ interface IPreviewCookieModal {
12
12
 
13
13
  const PreviewCookieModal = ({ toggleModal, setModal }: IPreviewCookieModal) => {
14
14
  const onAcceptAll = () => {
15
- localStorage.setItem('cookieConfig', JSON.stringify({}));
15
+ localStorage.setItem('cookieConfig', JSON.stringify({}));
16
16
  updateCookieList();
17
17
  toggleModal();
18
18
  };
@@ -54,6 +54,7 @@ const OfferRequestBtnWrapper: React.FunctionComponent<IOfferRequestButtonWrapper
54
54
 
55
55
  const getRequestButtonTitle = () => {
56
56
  if (isSale) return t('sidebar.requestOfferSale');
57
+ // tslint:disable-next-line:no-else-after-return
57
58
  else if (isAlternativeType) return t('sidebar.importRequest');
58
59
  else if (hasCheckout) return t('vehicleProps:title.toCheckoutCar');
59
60
  else if (isOfferRequested) return t('CheckoutPage:onlineCheckoutModal.redirectBtn');
@@ -15,6 +15,7 @@ import { SearchPage as SearchPageTranslate } from '../../locales/data';
15
15
  const PRICE_DEFAULT = DROP_DOWN_GROUP[PRICE].defaultValue;
16
16
 
17
17
  declare global {
18
+ // tslint:disable-next-line:interface-name
18
19
  interface Window {
19
20
  grantHotjarCookieConsent?: () => void;
20
21
  grantCookieConsent?: (list: string[]) => void;
package/tsconfig.json CHANGED
@@ -58,6 +58,8 @@
58
58
  },
59
59
  "exclude": [
60
60
  "node_modules",
61
- "static"
61
+ "static",
62
+ "__tests__",
63
+ "**/*.js"
62
64
  ]
63
65
  }
package/tslint.json CHANGED
@@ -20,7 +20,6 @@
20
20
  "no-console": [true, "warn", "error"],
21
21
  "switch-default": true,
22
22
  "no-empty-interface": true,
23
- // "no-magic-numbers": [true, 0, -1, 1, 2, 10, 8, 16],
24
23
  "no-parameter-reassignment": true,
25
24
  "no-duplicate-switch-case": true,
26
25
  "no-duplicate-imports": true,