'use client'; import { useState, useEffect } from 'react'; import { useRouter } from 'next/navigation'; import { FiArrowLeft, FiMapPin, FiNavigation, FiCheckCircle, FiClock, FiCamera, FiAlertCircle, FiPhone, FiMap } from 'react-icons/fi'; interface TourStop { id: string; stopOrder: number; stopType: string; status: string; arrivedAt: string | null; setupStartedAt: string | null; setupCompleteAt: string | null; pickupStartedAt: string | null; pickupCompleteAt: string | null; notes: string | null; issueDescription: string | null; booking: { id: string; bookingNumber: string; customerName: string; customerPhone: string; eventAddress: string; eventCity: string; eventZip: string; eventLocation: string | null; setupTimeStart: string; setupTimeLatest: string; photobox: { model: string; serialNumber: string; } | null; }; photos: Array<{ id: string; photoType: string; fileName: string; }>; } interface Tour { id: string; tourNumber: string; tourDate: string; status: string; totalDistance: number | null; estimatedDuration: number | null; tourStops: TourStop[]; } export default function DriverTourDetailPage({ params }: { params: { id: string } }) { const router = useRouter(); const [tour, setTour] = useState(null); const [loading, setLoading] = useState(true); const [updating, setUpdating] = useState(false); const [expandedStop, setExpandedStop] = useState(null); useEffect(() => { loadTour(); }, [params.id]); const loadTour = async () => { try { setLoading(true); const res = await fetch(`/api/driver/tours/${params.id}`); if (!res.ok) throw new Error('Tour nicht gefunden'); const data = await res.json(); setTour(data.tour); } catch (error) { console.error('Load error:', error); alert('Fehler beim Laden der Tour'); } finally { setLoading(false); } }; const updateStopStatus = async (stopId: string, newStatus: string) => { try { setUpdating(true); const res = await fetch(`/api/driver/tour-stops/${stopId}/status`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ status: newStatus }), }); if (!res.ok) throw new Error('Status-Update fehlgeschlagen'); await loadTour(); } catch (error) { console.error('Update error:', error); alert('Fehler beim Aktualisieren des Status'); } finally { setUpdating(false); } }; const startNavigation = (stop: TourStop) => { const address = `${stop.booking.eventAddress}, ${stop.booking.eventZip} ${stop.booking.eventCity}`; const googleMapsUrl = `https://www.google.com/maps/dir/?api=1&destination=${encodeURIComponent(address)}`; window.open(googleMapsUrl, '_blank'); }; const getStatusColor = (status: string) => { switch (status) { case 'PENDING': return 'bg-gray-100 text-gray-700 border-gray-300'; case 'ARRIVED': return 'bg-blue-100 text-blue-700 border-blue-300'; case 'SETUP_IN_PROGRESS': return 'bg-yellow-100 text-yellow-700 border-yellow-300'; case 'SETUP_COMPLETE': return 'bg-green-100 text-green-700 border-green-300'; case 'PICKUP_IN_PROGRESS': return 'bg-orange-100 text-orange-700 border-orange-300'; case 'PICKUP_COMPLETE': return 'bg-emerald-100 text-emerald-700 border-emerald-300'; case 'ISSUE': return 'bg-red-100 text-red-700 border-red-300'; default: return 'bg-gray-100 text-gray-700 border-gray-300'; } }; const getStatusLabel = (status: string) => { switch (status) { case 'PENDING': return 'Ausstehend'; case 'ARRIVED': return 'Angekommen'; case 'SETUP_IN_PROGRESS': return 'Aufbau läuft'; case 'SETUP_COMPLETE': return 'Aufgebaut'; case 'PICKUP_IN_PROGRESS': return 'Abbau läuft'; case 'PICKUP_COMPLETE': return 'Abgeholt'; case 'ISSUE': return 'Problem'; default: return status; } }; const getNextAction = (status: string) => { switch (status) { case 'PENDING': return { label: 'Angekommen', newStatus: 'ARRIVED', icon: FiMapPin }; case 'ARRIVED': return { label: 'Aufbau starten', newStatus: 'SETUP_IN_PROGRESS', icon: FiCheckCircle }; case 'SETUP_IN_PROGRESS': return { label: 'Aufbau abgeschlossen', newStatus: 'SETUP_COMPLETE', icon: FiCheckCircle }; case 'SETUP_COMPLETE': return { label: 'Abbau starten', newStatus: 'PICKUP_IN_PROGRESS', icon: FiCheckCircle }; case 'PICKUP_IN_PROGRESS': return { label: 'Abbau abgeschlossen', newStatus: 'PICKUP_COMPLETE', icon: FiCheckCircle }; default: return null; } }; if (loading) { return (
Lade Tour...
); } if (!tour) { return (
Tour nicht gefunden
); } const completedStops = tour.tourStops.filter(s => s.status === 'SETUP_COMPLETE' || s.status === 'PICKUP_COMPLETE' ).length; const totalStops = tour.tourStops.length; const progress = totalStops > 0 ? (completedStops / totalStops) * 100 : 0; return (

{tour.tourNumber}

{new Date(tour.tourDate).toLocaleDateString('de-DE', { weekday: 'long', day: '2-digit', month: 'long', year: 'numeric' })}

{tour.estimatedDuration && (
Geschätzte Dauer
{Math.floor(tour.estimatedDuration / 60)}h {tour.estimatedDuration % 60}min
)}
Fortschritt: {completedStops} von {totalStops} Stopps {progress.toFixed(0)}%
{tour.tourStops.length === 0 ? (

Keine Stopps für diese Tour

) : ( tour.tourStops.map((stop, index) => { const isExpanded = expandedStop === stop.id; const nextAction = getNextAction(stop.status); const isCompleted = stop.status === 'SETUP_COMPLETE' || stop.status === 'PICKUP_COMPLETE'; return (
{isCompleted ? : index + 1}

{stop.booking.customerName}

{stop.booking.bookingNumber}

{getStatusLabel(stop.status)}
{stop.booking.eventAddress}, {stop.booking.eventZip} {stop.booking.eventCity} {stop.booking.eventLocation && (
({stop.booking.eventLocation})
)}
Aufbau: {new Date(stop.booking.setupTimeStart).toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit', })} {' - '} {new Date(stop.booking.setupTimeLatest).toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit', })}
{stop.booking.photobox && (
{stop.booking.photobox.model} (SN: {stop.booking.photobox.serialNumber})
)}
{nextAction && ( )} {stop.booking.customerPhone && ( )}
{isExpanded && (
Timeline
{stop.arrivedAt && (
✓ Angekommen: {new Date(stop.arrivedAt).toLocaleTimeString('de-DE')}
)} {stop.setupStartedAt && (
✓ Aufbau gestartet: {new Date(stop.setupStartedAt).toLocaleTimeString('de-DE')}
)} {stop.setupCompleteAt && (
✓ Aufbau abgeschlossen: {new Date(stop.setupCompleteAt).toLocaleTimeString('de-DE')}
)} {stop.pickupStartedAt && (
✓ Abbau gestartet: {new Date(stop.pickupStartedAt).toLocaleTimeString('de-DE')}
)} {stop.pickupCompleteAt && (
✓ Abbau abgeschlossen: {new Date(stop.pickupCompleteAt).toLocaleTimeString('de-DE')}
)}
{stop.photos.length > 0 && (
Fotos ({stop.photos.length})
{stop.photos.map((photo) => (
{photo.photoType}
))}
)} {stop.notes && (
Notizen
{stop.notes}
)} {stop.issueDescription && (
Problem
{stop.issueDescription}
)}
)}
); }) )}
{tour.tourStops.length > 1 && (
)}
); }