import React, { useState } from "react"; import { FileText, Download, Code, Mail, Archive, MoreVertical, Share2, Link } from 'lucide-react'; import { Button } from "@/components/ui/button"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, DropdownMenuSeparator, DropdownMenuLabel } from "@/components/ui/dropdown-menu"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from "@/components/ui/dialog"; import { toast } from "sonner"; import { generateOfflineZip } from "@/utils/zipGenerator"; import { T } from "@/i18n"; import { PostItem, UserProfile } from "../types"; import { Picture } from "@/types-server"; interface ExportDropdownProps { post: PostItem | null; mediaItems: Picture[]; authorProfile: UserProfile | null; onExportMarkdown?: () => void; className?: string; } export const ExportDropdown: React.FC = ({ post, mediaItems, authorProfile, onExportMarkdown, className }) => { const [isZipping, setIsZipping] = useState(false); const [isEmbedDialogOpen, setIsEmbedDialogOpen] = useState(false); const [isEmailDialogOpen, setIsEmailDialogOpen] = useState(false); const [emailHtml, setEmailHtml] = useState(''); const baseUrl = import.meta.env.VITE_SERVER_IMAGE_API_URL || window.location.origin; const embedUrl = `${baseUrl}/embed/${post?.id}`; const embedCode = ``; const loadEmailHtml = async () => { if (!post?.id) { console.error('No post ID available'); setEmailHtml('Error: Post data missing'); return; } try { const res = await fetch(`${baseUrl}/api/render/email/${post.id}`); if (!res.ok) { const text = await res.text(); throw new Error(text || res.statusText); } const html = await res.text(); setEmailHtml(html); } catch (e) { console.error("Failed to load email html", e); toast.error("Failed to load email template"); setEmailHtml('Error loading template. Please try again later.'); } }; const handleExportPdf = async () => { if (!post?.id) return; try { // Get current URL and append .pdf extension const currentUrl = new URL(window.location.href); const pathWithExtension = currentUrl.pathname + '.pdf'; const exportUrl = `${currentUrl.origin}${pathWithExtension}${currentUrl.search}`; // Open in new tab to trigger download window.open(exportUrl, '_blank'); toast.success("PDF export opened"); } catch (e) { console.error(e); toast.error("Failed to export PDF"); } }; const handleDownloadZip = async () => { if (!post) return; setIsZipping(true); toast.info("Generating ZIP..."); try { await generateOfflineZip( post, mediaItems, authorProfile?.display_name || 'Author' ); toast.success("ZIP downloaded!"); } catch (e) { console.error(e); toast.error("Failed to generate ZIP"); } finally { setIsZipping(false); } }; const handleCopyLink = async () => { if (!post) return; const url = window.location.href; const title = post.title || 'PolyMech Post'; const text = post.description || ''; if (navigator.share && navigator.canShare({ url, title, text })) { try { await navigator.share({ url, title, text }); return; } catch (e) { // Ignore abort errors if ((e as Error).name !== 'AbortError') console.error('Share failed', e); } } // Fallback to clipboard try { await navigator.clipboard.writeText(url); toast.success("Link copied to clipboard"); } catch (e) { console.error('Clipboard failed', e); toast.error("Failed to copy link"); } }; return (
Embed Post Copy the code below to embed this post on your website.
{embedCode}
Preview: