diff --git a/frontend/src/App.js b/frontend/src/App.js index 09d65e4..202e30c 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -1,4 +1,4 @@ -import React, { useEffect } from "react"; +import React, { useEffect, useState } from "react"; import { BrowserRouter as Router, Routes, Route, Navigate, useLocation } from "react-router-dom"; import AdminDashboard from "./pages/AdminDashboard"; import MobileFormPage from "./pages/MobileFormPage"; @@ -27,7 +27,17 @@ function ThemeProvider({ children }) { } function App() { - const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent) || window.innerWidth < 768; + const [isMobile, setIsMobile] = useState( + () => /iPhone|iPad|iPod|Android/i.test(navigator.userAgent) || window.innerWidth < 768 + ); + + useEffect(() => { + const onResize = () => setIsMobile( + /iPhone|iPad|iPod|Android/i.test(navigator.userAgent) || window.innerWidth < 768 + ); + window.addEventListener('resize', onResize); + return () => window.removeEventListener('resize', onResize); + }, []); return ( diff --git a/frontend/src/components/CaseForm/CaseForm.jsx b/frontend/src/components/CaseForm/CaseForm.jsx index 848f206..59804b3 100644 --- a/frontend/src/components/CaseForm/CaseForm.jsx +++ b/frontend/src/components/CaseForm/CaseForm.jsx @@ -116,7 +116,6 @@ const CaseForm = ({ isMobile = false }) => { } const result = await response.json(); - console.log("Case created:", result); // Перенаправляем на страницу анализа с ID карточки window.location.href = `/analysis/${result.id}`; diff --git a/frontend/src/components/CaseForm/Step4Environment.jsx b/frontend/src/components/CaseForm/Step4Environment.jsx index aebb25b..cc96fcc 100644 --- a/frontend/src/components/CaseForm/Step4Environment.jsx +++ b/frontend/src/components/CaseForm/Step4Environment.jsx @@ -27,23 +27,23 @@ const Step4Environment = ({ data, updateData }) => { const handleGetLocation = () => { if (!navigator.geolocation) { - alert("Геолокация не поддерживается вашим браузером"); + updateData({ gps_error: 'Геолокация не поддерживается вашим браузером' }); return; } - updateData({ gps_loading: true }); + updateData({ gps_loading: true, gps_error: null }); navigator.geolocation.getCurrentPosition( (position) => { updateData({ tnp_lat: position.coords.latitude.toFixed(6), tnp_lon: position.coords.longitude.toFixed(6), - gps_loading: false + gps_loading: false, + gps_error: null }); }, (error) => { - alert("Ошибка получения координат: " + error.message); - updateData({ gps_loading: false }); + updateData({ gps_error: 'Ошибка получения координат: ' + error.message, gps_loading: false }); }, { enableHighAccuracy: true, @@ -55,7 +55,7 @@ const Step4Environment = ({ data, updateData }) => { return (
-

Шаг 5: Среда и местность

+

Среда и местность

{/* Сезон определяется автоматически, показываем только для информации */} {data.season && ( diff --git a/frontend/src/components/SearchMap.jsx b/frontend/src/components/SearchMap.jsx index 69e1e49..bb7a6c3 100644 --- a/frontend/src/components/SearchMap.jsx +++ b/frontend/src/components/SearchMap.jsx @@ -6,9 +6,9 @@ import L from 'leaflet'; // Fix default marker icon issue with webpack delete L.Icon.Default.prototype._getIconUrl; L.Icon.Default.mergeOptions({ - iconRetinaUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-icon-2x.png', - iconUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-icon.png', - shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-shadow.png', + iconRetinaUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon-2x.png', + iconUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon.png', + shadowUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-shadow.png', }); const SearchMap = ({ tnpLat, tnpLon, maxDistance, zones }) => { @@ -183,8 +183,8 @@ const SearchMap = ({ tnpLat, tnpLon, maxDistance, zones }) => { { const getTimeOfDay = (lostTime) => { if (!lostTime) return 'день'; - const hour = parseInt(lostTime.split(':')[0]); + // Значение может прийти как "YYYY-MM-DDTHH:MM" (input type="datetime-local") + // или как "HH:MM" — берём часы из обоих форматов. + const timePart = lostTime.includes('T') ? lostTime.split('T')[1] : lostTime; + const hour = parseInt(timePart.split(':')[0]); if (hour >= 6 && hour < 18) return 'день'; if (hour >= 18 && hour < 22) return 'сумерки'; return 'ночь';