feat(ui): enhance component share UX and add new interactive simulations
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 6s
Build & Deploy / 🏗️ Build (push) Failing after 26s
Build & Deploy / 🧪 QA (push) Failing after 1m14s
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🩺 Health Check (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 2s

This commit is contained in:
2026-02-22 16:58:42 +01:00
parent d9ddce412a
commit 38f2cc8b85
22 changed files with 918 additions and 163 deletions

View File

@@ -12,6 +12,7 @@ interface ShareModalProps {
url: string;
qrCodeData?: string;
title?: string;
description?: string;
diagramImage?: string;
}
@@ -21,6 +22,7 @@ export function ShareModal({
url,
qrCodeData,
title,
description,
diagramImage,
}: ShareModalProps) {
const [copied, setCopied] = useState(false);
@@ -47,6 +49,9 @@ export function ShareModal({
if (ogImage || ogTitle || ogDesc) {
setOgData({ image: ogImage, title: ogTitle, description: ogDesc });
}
} else {
// Force clear OG data if we HAVE a diagramImage, to prevent fallback flashes
setOgData(null);
}
}, [isOpen, diagramImage, qrCodeData, title]);
@@ -63,13 +68,6 @@ export function ShareModal({
const svgUrl = URL.createObjectURL(svgBlob);
setImagePreview(svgUrl);
}
// Optional: If we want to strictly apply the watermark via Canvas, we would do it here.
// But for the sake of getting the preview to work reliably first, just setting the imagePreview
// directly to the data URL or SVG blob URL is the safest approach. The watermark logic was
// likely failing because `IconBlack` wasn't resolving correctly or `img.onload` wasn't firing
// properly in all environments.
}
}, [diagramImage, isOpen]);
@@ -83,7 +81,8 @@ export function ShareModal({
if (navigator.share) {
try {
const shareData: ShareData = {
title: title || "Mintel Diagramm",
title: title || "Mintel Architektur Insights",
text: description || "Schauen Sie sich diesen Beitrag an.",
url: url,
};
@@ -125,12 +124,13 @@ export function ShareModal({
};
const handleShareX = () => {
const text = encodeURIComponent(title || "Mintel Diagramm");
const text = encodeURIComponent(`${description ? description + " " : ""}${title || "Mintel Architektur Insights"}`);
const shareUrl = `https://twitter.com/intent/tweet?text=${text}&url=${encodeURIComponent(url)}`;
window.open(shareUrl, "_blank", "width=550,height=420");
};
const handleShareLinkedIn = () => {
// LinkedIn share doesn't accept text directly via URL for personal profiles easily, but we pass url
const shareUrl = `https://www.linkedin.com/sharing/share-offsite/?url=${encodeURIComponent(url)}`;
window.open(shareUrl, "_blank", "width=550,height=420");
};
@@ -181,7 +181,7 @@ export function ShareModal({
<img
src={imagePreview}
alt={title || "Diagram"}
className="w-full max-h-[50vh] object-contain transition-transform duration-700 rounded-xl"
className="w-full max-h-[30vh] object-contain transition-transform duration-700 rounded-xl"
/>
</div>
@@ -288,11 +288,11 @@ export function ShareModal({
</div>
</div>
<div className="flex flex-col sm:flex-row items-center gap-4 pt-2">
<div className="flex items-center justify-between gap-2 pt-2">
<div className="flex items-center gap-2">
<button
onClick={handleShareX}
className="w-12 h-12 bg-black text-white rounded-xl flex items-center justify-center hover:bg-slate-900 transition-all border border-slate-800 active:scale-95"
className="w-12 h-12 bg-black text-white rounded-xl flex items-center justify-center hover:bg-slate-900 transition-all border border-slate-800 active:scale-95 shadow-sm"
title="Auf X teilen"
>
<svg
@@ -306,7 +306,7 @@ export function ShareModal({
<button
onClick={handleShareLinkedIn}
className="w-12 h-12 bg-[#0A66C2] text-white rounded-xl flex items-center justify-center hover:bg-[#004182] transition-all active:scale-95"
className="w-12 h-12 bg-[#0A66C2] text-white rounded-xl flex items-center justify-center hover:bg-[#004182] transition-all active:scale-95 shadow-sm"
title="Auf LinkedIn teilen"
>
<svg
@@ -321,10 +321,10 @@ export function ShareModal({
{typeof navigator !== "undefined" && !!navigator.share && (
<button
onClick={handleNativeShare}
className="w-12 h-12 bg-white border border-slate-200 text-slate-900 rounded-xl flex items-center justify-center hover:bg-slate-50 transition-all active:scale-95"
className="w-12 h-12 bg-white border border-slate-200 text-slate-900 rounded-xl flex items-center justify-center hover:bg-slate-50 transition-all active:scale-95 shadow-sm"
title="System-Dialog öffnen"
>
<Share2 size={20} className="text-slate-400" />
<Share2 size={20} className="text-slate-500" />
</button>
)}
</div>
@@ -332,10 +332,10 @@ export function ShareModal({
{imagePreview && (
<button
onClick={handleDownloadImage}
className="flex-1 w-full p-3 bg-slate-100 text-slate-900 rounded-xl font-bold flex items-center justify-center gap-3 hover:bg-slate-200 transition-all border border-slate-200 active:scale-[0.98]"
className="w-12 h-12 bg-slate-100 text-slate-600 rounded-xl flex items-center justify-center hover:bg-slate-200 transition-all active:scale-95 border border-slate-200 shrink-0"
title="Als PNG herunterladen"
>
<Download size={18} />
<span className="text-xs">Als Bild speichern (PNG)</span>
</button>
)}
</div>