import React, { useState } from 'react'; import { toast } from 'sonner'; import { Database, Download, FileSpreadsheet, AlertTriangle, CheckCircle2, XCircle, Loader2 } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { SectionCard } from './dataShared'; const USER_EXPORTS_AVAILABLE = true; function ExportCard({ icon: Icon, title, description, filename, endpoint }) { const [loading, setLoading] = useState(false); const handleDownload = async () => { setLoading(true); try { const res = await fetch(endpoint, { credentials: 'include' }); if (!res.ok) { let data = {}; try { data = await res.json(); } catch {} throw new Error(data.error || `HTTP ${res.status}`); } const disposition = res.headers.get('Content-Disposition'); const match = disposition?.match(/filename="?([^"]+)"?/i); const name = match ? match[1] : filename; const blob = await res.blob(); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = name; a.click(); URL.revokeObjectURL(url); toast.success(`${title} downloaded.`); } catch (err) { toast.error(err.message || 'Download failed.'); } finally { setLoading(false); } }; const disabled = !USER_EXPORTS_AVAILABLE || loading; return (
{title}
{!USER_EXPORTS_AVAILABLE && ( Coming soon )}{description}
Exports may contain sensitive account metadata (website URLs, usernames, account info). Store exported files securely and avoid sharing them unencrypted.
What's included
What's not included