import { useState, useEffect } from 'react'; // Список бетонных заводов const factories = [ { name: "Завод Полярная", address: "Киев, ул. Полярная, 20", lat: 50.5100, lng: 30.4670 }, { name: "Завод Новоконстантиновская", address: "Киев, ул. Новоконстантиновская, 4А", lat: 50.4800, lng: 30.4900 }, { name: "Завод Пироговский", address: "Киев, ул. Пироговский шлях, 34", lat: 50.4036, lng: 30.6667 }, { name: "Завод Сосниных", address: "Киев, ул. Семьи Сосниных, 7", lat: 50.4600, lng: 30.6300 }, { name: "Завод Промышленная", address: "Киев, ул. Промышленная, 1", lat: 50.4200, lng: 30.6700 } ]; // Таблица тарифов const tariffs = [ { range: [0, 10], cost: 500 }, { range: [10, 20], cost: 800 }, { range: [20, 30], cost: 1200 }, { range: [30, Infinity], cost: 1500, extraPerKm: 50 } ]; // Функция расчета стоимости function calculateCost(distance) { for (const tariff of tariffs) { if (distance >= tariff.range[0] && distance < tariff.range[1]) { return tariff.extraPerKm ? tariff.cost + (distance - 30) * tariff.extraPerKm : tariff.cost; } } return 0; } function App() { const [clientAddress, setClientAddress] = useState(""); const [results, setResults] = useState([]); const [clientCoords, setClientCoords] = useState(null); const [map, setMap] = useState(null); const [directionsRenderer, setDirectionsRenderer] = useState(null); const [error, setError] = useState(""); const [recommendedFactory, setRecommendedFactory] = useState(null); // Инициализация карты useEffect(() => { const mapInstance = new google.maps.Map(document.getElementById("map"), { zoom: 12, center: { lat: 50.5100, lng: 30.4670 } }); setMap(mapInstance); setDirectionsRenderer(new google.maps.DirectionsRenderer({ map: mapInstance })); }, []); // Обработчик расчета маршрутов const calculateRoutes = async () => { if (!clientAddress) { setError("Введите адрес клиента"); return; } setError(""); // Геокодирование адреса клиента const geocoder = new google.maps.Geocoder(); geocoder.geocode({ address: clientAddress }, async (geoResults, geoStatus) => { if (geoStatus !== "OK") { setError("Ошибка геокодирования: " + geoStatus); return; } const coords = geoResults[0].geometry.location; setClientCoords({ lat: coords.lat(), lng: coords.lng() }); // Расчет расстояний через Distance Matrix API const distanceService = new google.maps.DistanceMatrixService(); const request = { origins: [clientAddress], destinations: factories.map(f => `${f.lat},${f.lng}`), travelMode: google.maps.TravelMode.DRIVING, unitSystem: google.maps.UnitSystem.METRIC, drivingOptions: { departureTime: new Date(), trafficModel: "bestguess" } }; distanceService.getDistanceMatrix(request, (response, status) => { if (status !== "OK") { setError("Ошибка расчета расстояний: " + status); return; } const distances = response.rows[0].elements; const newResults = factories.map((factory, index) => { const distance = distances[index].distance.value / 1000; // км const duration = distances[index].duration.text; const cost = calculateCost(distance); return { ...factory, distance, duration, cost }; }); // Сортировка по стоимости и выбор рекомендованного завода newResults.sort((a, b) => a.cost - b.cost); setResults(newResults.slice(0, 5)); setRecommendedFactory(newResults[0]); // Отображение маршрута для рекомендованного завода if (newResults[0] && directionsRenderer) { const directionsService = new google.maps.DirectionsService(); directionsService.route( { origin: { lat: newResults[0].lat, lng: newResults[0].lng }, destination: { lat: coords.lat(), lng: coords.lng() }, travelMode: google.maps.TravelMode.DRIVING }, (result, status) => { if (status === "OK") { directionsRenderer.setDirections(result); } else { setError("Ошибка построения маршрута: " + status); } } ); } // Добавление меток на карту new google.maps.Marker({ position: { lat: coords.lat(), lng: coords.lng() }, map, title: "Клиент", icon: "http://maps.google.com/mapfiles/ms/icons/green-dot.png" }); factories.forEach(factory => { new google.maps.Marker({ position: { lat: factory.lat, lng: factory.lng }, map, title: factory.name }); }); }); }); }; return (

Калькулятор доставки бетона

setClientAddress(e.target.value)} className="w-full p-2 border rounded" placeholder="Например, Ирпень, ул. Чехова, 4М" />
{error &&

{error}

} {results.length > 0 && (

Результаты:

{results.map((result, index) => ( ))}
Завод Адрес Расстояние (км) Время Стоимость (грн)
{result.name} {result.address} {result.distance.toFixed(1)} {result.duration} {result.cost}
{recommendedFactory && (

Рекомендуемый завод: {recommendedFactory.name} ({recommendedFactory.cost} грн)

)}
)}
); } export default App;