Working on queries to get latest metar airports first

This commit is contained in:
2025-04-15 22:48:05 -04:00
parent d81f7bcedb
commit f5446ac0eb
8 changed files with 209 additions and 86 deletions

View File

@@ -1,5 +1,8 @@
import { Divider, Drawer, Group } from '@mantine/core';
import { Box, Divider, Drawer, Group, Text } from '@mantine/core';
import { Airport, AirportCategory } from '@lib/airport.types.ts';
import { getMarkerColor, Metar } from '@lib/metar.types.ts';
import { useEffect, useState } from 'react';
import { getMetars } from '@lib/metar.ts';
export default function AirportDrawer({
airport,
@@ -8,9 +11,24 @@ export default function AirportDrawer({
airport: Airport | null;
setAirport: (airport: Airport | null) => void;
}) {
const [metar, setMetar] = useState<Metar | undefined>(undefined);
useEffect(() => {
if (airport != null) {
getMetars({ icaos: [airport.icao] }).then((m) => {
if (m.length > 0) {
setMetar(m[0]);
}
});
}
}, [airport]);
if (!airport) {
return null;
}
const metarColor = getMarkerColor(metar?.flight_category || 'UNKN');
return (
<Drawer
opened={true}
@@ -25,27 +43,35 @@ export default function AirportDrawer({
withOverlay={false}
closeOnClickOutside={false}
>
<Group>
<div>ICAO: {airport.icao}</div>
<div>Category: {airportCategoryToText(airport.category)}</div>
<div>
Country / Region: {airport.iso_country}, {airport.iso_region}
</div>
<div>Municipality: {airport.municipality || 'N/A'}</div>
<div>Local Code: {airport.local || 'N/A'}</div>
<div>Elevation: {airport.elevation_ft}</div>
<div>
Coordinates: {airport.latitude.toFixed(4)}, {airport.longitude.toFixed(4)}
</div>
<div>Control Tower: {airport.has_tower ? 'Yes' : 'No'}</div>
<div>Beacon: {airport.has_beacon ? 'Yes' : 'No'}</div>
{airport.latest_metar && airport.latest_metar.flight_category && (
<>
<Divider my='sm' />
<div>Flight Category: {airport.latest_metar.flight_category}</div>
</>
<Box mb='lg'>
{metar && metar.flight_category && (
<Group justify='space-between' mb='md'>
<Text style={{ color: metarColor }}>{metar.flight_category}</Text>
<Text size='sm'>{metar.observation_time ? new Date(metar.observation_time).toLocaleString() : 'N/A'}</Text>
</Group>
)}
</Group>
<Group>
<div>ICAO: {airport.icao}</div>
<div>Category: {airportCategoryToText(airport.category)}</div>
<div>
Country / Region: {airport.iso_country}, {airport.iso_region}
</div>
<div>Municipality: {airport.municipality || 'N/A'}</div>
<div>Local Code: {airport.local || 'N/A'}</div>
<div>Elevation: {airport.elevation_ft}</div>
<div>
Coordinates: {airport.latitude.toFixed(4)}, {airport.longitude.toFixed(4)}
</div>
<div>Control Tower: {airport.has_tower ? 'Yes' : 'No'}</div>
<div>Beacon: {airport.has_beacon ? 'Yes' : 'No'}</div>
{metar && metar.flight_category && (
<>
<Divider my='sm' />
<div>Flight Category: {metar.flight_category}</div>
</>
)}
</Group>
</Box>
</Drawer>
);
}

View File

@@ -2,6 +2,7 @@ import { Airport, AirportCategory } from '@lib/airport.types.ts';
import { Marker, Popup } from 'react-leaflet';
import L from 'leaflet';
import { useRef } from 'react';
import { getMarkerColor } from '@lib/metar.types.ts';
export default function AirportMarker({
index,
@@ -34,21 +35,6 @@ export default function AirportMarker({
);
}
function getMarkerInfo(flightCategory: 'VFR' | 'MVFR' | 'LIFR' | 'IFR' | 'UNKN'): [string, number] {
switch (flightCategory) {
case 'IFR':
return ['#ff0100', 5];
case 'LIFR':
return ['#7f007f', 6];
case 'MVFR':
return ['#00f', 7];
case 'VFR':
return ['#018000', 8];
case 'UNKN':
return ['#696969', 4];
}
}
function createCustomIcon(airport: Airport): L.DivIcon {
if (airport.category === AirportCategory.HELIPORT) {
return L.divIcon({
@@ -73,12 +59,12 @@ function createCustomIcon(airport: Airport): L.DivIcon {
} else {
// Default to a filled circle.
const flightCategory = airport.latest_metar?.flight_category || 'UNKN';
const info = getMarkerInfo(flightCategory);
const color = getMarkerColor(flightCategory);
if (flightCategory == 'UNKN') {
return L.divIcon({
html: `
<div style="
background-color: ${info[0]};
background-color: ${color};
width: 10px;
height: 10px;
border-radius: 50%;
@@ -93,7 +79,7 @@ function createCustomIcon(airport: Airport): L.DivIcon {
return L.divIcon({
html: `
<div style="
background-color: ${info[0]};
background-color: ${color};
width: 18px;
height: 18px;
border-radius: 50%;