diff --git a/frontend/src/app/core/layout/navbar.component.scss b/frontend/src/app/core/layout/navbar.component.scss
index f132074..6b0da84 100644
--- a/frontend/src/app/core/layout/navbar.component.scss
+++ b/frontend/src/app/core/layout/navbar.component.scss
@@ -44,15 +44,29 @@
}
.lang-switch {
- background: none;
+ background-color: var(--color-bg-card);
border: 1px solid var(--color-border);
border-radius: var(--radius-sm);
- padding: 2px 6px;
+ padding: 2px 22px 2px 8px;
cursor: pointer;
font-size: 0.875rem;
font-weight: 600;
color: var(--color-text-muted);
+ appearance: none;
+ background-image:
+ linear-gradient(45deg, transparent 50%, currentColor 50%),
+ linear-gradient(135deg, currentColor 50%, transparent 50%);
+ background-position:
+ calc(100% - 10px) calc(50% - 2px),
+ calc(100% - 5px) calc(50% - 2px);
+ background-size: 5px 5px, 5px 5px;
+ background-repeat: no-repeat;
+
&:hover { color: var(--color-text); border-color: var(--color-text); }
+ &:focus-visible {
+ outline: 2px solid var(--color-brand);
+ outline-offset: 1px;
+ }
}
.icon-placeholder {
diff --git a/frontend/src/app/core/layout/navbar.component.ts b/frontend/src/app/core/layout/navbar.component.ts
index a2e548f..0cfe61a 100644
--- a/frontend/src/app/core/layout/navbar.component.ts
+++ b/frontend/src/app/core/layout/navbar.component.ts
@@ -2,7 +2,6 @@ import { Component } from '@angular/core';
import { RouterLink, RouterLinkActive } from '@angular/router';
import { TranslateModule } from '@ngx-translate/core';
import { LanguageService } from '../services/language.service';
-import { AppButtonComponent } from '../../shared/components/app-button/app-button.component';
@Component({
selector: 'app-navbar',
@@ -13,12 +12,19 @@ import { AppButtonComponent } from '../../shared/components/app-button/app-butto
})
export class NavbarComponent {
isMenuOpen = false;
+ readonly languageOptions: Array<{ value: 'it' | 'en' | 'de' | 'fr'; label: string }> = [
+ { value: 'it', label: 'IT' },
+ { value: 'en', label: 'EN' },
+ { value: 'de', label: 'DE' },
+ { value: 'fr', label: 'FR' }
+ ];
constructor(public langService: LanguageService) {}
- toggleLang() {
- const newLang = this.langService.currentLang() === 'it' ? 'en' : 'it';
- this.langService.switchLang(newLang);
+ onLanguageChange(event: Event): void {
+ const select = event.target as HTMLSelectElement;
+ const lang = select.value as 'it' | 'en' | 'de' | 'fr';
+ this.langService.switchLang(lang);
}
toggleMenu() {
diff --git a/frontend/src/app/core/services/language.service.ts b/frontend/src/app/core/services/language.service.ts
index ead4dc0..742101e 100644
--- a/frontend/src/app/core/services/language.service.ts
+++ b/frontend/src/app/core/services/language.service.ts
@@ -1,20 +1,126 @@
import { Injectable, signal } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
+import { NavigationEnd, PRIMARY_OUTLET, Router, UrlTree } from '@angular/router';
@Injectable({
providedIn: 'root'
})
export class LanguageService {
- currentLang = signal('it');
+ currentLang = signal<'it' | 'en' | 'de' | 'fr'>('it');
+ private readonly supportedLangs: Array<'it' | 'en' | 'de' | 'fr'> = ['it', 'en', 'de', 'fr'];
- constructor(private translate: TranslateService) {
- this.translate.addLangs(['it', 'en']);
+ constructor(
+ private translate: TranslateService,
+ private router: Router
+ ) {
+ this.translate.addLangs(this.supportedLangs);
this.translate.setDefaultLang('it');
- this.translate.use('it');
+
+ const initialTree = this.router.parseUrl(this.router.url);
+ const initialSegments = this.getPrimarySegments(initialTree);
+ const queryLang = this.getQueryLang(initialTree);
+ const initialLang = this.isSupportedLang(initialSegments[0])
+ ? initialSegments[0]
+ : (this.isSupportedLang(queryLang) ? queryLang : 'it');
+ this.applyLanguage(initialLang);
+ this.ensureLanguageInPath(initialTree);
+
+ this.router.events.subscribe(event => {
+ if (!(event instanceof NavigationEnd)) {
+ return;
+ }
+
+ this.ensureLanguageInPath(this.router.parseUrl(this.router.url));
+ });
}
- switchLang(lang: string) {
+ switchLang(lang: 'it' | 'en' | 'de' | 'fr') {
+ if (!this.isSupportedLang(lang)) {
+ return;
+ }
+ this.applyLanguage(lang);
+
+ const currentTree = this.router.parseUrl(this.router.url);
+ const segments = this.getPrimarySegments(currentTree);
+
+ let targetSegments: string[];
+ if (segments.length === 0) {
+ targetSegments = [lang];
+ } else if (this.isSupportedLang(segments[0]) || this.looksLikeLangToken(segments[0])) {
+ targetSegments = [lang, ...segments.slice(1)];
+ } else {
+ targetSegments = [lang, ...segments];
+ }
+
+ this.navigateIfChanged(currentTree, targetSegments);
+ }
+
+ private ensureLanguageInPath(urlTree: UrlTree): void {
+ const segments = this.getPrimarySegments(urlTree);
+
+ if (segments.length > 0 && this.isSupportedLang(segments[0])) {
+ this.applyLanguage(segments[0]);
+ return;
+ }
+
+ const queryLang = this.getQueryLang(urlTree);
+ const activeLang = this.isSupportedLang(queryLang) ? queryLang : this.currentLang();
+ if (activeLang !== this.currentLang()) {
+ this.applyLanguage(activeLang);
+ }
+ let targetSegments: string[];
+
+ if (segments.length === 0) {
+ targetSegments = [activeLang];
+ } else if (this.looksLikeLangToken(segments[0])) {
+ targetSegments = [activeLang, ...segments.slice(1)];
+ } else {
+ targetSegments = [activeLang, ...segments];
+ }
+
+ this.navigateIfChanged(urlTree, targetSegments);
+ }
+
+ private getPrimarySegments(urlTree: UrlTree): string[] {
+ const primaryGroup = urlTree.root.children[PRIMARY_OUTLET];
+ if (!primaryGroup) {
+ return [];
+ }
+ return primaryGroup.segments.map(segment => segment.path.toLowerCase());
+ }
+
+ private getQueryLang(urlTree: UrlTree): string | null {
+ const lang = urlTree.queryParams['lang'];
+ return typeof lang === 'string' ? lang.toLowerCase() : null;
+ }
+
+ private isSupportedLang(lang: string | null | undefined): lang is 'it' | 'en' | 'de' | 'fr' {
+ return typeof lang === 'string' && this.supportedLangs.includes(lang as 'it' | 'en' | 'de' | 'fr');
+ }
+
+ private looksLikeLangToken(segment: string | null | undefined): boolean {
+ return typeof segment === 'string' && /^[a-z]{2}(?:-[a-z]{2})?$/i.test(segment);
+ }
+
+ private applyLanguage(lang: 'it' | 'en' | 'de' | 'fr'): void {
+ if (this.currentLang() === lang && this.translate.currentLang === lang) {
+ return;
+ }
this.translate.use(lang);
this.currentLang.set(lang);
}
+
+ private navigateIfChanged(currentTree: UrlTree, targetSegments: string[]): void {
+ const { lang: _unusedLang, ...queryParams } = currentTree.queryParams;
+ const targetTree = this.router.createUrlTree(['/', ...targetSegments], {
+ queryParams,
+ fragment: currentTree.fragment ?? undefined
+ });
+
+ if (this.router.serializeUrl(targetTree) === this.router.serializeUrl(currentTree)) {
+ return;
+ }
+
+ this.router.navigateByUrl(targetTree, { replaceUrl: true });
+ }
}
diff --git a/frontend/src/assets/i18n/de.json b/frontend/src/assets/i18n/de.json
new file mode 100644
index 0000000..b1af8bc
--- /dev/null
+++ b/frontend/src/assets/i18n/de.json
@@ -0,0 +1,546 @@
+{
+ "NAV": {
+ "HOME": "Startseite",
+ "CALCULATOR": "Rechner",
+ "SHOP": "Shop",
+ "ABOUT": "Über uns",
+ "CONTACT": "Kontakt",
+ "LANGUAGE_SELECTOR": "Sprachauswahl"
+ },
+ "QUOTE": {
+ "CONSULT": "Beratung anfragen",
+ "PROCEED_ORDER": "Zur Bestellung",
+ "TOTAL": "Gesamt",
+ "MAX_QTY_NOTICE": "Für Mengen über {{max}} Stück bitte Beratung anfragen."
+ },
+ "USER_DETAILS": {
+ "TITLE": "Ihre Daten",
+ "SUMMARY_TITLE": "Zusammenfassung",
+ "NAME": "Vorname",
+ "NAME_PLACEHOLDER": "Ihr Vorname",
+ "SURNAME": "Nachname",
+ "SURNAME_PLACEHOLDER": "Ihr Nachname",
+ "EMAIL": "E-Mail",
+ "EMAIL_PLACEHOLDER": "ihre@email.com",
+ "PHONE": "Telefon",
+ "PHONE_PLACEHOLDER": "+41 ...",
+ "ADDRESS": "Adresse",
+ "ADDRESS_PLACEHOLDER": "Straße und Nummer",
+ "ZIP": "PLZ",
+ "ZIP_PLACEHOLDER": "0000",
+ "CITY": "Ort",
+ "CITY_PLACEHOLDER": "Ort",
+ "SUBMIT": "Weiter",
+ "DEFAULT_COLOR": "Standard"
+ },
+ "FOOTER": {
+ "PRIVACY": "Datenschutz",
+ "TERMS": "AGB",
+ "CONTACT": "Kontakt"
+ },
+ "CALC": {
+ "TITLE": "3D-Angebot berechnen",
+ "SUBTITLE": "Laden Sie Ihre 3D-Datei (STL, 3MF, STEP) hoch, stellen Sie Qualität und Farbe ein und berechnen Sie sofort Preis und Lieferzeit.",
+ "CTA_START": "Jetzt starten",
+ "BUSINESS": "Unternehmen",
+ "PRIVATE": "Privat",
+ "MODE_EASY": "Basis",
+ "MODE_ADVANCED": "Erweitert",
+ "UPLOAD_LABEL": "Ziehen Sie Ihre 3D-Datei hierher",
+ "UPLOAD_SUB": "Wir unterstützen STL, 3MF, STEP bis 50MB",
+ "MATERIAL": "Material",
+ "QUALITY": "Qualität",
+ "QUANTITY": "Menge",
+ "NOTES": "Zusätzliche Hinweise",
+ "NOZZLE": "Düsendurchmesser",
+ "INFILL": "Fülldichte (%)",
+ "PATTERN": "Füllmuster",
+ "LAYER_HEIGHT": "Schichthöhe",
+ "SUPPORT": "Stützstrukturen",
+ "SUPPORT_DESC": "Stützen für Überhänge aktivieren",
+ "CALCULATE": "Angebot berechnen",
+ "RESULT": "Geschätztes Angebot",
+ "TIME": "Druckzeit",
+ "MACHINE_COST": "Maschinenkosten",
+ "COST": "Gesamtkosten",
+ "ORDER": "Jetzt bestellen",
+ "CONSULT": "Beratung anfragen",
+ "ERROR_GENERIC": "Bei der Angebotsberechnung ist ein Fehler aufgetreten.",
+ "NEW_QUOTE": "Neues Angebot berechnen",
+ "ORDER_SUCCESS_TITLE": "Bestellung erfolgreich gesendet",
+ "ORDER_SUCCESS_DESC": "Wir haben die Details Ihrer Bestellung erhalten. Sie erhalten in Kürze eine Bestätigungs-E-Mail mit Zahlungsinformationen.",
+ "BENEFITS_TITLE": "Warum uns wählen?",
+ "BENEFITS_1": "Automatisches Angebot mit sofortigen Kosten und Zeiten",
+ "BENEFITS_2": "Ausgewählte Materialien und Qualitätskontrolle",
+ "BENEFITS_3": "CAD-Beratung, falls die Datei Änderungen benötigt",
+ "ERR_FILE_REQUIRED": "Die Datei ist erforderlich.",
+ "STEP_WARNING": "Die 3D-Ansicht ist mit STEP- und 3MF-Dateien nicht kompatibel",
+ "REMOVE_FILE": "Datei entfernen",
+ "FALLBACK_MATERIAL": "PLA (Fallback)",
+ "FALLBACK_QUALITY_STANDARD": "Standard",
+ "ERR_FILE_TOO_LARGE": "Einige Dateien überschreiten das 200MB-Limit und wurden nicht hinzugefügt.",
+ "PRINT_SPEED": "Druckgeschwindigkeit",
+ "COLOR": "Farbe",
+ "ANALYZING_TITLE": "Analyse läuft...",
+ "ANALYZING_TEXT": "Wir analysieren die Geometrie und berechnen den Werkzeugpfad.",
+ "QTY_SHORT": "MENGE",
+ "COLOR_LABEL": "FARBE",
+ "ADD_FILES": "Dateien hinzufügen",
+ "UPLOADING": "Hochladen...",
+ "PROCESSING": "Verarbeitung...",
+ "NOTES_PLACEHOLDER": "Spezifische Anweisungen...",
+ "SETUP_NOTE": "* Beinhaltet {{cost}} als Einrichtungskosten",
+ "SHIPPING_NOTE": "** Versandkosten ausgeschlossen, werden im nächsten Schritt berechnet"
+ },
+ "SHOP": {
+ "TITLE": "Technische Lösungen",
+ "SUBTITLE": "Fertige Produkte, die praktische Probleme lösen",
+ "WIP_EYEBROW": "Work in progress",
+ "WIP_TITLE": "Shop im Aufbau",
+ "WIP_SUBTITLE": "Wir bereiten einen Shop mit ausgewählten Produkten und Funktionen zur automatischen Erstellung vor!",
+ "WIP_CTA_CALC": "Zum Rechner",
+ "WIP_RETURN_LATER": "Kommen Sie später wieder",
+ "WIP_NOTE": "Wir legen Wert darauf, die Dinge richtig zu machen: In der Zwischenzeit können Sie Preis und Lieferzeit einer 3D-Datei sofort mit unserem Rechner berechnen.",
+ "ADD_CART": "In den Warenkorb",
+ "BACK": "Zurück zum Shop",
+ "NOT_FOUND": "Produkt nicht gefunden.",
+ "DETAILS": "Details",
+ "MOCK_ADD_CART": "Zum Warenkorb hinzugefügt (Mock)",
+ "SUCCESS_TITLE": "Zum Warenkorb hinzugefügt",
+ "SUCCESS_DESC": "Das Produkt wurde erfolgreich zum Warenkorb hinzugefügt.",
+ "CONTINUE": "Weiter",
+ "CATEGORIES": {
+ "FILAMENTS": "Filamente",
+ "ACCESSORIES": "Zubehör"
+ },
+ "PRODUCTS": {
+ "P1": {
+ "NAME": "PLA-Standardfilament",
+ "DESC": "Der Klassiker für jeden Druck, einfach und zuverlässig."
+ },
+ "P2": {
+ "NAME": "PETG Tough Filament",
+ "DESC": "Stoß- und temperaturbeständig."
+ },
+ "P3": {
+ "NAME": "Düsenset (0.4mm)",
+ "DESC": "Ersatzset für FDM-Extruder."
+ }
+ }
+ },
+ "ABOUT": {
+ "TITLE": "Über uns",
+ "EYEBROW": "3D-Druck-Labor",
+ "SUBTITLE": "Wir sind zwei Studenten mit viel Motivation und Lernbereitschaft.",
+ "HOW_TEXT": "3D Fab entstand aus Matteos anfänglichem Interesse am 3D-Druck. Er kaufte einen Drucker und begann ernsthaft zu experimentieren.\nIrgendwann kamen die ersten Anfragen: ein gebrochenes Teil zum Ersetzen, ein Ersatzteil, das man nicht findet, ein praktischer Adapter. Die Anfragen nahmen zu und wir sagten uns: okay, machen wir es richtig.\nSpäter haben wir einen Rechner entwickelt, um die Kosten im Voraus zu verstehen: das war einer der ersten Schritte vom „wir machen ein paar Teile“ zu einem echten Projekt – gemeinsam.",
+ "PASSIONS_TITLE": "Unsere Leidenschaften",
+ "PASSION_BIKE_TRIAL": "Bike Trial",
+ "PASSION_MOUNTAIN": "Berge",
+ "PASSION_SKI": "Ski",
+ "PASSION_SELF_HOSTING": "Self Hosting",
+ "PASSION_PRINT_3D": "3D-Druck",
+ "PASSION_TRAVEL": "Reisen",
+ "PASSION_SNOWBOARD": "Snowboard",
+ "PASSION_SNOWBOARD_INSTRUCTOR": "Snowboardlehrer",
+ "PASSION_ELECTRONICS": "Elektronik",
+ "PASSION_WOODWORKING": "Holzbearbeitung",
+ "PASSION_VAN_LIFE": "Van Life",
+ "PASSION_COFFEE": "Kaffee",
+ "PASSION_SOFTWARE_DEVELOPMENT": "Softwareentwicklung",
+ "SERVICES_TITLE": "Hauptleistungen",
+ "TARGET_TITLE": "Für wen",
+ "TARGET_TEXT": "Kleine Unternehmen, Freelancer, Tüftler und Kunden, die ein fertiges Produkt im Shop suchen.",
+ "TEAM_TITLE": "Unser Team",
+ "MEMBER_JOE_NAME": "Joe Küng",
+ "MEMBER_JOE_ROLE": "Informatik-Student",
+ "MEMBER_JOE_ALT": "Joe Küng",
+ "MEMBER_MATTEO_NAME": "Matteo Caletti",
+ "MEMBER_MATTEO_ROLE": "Elektrotechnik-Student",
+ "MEMBER_MATTEO_ALT": "Matteo Caletti"
+ },
+ "LOCATIONS": {
+ "TITLE": "Unsere Standorte",
+ "SUBTITLE": "Wir sind an zwei Standorten vertreten. Wählen Sie einen Standort, um Details zu sehen.",
+ "TICINO": "Tessin",
+ "BIENNE": "Bienne",
+ "ADDRESS_TICINO": "Via G. Pioda 29a, Biasca",
+ "ADDRESS_BIENNE": "Lyss-strasse 71, Nidau 2560 Bienne",
+ "CONTACT_US": "Kontaktieren Sie uns",
+ "BIASCA": "Biasca"
+ },
+ "LEGAL": {
+ "PRIVACY_TITLE": "Datenschutzerklärung",
+ "TERMS_TITLE": "Allgemeine Geschäftsbedingungen",
+ "LAST_UPDATE": "Letzte Aktualisierung",
+ "CONSENT": {
+ "UPLOAD_NOTICE_PREFIX": "Durch das Hochladen einer Datei akzeptieren Sie unsere",
+ "UPLOAD_NOTICE_LINK": "Datenschutzerklärung",
+ "LABEL_PREFIX": "Ich habe gelesen und akzeptiere die",
+ "TERMS_LINK": "Allgemeinen Geschäftsbedingungen",
+ "AND": "und die",
+ "PRIVACY_LINK": "Datenschutzerklärung",
+ "REQUIRED_ERROR": "Um fortzufahren müssen Sie AGB und Datenschutz akzeptieren."
+ },
+ "PRIVACY": {
+ "META": {
+ "CONTROLLER": "Verantwortliche: Matteo Caletti und Joe Kung (3D-Fab.ch).",
+ "CONTACT": "Datenschutzkontakt: info@3d-fab.ch"
+ },
+ "S1": {
+ "TITLE": "1. Welche Daten wir verarbeiten",
+ "P1": "1.1. Wir erfassen die für Angebote und Bestellungen erforderlichen Daten: Vorname, Nachname, E-Mail, Telefon, Adresse, Versand-/Rechnungsdaten und Bestelldetails.",
+ "P2": "1.2. Wenn Sie 3D-Dateien oder technische Anhänge hochladen, werden die Dateien nur für Analyse, Produktion, Support und Bestellverwaltung verarbeitet."
+ },
+ "S2": {
+ "TITLE": "2. Zweck der Verarbeitung",
+ "P1": "2.1. Wir verwenden Daten ausschließlich, um: Angebote zu erstellen, Bestellungen zu bestätigen, Zahlungen zu erhalten, Versand zu organisieren und After-Sales-Support bereitzustellen.",
+ "P2": "2.2. Wir verwenden Daten nicht für Profiling, automatisches Marketing oder Verkauf an Dritte."
+ },
+ "S3": {
+ "TITLE": "3. Speicherung von Dateien und Daten",
+ "P1": "3.1. Dateien, die nur für ein Angebot hochgeladen werden, werden für die Dauer der Sitzung gespeichert und bei Ablauf automatisch entfernt.",
+ "P2": "3.2. Dateien und Daten im Zusammenhang mit bestätigten Bestellungen werden so lange gespeichert, wie es für Produktion, Lieferung, Support und administrative/rechtliche Pflichten erforderlich ist, danach gelöscht oder minimiert.",
+ "P3": "3.3. Im Rechner hochgeladene Dateien werden nur für technische Analyse und Angebotsschätzung verwendet und bleiben ausschließlich mit der Rechner-Sitzung verknüpft."
+ },
+ "S4": {
+ "TITLE": "4. Cookies und Tracking",
+ "P1": "4.1. Wir verwenden keine Profiling-, Marketing- oder Drittanbieter-Tracking-Cookies.",
+ "P2": "4.2. Wir verwenden keine Advertising-Tracking-Systeme. Etwaige temporäre technische Daten werden nur für den Betrieb der Sitzung genutzt."
+ },
+ "S5": {
+ "TITLE": "5. Datenweitergabe",
+ "P1": "5.1. Wir teilen Daten nur mit für den Service strikt notwendigen Anbietern (Hosting, Zahlungen, Versand) und beschränken uns auf unerlässliche Informationen.",
+ "P2": "5.2. Anbieter verarbeiten Daten gemäß vertraglichen Weisungen und angemessenen Sicherheitsmaßnahmen."
+ },
+ "S6": {
+ "TITLE": "6. Rechte der Nutzer",
+ "P1": "6.1. Sie können Auskunft, Berichtigung, Löschung oder Einschränkung der Verarbeitung Ihrer Daten verlangen, im gesetzlich vorgesehenen Rahmen.",
+ "P2": "6.2. Für Datenschutzanfragen schreiben Sie an info@3d-fab.ch. Die italienische Version dieser Datenschutzerklärung ist die einzige rechtlich bindende Version, sofern nicht schriftlich anders vereinbart."
+ }
+ },
+ "TERMS": {
+ "META": {
+ "PROVIDER": "Anbieter: 3D-Fab.ch (Matteo Caletti und Joe Kung)",
+ "VERSION": "Version: v1.0",
+ "SCOPE": "Gültig für FDM/FFF-3D-Druck und verbundene Dienstleistungen, mit Verkauf und Lieferung ausschließlich in der Schweiz (CH)."
+ },
+ "S1": {
+ "TITLE": "1. Angaben zum Anbieter und Kontakte",
+ "P1": "1.1. Anbieter: Matteo Caletti und Joe Kung.",
+ "P2": "1.2. Adresse: Lyss-strasse 71, Nidau 2560, CH.",
+ "P3": "1.3. E-Mail: info@3d-fab.ch."
+ },
+ "S2": {
+ "TITLE": "2. Geltungsbereich",
+ "P1": "2.1. Diese AGB regeln 3D-Druck auf Anfrage, Zusatzleistungen (technische Beratung, CAD, Dateiprüfung, Nachbearbeitung) sowie eventuelle Standardartikel.",
+ "P2": "2.2. Der Anbieter verkauft und liefert ausschließlich in der Schweiz (CH).",
+ "P3": "2.3. Sie gelten für Bestellungen über Website, E-Mail oder andere vereinbarte Kanäle; abweichende Bedingungen des Kunden gelten nur bei schriftlicher Annahme."
+ },
+ "S3": {
+ "TITLE": "3. Definitionen",
+ "P1": "3.1. Kunde: natürliche oder juristische Person als Käufer. Kundendateien: bereitgestellte 3D-Modelle und technische Daten. Individuelles Produkt: nach Kundenspezifikation gefertigtes Teil. Bestellung: vom Anbieter angenommene Anfrage."
+ },
+ "S4": {
+ "TITLE": "4. Vertragsschluss und Bestellung",
+ "P1": "4.1. Der Vertrag kommt mit Auftragsbestätigung (E-Mail/Portal) oder mit Produktionsstart nach Zahlung/Anzahlung zustande.",
+ "P2": "4.2. Automatische Angebote können nach minimaler technischer Prüfung (Druckbarkeit, Stützen, Maschinenlimits) bestätigt oder aktualisiert werden.",
+ "P3": "4.3. Der Anbieter kann technisch nicht umsetzbare oder nicht konforme Bestellungen ablehnen."
+ },
+ "S5": {
+ "TITLE": "5. Preise, Steuern und Versand",
+ "P1": "5.1. Die Preise sind in CHF, sofern nicht anders angegeben bezüglich MwSt. inkl./exkl..",
+ "P2": "5.2. Versand und Verpackung werden, sofern anwendbar, separat ausgewiesen.",
+ "P3": "5.3. Für Kleinserien oder komplexes CAD können schriftliche Angebote mit spezifischen Bedingungen gelten (Muster, Staffelungen, Freigabe Erstteil)."
+ },
+ "S6": {
+ "TITLE": "6. Zahlungen",
+ "P1": "6.1. Akzeptierte Methoden: TWINT und Banküberweisung.",
+ "P2": "6.2. Sofern nicht anders vereinbart, startet die Produktion erst nach Zahlung.",
+ "P3": "6.3. Für CAD-Beratung und Kleinserien kann eine Anzahlung (30-100%) und/oder Restzahlung vor Lieferung verlangt werden.",
+ "P4": "6.4. Überweisungsdaten: Joe Kung, IBAN CH74 0900 0000 1548 2158 1, Via G. Pioda 29a, 6710 Biasca."
+ },
+ "S7": {
+ "TITLE": "7. Kundendateien und technische Verantwortung",
+ "P1": "7.1. Der Kunde garantiert, die Rechte an den Dateien zu haben und dass deren Nutzung keine Rechte Dritter verletzt (Urheberrecht, Patente, Lizenzen, Geschäftsgeheimnisse).",
+ "P2": "7.2. Der Kunde ist verantwortlich für Modellkorrektheit, Materialwahl, Eignung für den Endgebrauch und Einhaltung der anwendbaren Normen.",
+ "P3": "7.3. Der Anbieter kann Änderungen zur Verbesserung von Druckbarkeit und Ergebnis vorschlagen, übernimmt jedoch keine Zertifizierungsfunktion für das Endprodukt, außer bei schriftlicher Vereinbarung."
+ },
+ "S8": {
+ "TITLE": "8. FDM/FFF-Qualität und Toleranzen",
+ "P1": "8.1. FDM/FFF-Druck hat intrinsische Eigenschaften: Schichtlinien, mechanische Anisotropie, Mikro-Unvollkommenheiten, Farbabweichungen und mögliche Schrumpfung/Verzug in Abhängigkeit von Geometrie und Material.",
+ "P2": "8.2. Standardtoleranzen (sofern nicht schriftlich anders vereinbart): bis 100 mm +/-0.3 mm; über 100 mm +/-0.5% (mindestens +/-0.3 mm).",
+ "P3": "8.3. Kritische ästhetische oder dimensionale Anforderungen müssen vor der Bestellung vereinbart werden (z. B. Muster, Kontrollmaße, spezifische Oberflächen)."
+ },
+ "S9": {
+ "TITLE": "9. Nachbearbeitung und Zusatzarbeiten",
+ "P1": "9.1. Arbeiten wie Stützstrukturen entfernen, Schleifen, Grundieren/Lackieren oder Gewindeeinsätze erfolgen nur nach Vereinbarung und können dimensionale oder optische Abweichungen verursachen.",
+ "P2": "9.2. Auf Anfrage kann eine Freigabe des ersten Teils oder Musters vorgesehen werden, ggf. kostenpflichtig."
+ },
+ "S10": {
+ "TITLE": "10. Produktions- und Lieferzeiten",
+ "P1": "10.1. Die angegebenen Zeiten sind Schätzungen basierend auf Auslastung, Komplexität und Materialverfügbarkeit.",
+ "P2": "10.2. Verzögerungen durch externe Ursachen (Kuriere, Lieferanten, Ausfälle, höhere Gewalt) begründen keinen automatischen Anspruch auf Vertragsstrafen, außer bei schriftlicher Vereinbarung.",
+ "P3": "10.3. Der Kunde muss korrekte und vollständige Adressen angeben; etwaige Kosten für erneute Zustellung aufgrund falscher Adresse trägt der Kunde."
+ },
+ "S11": {
+ "TITLE": "11. Widerrufsrecht und Stornierung",
+ "P1": "11.1. Sofern nicht schriftlich bestätigte Ausnahmen vorliegen, besteht nach Bestellung kein Widerrufs- oder Rückgaberecht.",
+ "P2": "11.2. Individuelle Produkte sind nach Produktionsstart nicht stornierbar oder erstattbar.",
+ "P3": "11.3. Der Anbieter kann Ausnahmen vor Produktionsstart akzeptieren und bereits entstandene Kosten einbehalten.",
+ "P4": "11.4. Etwaige Sonderbedingungen müssen im Angebot, in der Auftragsbestätigung oder in schriftlicher Kommunikation festgehalten sein."
+ },
+ "S12": {
+ "TITLE": "12. Reklamationen, Mängel und Rechtsbehelfe",
+ "P1": "12.1. Der Kunde muss die Produkte bei Lieferung prüfen und eventuelle Mängel innerhalb von 7 Tagen schriftlich mit Foto/Video und Beschreibung melden.",
+ "P2": "12.2. Typische FDM-Merkmale, kleine Farbabweichungen, nicht-funktionale Unvollkommenheiten oder Toleranzen innerhalb der vereinbarten Grenzen gelten nicht automatisch als Mangel.",
+ "P3": "12.3. Bei einem vom Anbieter zu vertretenden Mangel sind die Rechtsbehelfe nach Wahl des Anbieters: Neudruck/Ersatz oder Rückerstattung begrenzt auf den Wert des mangelhaften Teils bzw. der Bestellung.",
+ "P4": "12.4. Vor Neudruck oder Rückerstattung kann die Rückgabe des Teils verlangt werden; wird der Mangel bestätigt, trägt der Anbieter die Rücksendekosten."
+ },
+ "S13": {
+ "TITLE": "13. Verbotene Nutzungen und Konformität",
+ "P1": "13.1. Der Anbieter kann Bestellungen zu illegalen Objekten, Waffen oder regulierten Teilen sowie sicherheitskritischen oder medizinischen Anwendungen ohne spezielle Vereinbarungen und Validierungen ablehnen.",
+ "P2": "13.2. Der Kunde bleibt für den Endgebrauch und die regulatorische Konformität des Produkts verantwortlich."
+ },
+ "S14": {
+ "TITLE": "14. Geistiges Eigentum und Lizenzen",
+ "P1": "14.1. Rechte an Kundendateien bleiben beim Kunden bzw. den jeweiligen Rechteinhabern. Der Kunde gewährt dem Anbieter eine auf technische Bewertung und Produktion beschränkte Lizenz.",
+ "P2": "14.2. Sofern nicht anders vereinbart, werden vom Anbieter entwickelte Dateien und CAD-Projekte nach Zahlung mit Nutzungsrecht für die vereinbarten Zwecke übergeben.",
+ "P3": "14.3. Der Kunde stellt den Anbieter von Ansprüchen Dritter im Zusammenhang mit vom Kunden bereitgestellten Dateien oder Anweisungen frei."
+ },
+ "S15": {
+ "TITLE": "15. Datenschutz",
+ "P1": "15.1. Der Anbieter verarbeitet personenbezogene Daten für Bestellverwaltung, Zahlungen, Versand und Support.",
+ "P2": "15.2. Daten können nur im erforderlichen Umfang zur Leistungserbringung mit technischen Anbietern und Kurieren geteilt werden."
+ },
+ "S16": {
+ "TITLE": "16. Haftungsbeschränkung",
+ "P1": "16.1. Im gesetzlichen Rahmen haftet der Anbieter nur für vorhersehbare direkte Schäden und in jedem Fall nicht über den Auftragswert des betroffenen Produkts oder der beanstandeten Dienstleistung hinaus.",
+ "P2": "16.2. Mittelbare Schäden, entgangener Gewinn, Betriebsunterbrechung, Datenverlust und Folgeschäden sind im zulässigen Rahmen ausgeschlossen.",
+ "P3": "16.3. Gesetzlich nicht ausschließbare Haftungen bleiben unberührt (z. B. Vorsatz oder grobe Fahrlässigkeit)."
+ },
+ "S17": {
+ "TITLE": "17. Höhere Gewalt",
+ "P1": "17.1. Ereignisse außerhalb der zumutbaren Kontrolle des Anbieters (Ausfälle, Blackout, Lieferverzögerungen, Streiks, behördliche Maßnahmen) können zu Fristverlängerungen oder Aussetzungen ohne Haftung führen."
+ },
+ "S18": {
+ "TITLE": "18. Anwendbares Recht und Gerichtsstand",
+ "P1": "18.1. Es gilt schweizerisches Recht.",
+ "P2": "18.2. Gerichtsstand: Sitz des Anbieters, vorbehaltlich zwingender Verbraucherschutzvorschriften.",
+ "P3": "18.3. Bei Auslegungsunterschieden gilt die italienische Version dieser Bedingungen und ist die einzige rechtlich bindende Version, sofern nicht schriftlich anders vereinbart."
+ }
+ },
+ "TERMS_UPDATE_DATE": "24. Februar 2026",
+ "PRIVACY_UPDATE_DATE": "24. Februar 2026"
+ },
+ "CONTACT": {
+ "TITLE": "Kontaktieren Sie uns",
+ "SEND": "Nachricht senden",
+ "REQ_TYPE_LABEL": "Anfrageart",
+ "TYPE_PRIVATE": "Privat",
+ "TYPE_COMPANY": "Unternehmen",
+ "REQ_TYPE_CUSTOM": "Individuelles Angebot",
+ "REQ_TYPE_SERIES": "Serienfertigung",
+ "REQ_TYPE_CONSULT": "Beratung",
+ "REQ_TYPE_QUESTION": "Allgemeine Fragen",
+ "PHONE": "Telefon",
+ "IS_COMPANY": "Sind Sie ein Unternehmen?",
+ "COMPANY_NAME": "Firmenname",
+ "REF_PERSON": "Ansprechperson",
+ "UPLOAD_LABEL": "Anhänge",
+ "UPLOAD_HINT": "Max. 15 Dateien. Unterstützt: Bilder, Videos, PDF, Office-Dokumente, STL/STEP/3MF/OBJ/IGES, DWG/DXF. Komprimierte Dateien sind nicht erlaubt.",
+ "DROP_FILES": "Dateien hier ablegen oder klicken zum Hochladen",
+ "PLACEHOLDER_NAME": "Ihr Name",
+ "PLACEHOLDER_EMAIL": "ihre@email.com",
+ "PLACEHOLDER_PHONE": "+41 00 000 00 00",
+ "PLACEHOLDER_COMPANY": "Firmenname",
+ "PLACEHOLDER_REF_PERSON": "Ansprechperson",
+ "LABEL_MESSAGE": "Nachricht *",
+ "LABEL_EMAIL": "E-Mail *",
+ "LABEL_NAME": "Name *",
+ "MSG_SENT": "Gesendet!",
+ "ERR_MAX_FILES": "Maximallimit von 15 Dateien erreicht.",
+ "ERR_COMPRESSED_FILES": "Komprimierte Dateien sind nicht erlaubt (ZIP/RAR/7z/TAR/GZ).",
+ "SUCCESS_TITLE": "Nachricht erfolgreich gesendet",
+ "SUCCESS_DESC": "Vielen Dank für Ihre Kontaktaufnahme. Wir haben Ihre Nachricht erhalten und senden Ihnen in Kürze eine Zusammenfassungs-E-Mail.",
+ "SEND_ANOTHER": "Weitere Nachricht senden",
+ "FILE_TYPE_PDF": "PDF",
+ "FILE_TYPE_3D": "3D",
+ "FILE_TYPE_VIDEO": "Video",
+ "FILE_TYPE_DOC": "DOC",
+ "FILE_TYPE_FILE": "DATEI",
+ "ERROR_SUBMIT": "Fehler beim Senden der Anfrage. Bitte versuchen Sie es erneut.",
+ "REMOVE_FILE": "Angehängte Datei entfernen",
+ "HERO_SUBTITLE": "Wir sind hier, um Ihnen zu helfen. Füllen Sie das untenstehende Formular für jede Anfrage aus."
+ },
+ "CHECKOUT": {
+ "TITLE": "Checkout",
+ "SUBTITLE": "Schließen Sie Ihre Bestellung ab, indem Sie Versand- und Zahlungsdetails eingeben.",
+ "CONTACT_INFO": "Kontaktinformationen",
+ "BILLING_ADDR": "Rechnungsadresse",
+ "SHIPPING_ADDR": "Lieferadresse",
+ "FIRST_NAME": "Vorname",
+ "LAST_NAME": "Nachname",
+ "EMAIL": "E-Mail",
+ "PHONE": "Telefon",
+ "COMPANY_NAME": "Firmenname",
+ "ADDRESS_1": "Adresse (Straße und Nummer)",
+ "ADDRESS_2": "Zusätzliche Informationen (optional)",
+ "ZIP": "PLZ",
+ "CITY": "Ort",
+ "COUNTRY": "Land",
+ "SHIPPING_SAME": "Die Lieferadresse ist gleich der Rechnungsadresse",
+ "PLACE_ORDER": "Bestellung absenden",
+ "PROCESSING": "Verarbeitung...",
+ "SUMMARY_TITLE": "Bestellübersicht",
+ "SUBTOTAL": "Zwischensumme",
+ "ITEMS_BASE_SUBTOTAL": "Artikelbasis-Zwischensumme",
+ "MACHINE_COST": "Maschinenkosten",
+ "SETUP_FEE": "Einrichtungskosten",
+ "TOTAL": "Gesamt",
+ "QTY": "Menge",
+ "PER_PIECE": "pro Stück",
+ "SHIPPING": "Versand (CH)",
+ "ERR_NO_SESSION_START": "Keine aktive Sitzung gefunden. Bitte starten Sie ein neues Angebot.",
+ "ERR_LOAD_SESSION": "Sitzungsdetails konnten nicht geladen werden. Bitte erneut versuchen.",
+ "ERR_NO_SESSION_CREATE_ORDER": "Keine aktive Sitzung gefunden. Bestellung kann nicht erstellt werden.",
+ "ERR_CREATE_ORDER": "Bestellung konnte nicht erstellt werden. Bitte erneut versuchen.",
+ "INVALID_EMAIL": "Ungültige E-Mail",
+ "COMPANY_OPTIONAL": "Firmenname (Optional)",
+ "REF_PERSON_OPTIONAL": "Ansprechperson (Optional)",
+ "SHIPPING_CALCULATED_NEXT_STEP": "Versandkosten werden im nächsten Schritt berechnet",
+ "EXCLUDES_SHIPPING": "Versandkosten ausgeschlossen"
+ },
+ "PAYMENT": {
+ "TITLE": "Zahlung",
+ "METHOD": "Zahlungsmethode",
+ "TWINT_TITLE": "Mit TWINT bezahlen",
+ "TWINT_DESC": "Scannen Sie den Code mit der TWINT-App, auf Mobilgeräten klicken Sie auf die Schaltfläche.",
+ "TWINT_OPEN": "Direkt in TWINT öffnen",
+ "TWINT_LINK": "Zahlungslink öffnen",
+ "BANK_TITLE": "Banküberweisung",
+ "BANK_OWNER": "Kontoinhaber",
+ "BANK_IBAN": "IBAN",
+ "BANK_REF": "Referenz",
+ "BILLING_INFO_HINT": "Wir haben die Felder für Sie ausgefüllt, bitte den Zahlungszweck nicht ändern",
+ "DOWNLOAD_QR": "QR-Rechnung herunterladen (PDF)",
+ "DOWNLOAD_CONFIRMATION": "Bestätigung herunterladen (PDF)",
+ "CONFIRM": "Ich habe die Zahlung abgeschlossen",
+ "SUMMARY_TITLE": "Bestellübersicht",
+ "SUBTOTAL": "Zwischensumme",
+ "SHIPPING": "Versand",
+ "SETUP_FEE": "Einrichtungskosten",
+ "TOTAL": "Gesamt",
+ "LOADING": "Bestelldetails werden geladen...",
+ "METHOD_TWINT": "TWINT",
+ "METHOD_BANK": "QR-Rechnung / Überweisung",
+ "STATUS_REPORTED_TITLE": "Bestellung in Bearbeitung",
+ "STATUS_REPORTED_DESC": "Wir haben Ihren Vorgang registriert. Sobald wir die Zahlung bestätigen, geht die Bestellung in Produktion.",
+ "IN_VERIFICATION": "Zahlung gemeldet",
+ "TWINT_QR_ALT": "TWINT-Zahlungs-QR",
+ "TWINT_BUTTON_ALT": "Eingebettete TWINT-Schaltfläche"
+ },
+ "TRACKING": {
+ "TITLE": "Bestellstatus",
+ "SUBTITLE": "Prüfen Sie den Status Ihrer Bestellung und verwalten Sie bei Bedarf die Zahlung.",
+ "STEP_PENDING": "Ausstehend",
+ "STEP_REPORTED": "In Prüfung",
+ "STEP_PRODUCTION": "In Produktion",
+ "STEP_SHIPPED": "Versendet"
+ },
+ "ORDER_CONFIRMED": {
+ "TITLE": "Bestellung bestätigt",
+ "SUBTITLE": "Zahlung erfasst. Ihre Bestellung wird nun bearbeitet.",
+ "STATUS": "In Bearbeitung",
+ "HEADING": "Wir bereiten Ihre Bestellung vor",
+ "ORDER_REF": "Bestellreferenz",
+ "PROCESSING_TEXT": "Sobald wir die Zahlung bestätigen, geht Ihre Bestellung in Produktion.",
+ "EMAIL_TEXT": "Wir senden Ihnen eine E-Mail mit Statusupdate und nächsten Schritten.",
+ "BACK_HOME": "Zur Startseite"
+ },
+ "STL_VIEWER": {
+ "LOADING": "3D-Modell wird geladen..."
+ },
+ "HOME": {
+ "SHOP_GALLERY_ARIA": "Produktgalerie Shop",
+ "FOUNDER_PREV_ARIA": "Vorheriges Foto",
+ "FOUNDER_NEXT_ARIA": "Nächstes Foto",
+ "SHOP_IMAGE_ALT_1": "Technisches 3D-gedrucktes Produkt",
+ "FOUNDER_IMAGE_ALT_1": "Gründer - Foto 1",
+ "FOUNDER_IMAGE_ALT_2": "Gründer - Foto 2",
+ "HERO_EYEBROW": "Technischer 3D-Druck für Unternehmen, Freelancer und Maker",
+ "HERO_TITLE": "Preis und Lieferzeit in wenigen Sekunden. Von der 3D-Datei zum fertigen Teil.",
+ "HERO_LEAD": "Der fortschrittlichste Rechner für Ihre 3D-Drucke: maximale Präzision und keine Überraschungen.",
+ "HERO_SUBTITLE": "Wir bieten auch CAD-Services für individuelle Teile an!",
+ "BTN_CALCULATE": "Angebot berechnen",
+ "BTN_SHOP": "Zum Shop",
+ "BTN_CONTACT": "Mit uns sprechen",
+ "SEC_CALC_TITLE": "Korrekte Preisberechnung in wenigen Sekunden",
+ "SEC_CALC_SUBTITLE": "Keine Registrierung erforderlich. Die Schätzung basiert auf echtem Slicing.",
+ "SEC_CALC_LIST_1": "Unterstützte Formate: STL, 3MF, STEP",
+ "CARD_CALC_EYEBROW": "Automatische Berechnung",
+ "CARD_CALC_TITLE": "Preis und Lieferzeit mit einem Klick",
+ "CARD_CALC_TAG": "Ohne Registrierung",
+ "CARD_CALC_STEP_1": "3D-Datei hochladen",
+ "CARD_CALC_STEP_2": "Material und Qualität wählen",
+ "CARD_CALC_STEP_3": "Kosten und Zeit sofort erhalten",
+ "BTN_OPEN_CALC": "Rechner öffnen",
+ "SEC_CAP_TITLE": "Was Sie erhalten können",
+ "SEC_CAP_SUBTITLE": "Maßgeschneiderte Produktion für Prototypen, Kleinserien und individuelle Teile.",
+ "CAP_1_TITLE": "Schnelles Prototyping",
+ "CAP_1_TEXT": "Von der digitalen Datei zum physischen Modell in 24/48 Stunden. Prüfen Sie Ergonomie, Passungen und Funktion vor der finalen Form.",
+ "CAP_2_TITLE": "Individuelle Teile",
+ "CAP_2_TEXT": "Einzigartige Komponenten, die am Markt schwer zu finden sind. Wir reproduzieren defekte Teile oder erstellen maßgeschneiderte Anpassungen.",
+ "CAP_3_TITLE": "Kleinserien",
+ "CAP_3_TEXT": "Brückenproduktion oder limitierte Serien (10-500 Stück) mit reproduzierbarer Qualität.",
+ "CAP_4_TITLE": "Beratung und CAD",
+ "CAP_4_TEXT": "Sie haben noch keine 3D-Datei? Wir helfen beim Entwurf, bei der Druckoptimierung und bei der Auswahl des richtigen Materials.",
+ "SEC_SHOP_TITLE": "Shop",
+ "SEC_SHOP_TEXT": "Ausgewählte Produkte, einsatzbereit.",
+ "SEC_SHOP_LIST_1": "Von uns entwickelte Produkte",
+ "SEC_SHOP_LIST_2": "Ersatzteile und Komponenten, die schwer zu beschaffen sind",
+ "SEC_SHOP_LIST_3": "Halterungen und Organizer zur Optimierung Ihrer Arbeitsabläufe",
+ "BTN_DISCOVER": "Produkte entdecken",
+ "BTN_REQ_SOLUTION": "Lösung anfragen",
+ "CARD_SHOP_1_TITLE": "Auswahl geprüfter Produkte",
+ "CARD_SHOP_1_TEXT": "Geprüft, um langfristige Funktionalität und Stabilität zu gewährleisten.",
+ "CARD_SHOP_2_TITLE": "Einsatzfertige Kits",
+ "CARD_SHOP_2_TEXT": "Kompatible Komponenten, leicht montierbar und ohne Überraschungen.",
+ "CARD_SHOP_3_TITLE": "Auf Anfrage",
+ "CARD_SHOP_3_TEXT": "Sie finden nicht, was Sie brauchen? Wir entwickeln und produzieren es für Sie.",
+ "SEC_ABOUT_TITLE": "Über uns",
+ "SEC_ABOUT_TEXT": "Wir sind zwei Ingenieurstudenten: 3D-Druck hat uns aus einem einfachen Grund begeistert – ein Problem sehen und die Lösung bauen. Aus dieser Idee entstehen Prototypen und Objekte, die im Alltag funktionieren.",
+ "FOUNDERS_PHOTO": "Foto der Gründer"
+ },
+ "ORDER": {
+ "ERR_ID_NOT_FOUND": "Bestell-ID nicht gefunden.",
+ "ERR_LOAD_ORDER": "Bestelldetails konnten nicht geladen werden.",
+ "ERR_REPORT_PAYMENT": "Zahlung konnte nicht gemeldet werden. Bitte erneut versuchen.",
+ "NOT_AVAILABLE": "N/V"
+ },
+ "DROPZONE": {
+ "DEFAULT_LABEL": "Dateien hierher ziehen oder klicken zum Hochladen",
+ "DEFAULT_SUBTEXT": "Unterstützt .STL, .3MF, .STEP"
+ },
+ "COLOR": {
+ "AVAILABLE_COLORS": "Verfügbare Farben",
+ "CATEGORY_GLOSSY": "Glänzend",
+ "CATEGORY_MATTE": "Matt",
+ "NAME": {
+ "BLACK": "Schwarz",
+ "WHITE": "Weiß",
+ "RED": "Rot",
+ "BLUE": "Blau",
+ "GREEN": "Grün",
+ "YELLOW": "Gelb",
+ "MATTE_BLACK": "Matt Schwarz",
+ "MATTE_WHITE": "Matt Weiß",
+ "MATTE_GRAY": "Matt Grau"
+ }
+ },
+ "COMMON": {
+ "REQUIRED": "Pflichtfeld",
+ "INVALID_EMAIL": "Ungültige E-Mail",
+ "BACK": "Zurück",
+ "OPTIONAL": "(Optional)"
+ }
+}
diff --git a/frontend/src/assets/i18n/en.json b/frontend/src/assets/i18n/en.json
index 11de056..cb443ef 100644
--- a/frontend/src/assets/i18n/en.json
+++ b/frontend/src/assets/i18n/en.json
@@ -4,7 +4,8 @@
"CALCULATOR": "Calculator",
"SHOP": "Shop",
"ABOUT": "About Us",
- "CONTACT": "Contact Us"
+ "CONTACT": "Contact Us",
+ "LANGUAGE_SELECTOR": "Language selector"
},
"QUOTE": {
"CONSULT": "Request Consultation",
@@ -214,7 +215,7 @@
"S6": {
"TITLE": "6. User rights",
"P1": "6.1. You can request access, rectification, deletion or restriction of processing of your data, within the limits provided by law.",
- "P2": "6.2. For any privacy request write to info@3d-fab.ch."
+ "P2": "6.2. For any privacy request write to info@3d-fab.ch. The Italian version of this privacy policy is the only legally binding version, unless otherwise agreed in writing."
}
},
"TERMS": {
diff --git a/frontend/src/assets/i18n/fr.json b/frontend/src/assets/i18n/fr.json
new file mode 100644
index 0000000..1dcf7f7
--- /dev/null
+++ b/frontend/src/assets/i18n/fr.json
@@ -0,0 +1,546 @@
+{
+ "NAV": {
+ "HOME": "Accueil",
+ "CALCULATOR": "Calculateur",
+ "SHOP": "Boutique",
+ "ABOUT": "Qui sommes-nous",
+ "CONTACT": "Contactez-nous",
+ "LANGUAGE_SELECTOR": "Sélecteur de langue"
+ },
+ "FOOTER": {
+ "PRIVACY": "Confidentialité",
+ "TERMS": "Conditions générales",
+ "CONTACT": "Contactez-nous"
+ },
+ "HOME": {
+ "HERO_EYEBROW": "Impression 3D technique pour entreprises, freelances et makers",
+ "HERO_TITLE": "Prix et délais en quelques secondes. Du fichier 3D à la pièce finie.",
+ "HERO_LEAD": "Le calculateur le plus avancé pour vos impressions 3D : précision totale et zéro surprise.",
+ "HERO_SUBTITLE": "Nous proposons aussi des services CAD pour des pièces personnalisées !",
+ "BTN_CALCULATE": "Calculer un devis",
+ "BTN_SHOP": "Aller à la boutique",
+ "BTN_CONTACT": "Parlez avec nous",
+ "SEC_CALC_TITLE": "Prix correct en quelques secondes",
+ "SEC_CALC_SUBTITLE": "Aucune inscription requise. L'estimation est effectuée via un vrai slicing.",
+ "SEC_CALC_LIST_1": "Formats pris en charge : STL, 3MF, STEP",
+ "CARD_CALC_EYEBROW": "Calcul automatique",
+ "CARD_CALC_TITLE": "Prix et délais en un clic",
+ "CARD_CALC_TAG": "Sans inscription",
+ "CARD_CALC_STEP_1": "Chargez le fichier 3D",
+ "CARD_CALC_STEP_2": "Choisissez le matériau et la qualité",
+ "CARD_CALC_STEP_3": "Recevez immédiatement coût et délai",
+ "BTN_OPEN_CALC": "Ouvrir le calculateur",
+ "SEC_CAP_TITLE": "Ce que vous pouvez obtenir",
+ "SEC_CAP_SUBTITLE": "Production sur mesure pour prototypes, petites séries et pièces personnalisées.",
+ "CAP_1_TITLE": "Prototypage rapide",
+ "CAP_1_TEXT": "Du fichier numérique au modèle physique en 24/48 heures. Vérifiez ergonomie, emboîtements et fonctionnement avant le moule définitif.",
+ "CAP_2_TITLE": "Pièces personnalisées",
+ "CAP_2_TEXT": "Composants uniques introuvables dans le commerce. Nous reproduisons des pièces cassées ou créons des adaptations sur mesure.",
+ "CAP_3_TITLE": "Petites séries",
+ "CAP_3_TEXT": "Production intermédiaire ou séries limitées (10-500 pièces) avec qualité reproductible.",
+ "CAP_4_TITLE": "Conseil et CAD",
+ "CAP_4_TEXT": "Vous n'avez pas de fichier 3D ? Nous vous aidons à le concevoir, à l'optimiser pour l'impression et à choisir le bon matériau ensemble.",
+ "SEC_SHOP_TITLE": "Boutique",
+ "SEC_SHOP_TEXT": "Produits sélectionnés et prêts à l'emploi.",
+ "SEC_SHOP_LIST_1": "Produits conçus par nous",
+ "SEC_SHOP_LIST_2": "Pièces de rechange et composants difficiles à trouver",
+ "SEC_SHOP_LIST_3": "Supports et organiseurs pour améliorer les flux de travail",
+ "BTN_DISCOVER": "Découvrir les produits",
+ "BTN_REQ_SOLUTION": "Demander une solution",
+ "CARD_SHOP_1_TITLE": "Sélection de produits vérifiés",
+ "CARD_SHOP_1_TEXT": "Contrôlés pour garantir fonctionnalité et stabilité dans le temps.",
+ "CARD_SHOP_2_TITLE": "Kits prêts à l'emploi",
+ "CARD_SHOP_2_TEXT": "Composants compatibles et faciles à monter, sans surprise.",
+ "CARD_SHOP_3_TITLE": "Sur demande",
+ "CARD_SHOP_3_TEXT": "Vous ne trouvez pas ce qu'il vous faut ? Nous le concevons et le produisons pour vous.",
+ "SEC_ABOUT_TITLE": "À propos de nous",
+ "SEC_ABOUT_TEXT": "Nous sommes deux étudiants en ingénierie : l'impression 3D nous a conquis pour une raison simple, voir un problème et construire la solution. De cette idée naissent des prototypes et des objets conçus pour fonctionner au quotidien.",
+ "FOUNDERS_PHOTO": "Photo des fondateurs",
+ "SHOP_GALLERY_ARIA": "Galerie produits boutique",
+ "FOUNDER_PREV_ARIA": "Photo précédente",
+ "FOUNDER_NEXT_ARIA": "Photo suivante",
+ "SHOP_IMAGE_ALT_1": "Produit technique imprimé en 3D",
+ "FOUNDER_IMAGE_ALT_1": "Fondateur - photo 1",
+ "FOUNDER_IMAGE_ALT_2": "Fondateur - photo 2"
+ },
+ "CALC": {
+ "TITLE": "Calculer un devis 3D",
+ "SUBTITLE": "Chargez votre fichier 3D (STL, 3MF, STEP), réglez la qualité et la couleur puis calculez immédiatement prix et délais.",
+ "CTA_START": "Commencer maintenant",
+ "BUSINESS": "Entreprises",
+ "PRIVATE": "Particuliers",
+ "MODE_EASY": "Base",
+ "MODE_ADVANCED": "Avancée",
+ "UPLOAD_LABEL": "Glissez votre fichier 3D ici",
+ "UPLOAD_SUB": "Nous prenons en charge STL, 3MF, STEP jusqu'à 50MB",
+ "MATERIAL": "Matériau",
+ "QUALITY": "Qualité",
+ "PRINT_SPEED": "Vitesse d'impression",
+ "QUANTITY": "Quantité",
+ "NOTES": "Notes supplémentaires",
+ "COLOR": "Couleur",
+ "INFILL": "Remplissage (%)",
+ "PATTERN": "Motif de remplissage",
+ "LAYER_HEIGHT": "Hauteur de couche",
+ "NOZZLE": "Diamètre de buse",
+ "SUPPORT": "Supports",
+ "SUPPORT_DESC": "Activer les supports pour les surplombs",
+ "CALCULATE": "Calculer le devis",
+ "RESULT": "Devis estimé",
+ "TIME": "Temps d'impression",
+ "MACHINE_COST": "Coût machine",
+ "COST": "Coût total",
+ "ORDER": "Commander maintenant",
+ "CONSULT": "Demander une consultation",
+ "ERROR_GENERIC": "Une erreur s'est produite pendant le calcul du devis.",
+ "NEW_QUOTE": "Calculer un nouveau devis",
+ "ORDER_SUCCESS_TITLE": "Commande envoyée avec succès",
+ "ORDER_SUCCESS_DESC": "Nous avons reçu les détails de votre commande. Vous recevrez bientôt un e-mail de confirmation avec les informations de paiement.",
+ "BENEFITS_TITLE": "Pourquoi nous choisir ?",
+ "BENEFITS_1": "Devis automatique avec coût et délai immédiats",
+ "BENEFITS_2": "Matériaux sélectionnés et qualité contrôlée",
+ "BENEFITS_3": "Conseil CAD si le fichier nécessite des modifications",
+ "ERR_FILE_REQUIRED": "Le fichier est obligatoire.",
+ "ANALYZING_TITLE": "Analyse en cours...",
+ "ANALYZING_TEXT": "Nous analysons la géométrie et calculons le parcours outil.",
+ "QTY_SHORT": "QTÉ",
+ "COLOR_LABEL": "COULEUR",
+ "ADD_FILES": "Ajouter des fichiers",
+ "UPLOADING": "Téléversement...",
+ "PROCESSING": "Traitement...",
+ "NOTES_PLACEHOLDER": "Instructions spécifiques...",
+ "SETUP_NOTE": "* Inclut {{cost}} comme coût de setup",
+ "SHIPPING_NOTE": "** Frais d'expédition exclus, calculés à l'étape suivante",
+ "STEP_WARNING": "La visualisation 3D n'est pas compatible avec les fichiers STEP et 3MF",
+ "REMOVE_FILE": "Supprimer le fichier",
+ "FALLBACK_MATERIAL": "PLA (fallback)",
+ "FALLBACK_QUALITY_STANDARD": "Standard",
+ "ERR_FILE_TOO_LARGE": "Certains fichiers dépassent la limite de 200MB et n'ont pas été ajoutés."
+ },
+ "QUOTE": {
+ "PROCEED_ORDER": "Procéder à la commande",
+ "CONSULT": "Demander une consultation",
+ "TOTAL": "Total",
+ "MAX_QTY_NOTICE": "Pour des quantités supérieures à {{max}} pièces, demandez une consultation."
+ },
+ "USER_DETAILS": {
+ "TITLE": "Vos données",
+ "NAME": "Prénom",
+ "NAME_PLACEHOLDER": "Votre prénom",
+ "SURNAME": "Nom",
+ "SURNAME_PLACEHOLDER": "Votre nom",
+ "EMAIL": "E-mail",
+ "EMAIL_PLACEHOLDER": "votre@email.com",
+ "PHONE": "Téléphone",
+ "PHONE_PLACEHOLDER": "+41 ...",
+ "ADDRESS": "Adresse",
+ "ADDRESS_PLACEHOLDER": "Rue et numéro",
+ "ZIP": "Code postal",
+ "ZIP_PLACEHOLDER": "0000",
+ "CITY": "Ville",
+ "CITY_PLACEHOLDER": "Ville",
+ "SUBMIT": "Continuer",
+ "SUMMARY_TITLE": "Récapitulatif",
+ "DEFAULT_COLOR": "Par défaut"
+ },
+ "COMMON": {
+ "REQUIRED": "Champ obligatoire",
+ "INVALID_EMAIL": "E-mail invalide",
+ "BACK": "Retour",
+ "OPTIONAL": "(Optionnel)"
+ },
+ "SHOP": {
+ "TITLE": "Solutions techniques",
+ "SUBTITLE": "Produits prêts à l'emploi qui résolvent des problèmes pratiques",
+ "WIP_EYEBROW": "Work in progress",
+ "WIP_TITLE": "Boutique en préparation",
+ "WIP_SUBTITLE": "Nous préparons une boutique avec des produits sélectionnés et des fonctionnalités de création automatique !",
+ "WIP_CTA_CALC": "Aller au calculateur",
+ "WIP_RETURN_LATER": "Revenez dans un moment",
+ "WIP_NOTE": "Nous tenons à bien faire les choses : en attendant, vous pouvez calculer immédiatement prix et délais d'un fichier 3D avec notre calculateur.",
+ "ADD_CART": "Ajouter au panier",
+ "BACK": "Retour à la boutique",
+ "NOT_FOUND": "Produit introuvable.",
+ "DETAILS": "Détails",
+ "MOCK_ADD_CART": "Ajouté au panier (Mock)",
+ "SUCCESS_TITLE": "Ajouté au panier",
+ "SUCCESS_DESC": "Le produit a été ajouté au panier avec succès.",
+ "CONTINUE": "Continuer",
+ "CATEGORIES": {
+ "FILAMENTS": "Filaments",
+ "ACCESSORIES": "Accessoires"
+ },
+ "PRODUCTS": {
+ "P1": {
+ "NAME": "Filament PLA Standard",
+ "DESC": "Le classique pour chaque impression, simple et fiable."
+ },
+ "P2": {
+ "NAME": "Filament PETG Tough",
+ "DESC": "Résistant aux chocs et aux températures."
+ },
+ "P3": {
+ "NAME": "Kit de buses (0.4mm)",
+ "DESC": "Kit de remplacement pour extrudeur FDM."
+ }
+ }
+ },
+ "ABOUT": {
+ "TITLE": "Qui sommes-nous",
+ "EYEBROW": "Atelier d'impression 3D",
+ "SUBTITLE": "Nous sommes deux étudiants avec beaucoup d'envie de faire et d'apprendre.",
+ "HOW_TEXT": "3D Fab est né de l'intérêt initial de Matteo pour l'impression 3D. Il a acheté une imprimante et a commencé à expérimenter sérieusement. \n À un certain moment, les premières demandes sont arrivées : une pièce cassée à remplacer, une pièce de rechange introuvable, un adaptateur pratique à avoir. Les demandes ont augmenté et nous nous sommes dit : d'accord, faisons-le bien.\nEnsuite, nous avons créé un calculateur pour connaître le coût à l'avance : cela a été l'un des premiers pas qui nous a fait passer de « on fait quelques pièces » à un vrai projet, ensemble.",
+ "PASSIONS_TITLE": "Nos passions",
+ "PASSION_BIKE_TRIAL": "Bike trial",
+ "PASSION_MOUNTAIN": "Montagne",
+ "PASSION_SKI": "Ski",
+ "PASSION_SELF_HOSTING": "Self hosting",
+ "PASSION_PRINT_3D": "Impression 3D",
+ "PASSION_TRAVEL": "Voyage",
+ "PASSION_SNOWBOARD": "Snowboard",
+ "PASSION_SNOWBOARD_INSTRUCTOR": "Moniteur de snowboard",
+ "PASSION_ELECTRONICS": "Électronique",
+ "PASSION_WOODWORKING": "Travail du bois",
+ "PASSION_VAN_LIFE": "Van life",
+ "PASSION_COFFEE": "Café",
+ "PASSION_SOFTWARE_DEVELOPMENT": "Développement logiciel",
+ "SERVICES_TITLE": "Services principaux",
+ "TARGET_TITLE": "Pour qui",
+ "TARGET_TEXT": "Petites entreprises, freelances, makers et clients qui cherchent un produit prêt à l'emploi dans la boutique.",
+ "TEAM_TITLE": "Notre équipe",
+ "MEMBER_JOE_NAME": "Joe Küng",
+ "MEMBER_JOE_ROLE": "Étudiant en ingénierie informatique",
+ "MEMBER_JOE_ALT": "Joe Küng",
+ "MEMBER_MATTEO_NAME": "Matteo Caletti",
+ "MEMBER_MATTEO_ROLE": "Étudiant en ingénierie électronique",
+ "MEMBER_MATTEO_ALT": "Matteo Caletti"
+ },
+ "LOCATIONS": {
+ "TITLE": "Nos sites",
+ "SUBTITLE": "Nous sommes présents sur deux sites. Sélectionnez le site pour voir les détails.",
+ "TICINO": "Tessin",
+ "BIASCA": "Biasca",
+ "BIENNE": "Bienne",
+ "ADDRESS_TICINO": "Via G. Pioda 29a, Biasca",
+ "ADDRESS_BIENNE": "Lyss-strasse 71, Nidau 2560 Bienne",
+ "CONTACT_US": "Contactez-nous"
+ },
+ "LEGAL": {
+ "PRIVACY_TITLE": "Politique de confidentialité",
+ "TERMS_TITLE": "Conditions générales",
+ "LAST_UPDATE": "Dernière mise à jour",
+ "TERMS_UPDATE_DATE": "24 février 2026",
+ "PRIVACY_UPDATE_DATE": "24 février 2026",
+ "CONSENT": {
+ "LABEL_PREFIX": "J'ai lu et j'accepte les",
+ "TERMS_LINK": "Conditions générales",
+ "AND": "et la",
+ "PRIVACY_LINK": "Politique de confidentialité",
+ "REQUIRED_ERROR": "Pour continuer vous devez accepter les Conditions et la Confidentialité.",
+ "UPLOAD_NOTICE_PREFIX": "En téléversant un fichier vous acceptez notre",
+ "UPLOAD_NOTICE_LINK": "Politique de confidentialité"
+ },
+ "PRIVACY": {
+ "META": {
+ "CONTROLLER": "Responsables du traitement : Matteo Caletti et Joe Kung (3D-Fab.ch).",
+ "CONTACT": "Contact confidentialité : info@3d-fab.ch"
+ },
+ "S1": {
+ "TITLE": "1. Quelles données nous traitons",
+ "P1": "1.1. Nous collectons les données nécessaires aux devis et aux commandes : prénom, nom, e-mail, téléphone, adresse, données de livraison/facturation et détails de la commande.",
+ "P2": "1.2. Lorsque vous téléversez des fichiers 3D ou des pièces jointes techniques, les fichiers sont traités uniquement pour l'analyse, la production, l'assistance et la gestion de la commande."
+ },
+ "S2": {
+ "TITLE": "2. Finalité du traitement",
+ "P1": "2.1. Nous utilisons les données exclusivement pour : préparer les devis, confirmer les commandes, recevoir les paiements, organiser les expéditions et fournir l'assistance après-vente.",
+ "P2": "2.2. Nous n'utilisons pas les données pour le profilage, le marketing automatisé ou la vente à des tiers."
+ },
+ "S3": {
+ "TITLE": "3. Conservation des fichiers et des données",
+ "P1": "3.1. Les fichiers téléversés uniquement pour un devis sont conservés pendant la durée de la session et supprimés automatiquement à son expiration.",
+ "P2": "3.2. Les fichiers et données liés aux commandes confirmées sont conservés le temps nécessaire à la production, la livraison, l'assistance et les obligations administratives/légales, puis supprimés ou minimisés.",
+ "P3": "3.3. Les fichiers téléversés dans le calculateur sont utilisés uniquement pour l'analyse technique et l'estimation du devis et restent associés exclusivement à la session du calculateur."
+ },
+ "S4": {
+ "TITLE": "4. Cookies et traçage",
+ "P1": "4.1. Nous n'utilisons pas de cookies de profilage, de marketing ou de traçage de tiers.",
+ "P2": "4.2. Nous n'utilisons pas de systèmes de tracking publicitaire. Les éventuelles données techniques temporaires sont utilisées uniquement pour le fonctionnement de la session."
+ },
+ "S5": {
+ "TITLE": "5. Partage des données",
+ "P1": "5.1. Nous partageons les données uniquement avec des fournisseurs strictement nécessaires au service (hébergement, paiements, expéditions), en nous limitant aux informations indispensables.",
+ "P2": "5.2. Les fournisseurs traitent les données selon des instructions contractuelles et des mesures de sécurité appropriées."
+ },
+ "S6": {
+ "TITLE": "6. Droits de l'utilisateur",
+ "P1": "6.1. Vous pouvez demander l'accès, la rectification, la suppression ou la limitation du traitement de vos données, dans les limites prévues par la loi.",
+ "P2": "6.2. Pour toute demande liée à la confidentialité, écrivez à info@3d-fab.ch. La version italienne de cette politique de confidentialité est la seule version juridiquement contraignante, sauf accord écrit contraire."
+ }
+ },
+ "TERMS": {
+ "META": {
+ "PROVIDER": "Fournisseur : 3D-Fab.ch (Matteo Caletti et Joe Kung)",
+ "VERSION": "Version : v1.0",
+ "SCOPE": "Valables pour l'impression 3D FDM/FFF et les services associés, avec vente et livraison exclusivement en Suisse (CH)."
+ },
+ "S1": {
+ "TITLE": "1. Données du fournisseur et contacts",
+ "P1": "1.1. Fournisseur : Matteo Caletti et Joe Kung.",
+ "P2": "1.2. Adresse : Lyss-strasse 71, Nidau 2560, CH.",
+ "P3": "1.3. E-mail : info@3d-fab.ch."
+ },
+ "S2": {
+ "TITLE": "2. Champ d'application",
+ "P1": "2.1. Les présentes Conditions générales régissent l'impression 3D à la demande, les services accessoires (conseil technique, CAD, vérification de fichiers, post-traitement) et les éventuels articles standard.",
+ "P2": "2.2. Le fournisseur vend et livre exclusivement en Suisse (CH).",
+ "P3": "2.3. Elles s'appliquent aux commandes effectuées via site, e-mail ou autres canaux convenus ; des conditions différentes du client ne valent que si elles sont acceptées par écrit."
+ },
+ "S3": {
+ "TITLE": "3. Définitions",
+ "P1": "3.1. Client : personne physique ou morale acheteuse. Fichiers du client : modèles 3D et données techniques fournis. Produit personnalisé : pièce réalisée selon les spécifications du client. Commande : demande acceptée par le fournisseur."
+ },
+ "S4": {
+ "TITLE": "4. Conclusion du contrat et commande",
+ "P1": "4.1. Le contrat est conclu avec la confirmation de commande (e-mail/portail) ou avec le démarrage de la production après paiement/acompte.",
+ "P2": "4.2. Les devis automatiques peuvent être confirmés ou mis à jour après vérification technique minimale (imprimabilité, supports, limites machine).",
+ "P3": "4.3. Le fournisseur peut refuser des commandes techniquement non réalisables ou non conformes aux présentes conditions."
+ },
+ "S5": {
+ "TITLE": "5. Prix, taxes et expédition",
+ "P1": "5.1. Les prix sont en CHF, sauf indication contraire concernant TVA incluse/exclue.",
+ "P2": "5.2. L'expédition et l'emballage sont indiqués séparément lorsque applicables.",
+ "P3": "5.3. Pour petites séries ou CAD complexe, des offres écrites avec conditions spécifiques peuvent être appliquées (échantillons, paliers, approbation première pièce)."
+ },
+ "S6": {
+ "TITLE": "6. Paiements",
+ "P1": "6.1. Méthodes acceptées : TWINT et virement bancaire.",
+ "P2": "6.2. Sauf accord contraire, la production démarre seulement après paiement.",
+ "P3": "6.3. Pour le conseil CAD et les petites séries, un acompte (30-100%) et/ou le solde avant livraison peut être demandé.",
+ "P4": "6.4. Coordonnées bancaires : Joe Kung, IBAN CH74 0900 0000 1548 2158 1, Via G. Pioda 29a, 6710 Biasca."
+ },
+ "S7": {
+ "TITLE": "7. Fichiers du client et responsabilité technique",
+ "P1": "7.1. Le client garantit disposer des droits sur les fichiers et que leur usage ne viole pas des droits de tiers (copyright, brevets, licences, secrets industriels).",
+ "P2": "7.2. Le client est responsable de la conformité du modèle, du choix du matériau, de l'adéquation à l'usage final et du respect des normes applicables.",
+ "P3": "7.3. Le fournisseur peut suggérer des modifications pour améliorer imprimabilité et résultat, mais n'exerce pas une fonction de certification du produit final sauf accord écrit."
+ },
+ "S8": {
+ "TITLE": "8. Qualité FDM/FFF et tolérances",
+ "P1": "8.1. L'impression FDM/FFF comporte des caractéristiques intrinsèques : lignes de couche, anisotropie mécanique, micro-imperfections, variations de couleur et possibles retraits/déformations liés à la géométrie et au matériau.",
+ "P2": "8.2. Tolérances standard (sauf accord écrit) : jusqu'à 100 mm +/-0.3 mm ; au-delà de 100 mm +/-0.5% (minimum +/-0.3 mm).",
+ "P3": "8.3. Les exigences esthétiques ou dimensionnelles critiques doivent être convenues avant la commande (ex. échantillon, mesures de contrôle, finition spécifique)."
+ },
+ "S9": {
+ "TITLE": "9. Post-traitement et travaux additionnels",
+ "P1": "9.1. Des travaux comme retrait des supports, ponçage, primaire/peinture ou inserts filetés sont réalisés seulement si convenus et peuvent introduire des variations dimensionnelles ou esthétiques.",
+ "P2": "9.2. Sur demande, une approbation de la première pièce ou d'un échantillon peut être prévue, éventuellement payante."
+ },
+ "S10": {
+ "TITLE": "10. Délais de production et de livraison",
+ "P1": "10.1. Les délais indiqués sont des estimations basées sur charge de travail, complexité et disponibilité des matériaux.",
+ "P2": "10.2. Les retards dus à des causes externes (transporteurs, fournisseurs, pannes, force majeure) ne donnent pas automatiquement droit à des pénalités sauf accord écrit.",
+ "P3": "10.3. Le client doit fournir des adresses correctes et complètes ; les éventuels coûts de relivraison pour adresse erronée restent à la charge du client."
+ },
+ "S11": {
+ "TITLE": "11. Droit de rétractation et annulation",
+ "P1": "11.1. Sauf exceptions confirmées par écrit, aucun droit de rétractation ou de retour n'est prévu après la commande.",
+ "P2": "11.2. Les produits personnalisés ne sont pas annulables ni remboursables après démarrage de la production.",
+ "P3": "11.3. Le fournisseur peut accepter des exceptions avant démarrage de la production, en retenant les éventuels coûts déjà engagés.",
+ "P4": "11.4. Toute condition spéciale doit figurer dans l'offre, la confirmation de commande ou des communications écrites."
+ },
+ "S12": {
+ "TITLE": "12. Réclamations, défauts et recours",
+ "P1": "12.1. Le client doit contrôler les produits à la livraison et signaler d'éventuels défauts sous 7 jours, par écrit, avec photo/vidéo et description.",
+ "P2": "12.2. Les signes typiques FDM, petites variations chromatiques, imperfections non fonctionnelles ou tolérances dans les limites convenues ne constituent pas automatiquement un défaut.",
+ "P3": "12.3. En cas de défaut imputable au fournisseur, les recours sont au choix du fournisseur : réimpression/remplacement ou remboursement limité à la valeur de la pièce ou de la commande défectueuse.",
+ "P4": "12.4. Avant réimpression ou remboursement, la restitution de la pièce peut être demandée ; si le défaut est confirmé, le retour est à la charge du fournisseur."
+ },
+ "S13": {
+ "TITLE": "13. Usages interdits et conformité",
+ "P1": "13.1. Le fournisseur peut refuser des commandes relatives à des objets illégaux, armes ou pièces réglementées, applications critiques pour la sécurité ou médicales sans accords et validations dédiés.",
+ "P2": "13.2. Le client reste responsable de l'usage final et de la conformité réglementaire du produit."
+ },
+ "S14": {
+ "TITLE": "14. Propriété intellectuelle et licences",
+ "P1": "14.1. Les droits sur les fichiers du client restent au client ou aux titulaires concernés. Le client concède au fournisseur une licence limitée à l'usage pour l'évaluation technique et la production.",
+ "P2": "14.2. Sauf accord contraire, les fichiers et projets CAD développés par le fournisseur sont livrés après paiement, avec droit d'usage pour les objectifs convenus.",
+ "P3": "14.3. Le client dégage le fournisseur de toute réclamation de tiers liée à des fichiers ou instructions fournis par le client."
+ },
+ "S15": {
+ "TITLE": "15. Protection des données",
+ "P1": "15.1. Le fournisseur traite les données personnelles pour la gestion des commandes, paiements, expéditions et assistance.",
+ "P2": "15.2. Les données peuvent être partagées avec des fournisseurs techniques et transporteurs uniquement dans la mesure nécessaire à la fourniture du service."
+ },
+ "S16": {
+ "TITLE": "16. Limitation de responsabilité",
+ "P1": "16.1. Dans les limites légales, le fournisseur répond seulement des dommages directs prévisibles et, en tout cas, pas au-delà de la valeur de la commande relative au produit ou service contesté.",
+ "P2": "16.2. Sont exclus, dans les limites autorisées, les dommages indirects, perte de profit, interruption d'activité, perte de données et dommages consécutifs.",
+ "P3": "16.3. Restent réservées les responsabilités non excluables par la loi (ex. dol ou faute grave)."
+ },
+ "S17": {
+ "TITLE": "17. Force majeure",
+ "P1": "17.1. Des événements hors du contrôle raisonnable du fournisseur (pannes, coupures, retards fournisseurs, grèves, mesures d'autorité) peuvent provoquer des prorogations ou suspensions sans responsabilité."
+ },
+ "S18": {
+ "TITLE": "18. Droit applicable et juridiction compétente",
+ "P1": "18.1. Le droit suisse s'applique.",
+ "P2": "18.2. Juridiction compétente : siège du fournisseur, sauf normes impératives de protection des consommateurs.",
+ "P3": "18.3. En cas de divergences d'interprétation, la version italienne des présentes conditions prévaut et constitue la seule version juridiquement contraignante, sauf accord écrit contraire."
+ }
+ }
+ },
+ "CONTACT": {
+ "TITLE": "Contactez-nous",
+ "SEND": "Envoyer le message",
+ "REQ_TYPE_LABEL": "Type de demande",
+ "TYPE_PRIVATE": "Privé",
+ "TYPE_COMPANY": "Entreprise",
+ "REQ_TYPE_CUSTOM": "Devis personnalisé",
+ "REQ_TYPE_SERIES": "Impression en série",
+ "REQ_TYPE_CONSULT": "Consultation",
+ "REQ_TYPE_QUESTION": "Questions générales",
+ "PHONE": "Téléphone",
+ "IS_COMPANY": "Êtes-vous une entreprise ?",
+ "COMPANY_NAME": "Raison sociale",
+ "REF_PERSON": "Personne de référence",
+ "UPLOAD_LABEL": "Pièces jointes",
+ "UPLOAD_HINT": "Max 15 fichiers. Pris en charge : images, vidéos, PDF, documents Office, STL/STEP/3MF/OBJ/IGES, DWG/DXF. Fichiers compressés non autorisés.",
+ "DROP_FILES": "Déposez les fichiers ici ou cliquez pour téléverser",
+ "PLACEHOLDER_NAME": "Votre nom",
+ "PLACEHOLDER_EMAIL": "votre@email.com",
+ "PLACEHOLDER_PHONE": "+41 00 000 00 00",
+ "PLACEHOLDER_COMPANY": "Nom de l'entreprise",
+ "PLACEHOLDER_REF_PERSON": "Personne de référence",
+ "LABEL_MESSAGE": "Message *",
+ "LABEL_EMAIL": "E-mail *",
+ "LABEL_NAME": "Nom *",
+ "MSG_SENT": "Envoyé !",
+ "ERR_MAX_FILES": "Limite maximale de 15 fichiers atteinte.",
+ "ERR_COMPRESSED_FILES": "Les fichiers compressés ne sont pas autorisés (ZIP/RAR/7z/TAR/GZ).",
+ "SUCCESS_TITLE": "Message envoyé avec succès",
+ "SUCCESS_DESC": "Merci de nous avoir contactés. Nous avons reçu votre message et vous enverrons un e-mail récapitulatif prochainement.",
+ "SEND_ANOTHER": "Envoyer un autre message",
+ "HERO_SUBTITLE": "Nous sommes là pour vous aider. Remplissez le formulaire ci-dessous pour toute demande.",
+ "FILE_TYPE_PDF": "PDF",
+ "FILE_TYPE_3D": "3D",
+ "FILE_TYPE_VIDEO": "Vidéo",
+ "FILE_TYPE_DOC": "DOC",
+ "FILE_TYPE_FILE": "FICHIER",
+ "ERROR_SUBMIT": "Erreur lors de l'envoi de la demande. Réessayez.",
+ "REMOVE_FILE": "Supprimer le fichier joint"
+ },
+ "CHECKOUT": {
+ "TITLE": "Checkout",
+ "SUBTITLE": "Complétez votre commande en saisissant les détails de livraison et de paiement.",
+ "CONTACT_INFO": "Informations de contact",
+ "BILLING_ADDR": "Adresse de facturation",
+ "SHIPPING_ADDR": "Adresse de livraison",
+ "FIRST_NAME": "Prénom",
+ "LAST_NAME": "Nom",
+ "EMAIL": "E-mail",
+ "PHONE": "Téléphone",
+ "COMPANY_NAME": "Nom de l'entreprise",
+ "ADDRESS_1": "Adresse (Rue et numéro)",
+ "ADDRESS_2": "Informations supplémentaires (optionnel)",
+ "ZIP": "Code postal",
+ "CITY": "Ville",
+ "COUNTRY": "Pays",
+ "SHIPPING_SAME": "L'adresse de livraison est la même que l'adresse de facturation",
+ "PLACE_ORDER": "Envoyer la commande",
+ "PROCESSING": "Traitement...",
+ "SUMMARY_TITLE": "Récapitulatif de la commande",
+ "SUBTOTAL": "Sous-total",
+ "ITEMS_BASE_SUBTOTAL": "Sous-total de base des articles",
+ "MACHINE_COST": "Coût machine",
+ "SETUP_FEE": "Coût de setup",
+ "TOTAL": "Total",
+ "QTY": "Qté",
+ "PER_PIECE": "par pièce",
+ "SHIPPING": "Expédition (CH)",
+ "INVALID_EMAIL": "E-mail invalide",
+ "COMPANY_OPTIONAL": "Nom de l'entreprise (Optionnel)",
+ "REF_PERSON_OPTIONAL": "Personne de référence (Optionnel)",
+ "SHIPPING_CALCULATED_NEXT_STEP": "le coût d'expédition est calculé à l'étape suivante",
+ "EXCLUDES_SHIPPING": "Coût d'expédition exclu",
+ "ERR_NO_SESSION_START": "Aucune session active trouvée. Commencez un nouveau devis.",
+ "ERR_LOAD_SESSION": "Impossible de charger les détails de la session. Réessayez.",
+ "ERR_NO_SESSION_CREATE_ORDER": "Aucune session active trouvée. Impossible de créer la commande.",
+ "ERR_CREATE_ORDER": "Impossible de créer la commande. Réessayez."
+ },
+ "PAYMENT": {
+ "TITLE": "Paiement",
+ "METHOD": "Méthode de paiement",
+ "TWINT_TITLE": "Payer avec TWINT",
+ "TWINT_DESC": "Scannez le code avec l'application TWINT, sur mobile cliquez sur le bouton.",
+ "TWINT_OPEN": "Ouvrir directement dans TWINT",
+ "TWINT_LINK": "Ouvrir le lien de paiement",
+ "BANK_TITLE": "Virement bancaire",
+ "BANK_OWNER": "Titulaire",
+ "BANK_IBAN": "IBAN",
+ "BANK_REF": "Référence",
+ "BILLING_INFO_HINT": "Nous avons rempli les champs pour vous, merci de ne pas modifier le motif de paiement",
+ "DOWNLOAD_QR": "Télécharger la facture QR (PDF)",
+ "DOWNLOAD_CONFIRMATION": "Télécharger la confirmation (PDF)",
+ "CONFIRM": "J'ai effectué le paiement",
+ "SUMMARY_TITLE": "Récapitulatif de la commande",
+ "SUBTOTAL": "Sous-total",
+ "SHIPPING": "Expédition",
+ "SETUP_FEE": "Coût de setup",
+ "TOTAL": "Total",
+ "LOADING": "Chargement des détails de la commande...",
+ "METHOD_TWINT": "TWINT",
+ "METHOD_BANK": "Facture QR / Virement",
+ "STATUS_REPORTED_TITLE": "Commande en cours",
+ "STATUS_REPORTED_DESC": "Nous avons enregistré votre opération. Dès que nous confirmons le paiement, la commande entrera en production.",
+ "IN_VERIFICATION": "Paiement signalé",
+ "TWINT_QR_ALT": "QR de paiement TWINT",
+ "TWINT_BUTTON_ALT": "Bouton TWINT intégré"
+ },
+ "TRACKING": {
+ "TITLE": "Statut de la commande",
+ "SUBTITLE": "Consultez le statut de votre commande et gérez le paiement si nécessaire.",
+ "STEP_PENDING": "En attente",
+ "STEP_REPORTED": "En vérification",
+ "STEP_PRODUCTION": "En production",
+ "STEP_SHIPPED": "Expédié"
+ },
+ "ORDER_CONFIRMED": {
+ "TITLE": "Commande confirmée",
+ "SUBTITLE": "Paiement enregistré. Votre commande est maintenant en traitement.",
+ "STATUS": "En traitement",
+ "HEADING": "Nous préparons votre commande",
+ "ORDER_REF": "Référence commande",
+ "PROCESSING_TEXT": "Dès que nous confirmons le paiement, votre commande passera en production.",
+ "EMAIL_TEXT": "Nous vous enverrons un e-mail avec mise à jour du statut et prochaines étapes.",
+ "BACK_HOME": "Retour à l'accueil"
+ },
+ "STL_VIEWER": {
+ "LOADING": "Chargement du modèle 3D..."
+ },
+ "ORDER": {
+ "ERR_ID_NOT_FOUND": "ID de commande introuvable.",
+ "ERR_LOAD_ORDER": "Impossible de charger les détails de la commande.",
+ "ERR_REPORT_PAYMENT": "Impossible de signaler le paiement. Réessayez.",
+ "NOT_AVAILABLE": "N/D"
+ },
+ "DROPZONE": {
+ "DEFAULT_LABEL": "Glissez les fichiers ici ou cliquez pour téléverser",
+ "DEFAULT_SUBTEXT": "Prend en charge .STL, .3MF, .STEP"
+ },
+ "COLOR": {
+ "AVAILABLE_COLORS": "Couleurs disponibles",
+ "CATEGORY_GLOSSY": "Brillants",
+ "CATEGORY_MATTE": "Mats",
+ "NAME": {
+ "BLACK": "Noir",
+ "WHITE": "Blanc",
+ "RED": "Rouge",
+ "BLUE": "Bleu",
+ "GREEN": "Vert",
+ "YELLOW": "Jaune",
+ "MATTE_BLACK": "Noir mat",
+ "MATTE_WHITE": "Blanc mat",
+ "MATTE_GRAY": "Gris mat"
+ }
+ }
+}
diff --git a/frontend/src/assets/i18n/it.json b/frontend/src/assets/i18n/it.json
index e2f781e..5e89136 100644
--- a/frontend/src/assets/i18n/it.json
+++ b/frontend/src/assets/i18n/it.json
@@ -4,7 +4,8 @@
"CALCULATOR": "Calcolatore",
"SHOP": "Shop",
"ABOUT": "Chi Siamo",
- "CONTACT": "Contattaci"
+ "CONTACT": "Contattaci",
+ "LANGUAGE_SELECTOR": "Selettore lingua"
},
"FOOTER": {
"PRIVACY": "Privacy",