@bytebrand/fe-ui-core 4.8.111 → 4.8.112

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.
Files changed (198) hide show
  1. package/.husky/pre-push +4 -0
  2. package/.storybook/addons.js +4 -0
  3. package/.storybook/config.js +64 -0
  4. package/.storybook/postcss.config.js +6 -0
  5. package/.storybook/preview-head.html +10 -0
  6. package/.storybook/webpack.config.js +130 -0
  7. package/__tests__/components/Checkout/OrderOverviewItem/OrderOverviewItem.test.tsx +42 -0
  8. package/__tests__/components/Checkout/PaymentTypeCard/PaymentTypeCard.test.tsx +50 -0
  9. package/__tests__/components/Checkout/RadioGroup.test.tsx +95 -0
  10. package/__tests__/components/Checkout/ServiceCardWrapper.test.tsx +53 -0
  11. package/__tests__/components/Checkout/Switcher.test.tsx +43 -0
  12. package/__tests__/components/UserDasboardPage/sections/CheckoutSection/CheckoutSection.test.tsx +613 -0
  13. package/__tests__/components/UserDasboardPage/sections/FavoriteSection/FavoriteSection.test.tsx +335 -0
  14. package/__tests__/components/UserDasboardPage/sections/OrderStatusSection/AdditionalOrderInfo.test.tsx +127 -0
  15. package/__tests__/components/UserDasboardPage/sections/OrderStatusSection/OrderStatusCar.test.tsx +58 -0
  16. package/__tests__/components/UserDasboardPage/sections/OrderStatusSection/OrderStatusCard.test.tsx +74 -0
  17. package/__tests__/components/UserDasboardPage/sections/OrderStatusSection/OrderStatusSection.test.tsx +62 -0
  18. package/__tests__/components/UserDasboardPage/sections/RequestedCarsSection/RequestedCarsSection.test.tsx +117 -0
  19. package/__tests__/components/Vehicle/VehicleFormattedPrice/VehicleFormattedPrice.test.tsx +58 -0
  20. package/__tests__/components/VehicleSmallCard/VehicleInfo.test.tsx +88 -0
  21. package/__tests__/components/VehicleSmallCard/VehicleTitle.test.tsx +91 -0
  22. package/__tests__/components/_common/Badge/Badge.test.tsx +15 -0
  23. package/__tests__/components/_common/IconSVG/IconSVG.test.tsx +23 -0
  24. package/__tests__/components/_common/Image/Image.test.tsx +82 -0
  25. package/__tests__/components/_common/MaterialAutocomplete/MaterialAutocomplete.test.tsx +49 -0
  26. package/__tests__/components/_common/MaterialDatePicker/MaterialDatePicker.test.tsx +54 -0
  27. package/__tests__/components/_common/MaterialField/MaterialField.test.tsx +58 -0
  28. package/__tests__/components/_common/StarButton/StarButton.test.tsx +46 -0
  29. package/__tests__/mockedData/financingConfig.js +202 -0
  30. package/__tests__/mockedData/mockedPendingRequestedCar.js +69 -0
  31. package/__tests__/utils/CommonUtils/addPrefixToKeys.test.ts +18 -0
  32. package/__tests__/utils/CommonUtils/arrToObj.test.js +32 -0
  33. package/__tests__/utils/CommonUtils/checkRangeValuesOnEqual.test.ts +17 -0
  34. package/__tests__/utils/CommonUtils/fixNumber.test.ts +20 -0
  35. package/__tests__/utils/CommonUtils/formatMileage.test.ts +8 -0
  36. package/__tests__/utils/CommonUtils/getChipFilterValue.test.ts +22 -0
  37. package/__tests__/utils/CommonUtils/getFormattedNumber.test.ts +19 -0
  38. package/__tests__/utils/CommonUtils/getFormattedPrice.test.ts +19 -0
  39. package/__tests__/utils/CommonUtils/getGroupValuesForQuery.test.ts +51 -0
  40. package/__tests__/utils/CommonUtils/getOfferSliders.test.ts +64 -0
  41. package/__tests__/utils/CommonUtils/getPriceRating.test.ts +26 -0
  42. package/__tests__/utils/CommonUtils/getPriceRatingConfig.test.ts +33 -0
  43. package/__tests__/utils/CommonUtils/preloadNearbyImages.test.ts +9 -0
  44. package/__tests__/utils/CommonUtils/sliceLessThan.test.ts +23 -0
  45. package/__tests__/utils/CommonUtils/sliceMoreThan.test.ts +23 -0
  46. package/media/locales/de/promoSlider.json +1 -0
  47. package/media/locales/en/promoSlider.json +1 -0
  48. package/package.json +118 -120
  49. package/source/components/AccordionWidget/AccordionWidget.styl +13 -1
  50. package/source/components/AccordionWidget/AccordionWidget.tsx +49 -8
  51. package/source/components/AdvantageItem/AdvantageItem.story.js +23 -0
  52. package/source/components/Alternative/Dealer.story.js +32 -0
  53. package/source/components/Alternative/Dealer.story.styl +3 -0
  54. package/source/components/Breadcrumbs/Breadcrumbs.story.js +40 -0
  55. package/source/components/Breadcrumbs/FirstInfoBlock/FirstInfoBlock.story.js +45 -0
  56. package/source/components/Checkout/OrderOverviewItem/OrderOverviewItem.story.js +243 -0
  57. package/source/components/Checkout/OrderOverviewItem/OrderOverviewItem.story.styl +21 -0
  58. package/source/components/Checkout/RadioCards/RadioGroupCheckout.story.js +105 -0
  59. package/source/components/Checkout/RadioCards/RadioGroupCheckout.story.styl +37 -0
  60. package/source/components/Checkout/Switcher/Switcher.story.js +41 -0
  61. package/source/components/Checkout/Switcher/Switcher.story.styl +2 -0
  62. package/source/components/CompactSearchWidget/CompactSearchWidget.story.js +187 -0
  63. package/source/components/ContactForm/ContactForm.story.js +94 -0
  64. package/source/components/ContactForm/ContactForm.story.styl +0 -0
  65. package/source/components/ContactInfo/ContactInfo.story.js +58 -0
  66. package/source/components/CustomerQuote/CustomerQuote.story.js +41 -0
  67. package/source/components/CustomerQuotesSlider/CustomerQuotesSlider.story.js +73 -0
  68. package/source/components/CustomerQuotesSlider/CustomerQuotesSlider.story.styl +5 -0
  69. package/source/components/FormattedNumber/FormattedNumber.story.js +114 -0
  70. package/source/components/InfoBlocks/InfoBlockWrapper.story.js +101 -0
  71. package/source/components/InfoBlocks/InfoBlockWrapper.story.styl +46 -0
  72. package/source/components/OfferPanel/AboAccordion/AboFaq/AboFaq.story.js +97 -0
  73. package/source/components/OfferPanel/OfferCheckboxGroup/CheckboxContainer.tsx +2 -2
  74. package/source/components/OfferPanel/OfferCheckboxGroup/OfferCheckboxGroup.styl +24 -0
  75. package/source/components/OfferPanel/OfferCheckboxGroup/OfferCheckboxGroup.tsx +1 -2
  76. package/source/components/OfferPanel/OfferPanel.story.js +139 -0
  77. package/source/components/OfferPanel/OfferPanel.tsx +1 -1
  78. package/source/components/OfferPanel/RangeGroup/RangeGroup.story.js +35 -0
  79. package/source/components/OfferPanel/RangeGroup/RangeGroup.story.styl +3 -0
  80. package/source/components/PriceRating/PriceRating.story.js +39 -0
  81. package/source/components/PriceRating/PriceRating.story.styl +2 -0
  82. package/source/components/PriceRatingDetailed/PriceRatingDetailed.story.js +78 -0
  83. package/source/components/PriceRatingDetailed/PriceRatingDetailed.story.styl +11 -0
  84. package/source/components/RateSearchValue/RateSearchValue.story.js +78 -0
  85. package/source/components/RateSearchValue/RateSearchValue.story.styl +2 -0
  86. package/source/components/RateSearchWidget/RateSearchWidget.story.js +57 -0
  87. package/source/components/RateSearchWidget/RateSearchWidget.story.styl +12 -0
  88. package/source/components/SearchFilters/FiltersFactory.story.js +273 -0
  89. package/source/components/SearchPage/Filters/MakeModel/MakeModel.story.js +12 -0
  90. package/source/components/SearchWidget/BasicDataWidget/BasicDataWidget.story.js +834 -0
  91. package/source/components/SearchWidget/BasicDataWidget/BasicDataWidget.story.styl +40 -0
  92. package/source/components/SearchWidget/SearchWidget.story.js +191 -0
  93. package/source/components/SearchWidget/SearchWidget.story.styl +6 -0
  94. package/source/components/Stepper/Stepper.story.js +119 -0
  95. package/source/components/Stepper/Stepper.story.styl +41 -0
  96. package/source/components/Theme.story.js +36 -0
  97. package/source/components/Theme.story.styl +85 -0
  98. package/source/components/TickerText/TickerText.story.js +17 -0
  99. package/source/components/UserDashboardPage/sections/OrderStatusSection/OrderStatusSection.story.js +95 -0
  100. package/source/components/UserDashboardPage/sections/RequestedCarsSection/RequestedCarsSection.story.js +97 -0
  101. package/source/components/Vehicle/VehicleConsumption/VehicleConsumption.story.js +31 -0
  102. package/source/components/Vehicle/VehicleFormattedPrice/VehicleFormattedPrice.story.js +247 -0
  103. package/source/components/VehicleCompared/CompareGeneral/CompareGeneral.story.js +30 -0
  104. package/source/components/VehicleCompared/ComparePrice/ComparePrice.story.js +18 -0
  105. package/source/components/VehicleCompared/CompareTitle/CompareTitle.story.js +19 -0
  106. package/source/components/VehicleDetailedSidebar/VehicleDetailedSidebar.story.js +44 -0
  107. package/source/components/VehicleDetailedSidebar/VehicleDetailedSidebar.tsx +23 -11
  108. package/source/components/VehicleDetailedSidebar/partials/Properties.styl +5 -0
  109. package/source/components/VehicleDetailedSidebar/partials/Properties.tsx +56 -18
  110. package/source/components/VehicleDetailedSlider/VehicleDetailedSlider.story.js +120 -0
  111. package/source/components/VehicleDetailedSlider/VehicleDetailedSlider.tsx +2 -6
  112. package/source/components/VehiclePromoSlider/VehiclePromoInfo/VehiclePromoInfo.story.js +42 -0
  113. package/source/components/VehiclePromoSlider/VehiclePromoSlide/VehiclePromoSlide.story.js +62 -0
  114. package/source/components/VehiclePromoSlider/VehiclePromoSlider.story.js +42 -0
  115. package/source/components/VehicleSmallCard/VehicleData/VechiclePriceItem/VechiclePriceItem.styl +42 -0
  116. package/source/components/VehicleSmallCard/VehicleData/VechiclePriceItem/VechiclePriceItem.tsx +23 -11
  117. package/source/components/VehicleSmallCard/VehicleData/VehicleInfo/VehicleInfo.styl +60 -5
  118. package/source/components/VehicleSmallCard/VehicleData/VehicleInfo/VehicleInfo.tsx +36 -12
  119. package/source/components/VehicleSmallCard/VehicleData/VehiclePrice/VehiclePrice.styl +3 -2
  120. package/source/components/VehicleSmallCard/VehicleData/VehiclePrice/VehiclePrice.tsx +18 -7
  121. package/source/components/VehicleSmallCard/VehicleData/VehicleProperty/VehicleProperty.styl +4 -1
  122. package/source/components/VehicleSmallCard/VehicleData/VehicleProperty/VehicleProperty.tsx +3 -2
  123. package/source/components/VehicleSmallCard/VehicleData/VehicleTitle/VehicleTitle.tsx +1 -1
  124. package/source/components/VehicleSmallCard/VehicleSmallCard.story.js +412 -0
  125. package/source/components/VehicleSmallCard/VehicleSmallCard.story.styl +56 -0
  126. package/source/components/VehicleSmallCard/VehicleSmallCard.styl +67 -2
  127. package/source/components/VehicleSmallCard/VehicleSmallCard.tsx +49 -3
  128. package/source/components/VehicleSmallCardForDealerships/VehicleSmallCardForDealerships.story.js +199 -0
  129. package/source/components/VehicleSmallCardForDealerships/VehicleSmallCardForDealerships.story.styl +40 -0
  130. package/source/components/_common/Accordion/Accordion.story.js +36 -0
  131. package/source/components/_common/Badge/Badge.story.js +27 -0
  132. package/source/components/_common/Badge/Badge.story.styl +5 -0
  133. package/source/components/_common/Bubble/Bubble.story.js +52 -0
  134. package/source/components/_common/Button/Button.story.js +52 -0
  135. package/source/components/_common/Button/Button.story.styl +5 -0
  136. package/source/components/_common/ButtonOld/Button.story.js +54 -0
  137. package/source/components/_common/ButtonOld/Button.story.styl +5 -0
  138. package/source/components/_common/Checkbox/Checkbox.story.js +85 -0
  139. package/source/components/_common/Checkbox/Checkbox.story.styl +14 -0
  140. package/source/components/_common/CheckboxMaterial/CheckboxMaterial.story.js +126 -0
  141. package/source/components/_common/CheckboxMaterial/CheckboxMaterial.story.styl +14 -0
  142. package/source/components/_common/Chip/Chip.story.js +43 -0
  143. package/source/components/_common/ChipList/ChipList.story.js +36 -0
  144. package/source/components/_common/DropDown/DropDown.story.js +35 -0
  145. package/source/components/_common/ExpandablePanel/ExpandablePanel.story.js +41 -0
  146. package/source/components/_common/Histogram/Histogram.story.js +51 -0
  147. package/source/components/_common/IconSVG/IconSVG.story.js +21 -0
  148. package/source/components/_common/IconSVG/IconSVG.story.styl +25 -0
  149. package/source/components/_common/Image/Image.story.js +142 -0
  150. package/source/components/_common/Image/Image.story.styl +18 -0
  151. package/source/components/_common/ImagesSet/ImagesSet.story.js +34 -0
  152. package/source/components/_common/ImagesSet/ImagesSet.story.styl +4 -0
  153. package/source/components/_common/Loader/Loader.story.js +21 -0
  154. package/source/components/_common/MaterialAccordionGroup/MaterialAccordionGroup.story.js +49 -0
  155. package/source/components/_common/MaterialAccordionGroup/MaterialAccordionGroup.styled.tsx +4 -1
  156. package/source/components/_common/MaterialDatePicker/MaterialDatePicker.story.js +45 -0
  157. package/source/components/_common/MaterialDatePicker/MaterialDatePicker.story.styl +6 -0
  158. package/source/components/_common/MaterialField/MaterialField.story.js +87 -0
  159. package/source/components/_common/MaterialField/MaterialField.story.styl +34 -0
  160. package/source/components/_common/MaterialSelect/MaterialSelect.story.js +52 -0
  161. package/source/components/_common/MaterialSelect/MaterialSelect.story.styl +6 -0
  162. package/source/components/_common/MaterialStepButton/MaterialStepButton.story.js +47 -0
  163. package/source/components/_common/MaterialStepButton/MaterialStepButton.story.styl +6 -0
  164. package/source/components/_common/MaterialSwitch/MaterialSwitch.story.js +17 -0
  165. package/source/components/_common/MaterialTooltip/MaterialTooltip.story.js +10 -0
  166. package/source/components/_common/MaterialTooltip/MaterialTooltip.tsx +4 -3
  167. package/source/components/_common/Modal/Modal.story.js +37 -0
  168. package/source/components/_common/MuiGroupedSelect/MuiGroupedSelect.story.js +21 -0
  169. package/source/components/_common/PropertySelector/PSGroup.story.js +93 -0
  170. package/source/components/_common/PropertySelector/PSGroup.story.styl +25 -0
  171. package/source/components/_common/PropertySelector/ProperySelector.story.js +83 -0
  172. package/source/components/_common/Radio/FormRadioGroup.story.js +28 -0
  173. package/source/components/_common/Radio/FormRadioGroup.story.styl +2 -0
  174. package/source/components/_common/Radio/Radio.story.js +54 -0
  175. package/source/components/_common/Radio/RadioGroup.story.js +90 -0
  176. package/source/components/_common/Radio/RadioGroup.story.styl +39 -0
  177. package/source/components/_common/Range/Range.story.js +46 -0
  178. package/source/components/_common/Range/Range.story.styl +5 -0
  179. package/source/components/_common/SliderArrow/SliderArrow.story.js +18 -0
  180. package/source/components/_common/Tabs/Tabs.story.js +56 -0
  181. package/source/components/_common/TimePicker/TimePicker.story.js +37 -0
  182. package/source/components/_common/Tooltip/Tooltip.story.js +28 -0
  183. package/source/components/_common/UserMenu/MaterialMenu.story.js +73 -0
  184. package/source/components/_common/VehicleSlider/VehicleSlider.story.js +99 -0
  185. package/source/components/_common/VehicleSlider/VehicleSlider.story.styl +0 -0
  186. package/source/components/_common/withLabel/withLabel.story.js +62 -0
  187. package/source/components/_common/withPopover/withPopover.story.js +48 -0
  188. package/source/components/_common/withPopover/withPopover.story.styl +54 -0
  189. package/source/components/_common/withStats/withStats.story.js +75 -0
  190. package/source/components/_common/withStats/withStats.styl +10 -0
  191. package/source/framework/DataTransformers.ts +2 -0
  192. package/source/framework/constants/common.ts +8 -4
  193. package/source/framework/types/types.ts +1 -0
  194. package/source/framework/vehiclesProps/decoratedLightProps.tsx +109 -18
  195. package/source/framework/vehiclesProps/decoratedProps.tsx +68 -9
  196. package/source/framework/vehiclesProps/vehicleDetails.ts +3 -1
  197. package/source/locales/data.ts +13 -3
  198. package/bytebrand-fe-ui-core-4.8.110.tgz +0 -0
