"use client"; import React, { useState } from "react"; import { Share2 } from "lucide-react"; import { ShareModal } from "./ShareModal"; import { useAnalytics } from "./analytics/useAnalytics"; import * as htmlToImage from "html-to-image"; import QRCode from "qrcode"; import LogoBlack from "../assets/logo/Logo-Black-Transparent.svg"; interface ComponentShareButtonProps { targetId: string; title?: string; shareText?: string; className?: string; } export const ComponentShareButton: React.FC = ({ targetId, title = "Mintel Architektur Insights", shareText = "Schauen Sie sich diese spannende interaktive Simulation an:", className = "" }) => { const [isModalOpen, setIsModalOpen] = useState(false); const [generatedImage, setGeneratedImage] = useState(); const [isCapturing, setIsCapturing] = useState(false); const { trackEvent } = useAnalytics(); const currentUrl = typeof window !== "undefined" ? `${window.location.origin}${window.location.pathname}#${targetId}` : ""; const applyWatermark = async (base64Img: string, qrCodeSrc: string): Promise => { return new Promise((resolve) => { const img = new Image(); img.onload = () => { const canvas = document.createElement("canvas"); // html-to-image uses pixelRatio: 2, so img.width/img.height are 2x canvas.width = img.width; canvas.height = img.height; const ctx = canvas.getContext("2d"); if (!ctx) return resolve(base64Img); // Draw main image ctx.drawImage(img, 0, 0); // Watermark styling for 2x resolution const padding = 32; const wHeight = 110; const wWidth = 360; const x = canvas.width - wWidth - padding; const y = canvas.height - wHeight - padding; // Draw pill shape background ctx.fillStyle = "rgba(255, 255, 255, 0.95)"; ctx.shadowColor = "rgba(0, 0, 0, 0.05)"; ctx.shadowBlur = 10; ctx.shadowOffsetY = 4; if (ctx.roundRect) { ctx.beginPath(); ctx.roundRect(x, y, wWidth, wHeight, 24); ctx.fill(); } else { ctx.fillRect(x, y, wWidth, wHeight); } // Draw text and logo ctx.shadowColor = "transparent"; ctx.textBaseline = "middle"; (async () => { try { const qrImg = new Image(); qrImg.src = qrCodeSrc; await new Promise(r => { qrImg.onload = r; qrImg.onerror = r; }); const logoSrc = typeof LogoBlack === 'string' ? LogoBlack : (LogoBlack as any).src; const logoImg = new Image(); logoImg.src = logoSrc; await new Promise(r => { logoImg.onload = r; logoImg.onerror = r; }); if (logoImg.width > 0) { // Calculate logo dimensions const logoHeight = 32; const logoWidth = logoImg.width * (logoHeight / logoImg.height); const logoX = x + 24; const logoY = y + (wHeight - logoHeight) / 2; // Draw Logo ctx.drawImage(logoImg, logoX, logoY, logoWidth, logoHeight); // Draw "Zum Artikel" text right of the logo ctx.font = "600 20px sans-serif"; ctx.fillStyle = "#64748b"; ctx.textAlign = "left"; ctx.fillText("Zum Artikel", logoX + logoWidth + 24, y + wHeight / 2 + 2); } else { // Fallback if logo fails to load for some reason ctx.font = "900 36px sans-serif"; ctx.fillStyle = "#0f172a"; ctx.textAlign = "left"; ctx.fillText("mintel.", x + 24, y + wHeight / 2 + 4); } // Draw solid line separator before QR const qrSize = wHeight - 24; // padding 12*2 inside pill const qrX = x + wWidth - qrSize - 12; const qrY = y + 12; const sepX = qrX - 12; ctx.beginPath(); ctx.moveTo(sepX, y + 20); ctx.lineTo(sepX, y + wHeight - 20); ctx.strokeStyle = "#e2e8f0"; ctx.lineWidth = 2; ctx.stroke(); // Draw QR Code if (qrImg.width > 0) { ctx.drawImage(qrImg, qrX, qrY, qrSize, qrSize); } resolve(canvas.toDataURL("image/png")); } catch (e) { resolve(base64Img); // Error fallback } })(); }; img.onerror = () => resolve(base64Img); // Error fallback img.src = base64Img; }); }; const handleOpenModal = async () => { setIsCapturing(true); try { const element = document.getElementById(targetId); if (element) { // Force explicit dimensions to prevent html-to-image from clipping const w = element.offsetWidth; const h = element.offsetHeight; const rawDataUrl = await htmlToImage.toPng(element, { quality: 1, type: 'image/png', pixelRatio: 2, backgroundColor: 'white', skipFonts: true, width: w, height: h, style: { transform: 'none', margin: '0', width: `${w}px`, height: `${h}px` }, filter: (node) => { const el = node as HTMLElement; if (el.tagName === 'BUTTON' || el.dataset?.shareButton === 'true' || el.dataset?.shareWrapper === 'true') { return false; } return true; } }); // Generate QR Code const qrDataUrl = await QRCode.toDataURL(currentUrl, { width: 120, // slightly larger for sharper scaling margin: 0, color: { dark: '#0f172a', light: '#ffffff' } }); // Add Watermark const watermarkedImage = await applyWatermark(rawDataUrl, qrDataUrl); setGeneratedImage(watermarkedImage); } } catch (err) { console.error("Failed to capture component:", err); } finally { setIsCapturing(false); setIsModalOpen(true); trackEvent("component_share_opened", { component_id: targetId, component_title: title }); } }; return (
setIsModalOpen(false)} url={currentUrl} title={title} description={shareText} diagramImage={generatedImage} qrCodeData={generatedImage} // Let's try sending it to both to be safe depending on ShareModal's internals />
); };