import React, { useState, useRef } from 'react'; import { api } from '../services/api'; import { X, UploadCloud, Download, Loader2, CheckCircle2 } from 'lucide-react'; interface OPMLModalProps { onClose: () => void; onImportComplete: () => void; } export const OPMLModal: React.FC = ({ onClose, onImportComplete, }) => { const [file, setFile] = useState(null); const [loading, setLoading] = useState(false); const [result, setResult] = useState<{ imported: number; total: number } | null>(null); const [error, setError] = useState(null); const fileInputRef = useRef(null); const handleFileChange = (e: React.ChangeEvent) => { if (e.target.files && e.target.files.length > 0) { setFile(e.target.files[0]); setError(null); setResult(null); } }; const handleDrop = (e: React.DragEvent) => { e.preventDefault(); if (e.dataTransfer.files && e.dataTransfer.files.length > 0) { setFile(e.dataTransfer.files[0]); setError(null); setResult(null); } }; const handleImport = async () => { if (!file) return; setLoading(true); setError(null); try { const res = await api.importOPML(file); setResult({ imported: res.imported_count, total: res.total_parsed }); onImportComplete(); } catch (err: any) { setError(err.message || 'Failed to import OPML file'); } finally { setLoading(false); } }; const handleExport = () => { const url = api.exportOPMLUrl(); window.open(url, '_blank'); }; return (
e.stopPropagation()}>

OPML Migration & Backup

{error &&
{error}
} {result && (
Successfully imported {result.imported} new feeds (out of {result.total} parsed in OPML). Background fetch initiated!
)} {/* Import Section */}

Import Subscriptions (from Miniflux / Google Reader / OPML)

Upload an OPML 2.0 XML file to seamlessly import all your feeds and categories.

e.preventDefault()} onDrop={handleDrop} onClick={() => fileInputRef.current?.click()} style={{ border: '2px dashed var(--border)', borderRadius: 'var(--radius-md)', padding: '2rem 1rem', textAlign: 'center', cursor: 'pointer', background: 'var(--bg-main)', transition: 'all 0.15s ease', }} >
{file ? file.name : 'Click to browse or drag & drop OPML file'}
Supports .opml or .xml
{file && (
)}
{/* Export Section */}

Export Subscriptions

Download a complete OPML backup of all your subscribed feeds and folders.

); };