mitai-jinkendo/frontend/src/components/dashboard-widgets/ReportExportWidget.jsx

111 lines
3.7 KiB
React
Raw Normal View History

import { Link } from 'react-router-dom'
import dayjs from 'dayjs'
import { FileDown } from 'lucide-react'
import { useAuth } from '../../context/AuthContext'
import { useProfile } from '../../context/ProfileContext'
import { exportDashboardToPdf } from '../../utils/dashboardPdfExport'
/**
* @param {{ reportExportConfig: { document_title: string, subtitle: string, capture_scale: number } }} props
*/
export default function ReportExportWidget({ reportExportConfig }) {
const { canExport } = useAuth()
const { activeProfile } = useProfile()
const [busy, setBusy] = useState(false)
const [err, setErr] = useState(null)
const profileName = activeProfile?.name?.trim() || 'Profil'
const title =
reportExportConfig.document_title || `${profileName} – Übersicht`
const subtitle =
reportExportConfig.subtitle ||
`Erstellt am ${dayjs().format('DD.MM.YYYY HH:mm')} · Mitai Jinkendo`
const runExport = async () => {
setErr(null)
setBusy(true)
try {
const slug = (reportExportConfig.document_title || profileName).replace(/\s+/g, '-').slice(0, 80)
await exportDashboardToPdf({
scale: reportExportConfig.capture_scale,
filenameBase: `bericht-${slug}-${dayjs().format('YYYY-MM-DD')}`,
})
} catch (e) {
setErr(e?.message || 'PDF-Export fehlgeschlagen.')
} finally {
setBusy(false)
}
}
return (
<div className="card" style={{ marginBottom: 16 }}>
<div
className="card-title"
style={{ display: 'flex', alignItems: 'center', gap: 8 }}
data-dashboard-pdf-exclude="true"
>
<FileDown size={18} color="var(--accent)" aria-hidden />
Übersicht als Bild-PDF
</div>
<div style={{ marginTop: 12 }}>
<h2
style={{
fontSize: 17,
fontWeight: 650,
margin: '0 0 6px',
color: 'var(--text1)',
lineHeight: 1.35,
}}
>
{title}
</h2>
<p style={{ margin: 0, fontSize: 13, color: 'var(--text2)', lineHeight: 1.5 }}>{subtitle}</p>
</div>
<div data-dashboard-pdf-exclude="true">
<p style={{ fontSize: 12, color: 'var(--text3)', marginTop: 14, lineHeight: 1.55 }}>
<strong>Layout-Schnappschuss:</strong> Die sichtbare Übersicht wird im Browser gerastert (html2canvas).
Für einen <strong>datenbasierten Bericht</strong> unabhängig vom Dashboard öffne{' '}
<Link to="/settings/reports" style={{ color: 'var(--accent)', fontWeight: 600 }}>
Einstellungen → PDF-Berichte
</Link>
.
</p>
<div style={{ marginTop: 14 }}>
{!canExport ? (
<p style={{ fontSize: 13, color: '#D85A30', margin: 0 }}>
PDF-Export ist für dieses Profil nicht freigeschaltet.
</p>
) : (
<>
{err && (
<p style={{ fontSize: 13, color: '#D85A30', margin: '0 0 10px' }} role="alert">
{err}
</p>
)}
<button
type="button"
className="btn btn-primary"
disabled={busy}
onClick={runExport}
style={{ display: 'inline-flex', alignItems: 'center', gap: 8 }}
>
{busy ? (
<>
<span className="spinner" style={{ width: 18, height: 18 }} aria-hidden />
PDF wird erzeugt…
</>
) : (
<>
<FileDown size={18} />
PDF-Schnappschuss herunterladen
</>
)}
</button>
</>
)}
</div>
</div>
</div>
)
}