import { useState } from "react"; import type { OpticsParams, OpticsResultType, Polarisation, RsaParams, RsaResultType } from "../../model/requestTypes"; import { parseLocal } from "../../utils/localTime"; import { DateTime24Field } from "../../components/timeFields"; export type RequestFormSubmit = { name: string; importance: number; beginDateTime: string; endDateTime: string; kpp: number[]; highPriorityTransmit: boolean; optics?: OpticsParams; rsa?: RsaParams; }; type Props = { vertexCount: number; drawing: boolean; defaultBegin: string; defaultEnd: string; submitting: boolean; error?: string; onUndoPoint: () => void; onClear: () => void; onFinishDrawing: () => void; onRestartDrawing: () => void; onSubmit: (form: RequestFormSubmit) => void; onCancel: () => void; }; const OPTICS_RESULT_TYPES: { value: OpticsResultType; label: string }[] = [ { value: "PANCHROMATIC", label: "Панхроматическая" }, { value: "MULTISPECTRAL", label: "Мультиспектральная" }, { value: "PANSHARPENING", label: "Паншарпенинг" } ]; const RSA_RESULT_TYPES: { value: RsaResultType; label: string }[] = [ { value: "SPOTLIGHT", label: "Spotlight" }, { value: "STRIPMAP", label: "Stripmap" }, { value: "SCANSAR", label: "ScanSAR" } ]; const POLARISATIONS: { value: Polarisation; label: string }[] = [ { value: "HH", label: "HH" }, { value: "VV", label: "VV" } ]; export function RequestCreatePanel({ vertexCount, drawing, defaultBegin, defaultEnd, submitting, error, onUndoPoint, onClear, onFinishDrawing, onRestartDrawing, onSubmit, onCancel }: Props) { const [name, setName] = useState(""); const [importance, setImportance] = useState("1"); const [begin, setBegin] = useState(defaultBegin); const [end, setEnd] = useState(defaultEnd); const [kpp, setKpp] = useState(""); const [highPriority, setHighPriority] = useState(false); const [opticsEnabled, setOpticsEnabled] = useState(true); const [opticsResultType, setOpticsResultType] = useState("PANCHROMATIC"); const [opticsResolution, setOpticsResolution] = useState("1"); const [sunAngleMin, setSunAngleMin] = useState("10"); const [sunAngleMax, setSunAngleMax] = useState("90"); const [clouds, setClouds] = useState("100"); const [rsaEnabled, setRsaEnabled] = useState(false); const [rsaResultType, setRsaResultType] = useState("STRIPMAP"); const [interferometry, setInterferometry] = useState(false); const [polarisation, setPolarisation] = useState("HH"); const [rsaResolution, setRsaResolution] = useState("1"); const importanceNum = Number(importance); const beginMs = parseLocal(begin); const endMs = parseLocal(end); const kppList = parseKpp(kpp); const kppValid = kppList !== null; const geometryReady = vertexCount >= 3 && !drawing; const validationError = buildValidationError({ geometryReady, drawing, vertexCount, name, importance, importanceNum, beginMs, endMs, kppValid, opticsEnabled, opticsResolution, rsaEnabled, rsaResolution }); const handleSubmit = () => { if (validationError || !kppList) return; const optics: OpticsParams | undefined = opticsEnabled ? { resultType: opticsResultType, resolution: Number(opticsResolution), sunAngleMin: Number(sunAngleMin), sunAngleMax: Number(sunAngleMax), clouds: Number(clouds) } : undefined; const rsa: RsaParams | undefined = rsaEnabled ? { resultType: rsaResultType, interferometry, polarisation, resolution: Number(rsaResolution) } : undefined; onSubmit({ name: name.trim(), importance: importanceNum, beginDateTime: begin, endDateTime: end, kpp: kppList, highPriorityTransmit: highPriority, optics, rsa }); }; return ( ); } function parseKpp(raw: string): number[] | null { const trimmed = raw.trim(); if (trimmed === "") return []; const parts = trimmed.split(/[,\s]+/).filter(Boolean); const result: number[] = []; for (const part of parts) { const n = Number(part); if (!Number.isInteger(n) || n < 0) return null; result.push(n); } return result; } function buildValidationError(input: { geometryReady: boolean; drawing: boolean; vertexCount: number; name: string; importance: string; importanceNum: number; beginMs: number; endMs: number; kppValid: boolean; opticsEnabled: boolean; opticsResolution: string; rsaEnabled: boolean; rsaResolution: string; }): string | null { if (input.drawing) return "Завершите рисование полигона (≥3 вершин)."; if (!input.geometryReady) return "Задайте полигон минимум из 3 вершин."; if (input.name.trim() === "") return "Укажите название заявки."; if (input.importance.trim() === "" || !Number.isFinite(input.importanceNum) || input.importanceNum < 0) { return "Важность должна быть числом ≥ 0."; } if (!Number.isFinite(input.beginMs) || !Number.isFinite(input.endMs) || input.beginMs >= input.endMs) { return "Начало должно быть раньше конца."; } if (!input.kppValid) return "КПП — список целых чисел через запятую."; if (!input.opticsEnabled && !input.rsaEnabled) { return "Включите хотя бы один блок съёмки: Оптика или РСА."; } if (input.opticsEnabled && !(Number(input.opticsResolution) >= 0.1)) { return "Разрешение оптики должно быть ≥ 0.1 м."; } if (input.rsaEnabled && !(Number(input.rsaResolution) >= 0.1)) { return "Разрешение РСА должно быть ≥ 0.1 м."; } return null; }