'use client' import React, { useEffect, useState } from 'react' import { useSession } from 'next-auth/react' import { useRouter } from 'next/navigation' import Link from 'next/link' import Cookies from 'js-cookie' interface Address { id: string street: string city: string postcode: string latitude: number longitude: number order: number } interface Route { id: string createdAt: string status: string addresses: Address[] } interface RouteClientProps { routeId: string } // İki nokta arası mesafeyi hesapla (Haversine formülü) function calculateDistance(lat1: number, lon1: number, lat2: number, lon2: number): number { const R = 6371; // Dünya'nın yarıçapı (km) const dLat = toRad(lat2 - lat1); const dLon = toRad(lon2 - lon1); const a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) * Math.sin(dLon/2) * Math.sin(dLon/2); const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); return Math.round(R * c * 10) / 10; // 1 ondalık basamak } function toRad(value: number): number { return value * Math.PI / 180; } // Toplam mesafeyi hesapla function calculateTotalDistance(addresses: any[]): number { let total = 0; const sortedAddresses = addresses.sort((a, b) => a.order - b.order); for (let i = 0; i < sortedAddresses.length - 1; i++) { const current = sortedAddresses[i]; const next = sortedAddresses[i + 1]; total += calculateDistance( current.latitude, current.longitude, next.latitude, next.longitude ); } return Math.round(total * 10) / 10; // 1 ondalık basamak } export default function RouteClient({ routeId }: RouteClientProps) { const router = useRouter() const { data: session, status: sessionStatus } = useSession() const [route, setRoute] = useState(null) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) const [messages, setMessages] = useState(null) const [visitedAddresses, setVisitedAddresses] = useState>(new Set()) useEffect(() => { const loadMessages = async () => { const lang = Cookies.get('NEXT_LOCALE') || 'tr' const messages = await import(`@/messages/${lang}.json`) setMessages(messages.default) } loadMessages() }, []) useEffect(() => { fetchRoute() }, [routeId]) const fetchRoute = async () => { try { setLoading(true) const response = await fetch(`/api/routes/${routeId}`, { credentials: 'include' }) if (!response.ok) { throw new Error(messages?.routeDetails?.error || 'Rota yüklenirken bir hata oluştu') } const data = await response.json() setRoute(data) setError(null) } catch (err) { console.error('Rota getirme hatası:', err) setError(err instanceof Error ? err.message : messages?.routeDetails?.error || 'Rota yüklenirken bir hata oluştu') } finally { setLoading(false) } } const startRoute = async () => { try { const response = await fetch(`/api/routes/${routeId}/start`, { method: 'POST', credentials: 'include' }) if (!response.ok) { throw new Error(messages?.routeDetails?.startError || 'Rota başlatılırken bir hata oluştu') } await fetchRoute() } catch (err) { console.error('Rota başlatma hatası:', err) setError(err instanceof Error ? err.message : messages?.routeDetails?.startError || 'Rota başlatılırken bir hata oluştu') } } const handleAddressClick = async (addressId: string) => { try { const address = route?.addresses.find(a => a.id === addressId); if (!address) return; // Google Maps URL'sini oluştur const googleMapsUrl = `https://www.google.com/maps/place/${encodeURIComponent( `${address.street}, ${address.postcode} ${address.city}` )}`; // Yeni sekmede Google Maps'i aç window.open(googleMapsUrl, '_blank', 'noopener,noreferrer'); // Ziyaret edilen adresleri güncelle setVisitedAddresses(prev => new Set(Array.from(prev).concat(addressId))); // Geçmişe kaydet await fetch('/api/history', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ routeId, addressId, action: 'ADDRESS_VIEWED' }) }); } catch (error) { console.error('Adres görüntüleme hatası:', error); } }; if (!messages || sessionStatus === 'loading' || loading) { return (
) } if (sessionStatus === 'unauthenticated') { router.push('/auth/login') return null } if (error || !route) { return (

{messages.common.error}

{error || messages.routeDetails.notFound}

) } return (
{messages.common.back}

{messages.routeDetails.title}

{route?.status === 'CREATED' && ( )}

{messages.routeDetails.routeInfo}

{messages.routeDetails.createdAt}: {new Date(route.createdAt).toLocaleDateString()}

{String(messages?.routeDetails?.status || 'Durum')}
{route?.status}
{String(messages?.routeDetails?.addressCount || 'Adres Sayısı')}
{route?.addresses.length}
{String(messages?.routeDetails?.optimizationStatus || 'Optimizasyon Durumu')}
{route?.status === 'OPTIMIZED' ? String(messages?.routeDetails?.status?.optimized || 'Optimize Edilmiş') : String(messages?.routeDetails?.status?.notOptimized || 'Optimize Edilmemiş')}
{String(messages?.routeDetails?.totalDistance || 'Toplam Mesafe')}
{calculateTotalDistance(route.addresses)} km
{String(messages?.routeDetails?.estimatedDuration)}
{Math.round(calculateTotalDistance(route.addresses) / 30 * 60)} dakika

{messages.routeDetails.addresses}

{route?.addresses.map((address, index) => (
handleAddressClick(address.id)} className="flex items-center justify-between p-4 bg-gray-50 rounded-lg cursor-pointer hover:bg-gray-100" >
{index + 1}. {address.street}, {address.postcode} {address.city}
{visitedAddresses.has(address.id) && ( )}
))}
) }