'use client'
import { useState, useRef, useEffect } from 'react'
import { IoChevronDownOutline, IoDocumentTextOutline } from 'react-icons/io5'
import { FiDownload } from 'react-icons/fi'
import { FileSystemItem } from '@/lib/types/database'
import { downloadCurrentFormat, downloadAsPDF, downloadAsPDFFromEditor, getFormatDisplayName } from '@/lib/utils/download-utils'
import { Editor } from '@tiptap/react'
interface DownloadDropdownProps {
file: FileSystemItem
className?: string
editor?: Editor | null // Optional TipTap editor instance for better PDF export
}
export default function DownloadDropdown({ file, className = '', editor }: DownloadDropdownProps) {
const [isOpen, setIsOpen] = useState(false)
const [isDownloading, setIsDownloading] = useState(false)
const [downloadType, setDownloadType] = useState<'current' | 'pdf' | null>(null)
const [error, setError] = useState<string | null>(null)
const dropdownRef = useRef<HTMLDivElement>(null)
// Close dropdown when clicking outside
useEffect(() => {
function handleClickOutside(event: MouseEvent) {
if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
setIsOpen(false)
}
}
document.addEventListener('mousedown', handleClickOutside)
return () => document.removeEventListener('mousedown', handleClickOutside)
}, [])
const handleDownloadCurrent = async () => {
setIsDownloading(true)
setDownloadType('current')
setIsOpen(false)
setError(null)
try {
downloadCurrentFormat(file)
} catch (error) {
console.error('Error downloading file:', error)
setError('Failed to download file')
} finally {
setTimeout(() => {
setIsDownloading(false)
setDownloadType(null)
}, 1000) // Small delay to show success
}
}
const handleDownloadPDF = async () => {
setIsDownloading(true)
setDownloadType('pdf')
setIsOpen(false)
setError(null)
try {
const fileName = file.name.replace(/\.[^/.]+$/, '')
// Use TipTap editor for better PDF export if available
if (editor) {
await downloadAsPDFFromEditor(editor, fileName)
} else {
// Fallback to markdown parsing
await downloadAsPDF(file)
}
} catch (error) {
console.error('Error downloading PDF:', error)
setError('Failed to generate PDF')
} finally {
setTimeout(() => {
setIsDownloading(false)
setDownloadType(null)
}, 1000) // Small delay to show success
}
}
if (!file || file.type !== 'file' || !file.content) {
return null
}
const formatName = getFormatDisplayName(file.file_extension || undefined)
const pdfDescription = editor
? 'Professional PDF with perfect formatting'
: 'Formatted document with tables & links'
return (
<div className={`relative ${className}`} ref={dropdownRef}>
<button
onClick={() => setIsOpen(!isOpen)}
disabled={isDownloading}
className="flex items-center gap-1.5 px-2.5 py-1.5 text-xs text-slate-400 hover:text-slate-200 hover:bg-slate-600/50 rounded-md transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed border border-slate-700/50 hover:border-slate-600/50"
title="Download file"
>
<FiDownload className="w-3.5 h-3.5" />
<IoChevronDownOutline className={`w-3 h-3 transition-transform duration-200 ${isOpen ? 'rotate-180' : ''}`} />
</button>
{isOpen && (
<div className="absolute right-0 top-full mt-1 bg-slate-800 border border-slate-700 rounded-md shadow-lg py-1 z-50 min-w-[180px]">
<button
onClick={handleDownloadCurrent}
disabled={isDownloading}
className="w-full px-3 py-2 text-left text-sm text-slate-200 hover:bg-slate-700 transition-colors flex items-center gap-2 disabled:opacity-50"
>
<IoDocumentTextOutline className="w-4 h-4 text-slate-400" />
<div className="flex flex-col">
<span>Current Format</span>
<span className="text-xs text-slate-500">{formatName}</span>
</div>
</button>
<button
onClick={handleDownloadPDF}
disabled={isDownloading}
className="w-full px-3 py-2 text-left text-sm text-slate-200 hover:bg-slate-700 transition-colors flex items-center gap-2 disabled:opacity-50"
>
<IoDocumentTextOutline className="w-4 h-4 text-red-400" />
<div className="flex flex-col">
<span>PDF {editor && <span className="text-xs text-teal-400">✨</span>}</span>
<span className="text-xs text-slate-500">{pdfDescription}</span>
</div>
</button>
{isDownloading && (
<div className="px-3 py-2 text-xs text-slate-400 border-t border-slate-600">
{error ? (
<span className="text-red-400">{error}</span>
) : (
<span>
{downloadType === 'pdf'
? (editor ? 'Generating PDF from editor...' : 'Converting markdown to PDF...')
: 'Preparing download...'
}
</span>
)}
</div>
)}
</div>
)}
</div>
)
}