@@ -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,31 @@
1
+ import React from 'react';
2
+ import { storiesOf } from '@storybook/react';
3
+
4
+ import VehicleConsumption from './VehicleConsumption';
5
+
6
+ // Stateful container for testing interaction
7
+ class VehicleConsumptionContainer extends React.Component {
8
+ render() {
9
+ const props = {
10
+ t: key => key,
11
+ consumption: {
12
+ consumptionCombined: 5.6
13
+ },
14
+ environmentEmissions: {
15
+ co2: 127
16
+ }
17
+ };
18
+
19
+ return (
20
+ <div>
21
+ <VehicleConsumption {...props} />
22
+ </div>
23
+ );
24
+ }
25
+ }
26
+
27
+ storiesOf('VehicleConsumption', module).add('Default', () => (
28
+ <div>
29
+ <VehicleConsumptionContainer />
30
+ </div>
31
+ ));
@@ -0,0 +1,247 @@
1
+ import React from 'react';
2
+ import { storiesOf } from '@storybook/react';
3
+
4
+ import VehicleFormattedPrice from './VehicleFormattedPrice';
5
+
6
+ const container = {
7
+ width: 400,
8
+ };
9
+
10
+ const item = {
11
+ display: 'flex',
12
+ justifyContent: 'space-between',
13
+ alignItems: 'center'
14
+ };
15
+
16
+ const storiesDefault = [
17
+ {
18
+ title: 'simple case',
19
+ props: {
20
+ price: 176,
21
+ isOld: true
22
+ }
23
+ },
24
+ {
25
+ title: 'falsie value',
26
+ props: {
27
+ price: 0,
28
+ isOld: true,
29
+ toRound: false
30
+ }
31
+ },
32
+ {
33
+ title: 'large number',
34
+ props: {
35
+ price: 6500000,
36
+ isOld: true
37
+ }
38
+ },
39
+ {
40
+ title: 'not rounded',
41
+ props: {
42
+ price: 19689.23,
43
+ toRound: false
44
+ }
45
+ },
46
+ {
47
+ title: 'type "new"',
48
+ props: {
49
+ price: 19689.23,
50
+ isNew: true
51
+ }
52
+ },
53
+ {
54
+ title: 'type "old"',
55
+ props: {
56
+ price: 19689.23,
57
+ isOld: true
58
+ }
59
+ }
60
+ // {
61
+ // title: 'short',
62
+ // props: {
63
+ // price: 42
64
+ // }
65
+ // },
66
+ // {
67
+ // title: 'short grouped',
68
+ // props: {
69
+ // price: 42069
70
+ // }
71
+ // },
72
+ // {
73
+ // title: 'long',
74
+ // props: {
75
+ // price: 69000000,
76
+ // unit: '₴'
77
+ // }
78
+ // },
79
+ // {
80
+ // title: 'very long',
81
+ // props: {
82
+ // price: 419999999999999
83
+ // }
84
+ // },
85
+ // {
86
+ // title: 'postfixed',
87
+ // props: {
88
+ // price: 12345,
89
+ // postfix: 1
90
+ // }
91
+ // }
92
+ ];
93
+
94
+ const storiesLarge= [
95
+ {
96
+ title: 'simple case',
97
+ props: {
98
+ price: 176,
99
+ size: 'large'
100
+ }
101
+ },
102
+ {
103
+ title: 'large number',
104
+ props: {
105
+ price: 6500000,
106
+ size: 'large'
107
+ }
108
+ },
109
+ {
110
+ title: 'not rounded',
111
+ props: {
112
+ price: 19689.23,
113
+ toRound: false,
114
+ size: 'large'
115
+ }
116
+ },
117
+ {
118
+ title: 'type "new"',
119
+ props: {
120
+ price: 19689.23,
121
+ isNew: true,
122
+ size: 'large'
123
+ }
124
+ },
125
+ {
126
+ title: 'type "old"',
127
+ props: {
128
+ price: 19689.23,
129
+ isOld: true,
130
+ size: 'large'
131
+ }
132
+ }
133
+ ];
134
+
135
+ const storiesSmall= [
136
+ {
137
+ title: 'simple case',
138
+ props: {
139
+ price: 176,
140
+ size: 'small'
141
+ }
142
+ },
143
+ {
144
+ title: 'large number',
145
+ props: {
146
+ price: 6500000,
147
+ size: 'small'
148
+ }
149
+ },
150
+ {
151
+ title: 'not rounded',
152
+ props: {
153
+ price: 19689.23,
154
+ toRound: false,
155
+ size: 'small'
156
+ }
157
+ },
158
+ {
159
+ title: 'type "new"',
160
+ props: {
161
+ price: 19689.23,
162
+ isNew: true,
163
+ size: 'small'
164
+ }
165
+ },
166
+ {
167
+ title: 'type "old"',
168
+ props: {
169
+ price: 19689.23,
170
+ isOld: true,
171
+ size: 'small'
172
+ }
173
+ }
174
+ ];
175
+
176
+ const otherCases = [
177
+ {
178
+ title: 'old',
179
+ props: {
180
+ price: 19689.23,
181
+ disableStyles: true,
182
+ toRound: false,
183
+ isOld: true
184
+ }
185
+ },
186
+ {
187
+ title: 'disable unit and not rounded',
188
+ props: {
189
+ price: 19689.23,
190
+ unit: '',
191
+ disableStyles: true,
192
+ toRound: false
193
+ }
194
+ },
195
+ {
196
+ title: 'disable formatting',
197
+ props: {
198
+ price: 19689.23,
199
+ unit: '',
200
+ disableStyles: true,
201
+ toRound: false,
202
+ disableFormatting: true
203
+ }
204
+ }
205
+ ];
206
+
207
+ storiesOf('FormattedPrice', module)
208
+ .add('default', () => (
209
+ <div style={container}>
210
+ {storiesDefault.map(({ title, props }, index) => (
211
+ <div style={item} key={index}>
212
+ <p>{title} ({props.price})</p>
213
+ <VehicleFormattedPrice {...props} />
214
+ </div>
215
+ ))}
216
+ </div>
217
+ ))
218
+ .add('large', () => (
219
+ <div style={container}>
220
+ {storiesLarge.map(({ title, props }, index) => (
221
+ <div style={item} key={index}>
222
+ <p>{title} ({props.price})</p>
223
+ <VehicleFormattedPrice {...props} />
224
+ </div>
225
+ ))}
226
+ </div>
227
+ ))
228
+ .add('small', () => (
229
+ <div style={container}>
230
+ {storiesSmall.map(({ title, props }, index) => (
231
+ <div style={item} key={index}>
232
+ <p>{title} ({props.price})</p>
233
+ <VehicleFormattedPrice {...props} />
234
+ </div>
235
+ ))}
236
+ </div>
237
+ ))
238
+ .add('other cases (without styles)', () => (
239
+ <div style={container}>
240
+ {otherCases.map(({ title, props }, index) => (
241
+ <div style={item} key={index}>
242
+ <p>{title} ({props.price})</p>
243
+ <VehicleFormattedPrice {...props} />
244
+ </div>
245
+ ))}
246
+ </div>
247
+ ));
@@ -0,0 +1,30 @@
1
+ import React from 'react';
2
+ import { storiesOf } from '@storybook/react';
3
+ import { action } from '@storybook/addon-actions';
4
+
5
+ import CompareGeneral from './CompareGeneral.tsx';
6
+
7
+ const props = {
8
+ imageURL: 'http://87.118.82.201/carimage/c8374aa8-8266-4b40-81ca-f5fb0c71f993/swiJg18-76KK/small',
9
+ title: {
10
+ manufacturer: 'bmw',
11
+ model: '320',
12
+ subModel: 'Sport V6 HSE',
13
+ powerKW: 120,
14
+ powerPS: 100
15
+ },
16
+ price: {
17
+ currentPrice: 29000,
18
+ perMonthPrice: 1000,
19
+ currency: '€',
20
+ months: 20
21
+ },
22
+ onDeleteClick: action('click')
23
+ };
24
+
25
+ storiesOf('Compared vehicle', module)
26
+ .add('Compare general', () => (
27
+ <div style={{ width: 300 }}>
28
+ <CompareGeneral {...props} />
29
+ </div>
30
+ ));
@@ -0,0 +1,18 @@
1
+ import React from 'react';
2
+
3
+ import { storiesOf } from '@storybook/react';
4
+ import ComparePrice from './ComparePrice.tsx';
5
+
6
+ const props = {
7
+ currentPrice: 29000,
8
+ perMonthPrice: 1000,
9
+ currency: '€',
10
+ months: 29
11
+ };
12
+
13
+ storiesOf('Compared vehicle', module)
14
+ .add('Compare price', () => (
15
+ <div style={{ background: 'lightgray', width: 300 }}>
16
+ <ComparePrice {...props} />
17
+ </div>
18
+ ));
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+
3
+ import { storiesOf } from '@storybook/react';
4
+ import CompareTitle from './CompareTitle.tsx';
5
+
6
+ const props = {
7
+ manufacturer: 'bmw',
8
+ model: '320',
9
+ subModel: 'Sport V6 HSE',
10
+ powerKW: 120,
11
+ powerPS: 100
12
+ };
13
+
14
+ storiesOf('Compared vehicle', module)
15
+ .add('Compare title', () => (
16
+ <div style={{ background: 'lightgray', width: 300 }}>
17
+ <CompareTitle {...props} />
18
+ </div>
19
+ ));
@@ -0,0 +1,44 @@
1
+ import React from 'react';
2
+ import { Resizable } from 're-resizable';
3
+ import { storiesOf } from '@storybook/react';
4
+ import { action } from '@storybook/addon-actions';
5
+ import VehicleDetailedSidebar from './VehicleDetailedSidebar.tsx';
6
+
7
+
8
+ const wrapperProps = {
9
+ border: '1px solid rgba(0,0,0,0.1)',
10
+ borderRadius: '2px',
11
+ backgroundColor: '#fff'
12
+ };
13
+
14
+ const resizableProps = {
15
+ minWidth: 595,
16
+ defaultSize: { width: 724, height: 'auto' }
17
+ };
18
+
19
+ const VehicleDetailedSidebarStory = () => {
20
+ const sidebarProps = {
21
+ title: {
22
+ make: 'BMW',
23
+ model: '218',
24
+ subModel: '218i Advantage',
25
+ powerKW: 100,
26
+ powerPS: 136,
27
+ isCarInFavorite: true,
28
+ onCarFavorite: action('onCarFavorite(event, id)')
29
+ }
30
+ };
31
+
32
+ return (
33
+ <>
34
+ <p>Sidebar on CDP</p>
35
+ <div style={wrapperProps}>
36
+ <Resizable {...resizableProps}>
37
+ <VehicleDetailedSidebar {...sidebarProps} />
38
+ </Resizable>
39
+ </div>
40
+ </>
41
+ );
42
+ };
43
+
44
+ storiesOf('VehicleDetailedSidebar', module).add('VehicleDetailedSidebar', () => <VehicleDetailedSidebarStory />);
@@ -1,4 +1,4 @@
1
- import React, { useState, useEffect, FunctionComponent } from 'react';
1
+ import React, { useState, useEffect, useRef, FunctionComponent } from 'react';
2
2
  import _get from 'lodash/get';
