Dialoge
Dialoge ermöglichen es, Modals und Warnungen im Konfigurator anzupassen. Es gibt zwei Hauptbereiche: den Bestell-Dialog (Order Dialog) und Inline-Warnungen.
Grundstruktur
Dialog-Erweiterungen werden im ui.dialogs Objekt registriert:
// In Plugin.tsx
export default {
// ...
ui: {
dialogs: {
order: {
root: { hoc: ..., description: "..." },
contactFields: { hoc: ..., description: "..." },
// weitere Order-Dialog Slots
},
warnings: {
invalidSelection: { hoc: ..., description: "..." },
// weitere Warning Slots
}
}
}
}
Bestell-Dialog (Order Dialog)
Der Bestell-Dialog wird angezeigt, wenn ein Kunde eine Konfiguration abschließt (Bestellung, Warenkorb, PDF-Download etc.).
root
Überschreibt den gesamten Order-Dialog Modal.
root: {
hoc: (Original) => (props) => (
<div className="custom-order-wrapper">
<Original {...props} />
</div>
),
description: "Wrapper um den gesamten Bestelldialog"
}
headline
Überschreibt die Überschrift des Bestell-Dialogs.
headline: {
hoc: (Original) => (props) => (
<div className="custom-headline">
<span className="icon">🛒</span>
<Original {...props} />
</div>
),
description: "Fügt Icon zur Überschrift hinzu"
}
contactFields
Überschreibt das Kontaktformular (Name, E-Mail, Telefon etc.).
Anwendungsbeispiele:
- Zusätzliche Felder hinzufügen (Firma, Abteilung)
- Feldvalidierung anpassen
- Layout ändern
contactFields: {
hoc: (Original) => (props) => (
<div>
<Original {...props} />
{/* Zusätzliche Felder */}
<div className="additional-fields">
<label>
Firma:
<input type="text" name="company" />
</label>
<label>
Abteilung:
<input type="text" name="department" />
</label>
</div>
</div>
),
description: "Fügt zusätzliche Kontaktfelder hinzu"
}
priceTable
Überschreibt die gesamte Preistabelle im Bestell-Dialog.
priceTable: {
hoc: (Original) => (props) => (
<div className="enhanced-price-table">
<div className="table-header">Ihre Auswahl:</div>
<Original {...props} />
<div className="table-footer">
* Alle Preise verstehen sich zzgl. Versandkosten
</div>
</div>
),
description: "Erweitert Preistabelle mit Header/Footer"
}
priceTableSelectionList
Überschreibt die Liste der ausgewählten Merkmale/Werte in der Preistabelle.
priceTableSelectionList: {
hoc: (Original) => (props) => (
<div className="custom-selection-list">
<h4>Ihre Konfiguration:</h4>
<Original {...props} />
</div>
),
description: "Fügt Überschrift über Auswahliste hinzu"
}
priceTableArticleList
Überschreibt die Artikelliste (Bill-of-Materials) in der Preistabelle.
priceTableArticleList: {
hoc: (Original) => (props) => (
<div className="custom-article-list">
<h4>Benötigte Artikel:</h4>
<Original {...props} />
</div>
),
description: "Fügt Überschrift über Artikelliste hinzu"
}
priceTableTotal
Überschreibt die Gesamtsummen-Zeile am Ende der Preistabelle.
priceTableTotal: {
hoc: (Original) => (props) => (
<div className="enhanced-total">
<Original {...props} />
<div className="savings-info">
Sie sparen 15% gegenüber Einzelkauf!
</div>
</div>
),
description: "Zeigt Ersparnis-Info unter Gesamtpreis"
}
confirmationSuccess
Überschreibt die Erfolgsbestätigung nach erfolgreicher Bestellung.
Anwendungsbeispiele:
- Custom Thank-You Message
- Tracking-Codes einbinden
- Zusätzliche Informationen anzeigen
confirmationSuccess: {
hoc: (Original) => (props) => (
<div className="custom-success">
<div className="success-animation">✓</div>
<Original {...props} />
<div className="next-steps">
<h4>Nächste Schritte:</h4>
<ol>
<li>Sie erhalten eine Bestätigungs-E-Mail</li>
<li>Wir prüfen Ihre Konfiguration</li>
<li>Sie erhalten ein detailliertes Angebot</li>
</ol>
</div>
</div>
),
description: "Erweiterte Erfolgsbestätigung mit Next-Steps"
}
confirmationError
Überschreibt die Fehleranzeige nach fehlgeschlagener Bestellung.
confirmationError: {
hoc: (Original) => (props) => (
<div className="custom-error">
<Original {...props} />
<div className="support-info">
<p>Probleme? Kontaktieren Sie uns:</p>
<a href="tel:+4912345678">+49 123 456 78</a>
</div>
</div>
),
description: "Fügt Support-Kontakt bei Fehler hinzu"
}
Warnungen (Warnings)
Warnungen werden inline in der Sidebar angezeigt, wenn Auswahlen ungültig sind.
invalidSelection
Überschreibt die gesamte ungültige-Auswahl-Warnung (Badge neben Merkmalswerten).
invalidSelection: {
hoc: (Original) => (props) => (
<div className="custom-invalid-badge">
<Original {...props} />
</div>
),
description: "Custom Styling für ungültige Auswahl"
}
invalidSelectionIcon
Überschreibt nur das Icon innerhalb der Warnung.
invalidSelectionIcon: {
hoc: (Original) => (props) => (
<span className="custom-warning-icon">⚠️</span>
),
description: "Verwendet Custom Warning Icon"
}
invalidSelectionTooltip
Überschreibt den Tooltip-Inhalt, der beim Hover über die Warnung erscheint.
invalidSelectionTooltip: {
hoc: (Original) => (props) => (
<div className="custom-tooltip">
<strong>Ungültige Auswahl</strong>
<Original {...props} />
<div className="tooltip-help">
Klicken Sie hier für Hilfe →
</div>
</div>
),
description: "Erweiterter Tooltip mit Hilfe-Link"
}
numberWarningTooltip
Überschreibt den Tooltip für Warnungen bei Zahlenwerten außerhalb des gültigen Bereichs.
numberWarningTooltip: {
hoc: (Original) => (props) => (
<div className="number-warning-tooltip">
<Original {...props} />
<div className="allowed-range">
Erlaubter Bereich: {props.min} - {props.max}
</div>
</div>
),
description: "Zeigt erlaubten Zahlenbereich im Tooltip"
}
Vollständiges Beispiel: Enhanced Order Dialog
import type { HOC } from "k3-plugin-api";
import { useState, useEffect } from "react";
// Root mit Badge
const orderRootHOC: HOC = (Original) => (props) => (
<div className="enhanced-order-dialog">
<div className="order-badge">Schnellbestellung</div>
<Original {...props} />
</div>
);
// Erweiterte Kontaktfelder
const contactFieldsHOC: HOC = (Original) => (props) => {
const [company, setCompany] = useState("");
return (
<div className="extended-contact-form">
<Original {...props} />
<div className="company-field">
<label>
Firma (optional):
<input
type="text"
value={company}
onChange={(e) => setCompany(e.target.value)}
placeholder="Ihre Firma"
/>
</label>
</div>
<div className="privacy-notice">
<input type="checkbox" id="privacy" required />
<label htmlFor="privacy">
Ich akzeptiere die{" "}
<a href="/datenschutz" target="_blank">
Datenschutzerklärung
</a>
</label>
</div>
</div>
);
};
// Preistabelle mit Versandinfo
const priceTotalHOC: HOC = (Original) => (props) => (
<div className="enhanced-total">
<Original {...props} />
<div className="shipping-info">
<small>zzgl. Versandkosten (werden im Checkout berechnet)</small>
</div>
<div className="payment-methods">
<span>Wir akzeptieren:</span>
<div className="payment-icons">
<img src="/icons/visa.svg" alt="Visa" />
<img src="/icons/mastercard.svg" alt="Mastercard" />
<img src="/icons/paypal.svg" alt="PayPal" />
</div>
</div>
</div>
);
// Erfolgsbestätigung mit Animation
const confirmationSuccessHOC: HOC = (Original) => (props) => {
useEffect(() => {
if (typeof window !== "undefined" && window.gtag) {
window.gtag("event", "purchase_success", {
order_id: props.orderId
});
}
}, [props.orderId]);
return (
<div className="success-wrapper">
<div className="success-icon-animation">
<svg className="checkmark" viewBox="0 0 52 52">
<circle className="checkmark-circle" />
<path className="checkmark-check" />
</svg>
</div>
<Original {...props} />
<div className="social-share">
<p>Teilen Sie Ihre Konfiguration:</p>
<button className="share-btn facebook">Facebook</button>
<button className="share-btn twitter">Twitter</button>
</div>
</div>
);
};
// Im Plugin registrieren:
export default {
// ...
ui: {
dialogs: {
order: {
root: {
hoc: orderRootHOC,
description: "Fügt Badge zum Bestelldialog hinzu"
},
contactFields: {
hoc: contactFieldsHOC,
description: "Erweitert Kontaktformular um Firma und Datenschutz"
},
priceTableTotal: {
hoc: priceTotalHOC,
description: "Zeigt Versandinfo und Zahlungsmethoden"
},
confirmationSuccess: {
hoc: confirmationSuccessHOC,
description: "Erweiterte Erfolgsseite mit Animation und Social Share"
}
},
warnings: {
invalidSelection: {
hoc: (Original) => (props) => (
<div className="custom-warning-badge">
<Original {...props} />
</div>
),
description: "Custom Styling für Warnungen"
}
}
}
}
};
Best Practices
1. Original-Komponente rendern
Wenn Sie nicht alles ersetzen wollen, rendern Sie die Original-Komponente:
hoc: (Original) => (props) => (
<>
<Original {...props} />
{/* Ihr zusätzlicher Content */}
</>
)
2. Formular-Validierung
Wenn Sie zusätzliche Formularfelder hinzufügen, implementieren Sie Validierung:
const [email, setEmail] = useState("");
const [error, setError] = useState("");
const validateEmail = (value: string) => {
if (!value.includes("@")) {
setError("Bitte gültige E-Mail eingeben");
return false;
}
return true;
};
3. Analytics Events
Nutzen Sie Confirmation-HOCs für Tracking:
confirmationSuccess: {
hoc: (Original) => (props) => {
useEffect(() => {
// Google Analytics
if (window.gtag) {
window.gtag("event", "order_complete");
}
// Facebook Pixel
if (window.fbq) {
window.fbq("track", "Purchase");
}
}, []);
return <Original {...props} />;
}
}
4. Responsive Design
Gestalten Sie Custom-Inhalte responsive:
<div className="custom-fields">
<style jsx>{`
.custom-fields {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1rem;
}
`}</style>
{/* Felder */}
</div>
5. Barrierefreiheit
Nutzen Sie semantisches HTML und ARIA-Attribute:
<div role="alert" aria-live="polite" className="success-message">
Bestellung erfolgreich!
</div>
TypeScript-Typen
Nutzen Sie die bereitgestellten Typen:
import type {
K3DialogExtensions,
K3OrderDialogExtensions,
K3WarningExtensions,
HOCWithDescription
} from "k3-plugin-api";
const orderExtensions: K3OrderDialogExtensions = {
headline: {
hoc: myHOC,
description: "Custom headline"
}
};
Lokalisierung
Beschreibungen können mehrsprachig sein:
confirmationSuccess: {
hoc: myHOC,
description: {
de: "Erweiterte Erfolgsbestätigung",
en: "Enhanced success confirmation",
fr: "Confirmation de succès améliorée",
nl: "Uitgebreide succesbevestiging"
}
}