refactor: komplettsanierung
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 10s
Build & Deploy / 🧪 QA (push) Failing after 1m26s
Build & Deploy / 🏗️ Build (push) Failing after 3m19s
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🩺 Health Check (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 2s
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 10s
Build & Deploy / 🧪 QA (push) Failing after 1m26s
Build & Deploy / 🏗️ Build (push) Failing after 3m19s
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:
104
apps/web/src/components/DiagramShareButton.tsx
Normal file
104
apps/web/src/components/DiagramShareButton.tsx
Normal file
@@ -0,0 +1,104 @@
|
||||
"use client";
|
||||
|
||||
import React, { useState } from "react";
|
||||
import { Share2 } from "lucide-react";
|
||||
import { ShareModal } from "./ShareModal";
|
||||
import { useAnalytics } from "./analytics/useAnalytics";
|
||||
|
||||
interface DiagramShareButtonProps {
|
||||
diagramId: string;
|
||||
title?: string;
|
||||
svgContent?: string;
|
||||
}
|
||||
|
||||
export const DiagramShareButton: React.FC<DiagramShareButtonProps> = ({
|
||||
diagramId,
|
||||
title = "Diagram",
|
||||
svgContent,
|
||||
}) => {
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
const { trackEvent } = useAnalytics();
|
||||
|
||||
const currentUrl =
|
||||
typeof window !== "undefined"
|
||||
? `${window.location.origin}${window.location.pathname}#${diagramId}`
|
||||
: "";
|
||||
|
||||
// Convert SVG to PNG for sharing
|
||||
const generateDiagramImage = async (): Promise<string | undefined> => {
|
||||
if (!svgContent) return undefined;
|
||||
|
||||
try {
|
||||
// Create a canvas to render the SVG
|
||||
const canvas = document.createElement("canvas");
|
||||
const ctx = canvas.getContext("2d");
|
||||
if (!ctx) return undefined;
|
||||
|
||||
// Create an image from the SVG
|
||||
const img = new Image();
|
||||
const svgBlob = new Blob([svgContent], {
|
||||
type: "image/svg+xml;charset=utf-8",
|
||||
});
|
||||
const url = URL.createObjectURL(svgBlob);
|
||||
|
||||
return new Promise((resolve) => {
|
||||
img.onload = () => {
|
||||
// Set canvas size to match image
|
||||
canvas.width = img.width * 2; // 2x for better quality
|
||||
canvas.height = img.height * 2;
|
||||
|
||||
// Fill with white background
|
||||
ctx.fillStyle = "#ffffff";
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
// Draw the image
|
||||
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
|
||||
|
||||
// Convert to data URL
|
||||
const dataUrl = canvas.toDataURL("image/png");
|
||||
URL.revokeObjectURL(url);
|
||||
resolve(dataUrl);
|
||||
};
|
||||
|
||||
img.onerror = () => {
|
||||
URL.revokeObjectURL(url);
|
||||
resolve(undefined);
|
||||
};
|
||||
|
||||
img.src = url;
|
||||
});
|
||||
} catch (err) {
|
||||
console.error("Failed to generate diagram image:", err);
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
const handleOpenModal = async () => {
|
||||
setIsModalOpen(true);
|
||||
trackEvent("diagram_share_opened", {
|
||||
diagram_id: diagramId,
|
||||
diagram_title: title,
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<button
|
||||
onClick={handleOpenModal}
|
||||
className="inline-flex items-center gap-2 px-4 py-2 bg-white border border-slate-200 rounded-lg text-slate-700 hover:bg-slate-50 hover:border-slate-300 transition-all text-xs font-medium"
|
||||
aria-label="Diagramm teilen"
|
||||
>
|
||||
<Share2 className="w-3.5 h-3.5" />
|
||||
<span>Teilen</span>
|
||||
</button>
|
||||
|
||||
<ShareModal
|
||||
isOpen={isModalOpen}
|
||||
onClose={() => setIsModalOpen(false)}
|
||||
url={currentUrl}
|
||||
title={title}
|
||||
diagramImage={svgContent}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user