3
3
  import { Hidden } from 'react-grid-system';
4
4
  import PriceContent from './partials/PriceContent';
@@ -104,19 +104,31 @@ const VehicleDetailedSidebar: FunctionComponent<IVehicleDetailedSidebarProps> =
104
104
  }
105
105
  ];
106
106
 
107
+ const initialDefaultAppliedForPath = useRef<string | null>(null);
108
+
107
109
  useEffect(() => {
108
110
  const getlocalStorageActiveTabCDP = localStorage.getItem('activeTabCDP');
109
- if (!getlocalStorageActiveTabCDP) return;
110
- const activeTab = tabsTitles.findIndex(({ title }: { title: string }) => {
111
- return title === getlocalStorageActiveTabCDP;
112
- });
113
- if (activeTab === -1) {
114
- setActiveTab(null, 0);
115
- } else {
116
- setActiveTab(null, activeTab);
111
+ if (getlocalStorageActiveTabCDP) {
112
+ const activeTab = tabsTitles.findIndex(({ title }: { title: string }) => {
113
+ return title === getlocalStorageActiveTabCDP;
114
+ });
115
+ if (activeTab === -1) {
116
+ setActiveTab(null, 0);
117
+ } else {
118
+ setActiveTab(null, activeTab);
119
+ }
120
+ localStorage.removeItem('activeTabCDP');
121
+ initialDefaultAppliedForPath.current = pathname;
122
+ return;
123
+ }
124
+ if (
125
+ initialDefaultAppliedForPath.current !== pathname
126
+ && _get(price, 'leasing.isActive', false)
127
+ ) {
128
+ setActiveTab(null, 1);
129
+ initialDefaultAppliedForPath.current = pathname;
117
130
  }
118
- localStorage.removeItem('activeTabCDP');
119
- }, [pathname, activeTab]); // tslint:disable-line:align
131
+ }, [pathname, activeTab, price]); // tslint:disable-line:align
120
132
 
