import React, { useState } from 'react'; import { Download, FileText, FileType, File, Check, X, Loader2 } from 'lucide-react'; import '../styles/ExportButton.css'; const ExportButton = ({ hasMessages = false, currentSessionId = null, authToken = null }) => { const [showDropdown, setShowDropdown] = useState(false); const [isExporting, setIsExporting] = useState(false); const [exportStatus, setExportStatus] = useState(null); const [selectedType, setSelectedType] = useState('chat'); const exportTypes = [ { id: 'chat', name: 'Full Chat', description: 'Complete conversation history', endpoint: 'export-chat' }, { id: 'summary', name: 'Chat Summary', description: 'AI-generated conversation summary', endpoint: 'chat-summary' } ]; const exportFormats = [ { id: 'txt', name: 'Text File', description: 'Plain text format (.txt)', icon: FileText, extension: '.txt' }, { id: 'docx', name: 'Word Document', description: 'Microsoft Word format (.docx)', icon: FileType, extension: '.docx' }, { id: 'pdf', name: 'PDF Document', description: 'Portable Document Format (.pdf)', icon: File, extension: '.pdf' } ]; const handleExportClick = () => { if (!hasMessages) return; setShowDropdown(!showDropdown); setExportStatus(null); }; const handleFormatSelect = async (format) => { setIsExporting(true); setShowDropdown(false); setExportStatus(null); try { const selectedTypeData = exportTypes.find(t => t.id === selectedType); const endpoint = selectedTypeData.endpoint; // Build the URL with session ID if available let url = `${process.env.REACT_APP_API_URL}/${endpoint}?format=${format}`; if (currentSessionId) { url += `&chat_session_id=${currentSessionId}`; } // Build headers - include auth token if available (needed for specific session export) const headers = { 'Content-Type': 'application/json', }; if (authToken && currentSessionId) { headers['Authorization'] = `Bearer ${authToken}`; } const response = await fetch(url, { method: 'GET', headers: headers, }); if (!response.ok) { const errorData = await response.json().catch(() => ({})); throw new Error(errorData.error || `Export failed with status ${response.status}`); } // Get the filename from the Content-Disposition header const contentDisposition = response.headers.get('Content-Disposition'); let filename = `${selectedType}_export.${format}`; if (contentDisposition) { const filenameMatch = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/); if (filenameMatch && filenameMatch[1]) { filename = filenameMatch[1].replace(/['"]/g, ''); } } // Create blob and download const blob = await response.blob(); const url_blob = window.URL.createObjectURL(blob); const link = document.createElement('a'); link.href = url_blob; link.download = filename; document.body.appendChild(link); link.click(); document.body.removeChild(link); window.URL.revokeObjectURL(url_blob); setExportStatus('success'); setTimeout(() => setExportStatus(null), 3000); } catch (error) { console.error('Export error:', error); setExportStatus('error'); setTimeout(() => setExportStatus(null), 5000); } finally { setIsExporting(false); } }; const handleClickOutside = (e) => { if (!e.target.closest('.export-button-container')) { setShowDropdown(false); } }; React.useEffect(() => { if (showDropdown) { document.addEventListener('click', handleClickOutside); return () => document.removeEventListener('click', handleClickOutside); } }, [showDropdown]); const getButtonIcon = () => { if (isExporting) return ; if (exportStatus === 'success') return ; if (exportStatus === 'error') return ; return ; }; const getButtonClass = () => { let baseClass = 'export-button'; if (!hasMessages) baseClass += ' disabled'; if (showDropdown) baseClass += ' active'; if (exportStatus === 'success') baseClass += ' success'; if (exportStatus === 'error') baseClass += ' error'; return baseClass; }; const getButtonTitle = () => { if (!hasMessages) return 'No messages to export'; if (isExporting) return 'Exporting chat...'; if (exportStatus === 'success') return 'Export successful!'; if (exportStatus === 'error') return 'Export failed - click to retry'; // Show whether we're exporting current session or specific saved chat const sessionInfo = currentSessionId ? 'this saved chat' : 'current session'; return `Export ${sessionInfo}`; }; return (
{showDropdown && (

Export Options

{currentSessionId ? 'Export this saved chat conversation' : 'Export current session' }

{/* Export Type Selection */}
What to export:
{exportTypes.map((type) => ( ))}
{/* Format Selection */}
Format:
{exportFormats.map((format) => { const Icon = format.icon; return ( ); })}
{selectedType === 'chat' ? 'Full conversation history will be included' : 'AI will generate a concise summary of your conversation' }
)} {exportStatus && (
{exportStatus === 'success' && 'Chat exported successfully!'} {exportStatus === 'error' && 'Export failed. Please try again.'}
)}
); }; export default ExportButton;