diff --git a/client/src/components/dashboard/share-dashboard-dialog.tsx b/client/src/components/dashboard/share-dashboard-dialog.tsx index e9cb6d9..582753d 100644 --- a/client/src/components/dashboard/share-dashboard-dialog.tsx +++ b/client/src/components/dashboard/share-dashboard-dialog.tsx @@ -1,24 +1,23 @@ -import { useState } from "react"; -import { - Dialog, - DialogContent, - DialogHeader, - DialogTitle, - DialogDescription, +import { useState, useEffect } from "react"; +import { useToast } from "@/hooks/use-toast"; +import { + Dialog, + DialogContent, + DialogDescription, DialogFooter, + DialogHeader, + DialogTitle, } from "@/components/ui/dialog"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; -import { Label } from "@/components/ui/label"; import { Textarea } from "@/components/ui/textarea"; -import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; +import { Label } from "@/components/ui/label"; import { Switch } from "@/components/ui/switch"; -import { Slider } from "@/components/ui/slider"; +import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { ColorPicker } from "@/components/ui/color-picker"; -import { CopyIcon, Share2, CheckIcon, Download } from "lucide-react"; -import { useToast } from "@/hooks/use-toast"; import { DashboardConfig } from "./dashboard-layout"; -import { generateSnapshot } from "@/lib/snapshot-utils"; +import { generateSnapshot, SnapshotBranding, SnapshotData } from "@/lib/snapshot-utils"; +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; interface ShareDashboardDialogProps { open: boolean; @@ -32,149 +31,84 @@ interface ShareDashboardDialogProps { }>; } -export function ShareDashboardDialog({ - open, - onOpenChange, +export function ShareDashboardDialog({ + open, + onOpenChange, dashboard, - dataSources + dataSources, }: ShareDashboardDialogProps) { const { toast } = useToast(); - const [shareUrl, setShareUrl] = useState(""); - const [copied, setCopied] = useState(false); - const [logoUrl, setLogoUrl] = useState(""); - const [companyName, setCompanyName] = useState(""); - const [customTitle, setCustomTitle] = useState(dashboard.name); - const [description, setDescription] = useState(""); - const [primaryColor, setPrimaryColor] = useState("#0f172a"); - const [secondaryColor, setSecondaryColor] = useState("#6366f1"); - const [showDate, setShowDate] = useState(true); - const [showFooter, setShowFooter] = useState(true); - const [footerText, setFooterText] = useState("Generated with Active Directory Management Platform"); - const [expiryDays, setExpiryDays] = useState(7); - const [includeData, setIncludeData] = useState(true); - const [isSharing, setIsSharing] = useState(false); + const [activeTab, setActiveTab] = useState("branding"); + const [isSaving, setIsSaving] = useState(false); const [isGenerating, setIsGenerating] = useState(false); + const [snapshotUrl, setSnapshotUrl] = useState(null); + const [branding, setBranding] = useState({ + logoUrl: "", + companyName: "", + title: dashboard.name || "Dashboard Snapshot", + description: "Dashboard snapshot generated from Active Directory Management", + primaryColor: "#3f51b5", + secondaryColor: "#f5f5f5", + showDate: true, + showFooter: true, + footerText: "© " + new Date().getFullYear() + " - Generated by Active Directory Management", + expiresInDays: 30, + }); - // When user uploads a logo - const handleLogoUpload = (e: React.ChangeEvent) => { - const file = e.target.files?.[0]; - if (file) { - const reader = new FileReader(); - reader.onloadend = () => { - setLogoUrl(reader.result as string); - }; - reader.readAsDataURL(file); + // Reset the snapshot URL when the dialog is opened + useEffect(() => { + if (open) { + setSnapshotUrl(null); + setActiveTab("branding"); } - }; + }, [open]); - // Generate a sharable URL with snapshot data - const handleGenerateShareLink = async () => { - setIsSharing(true); - try { - const snapshotData = generateSnapshot({ - dashboard, - dataSources: includeData ? dataSources : [], - branding: { - logoUrl, - companyName, - title: customTitle, - description, - primaryColor, - secondaryColor, - showDate, - showFooter, - footerText, - expiresInDays: expiryDays - } - }); - - // In a real app, this would make an API call to store the snapshot - // For now, we're simulating it with localStorage - const snapshotId = `dash_${Date.now().toString(36)}`; - localStorage.setItem(`snapshot_${snapshotId}`, JSON.stringify(snapshotData)); - - // Generate share URL - const shareUrl = `${window.location.origin}/dashboards/shared/${snapshotId}`; - setShareUrl(shareUrl); - - toast({ - title: "Share link generated", - description: "The share link for this dashboard has been created.", - }); - } catch (error) { - console.error("Error generating share link:", error); - toast({ - title: "Error", - description: "Failed to generate share link. Please try again.", - variant: "destructive", - }); - } finally { - setIsSharing(false); + // Update title when dashboard name changes + useEffect(() => { + if (dashboard.name) { + setBranding(prev => ({ ...prev, title: dashboard.name })); } + }, [dashboard.name]); + + const handleBrandingChange = (key: keyof SnapshotBranding, value: any) => { + setBranding((prev) => ({ + ...prev, + [key]: value, + })); }; - // Copy the URL to clipboard - const handleCopyLink = () => { - navigator.clipboard.writeText(shareUrl); - setCopied(true); - toast({ - title: "Copied!", - description: "Share link copied to clipboard.", - }); - - setTimeout(() => { - setCopied(false); - }, 2000); - }; - - // Generate a PDF or image snapshot for download - const handleDownloadSnapshot = async () => { - setIsGenerating(true); + const generateDashboardSnapshot = async () => { try { - const snapshotData = generateSnapshot({ + setIsGenerating(true); + + // Here you would normally make an API call to store the snapshot + // For now, we'll just simulate it + + const snapshotData: SnapshotData = generateSnapshot({ dashboard, - dataSources: includeData ? dataSources : [], - branding: { - logoUrl, - companyName, - title: customTitle, - description, - primaryColor, - secondaryColor, - showDate, - showFooter, - footerText, - expiresInDays: 0 // Download doesn't expire - } + dataSources, + branding, }); - // In a real implementation, we would generate a PDF or image here - // For now, we'll just download the JSON data - const dataStr = JSON.stringify(snapshotData, null, 2); - const dataBlob = new Blob([dataStr], { type: 'application/json' }); - const url = URL.createObjectURL(dataBlob); + // Mock API call - in production this would save to server and return a URL + await new Promise((resolve) => setTimeout(resolve, 1500)); - const a = document.createElement('a'); - a.href = url; - a.download = `${dashboard.name.replace(/\s+/g, '_')}_snapshot.json`; - document.body.appendChild(a); - a.click(); + // Simulate a returned URL + const mockSnapshotId = `snapshot-${Date.now().toString(36)}`; + const url = `${window.location.origin}/snapshot/${mockSnapshotId}`; - // Clean up - setTimeout(() => { - document.body.removeChild(a); - URL.revokeObjectURL(url); - }, 100); + setSnapshotUrl(url); + setActiveTab("share"); toast({ - title: "Snapshot downloaded", - description: "Your dashboard snapshot has been downloaded.", + title: "Snapshot Generated", + description: "Your dashboard snapshot has been created successfully.", }); } catch (error) { console.error("Error generating snapshot:", error); toast({ title: "Error", - description: "Failed to generate snapshot. Please try again.", + description: "Failed to generate dashboard snapshot. Please try again.", variant: "destructive", }); } finally { @@ -182,238 +116,218 @@ export function ShareDashboardDialog({ } }; + const copyToClipboard = async () => { + if (!snapshotUrl) return; + + try { + await navigator.clipboard.writeText(snapshotUrl); + toast({ + title: "Copied to Clipboard", + description: "Snapshot URL has been copied to your clipboard.", + }); + } catch (error) { + console.error("Error copying to clipboard:", error); + toast({ + title: "Error", + description: "Failed to copy URL to clipboard. Please try manually.", + variant: "destructive", + }); + } + }; + return ( - + Share Dashboard: {dashboard.name} - Create a shareable snapshot of this dashboard with custom branding. + Create a shareable snapshot of your dashboard with custom branding. - + - Share Link - Branding Options + Branding + Share - - -
-
- -
- +
+
+
+ + handleBrandingChange("companyName", e.target.value)} + placeholder="Enter your company name" /> -
-
- -
- -
-
- Expires after - - {expiryDays === 0 ? "Never expires" : `${expiryDays} days`} - -
- setExpiryDays(value[0])} + +
+ + handleBrandingChange("logoUrl", e.target.value)} + placeholder="https://example.com/logo.png" + /> +
+ +
+ + handleBrandingChange("title", e.target.value)} + placeholder="Dashboard Title" + /> +
+ +
+ +