Working on metars, updating ui drawer
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
import { Box, Divider, Drawer, Group, Text } from '@mantine/core';
|
||||
import { Box, Drawer, Group, Tabs, TabsList, Text, Tooltip } 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';
|
||||
import { useMediaQuery } from '@mantine/hooks';
|
||||
|
||||
export default function AirportDrawer({
|
||||
airport,
|
||||
@@ -12,15 +13,27 @@ export default function AirportDrawer({
|
||||
setAirport: (airport: Airport | null) => void;
|
||||
}) {
|
||||
const [metar, setMetar] = useState<Metar | undefined>(undefined);
|
||||
const isMobile = useMediaQuery('(max-width: 768px)');
|
||||
|
||||
useEffect(() => {
|
||||
if (airport != null) {
|
||||
if (!airport) return;
|
||||
function updateMetar() {
|
||||
if (!airport) return;
|
||||
console.log(airport.icao);
|
||||
getMetars({ icaos: [airport.icao] }).then((m) => {
|
||||
if (m.length > 0) {
|
||||
setMetar(m[0]);
|
||||
} else {
|
||||
setMetar(undefined);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
updateMetar();
|
||||
|
||||
const interval = setInterval(updateMetar, 60000);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, [airport]);
|
||||
|
||||
if (!airport) {
|
||||
@@ -35,47 +48,58 @@ export default function AirportDrawer({
|
||||
onClose={() => setAirport(null)}
|
||||
title={airport.name}
|
||||
withinPortal
|
||||
zIndex={10000}
|
||||
styles={{ root: { width: 0, height: 0 } }}
|
||||
zIndex={1000}
|
||||
styles={{ root: { padding: 0, margin: 0, width: 0, height: 0 } }}
|
||||
padding='md'
|
||||
size='md'
|
||||
size={isMobile ? '100%' : 'md'}
|
||||
position='left'
|
||||
withOverlay={false}
|
||||
closeOnClickOutside={false}
|
||||
>
|
||||
<Box mb='lg'>
|
||||
{metar && metar.flight_category && (
|
||||
<Group justify='space-between' mb='md'>
|
||||
<Group
|
||||
justify='space-between'
|
||||
mb='md'
|
||||
style={{
|
||||
backgroundColor: '#272f38',
|
||||
borderTop: '1px solid #1a242f',
|
||||
borderBottom: '1px solid #1a242f',
|
||||
padding: '10px'
|
||||
}}
|
||||
>
|
||||
<Text style={{ color: metarColor }}>{metar.flight_category}</Text>
|
||||
<Text size='sm'>{metar.observation_time ? new Date(metar.observation_time).toLocaleString() : 'N/A'}</Text>
|
||||
<Tooltip zIndex={1001} label={new Date(metar.observation_time).toLocaleString()}>
|
||||
<TimeSince date={metar.observation_time} />
|
||||
</Tooltip>
|
||||
</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>
|
||||
</>
|
||||
<Tabs variant={'outline'} defaultValue={'info'}>
|
||||
<TabsList grow>
|
||||
<Tabs.Tab value={'info'}>Info</Tabs.Tab>
|
||||
<Tabs.Tab value={'weather'}>Weather</Tabs.Tab>
|
||||
</TabsList>
|
||||
<Tabs.Panel value={'info'}><AirportInfo airport={airport}/></Tabs.Panel>
|
||||
{airport.latest_metar && (
|
||||
<Tabs.Panel value={'weather'}><WeatherInfo metar={airport.latest_metar} /></Tabs.Panel>
|
||||
)}
|
||||
</Group>
|
||||
</Tabs>
|
||||
</Box>
|
||||
</Drawer>
|
||||
);
|
||||
}
|
||||
|
||||
function AirportInfo({ airport }: { airport: Airport }) {
|
||||
return (<div>
|
||||
<Text>ICAO: {airport.icao}</Text>
|
||||
<Text>Category: {airportCategoryToText(airport.category)}</Text>
|
||||
</div>);
|
||||
}
|
||||
|
||||
function WeatherInfo({ metar }: { metar: Metar }) {
|
||||
return <>{metar.raw_text}</>
|
||||
}
|
||||
|
||||
function airportCategoryToText(category: AirportCategory): string {
|
||||
switch (category) {
|
||||
case AirportCategory.SMALL:
|
||||
@@ -96,3 +120,19 @@ function airportCategoryToText(category: AirportCategory): string {
|
||||
return 'Unknown';
|
||||
}
|
||||
}
|
||||
|
||||
function TimeSince({ date }: { date: string }) {
|
||||
const inputDate = new Date(date);
|
||||
// @ts-expect-error doing arithmetic with dates
|
||||
const seconds = Math.floor((new Date() - inputDate) / 1000);
|
||||
|
||||
if (seconds < 60) {
|
||||
const content = seconds + (seconds === 1 ? " second ago" : " seconds ago");
|
||||
return <Text>{content}</Text>;
|
||||
} else {
|
||||
const minutes = Math.floor(seconds / 60);
|
||||
const content = minutes + (minutes === 1 ? " minute ago" : " minutes ago");
|
||||
// If more than 60 minutes have passed, set the text color to yellow
|
||||
return <Text style={{ color: minutes >= 60 ? '#fca903' : undefined }}>{content}</Text>;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user