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;