From 1e09b2d7ef2bff2f13078c153101836a8a95fa93 Mon Sep 17 00:00:00 2001 From: ThePetrovich Date: Wed, 2 Jul 2025 19:00:26 +0800 Subject: [PATCH] Minimal error handling --- src/lib/components/ControlPanel.svelte | 289 ++++++++++++++--------- src/lib/components/PointListModal.svelte | 2 +- src/lib/prediction.ts | 4 +- src/lib/types.ts | 10 + 4 files changed, 184 insertions(+), 121 deletions(-) diff --git a/src/lib/components/ControlPanel.svelte b/src/lib/components/ControlPanel.svelte index 843cd10..ae60be1 100644 --- a/src/lib/components/ControlPanel.svelte +++ b/src/lib/components/ControlPanel.svelte @@ -13,53 +13,105 @@ } from "@sveltestrap/sveltestrap"; import { getForecast } from "$lib/prediction"; - import type { FlightParameters, ProfileName } from "$lib/types"; - import { PROFILE_MAP } from "$lib/types"; + import type { FlightParameters, ProfileName, ProfileIdentifier } from "$lib/types"; + import { PROFILE_MAP, PROFILE_NAMES } from "$lib/types"; import { SavedPointsStore, FlightParametersStore, writeLocalStorage } from "$lib/stores"; import { getSavedPoints } from "$lib/api/points"; - import type { SavedPoint } from "$lib/types"; import { onMount } from "svelte"; + import { addToast } from "$lib/components/Toast.svelte"; - let isCollapsed = false; - let selectedProfile: ProfileName = "Normal"; - let startPoint = "Custom"; + // TODO: Move to $lib/utils/datetime.js + // function getCurrentDateTime() { + // const now = new Date(); + // return { + // date: now.toISOString().split("T")[0], + // time: now.toISOString().split("T")[1].split(".")[0] + // }; + // } - let element: HTMLDivElement | null = null; + // TODO: Move to $lib/utils/validation.js + // function validateCoordinates(lat: string, lng: string): { isValid: boolean; lat?: number; lng?: number } { + // const latNum = parseFloat(lat); + // const lngNum = parseFloat(lng); + // if (isNaN(latNum) || isNaN(lngNum)) { + // return { isValid: false }; + // } + // return { isValid: true, lat: latNum, lng: lngNum }; + // } + // TODO: Move to $lib/components/PredictionService.js + // async function handlePredictionRequest(params: FlightParameters) { + // try { + // const response = await getForecast(params); + // // Emit event or update store + // return response; + // } catch (error) { + // console.error("Error fetching forecast:", error); + // throw error; + // } + // } + + interface Props { + handleClickSelectOnMap?: () => void; + handleClickPointListModal?: () => void; + } + + let { + handleClickSelectOnMap = () => console.log("Select on map clicked"), + handleClickPointListModal = () => console.log("Open Point List Modal") + }: Props = $props(); + + // State + let isCollapsed = $state(false); + let startPoint = $state("Custom"); + + // Initialize date/time const now = new Date(); - let startDate = now.toISOString().split("T")[0]; // YYYY-MM-DD - let startTime = now.toISOString().split("T")[1].split(".")[0]; // HH:MM:SS + let startDate = $state(now.toISOString().split("T")[0]); + let startTime = $state(now.toISOString().split("T")[1].split(".")[0]); - let inputLat = $FlightParametersStore.launch_latitude.toFixed(6).toString(); - let inputLng = $FlightParametersStore.launch_longitude.toFixed(6).toString(); + // Coordinate inputs + let inputLat = $state($FlightParametersStore.launch_latitude.toFixed(6)); + let inputLng = $state($FlightParametersStore.launch_longitude.toFixed(6)); - $: $FlightParametersStore = { - ...$FlightParametersStore, - profile: PROFILE_MAP[selectedProfile], - }; + // Reactive effects + $effect(() => { + $FlightParametersStore; + }); - $: $SavedPointsStore, setCoordinatesFromSavedPoint(); + $effect(() => { + // Watch for saved points changes + $SavedPointsStore; + + // This effect also depends on startPoint, which is changed by setCoordinatesFromSavedPoint + // via other state variables. To avoid an infinite loop, we only call this when startPoint changes. + const sp = startPoint; + setCoordinatesFromSavedPoint(); + }); + // Functions function setCoordinatesFromSavedPoint() { - console.log("Start point changed:", startPoint); - - if (startPoint === "Custom") { - $FlightParametersStore.launch_latitude = parseFloat(inputLat); - $FlightParametersStore.launch_longitude = parseFloat(inputLng); - } else { + const lat = parseFloat(inputLat); + const lng = parseFloat(inputLng); + if (!isNaN(lat) && !isNaN(lng)) { + $FlightParametersStore.launch_latitude = lat; + $FlightParametersStore.launch_longitude = lng; + } + else { const selectedOption = document.querySelector( `#startPoint option[value="${startPoint}"]` ) as HTMLOptionElement; + if (selectedOption) { const lat = parseFloat(selectedOption.getAttribute("data-lat") || "0"); const lng = parseFloat(selectedOption.getAttribute("data-lng") || "0"); const alt = parseFloat(selectedOption.getAttribute("data-alt") || "0"); - inputLat = lat.toFixed(6).toString(); - inputLng = lng.toFixed(6).toString(); + + inputLat = lat.toFixed(6); + inputLng = lng.toFixed(6); $FlightParametersStore.launch_latitude = lat; $FlightParametersStore.launch_longitude = lng; $FlightParametersStore.launch_altitude = alt; - console.log("Updated position from saved point:", lat, lng, alt); } } } @@ -67,102 +119,84 @@ function setToCustomOnChange() { if (startPoint !== "Custom") { startPoint = "Custom"; - console.log("Switched to Custom point"); } } - - onMount(async () => { - // Load saved points from the server or local storage - const savedPoints = await getSavedPoints(); - SavedPointsStore.set(savedPoints); - }); - const handleGetPrediction = async () => { - console.log("Fetching prediction with parameters:", $FlightParametersStore); - console.log(startDate, startTime); - - $FlightParametersStore.launch_datetime = `${startDate}T${startTime}Z`; - writeLocalStorage("flightParameters", $FlightParametersStore); - - try { - const response = await getForecast($FlightParametersStore); - console.log(response); - // TODO: Notify other components of the new prediction. - // const dispatch = createEventDispatcher(); - // dispatch('newPrediction', response); - } catch (error) { - console.error("Error fetching forecast:", error); - // TODO: Display a user-friendly error message in the UI. - } - }; - - export let handleClickSelectOnMap = () => { - console.log("Select on map clicked"); - } - - export let handleClickPointListModal = () => { - console.log("Open Point List Modal"); - }; - - const applyCoordinatesFromInput = () => { + function applyCoordinatesFromInput() { const lat = parseFloat(inputLat); const lng = parseFloat(inputLng); if (!isNaN(lat) && !isNaN(lng)) { $FlightParametersStore.launch_latitude = lat; $FlightParametersStore.launch_longitude = lng; - console.log( - "Updated position:", - $FlightParametersStore.launch_latitude, - $FlightParametersStore.launch_longitude, - ); } else { console.error("Invalid coordinate input"); - // TODO: Show a validation error to the user. + // TODO: Show validation error to user } - }; + } - /** - * Updates the launch coordinates. - * @param {number} lat The new latitude. - * @param {number} lng The new longitude. - */ - export const updateLaunchPosition = (lat: number, lng: number) => { + async function handleGetPrediction() { + $FlightParametersStore.launch_datetime = `${startDate}T${startTime}Z`; + writeLocalStorage("flightParameters", $FlightParametersStore); + + getForecast($FlightParametersStore).then( + (data) => { + console.log("Forecast request successful:", data); + addToast({ + header: "Forecast Request", + body: "Forecast request successful!", + color: "success" + }); + // Handle the response data as needed + }).catch((error) => { + console.error("Error getting forecast:", error); + addToast({ + header: "Forecast Error", + body: `Error getting forecast: ${error.message}`, + color: "danger" + }); + }); + } + + function toggleCollapse() { + isCollapsed = !isCollapsed; + } + + // Exported functions for parent components + export function updateLaunchPosition(lat: number, lng: number) { $FlightParametersStore.launch_latitude = lat; $FlightParametersStore.launch_longitude = lng; - console.log("Launch position updated:", lat, lng); - inputLat = lat.toFixed(6).toString(); - inputLng = lng.toFixed(6).toString(); + inputLat = lat.toFixed(6); + inputLng = lng.toFixed(6); setToCustomOnChange(); - }; + } - export const getElement = () => { - return element; - }; + export function getSelectedProfile() { + return $FlightParametersStore.profile; + } - export const getSelectedProfile = () => { - return selectedProfile; - }; + export function selectProfile(profile: ProfileName) { + $FlightParametersStore.profile = profile; + } - export const selectProfile = (profile: ProfileName) => { - selectedProfile = profile; - $FlightParametersStore.profile = PROFILE_MAP[selectedProfile]; - console.log("Selected profile:", selectedProfile); - }; - - export const collapsePanel = () => { + export function collapsePanel() { isCollapsed = true; - }; + } - export const expandPanel = () => { + export function expandPanel() { isCollapsed = false; - }; + } - export const togglePanel = () => { + export function togglePanel() { isCollapsed = !isCollapsed; - }; + } + onMount(async () => { + const savedPoints = await getSavedPoints(); + SavedPointsStore.set(savedPoints); + }); + (isCollapsed = !isCollapsed)} + onclick={toggleCollapse} > Параметры прогнозирования - + {#if !isCollapsed}
@@ -201,10 +235,10 @@ - + {#each Object.keys(PROFILE_MAP) as profileName} - + {/each} @@ -215,7 +249,7 @@ color="secondary" size="sm" title="Edit profile" - disabled={selectedProfile !== "Custom"} + disabled={$FlightParametersStore.profile !== "custom_profile"} > Редакт. @@ -226,13 +260,13 @@ - + - {#each $SavedPointsStore as point} - - {/each} + {#each $SavedPointsStore as point} + + {/each} @@ -241,7 +275,7 @@ + @@ -266,8 +317,10 @@ color="outline-secondary" size="sm" class="w-100" - on:click={ handleClickSelectOnMap }>Указать на карте + Указать на карте +
@@ -277,7 +330,7 @@ type="number" id="startHeight" class="form-control-sm" - on:change={setToCustomOnChange} + onchange={setToCustomOnChange} bind:value={$FlightParametersStore.launch_altitude} /> @@ -291,8 +344,8 @@ />
- - {#if selectedProfile != "Custom"} + + {#if $FlightParametersStore.profile !== "custom_profile"}
@@ -317,7 +370,9 @@
- +
{/if} diff --git a/src/lib/components/PointListModal.svelte b/src/lib/components/PointListModal.svelte index a7866cd..ae57d1f 100644 --- a/src/lib/components/PointListModal.svelte +++ b/src/lib/components/PointListModal.svelte @@ -132,7 +132,7 @@