72 lines
2.5 KiB
Svelte
72 lines
2.5 KiB
Svelte
<script lang="ts">
|
|
import Section from '$lib/components/Section.svelte';
|
|
import Card from '$lib/components/Cards/Card.svelte';
|
|
import { toasts } from 'svelte-toasts';
|
|
import Loading from '$lib/components/Loading.svelte';
|
|
|
|
import { icao } from '$lib/stores/icao';
|
|
import { aviationWeatherApi } from '$lib/api/weatherservice';
|
|
import type { Metar } from '$lib/api/types/metar'
|
|
import { onDestroy } from 'svelte';
|
|
|
|
let metar: Metar | null = null;
|
|
let loading = false;
|
|
let error: string | null = null;
|
|
|
|
let unsubscribe = icao.subscribe(async (val) => {
|
|
metar = null;
|
|
error = null;
|
|
if (val && val.length === 4) {
|
|
loading = true;
|
|
try {
|
|
const result = await aviationWeatherApi.fetchMetar(val);
|
|
metar = result;
|
|
if (!metar) error = 'No METAR found for this ICAO code.';
|
|
} catch (e) {
|
|
error = e instanceof Error ? e.message : 'Unknown error';
|
|
} finally {
|
|
loading = false;
|
|
}
|
|
}
|
|
});
|
|
|
|
onDestroy(() => unsubscribe());
|
|
</script>
|
|
|
|
<div style="display: none;">
|
|
{toasts.add({
|
|
title: 'Welcome',
|
|
duration: 5000,
|
|
type: 'success',
|
|
placement: 'bottom-center',
|
|
showProgress: true
|
|
})}
|
|
</div>
|
|
|
|
<Section label="[Output]">
|
|
<Card>
|
|
<h2 slot="headerLeft">METAR</h2>
|
|
<h2 slot="headerRight">Results</h2>
|
|
<div slot="content" class="flex h-96 w-full items-center justify-center">
|
|
{#if loading}
|
|
<Loading />
|
|
{:else if error}
|
|
<span class="text-red-600 text-xl">{error}</span>
|
|
{:else if metar}
|
|
<div class="text-left text-lg space-y-2">
|
|
<div><strong>ICAO:</strong> {metar.icaoId}</div>
|
|
<div><strong>Airport:</strong> {metar.name}</div>
|
|
<div><strong>Observed:</strong> {metar.reportTime}</div>
|
|
<div><strong>Temperature:</strong> {metar.temp}°C</div>
|
|
<div><strong>Dew Point:</strong> {metar.dewp}°C</div>
|
|
<div><strong>Wind:</strong> {metar.wdir}° at {metar.wspd}kt</div>
|
|
<div><strong>Visibility:</strong> {metar.visib}</div>
|
|
<div><strong>Pressure:</strong> {metar.altim} hPa</div>
|
|
<div><strong>Raw METAR:</strong> <code>{metar.rawOb}</code></div>
|
|
</div>
|
|
{:else}
|
|
<Loading />
|
|
{/if}
|
|
</div>
|
|
</Card>
|
|
</Section> |