@bytebrand/fe-ui-core-autobahn 1.0.10 → 1.0.12

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.
@@ -422,6 +422,12 @@ const PpRow: React.FunctionComponent<PpRowProps> = ({ label, value, unit, old, f
422
422
  */
423
423
  export const PricePaths: React.FunctionComponent<PricePathsProps> = ({ car, t }) => {
424
424
  const hasLease = car.lease != null;
425
+ // Terms of the config the displayed rate was actually computed with (per-car:
426
+ // dealer rate + the user's saved localStorage adjustments) — default config
427
+ // terms only when the car doesn't carry its own.
428
+ const finFirstInstallment =
429
+ car.finFirstInstallment != null ? car.finFirstInstallment.toLocaleString('de-DE') : _finFirstInstallment;
430
+ const finMonths = car.finMonths ?? _finMonths;
425
431
  return (
426
432
  <div className="pricepaths">
427
433
  <div className="pp-hero">
@@ -432,9 +438,9 @@ export const PricePaths: React.FunctionComponent<PricePathsProps> = ({ car, t })
432
438
  </div>
433
439
  <div className="pp-hero-terms">
434
440
  {t('autobahn:card.price.financeTerms', {
435
- firstInstallment: _finFirstInstallment,
436
- months: _finMonths,
437
- count: _finMonths,
441
+ firstInstallment: finFirstInstallment,
442
+ months: finMonths,
443
+ count: finMonths,
438
444
  })}
439
445
  </div>
440
446
  </div>
package/cards/types.ts CHANGED
@@ -57,6 +57,13 @@ export interface AutobahnCar {
57
57
  // --- price (always real) ---
58
58
  /** financing monthly rate in EUR — the LEAD price on every card. */
59
59
  monthly: number;
60
+ /**
61
+ * financing terms the `monthly` rate was computed with — the per-car merged
62
+ * config (dealer rate + the user's saved localStorage adjustments, ADV-157).
63
+ * Absent → the card falls back to the fe-financing default-config terms.
64
+ */
65
+ finFirstInstallment?: number;
66
+ finMonths?: number;
60
67
  /** purchase price in EUR (raw number; formatted de-DE by the cards). */
61
68
  price: number;
62
69
 
@@ -23,6 +23,7 @@ import styles from './VehicleDetailedSlider.styl';
23
23
 
24
24
  interface IProps {
25
25
  t: (phrase: string, config?: any) => string;
26
+ carId?: string;
26
27
  price: IPrice;
27
28
  photos: IImage[];
28
29
  exteriorPhotos: IImage[];
@@ -300,6 +301,7 @@ class VehicleDetailedSlider extends Component<IProps, IState> {
300
301
  render() {
301
302
  const {
302
303
  t = (phrase: string) => _get(VehicleDetailedSliderTranslate(statsData), phrase, phrase),
304
+ carId,
303
305
  price,
304
306
  photos,
305
307
  exteriorPhotos,
@@ -338,6 +340,7 @@ class VehicleDetailedSlider extends Component<IProps, IState> {
338
340
 
339
341
  const priceProps = {
340
342
  t,
343
+ carId,
341
344
  financingConfig,
342
345
  showNewLabel,
343
346
  showDownPayment,
@@ -6,6 +6,7 @@ import styles from './PriceData.styl';
6
6
 
7
7
  interface IProps {
8
8
  t: (phrase: string, config?: any) => string;
9
+ carId?: string;
9
10
  showNewLabel: boolean;
10
11
  historyPriceDifference: number;
11
12
  historyPriceDifferencePerCent: number;
@@ -19,16 +20,19 @@ const MIN_PERCENT = 5;
19
20
  const MIN_PRICE_DIFFERENCE = 500;
20
21
  const EUR = `\u20AC`;
21
22
 
22
- const PriceData: React.FunctionComponent<IProps> = ({ t, showDownPayment, showNewLabel, historyPriceDifference, historyPriceDifferencePerCent, activeTab, financingFirstInstallment, leasingFirstInstallment }) => {
23
+ const PriceData: React.FunctionComponent<IProps> = ({ t, carId, showDownPayment, showNewLabel, historyPriceDifference, historyPriceDifferencePerCent, activeTab, financingFirstInstallment, leasingFirstInstallment }) => {
23
24
  const [lsFinancingFirst, setLsFinancingFirst] = React.useState<number | undefined>(undefined);
24
25
  const [lsLeasingFirst, setLsLeasingFirst] = React.useState<number | undefined>(undefined);
25
26
 
26
27
  React.useEffect(() => {
28
+ // Per-car: only the user's own adjustments for THIS car (financing_store →
29
+ // userCarAdjustments[carId]) affect its 0-€-Anzahlung badge.
27
30
  const readFromStorage = () => {
28
31
  const raw = localStorage.getItem('financing_store');
29
32
  const parsed = raw ? JSON.parse(raw) : null;
30
- const fin = parsed?.userCommonConfig?.financing?.firstInstallment;
31
- const lea = parsed?.userCommonConfig?.leasing?.firstInstallment;
33
+ const carAdjustments = carId ? parsed?.userCarAdjustments?.[carId] : null;
34
+ const fin = carAdjustments?.financing?.firstInstallment;
35
+ const lea = carAdjustments?.leasing?.firstInstallment;
32
36
  setLsFinancingFirst(fin);
33
37
  setLsLeasingFirst(lea);
34
38
  };
@@ -36,7 +40,7 @@ const PriceData: React.FunctionComponent<IProps> = ({ t, showDownPayment, showNe
36
40
  readFromStorage();
37
41
  window.addEventListener('storage', readFromStorage);
38
42
  return () => window.removeEventListener('storage', readFromStorage);
39
- }, []);
43
+ }, [carId]);
40
44
 
41
45
  const rawFirstInstallment = activeTab === 0 ? financingFirstInstallment : activeTab === 1 ? leasingFirstInstallment : null;
42
46
  const firstInstallment = rawFirstInstallment ?? 0;
@@ -294,6 +294,7 @@ const VehicleSmallCard: FunctionComponent<IVehicleSmallCardProps> = (props) => {
294
294
 
295
295
  const statsProps = {
296
296
  t,
297
+ id,
297
298
  price,
298
299
  showNewLabel,
299
300
  showDownPayment: !!(offer as any)?.showDownPayment,
@@ -77,10 +77,15 @@ const withStats = (WrappedComponent: any) => ({
77
77
  const [anyLsBlocked, setAnyLsBlocked] = React.useState(false);
78
78
 
79
79
  React.useEffect(() => {
80
+ // Per-car: only the user's own adjustments for THIS car (financing_store →
81
+ // userCarAdjustments[id]) affect its 0-€-Anzahlung badge; adjustments made
82
+ // on other cars are ignored.
83
+ const carId = props.id;
80
84
  const raw = localStorage.getItem('financing_store');
81
85
  const parsed = raw ? JSON.parse(raw) : null;
82
- const fin = parsed?.userCommonConfig?.financing?.firstInstallment;
83
- const lea = parsed?.userCommonConfig?.leasing?.firstInstallment;
86
+ const carAdjustments = carId ? parsed?.userCarAdjustments?.[carId] : null;
87
+ const fin = carAdjustments?.financing?.firstInstallment;
88
+ const lea = carAdjustments?.leasing?.firstInstallment;
84
89
  const finBlocked = fin !== undefined && fin !== null && fin !== 0;
85
90
  const leaBlocked = lea !== undefined && lea !== null && lea !== 0;
86
91
  const anyBlocked = finBlocked || leaBlocked;
@@ -305,6 +305,11 @@ export function toAutobahnCar(storeCar: any, deps: ToAutobahnCarDeps = {}): Auto
305
305
  // (getFinancing.ts:82 `monthlyInstallment`), spread into price.financing by
306
306
  // transformDataForVehicles (DataTransformers.ts:345). It is the LEAD price.
307
307
  const monthly = num(price?.financing?.monthlyInstallment) ?? 0;
308
+ // financing terms the monthly rate was computed with — same merged per-car
309
+ // config (dealer rate + the user's saved localStorage adjustments, ADV-157).
310
+ // Emitted only when real; the cards fall back to the default-config terms.
311
+ const finFirstInstallment = num(price?.financing?.firstInstallment);
312
+ const finMonths = num(price?.financing?.rawPaybackPeriod) ?? num(price?.financing?.paybackPeriod);
308
313
  // price ← price.currentSalesPrice (DataTransformers.ts:352).
309
314
  const purchase = num(price?.currentSalesPrice) ?? 0;
310
315
 
@@ -410,6 +415,8 @@ export function toAutobahnCar(storeCar: any, deps: ToAutobahnCarDeps = {}): Auto
410
415
 
411
416
  // price
412
417
  monthly,
418
+ ...(finFirstInstallment != null ? { finFirstInstallment } : {}),
419
+ ...(finMonths != null ? { finMonths } : {}),
413
420
  price: purchase,
414
421
 
415
422
  // media
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bytebrand/fe-ui-core-autobahn",
3
- "version": "1.0.10",
3
+ "version": "1.0.12",
4
4
  "description": "auto.de md3 (Autobahn) design system — UI primitives, cards, chrome, VDP modules, theme CSS and locales. Ships raw TypeScript source (like fe-ui-core before it); each consumer's bundler compiles it.",
5
5
  "main": "index.ts",
6
6
  "license": "UNLICENSED",