'use client' import { useState, MutableRefObject } from 'react' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { FileText, Loader2 } from 'lucide-react' interface RapportDialogProps { projectId: string rapportForm: Record setRapportForm: React.Dispatch>> mapRef?: MutableRefObject mapScreenshot?: string onClose: () => void onRapportCreated: (link: string) => void } export function RapportDialog({ projectId, rapportForm, setRapportForm, mapRef, mapScreenshot: preCapuredScreenshot, onClose, onRapportCreated, }: RapportDialogProps) { const [creatingRapport, setCreatingRapport] = useState(false) const handleCreate = async () => { if (!projectId) return setCreatingRapport(true) try { // Capture map screenshot — compress to JPEG and resize for smaller payload let mapScreenshot = '' const rawScreenshot = preCapuredScreenshot || '' if (!rawScreenshot) { try { if (mapRef?.current) { const canvas = mapRef.current.getCanvas() if (canvas) { // Resize to max 2400px wide and convert to JPEG const maxW = 2400 const ratio = Math.min(1, maxW / canvas.width) const offscreen = document.createElement('canvas') offscreen.width = Math.round(canvas.width * ratio) offscreen.height = Math.round(canvas.height * ratio) const ctx = offscreen.getContext('2d') if (ctx) { ctx.drawImage(canvas, 0, 0, offscreen.width, offscreen.height) mapScreenshot = offscreen.toDataURL('image/jpeg', 0.85) } } } } catch (e) { console.warn('Map screenshot failed:', e) } } else if (rawScreenshot.length > 800000) { // Compress pre-captured screenshot if too large try { const img = new Image() img.src = rawScreenshot await new Promise(r => { img.onload = r; img.onerror = r }) const maxW = 2400 const ratio = Math.min(1, maxW / img.naturalWidth) const offscreen = document.createElement('canvas') offscreen.width = Math.round(img.naturalWidth * ratio) offscreen.height = Math.round(img.naturalHeight * ratio) const ctx = offscreen.getContext('2d') if (ctx) { ctx.drawImage(img, 0, 0, offscreen.width, offscreen.height) mapScreenshot = offscreen.toDataURL('image/jpeg', 0.85) } } catch { mapScreenshot = rawScreenshot } } else { mapScreenshot = rawScreenshot } // Convert logo URL to base64 for PDF rendering let logoDataUri = '' if (rapportForm.logoUrl) { try { const logoRes = await fetch(rapportForm.logoUrl) if (logoRes.ok) { const blob = await logoRes.blob() logoDataUri = await new Promise((resolve) => { const reader = new FileReader() reader.onloadend = () => resolve(reader.result as string) reader.readAsDataURL(blob) }) } } catch (e) { console.warn('Logo fetch failed:', e) } } const rapportData = { ...rapportForm, mapScreenshot, logoUrl: logoDataUri || rapportForm.logoUrl } console.log('[Rapport] Sending request, body size ~', JSON.stringify({ projectId, data: rapportData }).length, 'bytes') const res = await fetch('/api/rapports', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ projectId, data: rapportData }), }) if (res.ok) { const result = await res.json() onRapportCreated(`/rapport/${result.token}`) onClose() window.open(`/rapport/${result.token}`, '_blank') } else { const errData = await res.json().catch(() => ({ error: `HTTP ${res.status}` })) console.error('[Rapport] API error:', res.status, errData) alert(`Rapport-Fehler: ${errData.error || 'Unbekannter Fehler (Status ' + res.status + ')'}`) } } catch (err: any) { console.error('Error creating rapport:', err) alert('Rapport-Fehler: ' + (err?.message || 'Netzwerkfehler')) } finally { setCreatingRapport(false) } } return (

Einsatzrapport erstellen

{/* Organisation */}
setRapportForm(f => ({ ...f, organisation: e.target.value }))} />
setRapportForm(f => ({ ...f, abteilung: e.target.value }))} />
{/* Einsatzdaten */}
setRapportForm(f => ({ ...f, datum: e.target.value }))} />
setRapportForm(f => ({ ...f, uhrzeit: e.target.value }))} />
setRapportForm(f => ({ ...f, einsatzNr: e.target.value }))} />
setRapportForm(f => ({ ...f, prioritaet: e.target.value }))} placeholder="z.B. Hoch" />
{/* Ort */}
setRapportForm(f => ({ ...f, einsatzort: e.target.value }))} />
setRapportForm(f => ({ ...f, objekt: e.target.value }))} />
setRapportForm(f => ({ ...f, alarmierungsart: e.target.value }))} />
setRapportForm(f => ({ ...f, stichwort: e.target.value }))} />
{/* Zeitverlauf */}
setRapportForm(f => ({ ...f, zeitAlarm: e.target.value }))} />
setRapportForm(f => ({ ...f, zeitEintreffen: e.target.value }))} />
{/* Lagebild */}