A10-A16: datetime-local time parsing, step heading, gps_error state, unified leaflet 1.9.4 icons, drop debug log, dashboard error surfacing, isMobile on resize

This commit is contained in:
root
2026-07-25 12:02:56 +00:00
parent 0b033c402d
commit 5a631f6553
6 changed files with 28 additions and 15 deletions
+12 -2
View File
@@ -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 { BrowserRouter as Router, Routes, Route, Navigate, useLocation } from "react-router-dom";
import AdminDashboard from "./pages/AdminDashboard"; import AdminDashboard from "./pages/AdminDashboard";
import MobileFormPage from "./pages/MobileFormPage"; import MobileFormPage from "./pages/MobileFormPage";
@@ -27,7 +27,17 @@ function ThemeProvider({ children }) {
} }
function App() { 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 ( return (
<Router> <Router>
@@ -116,7 +116,6 @@ const CaseForm = ({ isMobile = false }) => {
} }
const result = await response.json(); const result = await response.json();
console.log("Case created:", result);
// Перенаправляем на страницу анализа с ID карточки // Перенаправляем на страницу анализа с ID карточки
window.location.href = `/analysis/${result.id}`; window.location.href = `/analysis/${result.id}`;
@@ -27,23 +27,23 @@ const Step4Environment = ({ data, updateData }) => {
const handleGetLocation = () => { const handleGetLocation = () => {
if (!navigator.geolocation) { if (!navigator.geolocation) {
alert("Геолокация не поддерживается вашим браузером"); updateData({ gps_error: 'Геолокация не поддерживается вашим браузером' });
return; return;
} }
updateData({ gps_loading: true }); updateData({ gps_loading: true, gps_error: null });
navigator.geolocation.getCurrentPosition( navigator.geolocation.getCurrentPosition(
(position) => { (position) => {
updateData({ updateData({
tnp_lat: position.coords.latitude.toFixed(6), tnp_lat: position.coords.latitude.toFixed(6),
tnp_lon: position.coords.longitude.toFixed(6), tnp_lon: position.coords.longitude.toFixed(6),
gps_loading: false gps_loading: false,
gps_error: null
}); });
}, },
(error) => { (error) => {
alert("Ошибка получения координат: " + error.message); updateData({ gps_error: 'Ошибка получения координат: ' + error.message, gps_loading: false });
updateData({ gps_loading: false });
}, },
{ {
enableHighAccuracy: true, enableHighAccuracy: true,
@@ -55,7 +55,7 @@ const Step4Environment = ({ data, updateData }) => {
return ( return (
<div className="form-step"> <div className="form-step">
<h2>Шаг 5: Среда и местность</h2> <h2>Среда и местность</h2>
{/* Сезон определяется автоматически, показываем только для информации */} {/* Сезон определяется автоматически, показываем только для информации */}
{data.season && ( {data.season && (
+5 -5
View File
@@ -6,9 +6,9 @@ import L from 'leaflet';
// Fix default marker icon issue with webpack // Fix default marker icon issue with webpack
delete L.Icon.Default.prototype._getIconUrl; delete L.Icon.Default.prototype._getIconUrl;
L.Icon.Default.mergeOptions({ L.Icon.Default.mergeOptions({
iconRetinaUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-icon-2x.png', iconRetinaUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon-2x.png',
iconUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-icon.png', iconUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon.png',
shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-shadow.png', shadowUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-shadow.png',
}); });
const SearchMap = ({ tnpLat, tnpLon, maxDistance, zones }) => { const SearchMap = ({ tnpLat, tnpLon, maxDistance, zones }) => {
@@ -183,8 +183,8 @@ const SearchMap = ({ tnpLat, tnpLon, maxDistance, zones }) => {
<Marker <Marker
position={tnpPosition} position={tnpPosition}
icon={L.icon({ icon={L.icon({
iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-red.png', iconUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon-2x.png',
shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-shadow.png', shadowUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-shadow.png',
iconSize: [25, 41], iconSize: [25, 41],
iconAnchor: [12, 41], iconAnchor: [12, 41],
popupAnchor: [1, -34], popupAnchor: [1, -34],
+1
View File
@@ -110,6 +110,7 @@ function AdminDashboard() {
} catch (err) { } catch (err) {
if (err.name !== 'AbortError') { if (err.name !== 'AbortError') {
setDashboard(null); setDashboard(null);
setError(err.message || 'Ошибка загрузки дашборда');
} }
} finally { } finally {
setDashboardLoading(false); setDashboardLoading(false);
@@ -41,7 +41,10 @@ const AnalysisResult = () => {
const getTimeOfDay = (lostTime) => { const getTimeOfDay = (lostTime) => {
if (!lostTime) return 'день'; 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 >= 6 && hour < 18) return 'день';
if (hour >= 18 && hour < 22) return 'сумерки'; if (hour >= 18 && hour < 22) return 'сумерки';
return 'ночь'; return 'ночь';