'use client' import { useState } from 'react' import { Download, FileText, FolderArchive, Code, Settings, Check, Loader2, Terminal } from 'lucide-react' import { createZipBundle, formatSize, getFileCount, calculateZipSize } from '@/lib/zip-builder' import { slugify } from '@/lib/parser' import { EXPORT_FORMATS, getExtensionForFormat, getMimeTypeForFormat } from '@/lib/exporters' import type { GeneratedOutputs } from '@/lib/output-generator' import type { ExportFormat } from '@/types' interface DownloadPanelProps { outputs: GeneratedOutputs siteName: string } export default function DownloadPanel({ outputs, siteName }: DownloadPanelProps) { const [downloading, setDownloading] = useState(null) const [downloadedFiles, setDownloadedFiles] = useState>(new Set()) const [exportFormat, setExportFormat] = useState('markdown') const downloadFile = (filename: string, content: string, mimeType: string = 'text/markdown') => { setDownloading(filename) const blob = new Blob([content], { type: mimeType }) const url = URL.createObjectURL(blob) const a = document.createElement('a') a.href = url a.download = filename document.body.appendChild(a) a.click() document.body.removeChild(a) URL.revokeObjectURL(url) setDownloadedFiles(prev => new Set(prev).add(filename)) setDownloading(null) } // Download full document in selected format const downloadFormatted = () => { const ext = getExtensionForFormat(exportFormat) const mimeType = getMimeTypeForFormat(exportFormat) const baseFilename = slugify(siteName) || 'docs' const filename = `${baseFilename}-full${ext}` let content: string if (exportFormat === 'json') { content = JSON.stringify({ meta: { source: siteName, extractedAt: new Date().toISOString(), version: '1.0', }, sections: outputs.sections.map(s => ({ title: s.filename.replace(/^\d+-/, '').replace(/\.md$/, ''), content: s.content, size: s.size, })), fullDocument: outputs.fullDocument.content, }, null, 2) } else if (exportFormat === 'yaml') { // Simple YAML serialization const lines = [ 'meta:', ` source: "${siteName}"`, ` extractedAt: "${new Date().toISOString()}"`, ' version: "1.0"', 'sections:', ] for (const section of outputs.sections) { const title = section.filename.replace(/^\d+-/, '').replace(/\.md$/, '') lines.push(` - title: "${title}"`) lines.push(` content: |`) const contentLines = section.content.split('\n') for (const line of contentLines) { lines.push(` ${line}`) } } content = lines.join('\n') } else { // Markdown - use full document as-is content = outputs.fullDocument.content } downloadFile(filename, content, mimeType) } const downloadZip = async () => { setDownloading('zip') try { const blob = await createZipBundle(outputs, siteName) const url = URL.createObjectURL(blob) const a = document.createElement('a') a.href = url a.download = `${slugify(siteName)}-docs.zip` document.body.appendChild(a) a.click() document.body.removeChild(a) URL.revokeObjectURL(url) setDownloadedFiles(prev => new Set(prev).add('zip')) } catch (error) { console.error('Failed to create ZIP:', error) } setDownloading(null) } const isDownloading = (key: string) => downloading === key const isDownloaded = (key: string) => downloadedFiles.has(key) const totalSize = calculateZipSize(outputs) const fileCount = getFileCount(outputs) return (

Download Files

{/* Format Selector */}
{/* Quick Download - ZIP */} {/* Individual Files */}

Or download individually:

{/* Full Documentation */} downloadFile(outputs.fullDocument.filename, outputs.fullDocument.content)} icon={} filename={outputs.fullDocument.filename} size={outputs.fullDocument.size} isDownloading={isDownloading(outputs.fullDocument.filename)} isDownloaded={isDownloaded(outputs.fullDocument.filename)} /> {/* Agent Prompt */} downloadFile(outputs.agentPrompt.filename, outputs.agentPrompt.content)} icon={} filename={outputs.agentPrompt.filename} size={outputs.agentPrompt.size} isDownloading={isDownloading(outputs.agentPrompt.filename)} isDownloaded={isDownloaded(outputs.agentPrompt.filename)} /> {/* MCP Config */} downloadFile(outputs.mcpConfig.filename, outputs.mcpConfig.content, 'application/json') } icon={} filename={outputs.mcpConfig.filename} size={outputs.mcpConfig.size} isDownloading={isDownloading(outputs.mcpConfig.filename)} isDownloaded={isDownloaded(outputs.mcpConfig.filename)} /> {/* README */} downloadFile(outputs.readme.filename, outputs.readme.content)} icon={} filename={outputs.readme.filename} size={outputs.readme.size} isDownloading={isDownloading(outputs.readme.filename)} isDownloaded={isDownloaded(outputs.readme.filename)} /> {/* install.md (if available) */} {outputs.installMd && ( downloadFile(outputs.installMd!.filename, outputs.installMd!.content)} icon={} filename={outputs.installMd.filename} size={outputs.installMd.size} isDownloading={isDownloading(outputs.installMd.filename)} isDownloaded={isDownloaded(outputs.installMd.filename)} highlight={true} /> )} {/* Sections Count */}
+ {outputs.sections.length} section files (included in ZIP)
) } interface DownloadButtonProps { onClick: () => void icon: React.ReactNode filename: string size: number isDownloading: boolean isDownloaded: boolean highlight?: boolean } function DownloadButton({ onClick, icon, filename, size, isDownloading, isDownloaded, highlight = false, }: DownloadButtonProps) { return ( ) }