@bytebrand/fe-ui-core-autobahn 1.0.73 → 1.0.75
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cards/CarCard.tsx +37 -4
- package/cards/cardParts.tsx +47 -21
- package/chrome/Footer.tsx +23 -18
- package/constants.ts +31 -31
- package/locales/de/autobahn.json +29 -8
- package/locales/en/autobahn.json +27 -6
- package/package.json +1 -1
- package/theme/md3.css +107 -28
- package/utils/financeFormat.ts +62 -62
- package/utils/priceRating.ts +58 -58
- package/vdp/VdpModules.tsx +398 -109
package/cards/CarCard.tsx
CHANGED
|
@@ -72,6 +72,15 @@ export interface CarCardProps {
|
|
|
72
72
|
* the same one.
|
|
73
73
|
*/
|
|
74
74
|
onOpenRateAdjust?: (mode: PaymentMode) => void;
|
|
75
|
+
/**
|
|
76
|
+
* takes over the "Finanzierungsdetails"/"Details" link under the price row — e.g. navigate to
|
|
77
|
+
* this car's own VDP and open its finance modal already expanded/scrolled to the breakdown,
|
|
78
|
+
* instead of the default plain onOpen(car) navigation. Receives the tab the card was showing
|
|
79
|
+
* (Finanzierung/Leasing/Kaufen) so the destination modal opens on the same one. Optional/
|
|
80
|
+
* page-owned like onOpenRateAdjust; the mobile CTA row's "Rate anpassen" button is untouched
|
|
81
|
+
* (still onOpenRateAdjust).
|
|
82
|
+
*/
|
|
83
|
+
onShowFinancingDetails?: (car: AutobahnCar, mode: PaymentMode) => void;
|
|
75
84
|
}
|
|
76
85
|
|
|
77
86
|
const CarCard: React.FunctionComponent<CarCardProps> = ({
|
|
@@ -85,6 +94,7 @@ const CarCard: React.FunctionComponent<CarCardProps> = ({
|
|
|
85
94
|
onRequestOffer,
|
|
86
95
|
onCall,
|
|
87
96
|
onOpenRateAdjust,
|
|
97
|
+
onShowFinancingDetails,
|
|
88
98
|
}) => {
|
|
89
99
|
const [mode, setMode] = useState<PaymentMode>('financing');
|
|
90
100
|
const [photoIndex, setPhotoIndex] = useState(0);
|
|
@@ -103,11 +113,11 @@ const CarCard: React.FunctionComponent<CarCardProps> = ({
|
|
|
103
113
|
onMouseEnter={onMediaEnter}
|
|
104
114
|
onTouchStart={onMediaEnter}
|
|
105
115
|
>
|
|
106
|
-
<CardCarousel images={car.gallery} height="100%" fit="contain" onChange={setPhotoIndex} />
|
|
116
|
+
<CardCarousel images={car.gallery} height="100%" fit="contain" padded={false} onChange={setPhotoIndex} />
|
|
107
117
|
{/* max two overlays: heart + ONE deal signal — rating moved next to the price */}
|
|
108
118
|
<div
|
|
109
119
|
className="cc-fav"
|
|
110
|
-
style={{ position: 'absolute', top: 6, right: 6, zIndex:
|
|
120
|
+
style={{ position: 'absolute', top: 6, right: 6, zIndex: 6 }}
|
|
111
121
|
onClick={(e) => e.stopPropagation()}
|
|
112
122
|
>
|
|
113
123
|
<IconButton name="heart" filled active={isFavorite} onClick={onToggleFavorite} label={t('autobahn:card.action.save')} />
|
|
@@ -133,7 +143,24 @@ const CarCard: React.FunctionComponent<CarCardProps> = ({
|
|
|
133
143
|
<div style={{ display: 'flex', flexWrap: 'nowrap', gap: 5, alignItems: 'center' }}>
|
|
134
144
|
{car.isNew && <span className="neu-badge">NEU</span>}
|
|
135
145
|
{car.drop != null ? <DropChip t={t} amount={car.drop} /> : showSave && <SaveChip t={t} amount={car.savings!} />}
|
|
136
|
-
<ZeroDownChip
|
|
146
|
+
<ZeroDownChip
|
|
147
|
+
t={t}
|
|
148
|
+
show={car.zeroDown}
|
|
149
|
+
style={{
|
|
150
|
+
width: 104,
|
|
151
|
+
height: 30,
|
|
152
|
+
padding: 0,
|
|
153
|
+
justifyContent: 'center',
|
|
154
|
+
background: 'rgb(204, 222, 255)',
|
|
155
|
+
border: '1px solid rgba(0, 92, 255, 0.05)',
|
|
156
|
+
borderRadius: 15,
|
|
157
|
+
fontFamily: 'Arial',
|
|
158
|
+
fontWeight: 700,
|
|
159
|
+
fontSize: 13,
|
|
160
|
+
lineHeight: '15px',
|
|
161
|
+
color: '#005CFF',
|
|
162
|
+
}}
|
|
163
|
+
/>
|
|
137
164
|
<PercentChip pct={car.dropPct} />
|
|
138
165
|
</div>
|
|
139
166
|
<OfferBadge show={showOfferBadge} t={t} />
|
|
@@ -172,7 +199,13 @@ const CarCard: React.FunctionComponent<CarCardProps> = ({
|
|
|
172
199
|
</div>
|
|
173
200
|
{/* same fallback CardCtaRow already uses below: pages that haven't wired a real
|
|
174
201
|
"Rate anpassen" sheet yet still get a working "Details" link (opens the car). */}
|
|
175
|
-
<PriceTerms
|
|
202
|
+
<PriceTerms
|
|
203
|
+
car={car}
|
|
204
|
+
mode={mode}
|
|
205
|
+
onOpenRateAdjust={onOpenRateAdjust || (() => onOpen(car))}
|
|
206
|
+
onShowDetails={onShowFinancingDetails ? () => onShowFinancingDetails(car, mode) : undefined}
|
|
207
|
+
t={t}
|
|
208
|
+
/>
|
|
176
209
|
</div>
|
|
177
210
|
<EcoLine
|
|
178
211
|
t={t}
|
package/cards/cardParts.tsx
CHANGED
|
@@ -564,22 +564,34 @@ export const PriceHero: React.FunctionComponent<PriceHeroProps> = ({ car, mode,
|
|
|
564
564
|
eyebrow/unit have nothing to caption, so the whole group stays hidden. */}
|
|
565
565
|
{!isMoney && showOld && (
|
|
566
566
|
<span className="pp-hero-unit-group">
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
)}
|
|
580
|
-
|
|
567
|
+
{/* a real (not display:contents) flex-column box, matching .pp-hero-unit-group's own
|
|
568
|
+
column layout exactly — so the click target covers the full area INCLUDING the
|
|
569
|
+
gap between the two stacked lines, not just their text glyphs (display:contents
|
|
570
|
+
has no box of its own there, so clicks in that gap fell through to the card link
|
|
571
|
+
behind it instead of opening the tooltip). */}
|
|
572
|
+
<span
|
|
573
|
+
style={{ display: 'flex', flexDirection: 'column' }}
|
|
574
|
+
role="button"
|
|
575
|
+
tabIndex={0}
|
|
576
|
+
onClick={() => setUvpTooltipOpen((v) => !v)}
|
|
577
|
+
>
|
|
578
|
+
<span className="pp-eyebrow">
|
|
579
|
+
{t('autobahn:card.price.uvpRateLabel')}
|
|
580
|
+
<UvpBadge
|
|
581
|
+
n={3}
|
|
582
|
+
open={uvpTooltipOpen}
|
|
583
|
+
onToggle={() => setUvpTooltipOpen((v) => !v)}
|
|
584
|
+
onClose={() => setUvpTooltipOpen(false)}
|
|
585
|
+
closeLabel={t('autobahn:modal.close')}
|
|
586
|
+
body={t(
|
|
587
|
+
mode === 'leasing'
|
|
588
|
+
? 'autobahn:card.price.uvpRateTooltipBodyLeasing'
|
|
589
|
+
: 'autobahn:card.price.uvpRateTooltipBody',
|
|
590
|
+
)}
|
|
591
|
+
/>
|
|
592
|
+
</span>
|
|
593
|
+
<span className={'pp-hero-old' + oldLenClass}>{Math.round(oldValue as number).toLocaleString('de-DE')} €</span>
|
|
581
594
|
</span>
|
|
582
|
-
<span className={'pp-hero-old' + oldLenClass}>{Math.round(oldValue as number).toLocaleString('de-DE')} €</span>
|
|
583
595
|
<span className="pp-hero-unit">{t('autobahn:card.price.perMonth')}</span>
|
|
584
596
|
</span>
|
|
585
597
|
)}
|
|
@@ -591,7 +603,15 @@ export const PriceHero: React.FunctionComponent<PriceHeroProps> = ({ car, mode,
|
|
|
591
603
|
car.listPrice already used by DropChip/PpRow. */}
|
|
592
604
|
{isMoney && showOld && (
|
|
593
605
|
<span className="pp-hero-unit-group">
|
|
594
|
-
<span
|
|
606
|
+
<span
|
|
607
|
+
className={'pp-hero-old' + oldLenClass}
|
|
608
|
+
role="button"
|
|
609
|
+
tabIndex={0}
|
|
610
|
+
onClick={(e) => {
|
|
611
|
+
e.stopPropagation();
|
|
612
|
+
setUvpTooltipOpen((v) => !v);
|
|
613
|
+
}}
|
|
614
|
+
>
|
|
595
615
|
{Math.round(oldValue as number).toLocaleString('de-DE')} €
|
|
596
616
|
<UvpBadge
|
|
597
617
|
n={2}
|
|
@@ -621,8 +641,13 @@ export const PriceTerms: React.FunctionComponent<{
|
|
|
621
641
|
car: AutobahnCar;
|
|
622
642
|
mode: PaymentMode;
|
|
623
643
|
onOpenRateAdjust?: (mode: PaymentMode) => void;
|
|
644
|
+
/** takes over the "Finanzierungsdetails"/"Details" link's click (e.g. navigate to the VDP and
|
|
645
|
+
* open the finance modal already expanded, scrolled to the breakdown) — when given, it wins
|
|
646
|
+
* over onOpenRateAdjust for THIS link only; the mobile CTA row's own "Rate anpassen" button
|
|
647
|
+
* keeps using onOpenRateAdjust regardless. */
|
|
648
|
+
onShowDetails?: () => void;
|
|
624
649
|
t: TranslationFunction;
|
|
625
|
-
}> = ({ car, mode, onOpenRateAdjust, t }) => {
|
|
650
|
+
}> = ({ car, mode, onOpenRateAdjust, onShowDetails, t }) => {
|
|
626
651
|
if (mode === 'buy') return null;
|
|
627
652
|
const finFirstInstallment =
|
|
628
653
|
car.finFirstInstallment != null ? car.finFirstInstallment.toLocaleString('de-DE') : _finFirstInstallment;
|
|
@@ -639,7 +664,7 @@ export const PriceTerms: React.FunctionComponent<{
|
|
|
639
664
|
? t('autobahn:card.price.leaseTerms', { firstInstallment: leasFirstInstallment, months: leasMonths, mileage: leasMileageStr })
|
|
640
665
|
: ''
|
|
641
666
|
: t('autobahn:card.price.financeTerms', { firstInstallment: finFirstInstallment, months: finMonths, count: finMonths });
|
|
642
|
-
if (!termsText && !onOpenRateAdjust) return null;
|
|
667
|
+
if (!termsText && !onOpenRateAdjust && !onShowDetails) return null;
|
|
643
668
|
const detailsLabel = mode === 'leasing' ? t('autobahn:card.price.detailsLink') : t('autobahn:modal.financingDetails');
|
|
644
669
|
// split on the translation's own ' · ' separator so the dot can be styled lighter than the
|
|
645
670
|
// two figures around it (same literal separator convention as FinanceCalculator's condParts).
|
|
@@ -652,7 +677,7 @@ export const PriceTerms: React.FunctionComponent<{
|
|
|
652
677
|
{part}
|
|
653
678
|
</React.Fragment>
|
|
654
679
|
))}
|
|
655
|
-
{onOpenRateAdjust && (
|
|
680
|
+
{(onOpenRateAdjust || onShowDetails) && (
|
|
656
681
|
<>
|
|
657
682
|
{termsText && <span className="cc-terms-dot"> · </span>}
|
|
658
683
|
<button
|
|
@@ -660,7 +685,8 @@ export const PriceTerms: React.FunctionComponent<{
|
|
|
660
685
|
className="cc-terms-link"
|
|
661
686
|
onClick={(e) => {
|
|
662
687
|
e.stopPropagation();
|
|
663
|
-
|
|
688
|
+
if (onShowDetails) onShowDetails();
|
|
689
|
+
else onOpenRateAdjust!(mode);
|
|
664
690
|
}}
|
|
665
691
|
>
|
|
666
692
|
{detailsLabel}
|
|
@@ -706,7 +732,7 @@ export interface CardCtaRowProps {
|
|
|
706
732
|
* keeps its text label — only the phone button is icon-only, matching the mockup.
|
|
707
733
|
*/
|
|
708
734
|
export const CardCtaRow: React.FunctionComponent<CardCtaRowProps> = ({ car, mode, onRequestOffer, onCall, onOpenRateAdjust, t }) => (
|
|
709
|
-
<div className="card-cta-row show-mobile" style={{ display: 'flex', gap: 8
|
|
735
|
+
<div className="card-cta-row show-mobile" style={{ display: 'flex', gap: 8 }}>
|
|
710
736
|
<Button
|
|
711
737
|
variant="filled"
|
|
712
738
|
style={{ flex: 2 }}
|
package/chrome/Footer.tsx
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { TranslationFunction } from '../types';
|
|
3
|
-
import { defaultConfig } from '@bytebrand/fe-financing';
|
|
4
3
|
|
|
5
4
|
import logoUrl from '../assets/autode-logo.svg';
|
|
6
5
|
|
|
@@ -73,10 +72,6 @@ const APPS: ReadonlyArray<{ name: string; labelKey: string; href: string }> = [
|
|
|
73
72
|
{ name: 'android', labelKey: 'autobahn:chrome.androidApp', href: 'https://play.google.com/store/apps/details?id=de.auto.app' },
|
|
74
73
|
];
|
|
75
74
|
|
|
76
|
-
/** financing defaults for the §17a PAngV representative example (same source the legacy footer uses). */
|
|
77
|
-
const FIN = defaultConfig.financing;
|
|
78
|
-
const fmt2 = (n: number): string => Number(n).toFixed(2);
|
|
79
|
-
|
|
80
75
|
export interface FooterProps {
|
|
81
76
|
/**
|
|
82
77
|
* i18n function. The footer: namespace holds the LEGALLY REQUIRED disclaimer text (PAngV
|
|
@@ -93,7 +88,12 @@ export interface FooterProps {
|
|
|
93
88
|
*/
|
|
94
89
|
const Footer: React.FunctionComponent<FooterProps> = ({ t }) => {
|
|
95
90
|
const scrollTop = (): void => window.scroll({ top: 0, left: 0, behavior: 'smooth' });
|
|
96
|
-
const
|
|
91
|
+
const now = new Date();
|
|
92
|
+
const year = now.getFullYear();
|
|
93
|
+
// de-DE always renders DD.MM.YYYY — the disclaimer's "Stand: …" date, same format regardless
|
|
94
|
+
// of UI language (this is a German-market legal notice). Computed fresh on every render, so it
|
|
95
|
+
// reads correctly on any future day without needing a manual update.
|
|
96
|
+
const today = now.toLocaleDateString('de-DE');
|
|
97
97
|
|
|
98
98
|
return (
|
|
99
99
|
<footer style={{ background: 'var(--md-sc-low)', borderTop: '1px solid var(--md-outline-variant)' }}>
|
|
@@ -167,18 +167,23 @@ const Footer: React.FunctionComponent<FooterProps> = ({ t }) => {
|
|
|
167
167
|
term, DAT CO₂-Leitfaden, MwSt, Streichpreis, image notice). Same text as the legacy footer. */}
|
|
168
168
|
<div style={{ borderTop: '1px solid var(--md-outline-variant)' }}>
|
|
169
169
|
<div className="container" style={{ padding: '18px 24px' }}>
|
|
170
|
-
<p
|
|
171
|
-
|
|
172
|
-
{
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
170
|
+
<p
|
|
171
|
+
className="md-label-sm"
|
|
172
|
+
style={{ lineHeight: 1.55, color: 'var(--md-on-surface-variant)', margin: 0 }}
|
|
173
|
+
// legal disclaimer text only (no user input) — <b> tags on the defined terms
|
|
174
|
+
// (Hersteller-UVP / UVP-Vergleichsrate / Fahrzeugabbildungen und Fahrzeugdaten) live
|
|
175
|
+
// directly in the translation strings, one key per footnote like the rest of this file.
|
|
176
|
+
dangerouslySetInnerHTML={{
|
|
177
|
+
__html: [
|
|
178
|
+
t('footer:vatReportable'),
|
|
179
|
+
t('footer:manufacturerUvp'),
|
|
180
|
+
t('footer:uvpComparisonRate'),
|
|
181
|
+
t('footer:priceEvaluation', { date: today }),
|
|
182
|
+
t('footer:consumptionInfo'),
|
|
183
|
+
t('footer:vehicleImages'),
|
|
184
|
+
].join('<br />'),
|
|
185
|
+
}}
|
|
186
|
+
/>
|
|
182
187
|
</div>
|
|
183
188
|
</div>
|
|
184
189
|
|
package/constants.ts
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
// Autobahn (auto.de redesign) — shared lookup constants barrel.
|
|
2
|
-
// Pure data re-exported from ./constants/autobahn (kept import-safe for plain Node consumers,
|
|
3
|
-
// see that file's header) plus the legacy fe-ui-core shim re-exports below.
|
|
4
|
-
export * from './constants/autobahn';
|
|
5
|
-
|
|
6
|
-
// ---------------------------------------------------------------------------
|
|
7
|
-
// Legacy shared constants (moved here from fe-ui-core).
|
|
8
|
-
//
|
|
9
|
-
// This block mirrors the public symbol set of the old
|
|
10
|
-
// `@bytebrand/fe-ui-core/constants` barrel so consumers can swap that
|
|
11
|
-
// specifier for `@bytebrand/fe-ui-core-autobahn/constants` 1:1. The
|
|
12
|
-
// implementations live under ./constants/ (core.ts, app.ts, price.ts,
|
|
13
|
-
// Search.ts, …); fe-ui-core re-exports them via shims until it is deleted.
|
|
14
|
-
// ---------------------------------------------------------------------------
|
|
15
|
-
|
|
16
|
-
export {
|
|
17
|
-
offers,
|
|
18
|
-
checkoutOffers,
|
|
19
|
-
checkoutWarranties,
|
|
20
|
-
checkoutSteps,
|
|
21
|
-
checkoutSubStep,
|
|
22
|
-
DELIVERY_PERIODS_EXTRA,
|
|
23
|
-
THREE,
|
|
24
|
-
WLTP_ENERGY_EFFICIENCY_CLASS
|
|
25
|
-
} from './constants/core';
|
|
26
|
-
|
|
27
|
-
export { CUSTOM_ERROR_MESSAGES, supportPhone, supportPhoneLink } from './constants/app';
|
|
28
|
-
|
|
29
|
-
export { priceRatings } from './constants/price';
|
|
30
|
-
|
|
31
|
-
export { THROTTLE_DELAY } from './constants/Search';
|
|
1
|
+
// Autobahn (auto.de redesign) — shared lookup constants barrel.
|
|
2
|
+
// Pure data re-exported from ./constants/autobahn (kept import-safe for plain Node consumers,
|
|
3
|
+
// see that file's header) plus the legacy fe-ui-core shim re-exports below.
|
|
4
|
+
export * from './constants/autobahn';
|
|
5
|
+
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
// Legacy shared constants (moved here from fe-ui-core).
|
|
8
|
+
//
|
|
9
|
+
// This block mirrors the public symbol set of the old
|
|
10
|
+
// `@bytebrand/fe-ui-core/constants` barrel so consumers can swap that
|
|
11
|
+
// specifier for `@bytebrand/fe-ui-core-autobahn/constants` 1:1. The
|
|
12
|
+
// implementations live under ./constants/ (core.ts, app.ts, price.ts,
|
|
13
|
+
// Search.ts, …); fe-ui-core re-exports them via shims until it is deleted.
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
|
|
16
|
+
export {
|
|
17
|
+
offers,
|
|
18
|
+
checkoutOffers,
|
|
19
|
+
checkoutWarranties,
|
|
20
|
+
checkoutSteps,
|
|
21
|
+
checkoutSubStep,
|
|
22
|
+
DELIVERY_PERIODS_EXTRA,
|
|
23
|
+
THREE,
|
|
24
|
+
WLTP_ENERGY_EFFICIENCY_CLASS
|
|
25
|
+
} from './constants/core';
|
|
26
|
+
|
|
27
|
+
export { CUSTOM_ERROR_MESSAGES, supportPhone, supportPhoneLink } from './constants/app';
|
|
28
|
+
|
|
29
|
+
export { priceRatings } from './constants/price';
|
|
30
|
+
|
|
31
|
+
export { THROTTLE_DELAY } from './constants/Search';
|
package/locales/de/autobahn.json
CHANGED
|
@@ -66,7 +66,6 @@
|
|
|
66
66
|
"finance": {
|
|
67
67
|
"termSelection": "Laufzeit",
|
|
68
68
|
"termSelectionMonths": "Laufzeit (Monate)",
|
|
69
|
-
"exampleLabel": "z.B.",
|
|
70
69
|
"headerTitle": "Dein Angebot",
|
|
71
70
|
"adjustRate": "Rate anpassen",
|
|
72
71
|
"secureOffer": "Angebot anfragen",
|
|
@@ -91,19 +90,22 @@
|
|
|
91
90
|
"warrantyValue": "1 Jahr inklusive",
|
|
92
91
|
"deliveryLabel": "Lieferung",
|
|
93
92
|
"deliveryValue": "ca. 7–14 Tage · oder Abholung",
|
|
93
|
+
"availabilityLabel": "Verfügbarkeit",
|
|
94
|
+
"availabilityValue": "Sofort",
|
|
94
95
|
"downPaymentSliderLabel": "Anzahlung",
|
|
95
96
|
"annualMileageLabel": "Laufleistung / Jahr",
|
|
96
97
|
"purchasePrice": "Kaufpreis",
|
|
97
98
|
"perMonth": "/mtl.",
|
|
98
99
|
"leasingDetails": "Leasing-Details",
|
|
99
|
-
"financingDetails": "
|
|
100
|
+
"financingDetails": "Finanzierungs-Details",
|
|
100
101
|
"personalConsultationLine": "Persönliche Beratung. Wir sind für Sie da!",
|
|
101
102
|
"requestRate": "Rate anfragen",
|
|
102
103
|
"callCta": "Anrufen",
|
|
103
104
|
"finalInstallmentToggle": "Mit Schlussrate",
|
|
104
105
|
"addServicesToggle": "Rundum-Sorglos-Paket",
|
|
105
106
|
"addServicesPerMonth": "+{{value}} € / Monat",
|
|
106
|
-
"addServicesOnce": "+{{value}} €"
|
|
107
|
+
"addServicesOnce": "+{{value}} €",
|
|
108
|
+
"addServicesIncluded": "inklusive"
|
|
107
109
|
},
|
|
108
110
|
"specTable": {
|
|
109
111
|
"title": "Fahrzeugdaten",
|
|
@@ -684,7 +686,7 @@
|
|
|
684
686
|
},
|
|
685
687
|
"modal": {
|
|
686
688
|
"leasingDetails": "Leasingdetails",
|
|
687
|
-
"financingDetails": "
|
|
689
|
+
"financingDetails": "Finanzierungs-Details",
|
|
688
690
|
"close": "Schließen",
|
|
689
691
|
"vehiclePrice": "Fahrzeugpreis ggf. inkl. MwSt.",
|
|
690
692
|
"leasingAmount": "Leasingbetrag",
|
|
@@ -699,8 +701,8 @@
|
|
|
699
701
|
"finalInstallment": "Schlussrate",
|
|
700
702
|
"leasingRate": "Leasingrate",
|
|
701
703
|
"monthlyRate": "Monatsrate",
|
|
702
|
-
"leasingRateCount": "{{count}}
|
|
703
|
-
"leasingRateCount_plural": "{{count}}
|
|
704
|
+
"leasingRateCount": "{{count}} Monatsrate à",
|
|
705
|
+
"leasingRateCount_plural": "{{count}} Monatsraten à",
|
|
704
706
|
"monthlyRateCount": "{{count}} Rate à",
|
|
705
707
|
"monthlyRateCount_plural": "{{count}} Raten à",
|
|
706
708
|
"addServicesRow": "Rundum-Sorglos-Paket (einmalig)",
|
|
@@ -709,11 +711,30 @@
|
|
|
709
711
|
"totalRepayment": "Gesamtbetrag Finanzierung",
|
|
710
712
|
"totalCostWithPackage": "Gesamtbelastung inkl. Anzahlung & Paket",
|
|
711
713
|
"totalCost": "Gesamtbelastung inkl. Anzahlung",
|
|
712
|
-
"listPrice": "Listenpreis (UVP)",
|
|
714
|
+
"listPrice": "Listenpreis (UVP)³",
|
|
715
|
+
"leaseVehiclePrice": "Anschaffungspreis¹",
|
|
716
|
+
"leaseDownPayment": "Einmalige Sonderzahlung",
|
|
717
|
+
"finalPaymentDue": "Schlusszahlung (fällig am Vertragsende)",
|
|
718
|
+
"residualValue": "Restwert (verpflichtend)",
|
|
719
|
+
"rateSumLabel": "Summe der Leasingraten ({{term}} × {{amount}} €)",
|
|
720
|
+
"addServicesRowLease": "Rundum-Sorglos-Paket (Einmalzahlung)",
|
|
721
|
+
"subtotalWithPackage": "Gesamt inkl. Sonderzahl. & Paket",
|
|
722
|
+
"subtotalNoPackage": "Gesamt inkl. Sonderzahlung",
|
|
723
|
+
"grandTotalWithResidual": "Gesamt inkl. Restwert (verpflichtend)",
|
|
724
|
+
"listPriceLease": "Listenpreis (UVP)²",
|
|
713
725
|
"representativeExample": "Repräsentatives Beispiel",
|
|
714
726
|
"vatDisclaimer": "(alle Preisangaben ggf. inkl. der jeweils gesetzlich gültigen MwSt., derzeit 19%)",
|
|
715
727
|
"lenderLabel": "Darlehensgeber:",
|
|
716
|
-
"lenderName": "
|
|
728
|
+
"lenderName": "Santander Consumer Bank AG, Santander-Platz 1, 41061 Mönchengladbach",
|
|
729
|
+
"leaseLenderLabel": "Leasinggeber:",
|
|
730
|
+
"leaseLenderName": "Santander Consumer Leasing GmbH, Santander-Platz 1, 41061 Mönchengladbach",
|
|
731
|
+
"contractTypeLabel": "Vertragsart:",
|
|
732
|
+
"contractTypeValue": "Restwertleasing",
|
|
733
|
+
"packageMandatoryNotice": "Das Rundum-Sorglos-Paket ist verpflichtend. In der dargestellten Konfiguration ist es als Einmalzahlung von {{amount}} € zu leisten und nicht in der Monatsrate enthalten. Bei Rateneinrechnung werden Monatsrate und Gesamtbeträge entsprechend angepasst.",
|
|
734
|
+
"legalFootnoteAcquisitionPrice": "¹ Der Anschaffungspreis bezeichnet den Preis, den die Santander Consumer Leasing GmbH für das Fahrzeug zu bezahlen hat.",
|
|
735
|
+
"legalFootnoteListPriceLease": "² Listenpreis (UVP) = unverbindliche Preisempfehlung des Herstellers.",
|
|
736
|
+
"closingDisclaimerLine1": "Änderungen und Irrtümer vorbehalten. Farbe und Ausstattung können vom Angebot abweichen.",
|
|
737
|
+
"closingDisclaimerLine2": "Kostenpflichtige Sonderausstattung möglich.",
|
|
717
738
|
"legalNoticesTitle": "Rechtliche Hinweise",
|
|
718
739
|
"legalNoticeCreditworthiness": "Bonität vorausgesetzt.",
|
|
719
740
|
"legalNoticeExample": "Repräsentatives Beispiel gem. § 17 PAngV.",
|
package/locales/en/autobahn.json
CHANGED
|
@@ -66,7 +66,6 @@
|
|
|
66
66
|
"finance": {
|
|
67
67
|
"termSelection": "Term",
|
|
68
68
|
"termSelectionMonths": "Term (months)",
|
|
69
|
-
"exampleLabel": "e.g.",
|
|
70
69
|
"headerTitle": "Your offer",
|
|
71
70
|
"adjustRate": "Adjust rate",
|
|
72
71
|
"secureOffer": "Request offer",
|
|
@@ -91,6 +90,8 @@
|
|
|
91
90
|
"warrantyValue": "1 year included",
|
|
92
91
|
"deliveryLabel": "Delivery",
|
|
93
92
|
"deliveryValue": "approx. 7–14 days · or collection",
|
|
93
|
+
"availabilityLabel": "Availability",
|
|
94
|
+
"availabilityValue": "Immediately",
|
|
94
95
|
"downPaymentSliderLabel": "Down payment",
|
|
95
96
|
"annualMileageLabel": "Mileage / year",
|
|
96
97
|
"purchasePrice": "Purchase price",
|
|
@@ -103,7 +104,8 @@
|
|
|
103
104
|
"finalInstallmentToggle": "With final installment",
|
|
104
105
|
"addServicesToggle": "All-round care package",
|
|
105
106
|
"addServicesPerMonth": "+€{{value}} / month",
|
|
106
|
-
"addServicesOnce": "+€{{value}}"
|
|
107
|
+
"addServicesOnce": "+€{{value}}",
|
|
108
|
+
"addServicesIncluded": "included"
|
|
107
109
|
},
|
|
108
110
|
"specTable": {
|
|
109
111
|
"title": "Vehicle data",
|
|
@@ -699,8 +701,8 @@
|
|
|
699
701
|
"finalInstallment": "Final installment",
|
|
700
702
|
"leasingRate": "Leasing rate",
|
|
701
703
|
"monthlyRate": "Monthly rate",
|
|
702
|
-
"leasingRateCount": "{{count}}
|
|
703
|
-
"leasingRateCount_plural": "{{count}}
|
|
704
|
+
"leasingRateCount": "{{count}} monthly installment of",
|
|
705
|
+
"leasingRateCount_plural": "{{count}} monthly installments of",
|
|
704
706
|
"monthlyRateCount": "{{count}} installment of",
|
|
705
707
|
"monthlyRateCount_plural": "{{count}} installments of",
|
|
706
708
|
"addServicesRow": "Complete care package (one-time)",
|
|
@@ -709,11 +711,30 @@
|
|
|
709
711
|
"totalRepayment": "Total financing amount",
|
|
710
712
|
"totalCostWithPackage": "Total cost incl. down payment & package",
|
|
711
713
|
"totalCost": "Total cost incl. down payment",
|
|
712
|
-
"listPrice": "List price (RRP)",
|
|
714
|
+
"listPrice": "List price (RRP)³",
|
|
715
|
+
"leaseVehiclePrice": "Acquisition price¹",
|
|
716
|
+
"leaseDownPayment": "One-time special payment",
|
|
717
|
+
"finalPaymentDue": "Final payment (due at contract end)",
|
|
718
|
+
"residualValue": "Residual value (mandatory)",
|
|
719
|
+
"rateSumLabel": "Sum of leasing installments ({{term}} × {{amount}} €)",
|
|
720
|
+
"addServicesRowLease": "Complete care package (one-time payment)",
|
|
721
|
+
"subtotalWithPackage": "Total incl. special payment & package",
|
|
722
|
+
"subtotalNoPackage": "Total incl. special payment",
|
|
723
|
+
"grandTotalWithResidual": "Total incl. residual value (mandatory)",
|
|
724
|
+
"listPriceLease": "List price (RRP)²",
|
|
713
725
|
"representativeExample": "Representative example",
|
|
714
726
|
"vatDisclaimer": "(all prices may incl. the applicable statutory VAT, currently 19%)",
|
|
715
727
|
"lenderLabel": "Lender:",
|
|
716
|
-
"lenderName": "
|
|
728
|
+
"lenderName": "Santander Consumer Bank AG, Santander-Platz 1, 41061 Mönchengladbach",
|
|
729
|
+
"leaseLenderLabel": "Lessor:",
|
|
730
|
+
"leaseLenderName": "Santander Consumer Leasing GmbH, Santander-Platz 1, 41061 Mönchengladbach",
|
|
731
|
+
"contractTypeLabel": "Contract type:",
|
|
732
|
+
"contractTypeValue": "Residual value leasing",
|
|
733
|
+
"packageMandatoryNotice": "The complete care package is mandatory. In the configuration shown, it must be paid as a one-time payment of {{amount}} € and is not included in the monthly rate. If rolled into the installments, the monthly rate and totals are adjusted accordingly.",
|
|
734
|
+
"legalFootnoteAcquisitionPrice": "¹ The acquisition price denotes the price Santander Consumer Leasing GmbH pays for the vehicle.",
|
|
735
|
+
"legalFootnoteListPriceLease": "² List price (RRP) = manufacturer's non-binding recommended retail price.",
|
|
736
|
+
"closingDisclaimerLine1": "Subject to change and errors. Color and equipment may differ from the offer shown.",
|
|
737
|
+
"closingDisclaimerLine2": "Optional equipment may incur additional costs.",
|
|
717
738
|
"legalNoticesTitle": "Legal notices",
|
|
718
739
|
"legalNoticeCreditworthiness": "Subject to creditworthiness.",
|
|
719
740
|
"legalNoticeExample": "Representative example per § 17 PAngV.",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bytebrand/fe-ui-core-autobahn",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.75",
|
|
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",
|