'use client'; import Link from 'next/link'; import { useState, useEffect } from 'react'; import { FiCalendar, FiMapPin, FiUser, FiMail, FiPhone, FiCamera, FiTruck, FiClock, FiPlus, FiX, FiCheck, FiStar, FiFileText, FiDollarSign, FiRefreshCw, FiEdit } from 'react-icons/fi'; interface BookingDetailProps { booking: any; emails: any[]; user: any; } export default function BookingDetail({ booking, emails, user }: BookingDetailProps) { const [setupWindows, setSetupWindows] = useState([]); const [showAddWindow, setShowAddWindow] = useState(false); const [newWindow, setNewWindow] = useState({ setupDate: '', setupTimeStart: '', setupTimeEnd: '', preferred: false, notes: '', }); const [selectedStatus, setSelectedStatus] = useState(booking.status); const [syncing, setSyncing] = useState(false); const [actionMessage, setActionMessage] = useState(''); useEffect(() => { fetchSetupWindows(); }, [booking.id]); const fetchSetupWindows = async () => { try { const res = await fetch(`/api/bookings/${booking.id}/setup-windows`); const data = await res.json(); setSetupWindows(data.setupWindows || []); } catch (error) { console.error('Failed to fetch setup windows:', error); } }; const handleStatusChange = async (newStatus: string) => { if (!confirm(`Status wirklich zu "${getStatusLabel(newStatus)}" ändern?`)) { setSelectedStatus(booking.status); return; } try { const res = await fetch(`/api/bookings/${booking.id}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ status: newStatus }), }); if (res.ok) { setActionMessage('✅ Status erfolgreich geändert'); setTimeout(() => window.location.reload(), 1500); } else { alert('Fehler beim Ändern des Status'); setSelectedStatus(booking.status); } } catch (error) { console.error('Status update error:', error); alert('Fehler beim Ändern des Status'); setSelectedStatus(booking.status); } }; const handleCalendarSync = async () => { setSyncing(true); setActionMessage(''); try { const res = await fetch('/api/calendar/sync', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ action: 'sync-booking', bookingId: booking.id }), }); const data = await res.json(); if (data.success) { setActionMessage('✅ Mit Kalender synchronisiert'); setTimeout(() => setActionMessage(''), 3000); } else { setActionMessage('❌ Sync fehlgeschlagen: ' + data.error); } } catch (error) { console.error('Calendar sync error:', error); setActionMessage('❌ Sync fehlgeschlagen'); } finally { setSyncing(false); } }; const handleGenerateContract = async () => { setActionMessage('📄 Vertrag wird generiert...'); try { const res = await fetch(`/api/bookings/${booking.id}/contract`, { method: 'POST', }); if (res.ok) { const data = await res.json(); if (data.contractUrl) { setActionMessage('✅ Vertrag generiert! Wird heruntergeladen...'); const downloadRes = await fetch(data.contractUrl); const blob = await downloadRes.blob(); const url = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = data.filename; document.body.appendChild(a); a.click(); window.URL.revokeObjectURL(url); document.body.removeChild(a); setTimeout(() => setActionMessage(''), 3000); } } else { const error = await res.json(); setActionMessage('❌ Fehler: ' + (error.error || 'Unbekannter Fehler')); } } catch (error: any) { console.error('Contract generation error:', error); setActionMessage('❌ Fehler beim Generieren'); } }; const handleGenerateInvoice = async () => { setActionMessage('💰 Rechnung wird erstellt...'); try { const res = await fetch(`/api/bookings/${booking.id}/invoice`, { method: 'POST', }); if (res.ok) { const data = await res.json(); setActionMessage('✅ Rechnung in lexoffice erstellt'); if (data.invoiceUrl) { window.open(data.invoiceUrl, '_blank'); } setTimeout(() => setActionMessage(''), 3000); } else { setActionMessage('❌ Fehler beim Erstellen'); } } catch (error) { console.error('Invoice generation error:', error); setActionMessage('❌ Fehler beim Erstellen'); } }; const handleSendContract = async () => { if (!booking.contractGenerated) { alert('Bitte generieren Sie zuerst den Vertrag!'); return; } if (!confirm(`Vertrag wirklich an ${booking.customerEmail} senden?`)) { return; } setActionMessage('📧 Vertrag wird versendet...'); try { const res = await fetch(`/api/bookings/${booking.id}/contract/send`, { method: 'POST', }); const data = await res.json(); if (data.success) { setActionMessage('✅ Vertrag per E-Mail versendet!'); setTimeout(() => window.location.reload(), 2000); } else { setActionMessage('❌ ' + (data.error || 'Fehler beim Versenden')); } } catch (error) { console.error('Contract send error:', error); setActionMessage('❌ Fehler beim Versenden'); } }; const handleAddWindow = async (e: React.FormEvent) => { e.preventDefault(); const setupDateObj = new Date(newWindow.setupDate); const [startHours, startMinutes] = newWindow.setupTimeStart.split(':'); const [endHours, endMinutes] = newWindow.setupTimeEnd.split(':'); const setupTimeStart = new Date(setupDateObj); setupTimeStart.setHours(parseInt(startHours), parseInt(startMinutes), 0, 0); const setupTimeEnd = new Date(setupDateObj); setupTimeEnd.setHours(parseInt(endHours), parseInt(endMinutes), 0, 0); try { const res = await fetch(`/api/bookings/${booking.id}/setup-windows`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ setupDate: setupDateObj.toISOString(), setupTimeStart: setupTimeStart.toISOString(), setupTimeEnd: setupTimeEnd.toISOString(), preferred: newWindow.preferred, notes: newWindow.notes, }), }); if (res.ok) { setShowAddWindow(false); setNewWindow({ setupDate: '', setupTimeStart: '', setupTimeEnd: '', preferred: false, notes: '', }); fetchSetupWindows(); } else { alert('Fehler beim Hinzufügen des Zeitfensters'); } } catch (error) { console.error('Failed to add setup window:', error); alert('Fehler beim Hinzufügen des Zeitfensters'); } }; const handleDeleteWindow = async (windowId: string) => { if (!confirm('Zeitfenster wirklich löschen?')) return; try { const res = await fetch(`/api/bookings/${booking.id}/setup-windows?windowId=${windowId}`, { method: 'DELETE', }); if (res.ok) { fetchSetupWindows(); } else { alert('Fehler beim Löschen'); } } catch (error) { console.error('Failed to delete setup window:', error); alert('Fehler beim Löschen'); } }; const handleTogglePreferred = async (windowId: string, currentPreferred: boolean) => { try { const res = await fetch(`/api/bookings/${booking.id}/setup-windows`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ windowId, preferred: !currentPreferred, }), }); if (res.ok) { fetchSetupWindows(); } } catch (error) { console.error('Failed to update setup window:', error); } }; const getStatusColor = (status: string) => { switch (status) { case 'RESERVED': return 'bg-yellow-500/20 text-yellow-400 border-yellow-500/50'; case 'CONFIRMED': return 'bg-green-500/20 text-green-400 border-green-500/50'; case 'COMPLETED': return 'bg-blue-500/20 text-blue-400 border-blue-500/50'; case 'CANCELLED': return 'bg-red-500/20 text-red-400 border-red-500/50'; default: return 'bg-gray-500/20 text-gray-400 border-gray-500/50'; } }; const getStatusLabel = (status: string) => { const labels: any = { RESERVED: 'Reserviert', CONFIRMED: 'Bestätigt', COMPLETED: 'Abgeschlossen', CANCELLED: 'Storniert', }; return labels[status] || status; }; return (
← Zurück zu Buchungen

Buchung {booking.bookingNumber}

{/* Status Card */}

Status

{getStatusLabel(booking.status)}
{/* Customer Data Card */}

Kundendaten

{booking.customerName}

{booking.customerEmail}

{booking.customerPhone}

{booking.invoiceType === 'PRIVATE' ? 'Privat' : 'Firma'}

{/* Event Details Card */}

Event-Details

{new Date(booking.eventDate).toLocaleDateString('de-DE')}

{booking.location?.name || 'N/A'}

{booking.eventAddress}

{booking.eventZip} {booking.eventCity}

{booking.eventLocation}

{/* Setup Windows Card */}

Aufbau-Zeitfenster

{setupWindows.length === 0 ? (

Keine Aufbau-Zeitfenster definiert. Standard-Aufbauzeit am Event-Tag.

) : (
{setupWindows.map((window: any) => (

{new Date(window.setupDate).toLocaleDateString('de-DE')}

{window.selected && ( Ausgewählt )} {window.preferred && !window.selected && ( Bevorzugt )}

{new Date(window.setupTimeStart).toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit', })}{' '} -{' '} {new Date(window.setupTimeEnd).toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit', })}

{window.notes && (

{window.notes}

)}
))}
)} {showAddWindow && (

Aufbau-Zeitfenster hinzufügen

setNewWindow({ ...newWindow, setupDate: e.target.value })} className="w-full px-4 py-2 bg-gray-700 border border-gray-600 text-white rounded-lg focus:ring-2 focus:ring-blue-500" required />
setNewWindow({ ...newWindow, setupTimeStart: e.target.value })} className="w-full px-4 py-2 bg-gray-700 border border-gray-600 text-white rounded-lg focus:ring-2 focus:ring-blue-500" required />
setNewWindow({ ...newWindow, setupTimeEnd: e.target.value })} className="w-full px-4 py-2 bg-gray-700 border border-gray-600 text-white rounded-lg focus:ring-2 focus:ring-blue-500" required />