121
133
  const priceProps = {
122
134
  tabsTitles,
@@ -15,6 +15,11 @@
15
15
  &:nth-child(2)
16
16
  border-top-color: transparent;
17
17
 
18
+ // ADV-70: full-width consumption/CO2 row in the sidebar Overview tab.
19
+ .propertyFull
20
+ flex-basis: 100%
21
+ width: 100%
22
+
18
23
  .details
19
24
  display: flex
20
25
  flex-direction: row
@@ -1,4 +1,5 @@
1
1
  import React, { useState } from 'react';
2
+ import classNames from 'classnames';
2
3
  import _get from 'lodash/get';
3
4
  import { IPropertiesProps, ICarPropElement } from '../../../framework/types/types';
4
5
  import { getActualHighlights } from '../../../framework/constants/highlights';
@@ -40,18 +41,19 @@ const Properties: React.FunctionComponent<IPropertiesProps> = ({ t, car, decorat
40
41
  : <div className={styles.empty}>{t(`sidebar.empty`)}</div>;
41
42
  };
42
43
 
43
- const renderDetails = (): React.ReactNode => {
44
- const sectionNames = [
45
- t(`sidebar.dataEngine`),
46
- t(`sidebar.dimensions`),
47
- t(`sidebar.generalData`),
48
- t(`sidebar.equipments`)
49
- ];
50
- const detailPropertiesList = ['cubicCapacity', 'torque', 'length', 'width', 'doors', 'fuel'];
51
- const detailProperties = detailPropertiesList.map(
52
- (prop: string) => (`${decoratedProps[prop].title}: ${decoratedProps[prop].value}`)
53
- );
44
+ // ADV-70: hide a spec line whose value is "N/A", a zero ("0 mm", "0 kWh", "0 g CO2/km", ...),
45
+ // null or empty — mirrors AccordionWidget.isHiddenSpecValue. de-DE thousands "." / decimal ","
46
+ // are normalised so only a true zero magnitude hides; codes like HSN "0588" stay visible.
47
+ const isHiddenSpecValue = (value: any): boolean => {
48
+ if (value === null || value === undefined) return true;
49
+ if (typeof value !== 'string') return false; // JSX / non-string content → always keep
50
+ const trimmed = value.trim();
51
+ if (trimmed === '' || trimmed === t('vehicleProps:value.na')) return true;
52
+ const numeric = parseFloat(trimmed.replace(/\./g, '').replace(',', '.'));
53
+ return numeric === 0;
54
+ };
54
55
 
56
+ const renderDetails = (): React.ReactNode => {
55
57
  const equipmentsObj = {
56
58
  ...addPrefixToKeys(car.lights, 'lights'),
57
59
  ...addPrefixToKeys(car.multimedia, 'multimedia'),
@@ -63,14 +65,41 @@ const Properties: React.FunctionComponent<IPropertiesProps> = ({ t, car, decorat
63
65
  .slice(0, 2)
64
66
  .map(prop => t(`cbd:${prop}`));
65
67
 
66
- detailProperties.push(equipmentsArr.join(', '));
68
+ // ADV-70: build each section's visible lines, dropping N/A/0 values. A section that loses
69
+ // all its lines (e.g. "Maße & Abmessungen" when length+width are both N/A) is removed and
70
+ // the next section flows up so there is no gap in the 2-column grid.
71
+ const sectionsConfig: Array<{ title: string; props?: string[]; lines?: string[] }> = [
72
+ { title: t(`sidebar.dataEngine`), props: ['cubicCapacity', 'torque'] },
73
+ { title: t(`sidebar.dimensions`), props: ['length', 'width'] },
74
+ { title: t(`sidebar.generalData`), props: ['doors', 'fuel'] },
75
+ { title: t(`sidebar.equipments`), lines: equipmentsArr.length ? [equipmentsArr.join(', ')] : [] }
76
+ ];
77
+
78
+ const visibleSections = sectionsConfig
79
+ .map(({ title, props, lines }) => ({
80
+ title,
81
+ lines: props
82
+ ? props
83
+ .filter(prop => decoratedProps[prop] && !isHiddenSpecValue(decoratedProps[prop].value))
84
+ .map(prop => `${decoratedProps[prop].title}: ${decoratedProps[prop].value}`)
85
+ : (lines || [])
86
+ }))
87
+ .filter(section => section.lines.length > 0);
88
+
89
+ if (!visibleSections.length) return null;
90
+
91
+ // Class by VISIBLE position, not original index: the first two sections form the top row
92
+ // (detailsItemFirstLine — padding-top 7px), the rest the bottom row (detailsItemLastLine —
93
+ // padding-top 20px). So a section promoted into the top row drops its 20px top padding,
94
+ // while a section that stays in the bottom row keeps it.
67
95
  return (
68
96
  <div className={styles.details}>
69
- {sectionNames.map((title, i) => (
97
+ {visibleSections.map(({ title, lines }, i) => (
70
98
  <div key={i} className={i > 1 ? styles.detailsItemLastLine : styles.detailsItemFirstLine}>
71
99
  <h4 className={styles.detailsTitle}>{title}</h4>
72
- <span className={styles.detailsContent}>{detailProperties[0 + i * 2]}</span>
73
- <span className={styles.detailsContent}>{detailProperties[1 + i * 2]}</span>
100
+ {lines.map((line, j) => (
101
+ <span key={j} className={styles.detailsContent}>{line}</span>
102
+ ))}
74
103
  </div>
75
104
  ))}
76
105
  </div>
@@ -78,15 +107,24 @@ const Properties: React.FunctionComponent<IPropertiesProps> = ({ t, car, decorat
78
107
  };
79
108
 
80
109
  const mainPropertiesList = getOverviewDetails(car.consumption.fuel);
81
- const mainProperties = mainPropertiesList.map((prop: string) => ({ icon: decoratedProps[prop].icon, description: decoratedProps[prop].value }));
110
+ // ADV-70: the consumption/CO2 line is long let it span the full sidebar width on its own
111
+ // row (and drop the fuel icon) instead of being squeezed into one 50% column.
112
+ const mainProperties = mainPropertiesList.map((prop: string) => {
113
+ const isConsumptionAlternateView = prop.startsWith('consumption') && prop.endsWith('AlternateView');
114
+ return {
115
+ icon: isConsumptionAlternateView ? '' : decoratedProps[prop].icon,
116
+ description: decoratedProps[prop].value,
117
+ fullWidth: isConsumptionAlternateView
118
+ };
119
+ });
82
120
 
83
121
  const tabsTitles = [
84
122
  {
85
123
  title: `${t(`sidebar.overview`)}`,
86
124
  children: (
87
125
  <div className={`${styles.tabContentPadding} ${styles.tabContentOverviewPadding}`}>
88
- {mainProperties.map((property: any, index: number) => (
89
- <VehicleProperty {...property} className={styles.property} key={index} />
126
+ {mainProperties.map(({ fullWidth, ...property }: any, index: number) => (
127
+ <VehicleProperty {...property} className={classNames(styles.property, fullWidth ? styles.propertyFull : '')} key={index} />
90
128
  ))}
91
129
  </div>
92
130
  )