diff --git a/frontend/src/pages/analysis/AnalysisResult.css b/frontend/src/pages/analysis/AnalysisResult.css index c384c34..081648b 100644 --- a/frontend/src/pages/analysis/AnalysisResult.css +++ b/frontend/src/pages/analysis/AnalysisResult.css @@ -4,19 +4,24 @@ color: var(--text-primary); } -/* Header */ +/* ===== Header: кейс + панель решения ===== */ .result-header { background: linear-gradient(135deg, rgba(255, 77, 0, 0.1) 0%, rgba(255, 77, 0, 0.05) 100%); border-bottom: 2px solid rgba(255, 77, 0, 0.3); - padding: 32px 24px; - margin-bottom: 32px; + padding: 24px 24px 20px; + margin-bottom: 24px; +} + +.header-top { + max-width: 1400px; + margin: 0 auto; } .result-header h1 { - font-size: 36px; + font-size: 28px; font-weight: 700; color: var(--text-primary); - margin: 0 0 16px 0; + margin: 0 0 10px 0; display: flex; align-items: center; gap: 12px; @@ -30,8 +35,8 @@ .case-info { display: flex; flex-wrap: wrap; - gap: 16px; - font-size: 16px; + gap: 12px; + font-size: 14px; color: var(--text-secondary); align-items: center; } @@ -41,167 +46,244 @@ font-weight: 700; } -/* Content */ +/* Панель решения: срочность | радиус | критические действия */ +.decision-strip { + max-width: 1400px; + margin: 18px 0 0 0; + display: grid; + grid-template-columns: 200px 220px 1fr; + gap: 12px; +} + +.decision-cell { + background: var(--bg-secondary); + border: 1px solid rgba(255, 77, 0, 0.25); + border-radius: 10px; + padding: 12px 16px; + min-width: 0; +} + +.decision-label { + font-size: 12px; + text-transform: uppercase; + letter-spacing: 0.6px; + color: var(--text-secondary); + margin-bottom: 6px; +} + +.decision-value { + font-size: 24px; + font-weight: 700; + color: var(--text-primary); + display: flex; + align-items: baseline; + gap: 8px; + line-height: 1.2; +} + +.radius-mult { + font-size: 14px; + font-weight: 600; + color: var(--accent); + background: rgba(255, 77, 0, 0.12); + padding: 2px 8px; + border-radius: 6px; +} + +/* Срочность — та же цветовая схема (акцентные тона ЦОУ) */ +.urgency-cell.urgency-критический { + border-color: #ff4d00; + background: rgba(255, 77, 0, 0.12); +} +.urgency-cell.urgency-критический .decision-value { color: #ff4d00; } + +.urgency-cell.urgency-высокий { + border-color: #ff9f1a; + background: rgba(255, 159, 26, 0.12); +} +.urgency-cell.urgency-высокий .decision-value { color: #ff9f1a; } + +.urgency-cell.urgency-средний { + border-color: #ffd166; + background: rgba(255, 209, 102, 0.1); +} +.urgency-cell.urgency-средний .decision-value { color: #ffd166; } + +.urgency-cell.urgency-стандартный .decision-value { color: var(--text-primary); } + +.warnings-cell { display: flex; flex-direction: column; } + +.decision-warnings { + margin: 0; + padding: 0; + list-style: none; + display: flex; + flex-direction: column; + gap: 4px; + font-size: 13px; + line-height: 1.45; + color: var(--text-primary); +} + +.decision-warnings li::before { + content: '🚨 '; + color: #ff4d00; +} + +.decision-warnings.muted { + color: var(--text-secondary); + font-size: 13px; +} + +.header-summary { + max-width: 1400px; + margin: 14px 0 0 0; + font-size: 14px; + line-height: 1.6; + color: var(--text-secondary); +} + +/* ===== Content ===== */ .result-content { max-width: 1400px; margin: 0 auto; padding: 0 24px 48px; display: flex; flex-direction: column; - gap: 24px; + gap: 20px; } -/* Urgency Block */ -.urgency-block { - padding: 24px; - border-radius: 12px; - border: 2px solid; +/* ===== Ряд 1: карта + зоны ===== */ +.main-row { + display: grid; + gap: 16px; + align-items: start; +} + +.main-row.with-map { + grid-template-columns: minmax(0, 1.7fr) minmax(320px, 1fr); +} + +.main-row.no-map { + grid-template-columns: 1fr; +} + +.section-head { display: flex; - flex-direction: column; + align-items: center; + justify-content: space-between; gap: 12px; + margin-bottom: 12px; } -.urgency-block.urgency-высокий { - background: rgba(255, 77, 0, 0.15); - border-color: #ff4d00; +.section-head h2, +.info-card h3 { + font-size: 17px; + font-weight: 600; + color: var(--text-primary); + margin: 0; } -.urgency-block.urgency-средний { - background: rgba(255, 159, 26, 0.15); - border-color: #ff9f1a; -} - -.urgency-block.urgency-стандартный { - background: rgba(255, 209, 102, 0.15); - border-color: #ffd166; -} - -.urgency-level { - font-size: 24px; - font-weight: 700; - letter-spacing: 0.5px; -} - -.urgency-block.urgency-высокий .urgency-level { - color: #ff4d00; -} - -.urgency-block.urgency-средний .urgency-level { - color: #ff9f1a; -} - -.urgency-block.urgency-стандартный .urgency-level { - color: #ffd166; -} - -.urgency-reason { - font-size: 16px; - line-height: 1.6; - color: var(--text-secondary); -} - -/* Info Cards */ +.map-section, +.zones-panel, .info-card { background: var(--bg-secondary); border: 1px solid rgba(255, 77, 0, 0.2); border-radius: 12px; - padding: 24px; + padding: 18px; + min-width: 0; } -.info-card h3 { - font-size: 20px; - font-weight: 600; - color: var(--text-primary); - margin: 0 0 20px 0; +/* Гео-чипы в шапке карты */ +.geo-chips { display: flex; - align-items: center; gap: 8px; } -.info-card p { - margin: 12px 0; - line-height: 1.8; +.geo-chip { + font-size: 12px; + font-weight: 600; + padding: 4px 10px; + border-radius: 6px; + border: 1px solid var(--border); + color: var(--text-secondary); + background: var(--input-bg); +} + +.geo-chip.water { border-color: rgba(47, 129, 247, 0.5); color: #79b8ff; } +.geo-chip.rail { border-color: rgba(138, 47, 47, 0.7); color: #ff9d9d; } + +/* Предупреждения геослоя — компактные плашки */ +.geo-warning { + font-size: 13px; + line-height: 1.5; + color: #ff4d00; + background: rgba(255, 77, 0, 0.08); + border: 1px solid rgba(255, 77, 0, 0.4); + border-radius: 8px; + padding: 8px 12px; + margin-bottom: 10px; +} + +.geo-warning.rail { + color: #ff7b72; + border-color: rgba(138, 47, 47, 0.7); + background: rgba(138, 47, 47, 0.12); +} + +.map-empty { + height: 320px; + display: flex; + align-items: center; + justify-content: center; + color: var(--text-secondary); + background: var(--input-bg); + border-radius: 8px; + border: 1px dashed var(--border); + font-size: 14px; +} + +.map-info { + margin-top: 10px; + display: flex; + flex-wrap: wrap; + gap: 8px; + font-size: 13px; color: var(--text-secondary); } -.info-card p strong { - color: var(--text-primary); - font-weight: 600; -} +.map-info .sep { color: rgba(255, 77, 0, 0.5); } -.info-card hr { - margin: 16px 0; - border: none; - border-top: 1px solid rgba(255, 77, 0, 0.2); -} - -/* Distance Info */ -.distance-info { - display: grid; - gap: 24px; -} - -.distance-value { - font-size: 48px; - font-weight: 700; - color: var(--accent); - text-align: center; - padding: 24px; - background: rgba(255, 77, 0, 0.1); - border-radius: 12px; - border: 2px solid rgba(255, 77, 0, 0.3); -} - -.distance-details { - display: grid; - gap: 8px; -} - -.distance-details p { - padding: 12px 16px; - background: rgba(255, 77, 0, 0.05); - border-radius: 8px; - border-left: 3px solid var(--accent); - margin: 0; - font-size: 15px; -} - -/* Zones Section */ -.zones-section { - background: var(--bg-secondary); - border: 1px solid rgba(255, 77, 0, 0.2); - border-radius: 12px; - padding: 24px; -} - -.zones-section h2 { - font-size: 24px; - font-weight: 600; - color: var(--text-primary); - margin: 0 0 24px 0; +/* ===== Зоны ===== */ +.zones-count { + font-size: 13px; + color: var(--text-secondary); } .zones-list { - display: grid; - gap: 16px; + display: flex; + flex-direction: column; + gap: 10px; + max-height: 560px; + overflow-y: auto; + padding-right: 4px; } .zone-card { - background: rgba(255, 77, 0, 0.05); - border-radius: 10px; - padding: 20px; - border-left: 4px solid; - transition: all 0.2s ease; + background: rgba(255, 77, 0, 0.04); + border-radius: 8px; + padding: 12px 14px; + border-left: 3px solid var(--border); + transition: background 0.15s ease; } .zone-card:hover { background: rgba(255, 77, 0, 0.08); - transform: translateX(4px); } .zone-card.priority-1 { border-left-color: #ff4d00; - background: rgba(255, 77, 0, 0.1); + background: rgba(255, 77, 0, 0.09); } .zone-card.priority-2 { @@ -216,95 +298,308 @@ display: flex; justify-content: space-between; align-items: center; - margin-bottom: 12px; - gap: 16px; + gap: 10px; } .zone-title { display: flex; align-items: center; - gap: 12px; - flex: 1; + gap: 10px; + min-width: 0; } .zone-priority { display: inline-flex; align-items: center; justify-content: center; - width: 32px; - height: 32px; + width: 26px; + height: 26px; background: var(--accent); color: var(--bg-primary); border-radius: 50%; font-weight: 700; - font-size: 16px; + font-size: 13px; flex-shrink: 0; } .zone-name { - font-size: 18px; + font-size: 15px; font-weight: 600; color: var(--text-primary); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; } -.zone-score { - font-size: 28px; - font-weight: 700; - color: var(--accent); +/* Направление / дистанция / score — справа компактно */ +.zone-meta { + display: flex; + align-items: center; + gap: 8px; flex-shrink: 0; } -.zone-details { - display: flex; - flex-wrap: wrap; - gap: 16px; - margin-bottom: 12px; - font-size: 14px; +.zone-dir { + font-size: 12px; + font-weight: 700; color: var(--text-secondary); + background: var(--input-bg); + border: 1px solid var(--border); + border-radius: 4px; + padding: 2px 6px; + min-width: 26px; + text-align: center; } -.zone-details .separator { - color: rgba(255, 77, 0, 0.5); +.zone-dist { + font-size: 13px; + color: var(--text-secondary); + font-variant-numeric: tabular-nums; +} + +.zone-score { + font-size: 17px; + font-weight: 700; + color: var(--accent); + min-width: 48px; + text-align: right; + font-variant-numeric: tabular-nums; } .zone-reasoning { - padding: 12px 16px; - background: rgba(255, 77, 0, 0.08); - border-radius: 6px; + margin-top: 8px; + font-size: 12.5px; + color: var(--text-secondary); + line-height: 1.5; +} + +.zones-empty { + padding: 24px; + text-align: center; + color: var(--text-secondary); font-size: 14px; +} + +/* ===== Ряд 2: поведение + действия ===== */ +.behavior-row { + display: grid; + grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); + gap: 20px; + align-items: stretch; +} + +.profile-tags { + display: flex; + flex-wrap: wrap; + gap: 6px; +} + +.profile-tag { + font-size: 12px; + font-weight: 600; + color: var(--accent); + background: rgba(255, 77, 0, 0.1); + border: 1px solid rgba(255, 77, 0, 0.35); + border-radius: 12px; + padding: 3px 10px; +} + +.profile-tag.unmodeled { + color: var(--text-secondary); + border-color: var(--border); + background: var(--input-bg); +} + +.prediction { + margin: 12px 0 0 0; + font-size: 14.5px; + line-height: 1.6; + color: var(--text-primary); +} + +/* Тактика психотипа — сетка 2×2 */ +.tactics-grid { + margin-top: 12px; + display: grid; + grid-template-columns: 1fr 1fr; + gap: 10px; +} + +.tactic { + background: var(--input-bg); + border: 1px solid var(--border); + border-radius: 8px; + padding: 10px 12px; + font-size: 13px; + line-height: 1.5; + color: var(--text-secondary); +} + +.tactic-label { + font-size: 11px; + text-transform: uppercase; + letter-spacing: 0.5px; + color: rgba(255, 77, 0, 0.8); + margin-bottom: 4px; + font-weight: 600; +} + +.unmodeled-note { + margin-top: 10px; + padding: 8px 12px; + background: var(--input-bg); + border-left: 3px solid var(--border); + border-radius: 6px; + font-size: 12.5px; color: var(--text-secondary); line-height: 1.6; } -/* Map Section */ -.map-section { - background: var(--bg-secondary); - border: 1px solid rgba(255, 77, 0, 0.2); - border-radius: 12px; - padding: 24px; +.unmodeled-note p { margin: 2px 0; } + +/* Немедленные действия — нумерованный список с акцентом */ +.actions-list { + margin: 12px 0 0 0; + padding: 0; + list-style: none; + counter-reset: action; + display: flex; + flex-direction: column; + gap: 8px; } -.map-section h2 { - font-size: 24px; +.actions-list li { + counter-increment: action; + display: flex; + gap: 10px; + font-size: 14px; + line-height: 1.5; + color: var(--text-primary); + background: var(--input-bg); + border: 1px solid var(--border); + border-radius: 8px; + padding: 10px 12px; +} + +.actions-list li::before { + content: counter(action); + flex-shrink: 0; + display: inline-flex; + align-items: center; + justify-content: center; + width: 22px; + height: 22px; + border-radius: 50%; + background: var(--accent); + color: var(--bg-primary); + font-weight: 700; + font-size: 12px; +} + +.actions-list li.critical { + border-color: #ff4d00; + background: rgba(255, 77, 0, 0.1); + font-weight: 600; +} + +.actions-list li.critical::before { + background: #ff4d00; +} + +/* ===== Ряд 3: обоснование радиуса ===== */ +.radius-formula { + font-size: 12px; + color: var(--text-secondary); + font-family: ui-monospace, 'SF Mono', Menlo, monospace; +} + +.coeff-grid { + margin-top: 14px; + display: grid; + grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); + gap: 10px; +} + +.coeff-chip { + background: var(--input-bg); + border: 1px solid var(--border); + border-left: 3px solid var(--accent); + border-radius: 8px; + padding: 10px 12px; +} + +.coeff-name { + font-size: 13px; + color: var(--text-secondary); + display: flex; + justify-content: space-between; + align-items: baseline; + gap: 6px; +} + +.coeff-value { + font-size: 16px; + font-weight: 700; + color: var(--text-primary); + font-variant-numeric: tabular-nums; +} + +.coeff-hint { + margin-top: 3px; + font-size: 11.5px; + color: var(--text-secondary); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +/* Психотип-поправки */ +.psy-mods { + margin-top: 14px; + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 8px; +} + +.psy-mods-title { + font-size: 13px; + color: var(--text-secondary); + margin-right: 4px; +} + +.psy-mod-chip { + font-size: 12.5px; font-weight: 600; color: var(--text-primary); - margin: 0 0 20px 0; + background: rgba(255, 77, 0, 0.07); + border: 1px solid rgba(255, 77, 0, 0.25); + border-radius: 6px; + padding: 4px 10px; + font-variant-numeric: tabular-nums; } -.map-info { - margin-top: 16px; - padding: 16px; - background: rgba(255, 77, 0, 0.05); - border-radius: 8px; - font-size: 14px; +/* ===== Ряд 4: справочные данные ===== */ +.reference-grid { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 20px; + align-items: start; +} + +.info-card p { + margin: 8px 0; + font-size: 13.5px; + line-height: 1.6; color: var(--text-secondary); } -.map-info p { - margin: 4px 0; +.info-card p strong { + color: var(--text-primary); + font-weight: 600; } -/* Loading & Error States */ +/* ===== Loading & Error ===== */ .loading-state, .error-state { display: flex; @@ -354,45 +649,34 @@ } .error-state button:hover { - background: #ff6a1a; + background: var(--accent-hover); transform: translateY(-2px); } -/* Responsive */ -@media (max-width: 768px) { - .result-header { - padding: 24px 16px; +/* ===== Responsive ===== */ +@media (max-width: 1100px) { + .main-row.with-map { + grid-template-columns: 1fr; } - - .result-header h1 { - font-size: 28px; + .behavior-row { + grid-template-columns: 1fr; } - - .result-content { - padding: 0 16px 32px; - } - - .distance-value { - font-size: 36px; - padding: 20px; - } - - .zone-header { - flex-direction: column; - align-items: flex-start; - } - - .zone-score { - font-size: 24px; - } - - .case-info { - flex-direction: column; - align-items: flex-start; - gap: 8px; - } - - .separator { - display: none; + .reference-grid { + grid-template-columns: 1fr 1fr; } } + +@media (max-width: 768px) { + .result-header { padding: 20px 16px 16px; } + .result-header h1 { font-size: 22px; } + .decision-strip { + grid-template-columns: 1fr 1fr; + } + .warnings-cell { grid-column: 1 / -1; } + .result-content { padding: 0 16px 32px; } + .reference-grid { grid-template-columns: 1fr; } + .coeff-grid { grid-template-columns: 1fr 1fr; } + .case-info { flex-direction: column; align-items: flex-start; gap: 6px; } + .separator { display: none; } + .tactics-grid { grid-template-columns: 1fr; } +} \ No newline at end of file diff --git a/frontend/src/pages/analysis/AnalysisResult.jsx b/frontend/src/pages/analysis/AnalysisResult.jsx index d8f4402..7580142 100644 --- a/frontend/src/pages/analysis/AnalysisResult.jsx +++ b/frontend/src/pages/analysis/AnalysisResult.jsx @@ -5,10 +5,12 @@ import { apiFetch } from "../../api/client"; import "./AnalysisResult.css"; const GENDER_LABEL = { m: 'М', f: 'Ж' }; +const DIRECTION_RU = { N: 'С', NE: 'СВ', E: 'В', SE: 'ЮВ', S: 'Ю', SW: 'ЮЗ', W: 'З', NW: 'СЗ' }; // Маппинг уровня срочности бэкенда → CSS-класс (фронтовые классы в Cyrillic) const urgencyClass = (urgency) => { const u = (urgency || '').toLowerCase(); + if (u.includes('крит')) return 'критический'; if (u.includes('высок')) return 'высокий'; if (u.includes('сред')) return 'средний'; return 'стандартный'; @@ -119,228 +121,246 @@ const AnalysisResult = () => { const urgencyLevel = urgencyClass(analysisData?.urgency); const profiles = analysisData?.active_profiles || []; const warnings = analysisData?.critical_warnings || []; + const unmodeled = analysisData?.unmodeled_profiles || []; const tnpLat = caseData.tnp_lat || caseData.gps_lat; const tnpLon = caseData.tnp_lon || caseData.gps_lon; + const waterCount = (waterData?.features || []).filter(f => f.layer !== 'railway').length; + const railCount = (waterData?.features || []).filter(f => f.layer === 'railway').length; + + // Коэффициенты формулы Экстремум — компактные чипы (название: значение) + const coeffChips = [ + { label: 'Время', value: `${caseData.elapsed_hours || 1} ч`, hint: 'от потери' }, + { label: 'НормС', value: coeffs.base_speed, hint: `баз. скорость, ${caseData.age_years} лет` }, + { label: 'СП', value: coeffs.terrain, hint: caseData.terrain?.join(', ') || 'местность' }, + { label: 'СКД', value: coeffs.diagnosis, hint: caseData.diagnosis_type?.join(', ') || 'без диагноза' }, + { label: 'СУ', value: coeffs.urgency, hint: caseData.has_transport && caseData.has_transport !== 'none' ? caseData.has_transport : 'без транспорта' }, + { label: 'СУТ', value: coeffs.fatigue?.toFixed(2), hint: 'усталость' }, + { label: 'ВВС', value: coeffs.time_of_day, hint: analysisData?.time_of_day || 'время суток' }, + { label: 'ВП', value: coeffs.weather, hint: caseData.weather || caseData.precipitation || 'без осадков' }, + ]; + + // Средний ряд: карта + зоны рядом + const hasMap = tnpLat && tnpLon; return (
{analysisData.summary}
}Формула: Distance = Time × НормС × СП × СКД × СУ × СУТ × ВВС × ВП
-Время (Time): {caseData.elapsed_hours || 1} ч
-Базовая скорость (НормС): {coeffs.base_speed} км/ч (возраст {caseData.age_years} лет)
-Местность (СП): {coeffs.terrain} ({caseData.terrain?.join(', ') || 'не указана'})
-Диагноз (СКД): {coeffs.diagnosis} {caseData.has_diagnosis ? `(${caseData.diagnosis_type?.join(', ')})` : '(нет)'}
-Транспорт (СУ): {coeffs.urgency} {caseData.has_transport && caseData.has_transport !== 'none' ? `(${caseData.has_transport})` : '(нет)'}
-Усталость (СУТ): {coeffs.fatigue?.toFixed(2)} (снижение 5%/час)
-Время суток (ВВС): {coeffs.time_of_day} ({analysisData?.time_of_day})
-Погода (ВП): {coeffs.weather} ({caseData.weather || caseData.precipitation || 'нет'})
-Радиус поиска: {analysisData?.search_radius_km} км × {analysisData?.distance_multiplier} (профили)
-{p.name}
- {p.note &&{p.note}
} - {p.critical_warning && ( -🚨 {p.critical_warning}
- )} -Психотип: {analysisData.psychotype}
-Модель движения: {psyMods.description}
-Модификаторы зон:
-
- • 0-500м: ×{psyMods.zone_0_500}
- • 500-1500м: ×{psyMods.zone_500_1500}
- • 1500-2500м: ×{psyMods.zone_1500_2500}
- • 2500м+: ×{psyMods.zone_2500plus}
-
Тактика поиска:
-Приоритетные зоны: {psyRec.priority_zones}
-Патрун: {psyRec.search_pattern}
-Ключевые объекты: {psyRec.key_locations}
-Связь: {psyRec.communication}
-Причина: {caseData.reason || caseData.loss_reason || 'не указана'}
-Последнее известное место: {caseData.last_known_place || 'не указано'}
- {caseData.direction &&Направление движения: {caseData.direction}
} - {caseData.behavior_description && ( -Описание: {caseData.behavior_description}
- )} - {analysisData?.behavioral_prediction && ( -Поведенческий прогноз: {analysisData.behavioral_prediction}
- )} -- 🚨 {waterData.warning} -
+- 🚂 {waterData.railway_warning} -
+ {waterData?.railway_warning && railCount > 0 && ( +- 💧 Водоёмы в зоне поиска: {waterData.features.filter(f => f.layer !== 'railway').length} - {' '}· 🚂 Ж/д линий: {waterData.features.filter(f => f.layer === 'railway').length} - {waterData.warning && ' — приоритетная проверка'} (данные OSM) -
+ {hasMap ? ( +Координаты ТНП: {tnpLat}, {tnpLon}
- {caseData.tnp_address &&Адрес: {caseData.tnp_address}
} +Диагнозы: {caseData.diagnosis_type?.join(', ') || 'есть'}
+{analysisData.behavioral_prediction}
)} - {caseData.fitness_level && ( -Физическая подготовка: {caseData.fitness_level}
+ {psyRec && ( +⚠️ Не умеет плавать — приоритет ближайшим водоёмам
} - {caseData.has_transport && caseData.has_transport !== 'none' && ( -Транспорт: {caseData.has_transport}
+ {unmodeled.length > 0 && ( +• {u.profile}: {u.note}
+ ))} +- Вне поведенческой модели (на скоринг зон не влияют): -
- {analysisData.unmodeled_profiles.map((u, i) => ( -- • {u.profile}: {u.note} -
+Сезон: {caseData.season || 'не указан'}
- {caseData.temperature_c != null &&Температура: {caseData.temperature_c}°C
} -Осадки: {caseData.weather || caseData.precipitation || 'нет'}
- {caseData.visibility &&Видимость: {caseData.visibility}
} + {/* ===== Ряд 4: Справочные данные (3 колонки) ===== */} +Причина: {caseData.reason || caseData.loss_reason || 'не указана'}
+Последнее известное место: {caseData.last_known_place || 'не указано'}
+ {caseData.direction &&Направление движения: {caseData.direction}
} + {caseData.behavior_description &&Описание: {caseData.behavior_description}
} +Диагнозы: {caseData.diagnosis_type?.join(', ')}
+ ) : ( +Диагнозы: нет
+ )} + {caseData.fitness_level &&Физподготовка: {caseData.fitness_level}
} + {caseData.cant_swim &&⚠️ Не умеет плавать — приоритет ближайшим водоёмам
} + {caseData.has_transport && caseData.has_transport !== 'none' && ( +Транспорт: {caseData.has_transport}
+ )} +Сезон: {caseData.season || 'не указан'}
+ {caseData.temperature_c != null &&Температура: {caseData.temperature_c}°C
} +Осадки: {caseData.weather || caseData.precipitation || 'нет'}
+ {caseData.visibility &&Видимость: {caseData.visibility}
} +