From 17b76ade1f53f4fc39d829e7bd401edec9e81036 Mon Sep 17 00:00:00 2001 From: Ben Sherriff Date: Fri, 8 Sep 2023 08:59:21 -0400 Subject: [PATCH] Refactored code, working with database data --- weather-ui/README.md => README.md | 0 weather-service/src/airports/routes.rs | 56 +++++------ weather-service/src/main.rs | 3 +- weather-ui/.eslintrc.json | 50 +++------- weather-ui/.prettierrc.json | 7 +- weather-ui/next.config.js | 4 +- weather-ui/postcss.config.js | 6 +- weather-ui/src/app/page.tsx | 2 +- weather-ui/src/components/Metar.tsx | 124 ++++++------------------- weather-ui/src/components/MetarMap.tsx | 121 ++++++++++++++---------- weather-ui/src/js/airport.ts | 17 ---- weather-ui/src/js/api/airport.ts | 7 ++ weather-ui/src/js/api/airport.types.ts | 9 ++ weather-ui/src/js/api/metar.ts | 10 ++ weather-ui/src/js/api/metar.types.ts | 30 ++++++ weather-ui/src/js/state.ts | 15 --- weather-ui/src/js/weather.ts | 116 ----------------------- weather-ui/tailwind.config.js | 11 +-- weather-ui/tsconfig.json | 2 +- 19 files changed, 211 insertions(+), 379 deletions(-) rename weather-ui/README.md => README.md (100%) delete mode 100644 weather-ui/src/js/airport.ts create mode 100644 weather-ui/src/js/api/airport.ts create mode 100644 weather-ui/src/js/api/airport.types.ts create mode 100644 weather-ui/src/js/api/metar.ts create mode 100644 weather-ui/src/js/api/metar.types.ts delete mode 100644 weather-ui/src/js/state.ts delete mode 100644 weather-ui/src/js/weather.ts diff --git a/weather-ui/README.md b/README.md similarity index 100% rename from weather-ui/README.md rename to README.md diff --git a/weather-service/src/airports/routes.rs b/weather-service/src/airports/routes.rs index 20a2f3e..e511fd2 100644 --- a/weather-service/src/airports/routes.rs +++ b/weather-service/src/airports/routes.rs @@ -1,67 +1,61 @@ use crate::airports::{Airport, Airports}; -use crate::error_handler::CustomError; use actix_web::{delete, get, post, put, web, HttpResponse}; use log::error; use serde_json::json; #[get("/airports")] -async fn find_all() -> Result { - let airports = match web::block(|| Airports::find_all()).await.unwrap() { - Ok(a) => a, +async fn find_all() -> HttpResponse { + match web::block(|| Airports::find_all()).await.unwrap() { + Ok(a) => HttpResponse::Ok().json(a), Err(err) => { error!("{}", err); - return Err(err); + HttpResponse::InternalServerError().finish() } - }; - Ok(HttpResponse::Ok().json(airports)) + } } #[get("/airports/{id}")] -async fn find(id: web::Path) -> Result { - let airport = match Airports::find(id.into_inner()) { - Ok(a) => a, +async fn find(id: web::Path) -> HttpResponse { + match Airports::find(id.into_inner()) { + Ok(a) => HttpResponse::Ok().json(a), Err(err) => { error!("{}", err); - return Err(err); + HttpResponse::InternalServerError().finish() } - }; - Ok(HttpResponse::Ok().json(airport)) + } } #[post("/airports")] -async fn create(airport: web::Json) -> Result { - let airport = match Airports::create(airport.into_inner()) { - Ok(a) => a, +async fn create(airport: web::Json) -> HttpResponse { + match Airports::create(airport.into_inner()) { + Ok(a) => HttpResponse::Ok().json(a), Err(err) => { error!("{}", err); - return Err(err); + HttpResponse::InternalServerError().finish() } - }; - Ok(HttpResponse::Ok().json(airport)) + } } #[put("/airports/{id}")] -async fn update(id: web::Path, airport: web::Json) -> Result { - let airport = match Airports::update(id.into_inner(), airport.into_inner()) { - Ok(a) => a, +async fn update(id: web::Path, airport: web::Json) -> HttpResponse { + match Airports::update(id.into_inner(), airport.into_inner()) { + Ok(a) => HttpResponse::Ok().json(a), Err(err) => { error!("{}", err); - return Err(err); + HttpResponse::InternalServerError().finish() } - }; - Ok(HttpResponse::Ok().json(airport)) + } } #[delete("/airports/{id}")] -async fn delete(id: web::Path) -> Result { - let deleted_airport = match Airports::delete(id.into_inner()) { - Ok(a) => a, +async fn delete(id: web::Path) -> HttpResponse { + match Airports::delete(id.into_inner()) { + Ok(a) => HttpResponse::Ok().json(json!({ "deleted": a })), Err(err) => { error!("{}", err); - return Err(err); + HttpResponse::InternalServerError().finish() } - }; - Ok(HttpResponse::Ok().json(json!({ "deleted": deleted_airport }))) + } } pub fn init_routes(config: &mut web::ServiceConfig) { diff --git a/weather-service/src/main.rs b/weather-service/src/main.rs index f0b4b39..9b48c9f 100644 --- a/weather-service/src/main.rs +++ b/weather-service/src/main.rs @@ -6,6 +6,7 @@ extern crate diesel_migrations; use actix_cors::Cors; use actix_web::{App, HttpServer, middleware::Logger}; use dotenv::dotenv; +use env_logger::Env; use listenfd::ListenFd; use log::debug; use std::env; @@ -22,7 +23,7 @@ async fn main() -> std::io::Result<()> { if std::env::var_os("RUST_LOG").is_none() { std::env::set_var("RUST_LOG", "info,actix=info,diesel_migrations=warn,reqwest=warn,hyper=warn"); } - env_logger::init(); + env_logger::init_from_env(Env::default().default_filter_or("info")); db::init(); let mut listenfd = ListenFd::from_env(); diff --git a/weather-ui/.eslintrc.json b/weather-ui/.eslintrc.json index 6ff8413..88dd4f0 100755 --- a/weather-ui/.eslintrc.json +++ b/weather-ui/.eslintrc.json @@ -1,37 +1,17 @@ { - "root": true, - "parser": "@typescript-eslint/parser", - "plugins": [ - // "@typescript-eslint", - // "prettier" - ], - "extends": [ - // "prettier", - // "eslint:recommended", - // "next/core-web-vitals", - // "plugin:import/typescript", - // "plugin:prettier/recommended", - // "plugin:react/recommended", - // "plugin:@typescript-eslint/recommended", - // "plugin:@typescript-eslint/eslint-recommended", - // "plugin:@typescript-eslint/recommended-requiring-type-checking" - ], - "rules": { - "react-hooks/rules-of-hooks": "off", // error - "react-hooks/exhaustive-deps": "off", - "prettier/prettier": "off", - "@typescript-eslint/no-unused-vars": "off", // error - "@typescript-eslint/no-unsafe-argument": "off" - }, - "overrides": [ - { - "files": ["*.ts", "*.tsx"], - "extends": [ - "plugin:@typescript-eslint/recommended", - "plugin:@typescript-eslint/recommended-requiring-type-checking" - ], - "parserOptions": { - "project": ["./tsconfig.json"] - } - }] + "root": true, + "parser": "@typescript-eslint/parser", + "plugins": [ + "@typescript-eslint/eslint-plugin" + ], + "extends": [ + "plugin:@typescript-eslint/recommended", + "plugin:prettier/recommended" + ], + "rules": { + "@typescript-eslint/interface-name-prefix": "off", + "@typescript-eslint/explicit-function-return-type": "off", + "@typescript-eslint/explicit-module-boundary-types": "off", + "@typescript-eslint/no-explicit-any": "off" + } } \ No newline at end of file diff --git a/weather-ui/.prettierrc.json b/weather-ui/.prettierrc.json index 9dfaddd..56ccdc9 100644 --- a/weather-ui/.prettierrc.json +++ b/weather-ui/.prettierrc.json @@ -1,7 +1,8 @@ { - "trailingComma": "es5", - "tabWidth": 4, + "trailingComma": "none", + "tabWidth": 2, "semi": true, "singleQuote": true, - "printWidth": 100 + "jsxSingleQuote": true, + "printWidth": 120 } \ No newline at end of file diff --git a/weather-ui/next.config.js b/weather-ui/next.config.js index 9cc35f3..6682e67 100755 --- a/weather-ui/next.config.js +++ b/weather-ui/next.config.js @@ -5,6 +5,6 @@ const nextConfig = { eslint: { ignoreDuringBuilds: true } -} +}; -module.exports = nextConfig +module.exports = nextConfig; diff --git a/weather-ui/postcss.config.js b/weather-ui/postcss.config.js index 33ad091..5cbc2c7 100644 --- a/weather-ui/postcss.config.js +++ b/weather-ui/postcss.config.js @@ -1,6 +1,6 @@ module.exports = { plugins: { tailwindcss: {}, - autoprefixer: {}, - }, -} + autoprefixer: {} + } +}; diff --git a/weather-ui/src/app/page.tsx b/weather-ui/src/app/page.tsx index acda07d..7a1e510 100644 --- a/weather-ui/src/app/page.tsx +++ b/weather-ui/src/app/page.tsx @@ -4,7 +4,7 @@ import { Airport } from "@/js/airport"; import Metar from '@/components/Metar'; // setAirport('KJYO', new Airport('Leesburg Executive Airport', 'KJYO')) -setAirport('KHEF', new Airport('Manassas Regional Airpoirt', 'KHEF', 38.724, -77517)) +// setAirport('KHEF', new Airport('Manassas Regional Airpoirt', 'KHEF', 38.724, -77517)) // setAirport('KIAD', new Airport('Dulles International Airport', 'KIAD')) // setAirport('KFDK', new Airport('Frederick Municipal Airport', 'KFDK')) // setAirport('KMRB', new Airport('Eastern West Virginia Regional Airport', 'KMRB')) diff --git a/weather-ui/src/components/Metar.tsx b/weather-ui/src/components/Metar.tsx index a89e83f..2df3b43 100644 --- a/weather-ui/src/components/Metar.tsx +++ b/weather-ui/src/components/Metar.tsx @@ -1,101 +1,31 @@ -import { Airport } from "@/js/airport"; -import { getAirports, setAirport } from "@/js/state"; -import { Metar, getMetars } from "@/js/weather" -import Link from "next/link" -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faArrowsSpin, faLocationArrow } from '@fortawesome/free-solid-svg-icons' -import dynamic from "next/dynamic"; +import { Airport } from '@/js/api/airport.types'; +import { getAirports } from '@/js/api/airport'; +import { Metar } from '@/js/api/metar.types'; +import { getMetars } from '@/js/api/metar'; +import dynamic from 'next/dynamic'; export default async function Metar() { - const Map = dynamic(() => import("@/components/MetarMap"), { - loading: () =>
-

Loading...

-
, - ssr: false - }); - - async function update() { - const airports: Airport[] = getAirports(); - const metars = await getMetars(airports); - for (let i = 0; i < metars.length; i++) { - airports[i].metar = metars[i]; - airports[i].latitude = metars[i].latitude; - airports[i].longitude = metars[i].longitude; - setAirport(airports[i].icao, airports[i]); - } - return getAirports(); - } - await update(); - - return <> - - -} - -export function MetarGrid() { - const airports: Airport[] = getAirports(); - - return <> -
- {airports.map((airport) => ( - - ))} + const Map = dynamic(() => import('@/components/MetarMap'), { + loading: () => ( +
+
+

Loading...

- +
+ ), + ssr: false + }); + + let airports: Airport[] = []; + + async function update() { + airports = await getAirports(); + const metars = await getMetars(airports); + for (let i = 0; i < metars.length; i++) { + airports[i].metar = metars[i]; + } + } + await update(); + + return ; } - -function MetarCard({ airport}: { airport: Airport}) { - function metarBGColor(metar: Metar | undefined) { - if (metar?.flight_category == 'VFR') { - return 'bg-emerald-600' - } else if (metar?.flight_category == 'MVFR') { - return 'bg-blue-600' - } else if (metar?.flight_category == 'IFR') { - return 'bg-orange-600' - } else if (metar?.flight_category == 'LIFR') { - return 'bg-red-600' - } else { - return 'bg-black' - } - } - - function windColor(metar: Metar | undefined) { - if (Number(metar?.wind_speed_kt) <= 9) { - return 'bg-green-300'; - } else if (Number(metar?.wind_speed_kt) > 9) { - return 'bg-orange-300'; - } else if (Number(metar?.wind_speed_kt) > 12) { - return 'bg-red-300'; - } - } - - return ( -
-
- -
-
- ); -} \ No newline at end of file diff --git a/weather-ui/src/components/MetarMap.tsx b/weather-ui/src/components/MetarMap.tsx index e8f3121..cf260a8 100644 --- a/weather-ui/src/components/MetarMap.tsx +++ b/weather-ui/src/components/MetarMap.tsx @@ -1,20 +1,17 @@ 'use client'; -import { Airport } from '@/js/airport'; -import { Metar } from '@/js/weather'; +import { Airport } from '@/js/api/airport.types'; +import { Metar } from '@/js/api/metar.types'; import { faArrowsSpin, faLocationArrow, faLocationPin } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { DivIcon } from 'leaflet'; import Link from 'next/link'; -import { useEffect, useState } from 'react'; +import { useState } from 'react'; import ReactDOMServer from 'react-dom/server'; import { MapContainer, Marker, Popup, TileLayer, Tooltip, useMapEvents } from 'react-leaflet'; export default function Map({ airportString }: { airportString: string }) { const [airports, setAirports] = useState(JSON.parse(airportString)); - useEffect(() => { - }, []); - return ( - - + + ); } -function MapTiles({ airports }: {airports: Airport[] }) { +function MapTiles({ airports }: { airports: Airport[] }) { const [zoomLevel, setZoomLevel] = useState(8); // const [dragging, setDragging] = useState(false); // const [center, setCenter] = useState([50, 10.5]); const mapEvents = useMapEvents({ zoomend: () => { setZoomLevel(mapEvents.getZoom()); - }, + } // mouseup: () => { // setCenter([mapEvents.getCenter().lat, mapEvents.getCenter().lng]); // } @@ -46,45 +43,45 @@ function MapTiles({ airports }: {airports: Airport[] }) { function metarBGColor(metar: Metar | undefined) { if (metar?.flight_category == 'VFR') { - return 'bg-emerald-600' + return 'bg-emerald-600'; } else if (metar?.flight_category == 'MVFR') { - return 'bg-blue-600' + return 'bg-blue-600'; } else if (metar?.flight_category == 'IFR') { - return 'bg-orange-600' + return 'bg-orange-600'; } else if (metar?.flight_category == 'LIFR') { - return 'bg-red-600' + return 'bg-red-600'; } else { - return 'bg-black' + return 'bg-black'; } } function metarTextColor(metar: Metar | undefined) { if (metar?.flight_category == 'VFR') { - return 'text-emerald-700' + return 'text-emerald-700'; } else if (metar?.flight_category == 'MVFR') { - return 'text-blue-700' + return 'text-blue-700'; } else if (metar?.flight_category == 'IFR') { - return 'text-orange-700' + return 'text-orange-700'; } else if (metar?.flight_category == 'LIFR') { - return 'text-red-700' + return 'text-red-700'; } else { - return 'text-black' + return 'text-black'; } } function windColor(metar: Metar | undefined) { if (Number(metar?.wind_speed_kt) <= 9) { - return 'bg-green-300'; + return 'bg-green-300'; } else if (Number(metar?.wind_speed_kt) > 9) { - return 'bg-orange-300'; + return 'bg-orange-300'; } else if (Number(metar?.wind_speed_kt) > 12) { - return 'bg-red-300'; + return 'bg-red-300'; } } function iconSize() { if (zoomLevel <= 4) { - return 'text-xs' + return 'text-xs'; } else if (zoomLevel <= 5) { return 'text-sm'; } else if (zoomLevel <= 6) { @@ -102,45 +99,69 @@ function MapTiles({ airports }: {airports: Airport[] }) { function icon(airport: Airport) { return new DivIcon({ - html: ReactDOMServer.renderToString(), + html: ReactDOMServer.renderToString( + + ), className: 'metar-marker-icon' }); } - return <> - + {airports.map((airport) => ( <> - {airport.icao} + + {airport.icao} + -
+
-

{airport.icao} {airport.name}

+

+ {airport.icao} {airport.name} +

-
-

{airport.metar?.raw_text}

-
- {airport.metar?.flight_category? airport.metar?.flight_category : 'UNKN'} -
- - {airport.metar && airport.metar.wind_dir_degrees && Number(airport.metar.wind_dir_degrees) > 0? - : <> - } - {airport.metar && airport.metar.wind_dir_degrees && airport.metar.wind_dir_degrees == 'VRB'? - : <> - } - {airport.metar?.wind_speed_kt != undefined && airport.metar?.wind_speed_kt > 0? `${airport.metar?.wind_speed_kt} KT` : 'CALM'} - -
+
+

{airport.metar?.raw_text}

+
+ + {airport.metar?.flight_category ? airport.metar?.flight_category : 'UNKN'} + +
+ + {airport.metar && airport.metar.wind_dir_degrees && Number(airport.metar.wind_dir_degrees) > 0 ? ( + + ) : ( + <> + )} + {airport.metar && airport.metar.wind_dir_degrees && airport.metar.wind_dir_degrees == 'VRB' ? ( + + ) : ( + <> + )} + {airport.metar?.wind_speed_kt != undefined && airport.metar?.wind_speed_kt > 0 + ? `${airport.metar?.wind_speed_kt} KT` + : 'CALM'} +
+
- + ))} - ; -} \ No newline at end of file + + ); +} diff --git a/weather-ui/src/js/airport.ts b/weather-ui/src/js/airport.ts deleted file mode 100644 index 6860b2c..0000000 --- a/weather-ui/src/js/airport.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Metar } from "./weather"; - -export class Airport { - name: string; - icao: string; - latitude: number; - longitude: number; - metar: Metar | undefined; - - constructor(name: string, icao: string, latitude: number, longitude: number) { - this.name = name; - this.icao = icao; - this.latitude = latitude; - this.longitude = longitude; - this.metar = undefined; - } -} diff --git a/weather-ui/src/js/api/airport.ts b/weather-ui/src/js/api/airport.ts new file mode 100644 index 0000000..9c50639 --- /dev/null +++ b/weather-ui/src/js/api/airport.ts @@ -0,0 +1,7 @@ +import axios from 'axios'; +import { Airport } from './airport.types'; + +export async function getAirports(): Promise { + const response = await axios.get(`http://localhost:5000/airports`).catch((error) => console.error(error)); + return response?.data; +} diff --git a/weather-ui/src/js/api/airport.types.ts b/weather-ui/src/js/api/airport.types.ts new file mode 100644 index 0000000..822b08e --- /dev/null +++ b/weather-ui/src/js/api/airport.types.ts @@ -0,0 +1,9 @@ +import { Metar } from './metar.types'; + +export interface Airport { + name: string; + icao: string; + latitude: number; + longitude: number; + metar?: Metar; +} diff --git a/weather-ui/src/js/api/metar.ts b/weather-ui/src/js/api/metar.ts new file mode 100644 index 0000000..d80ae19 --- /dev/null +++ b/weather-ui/src/js/api/metar.ts @@ -0,0 +1,10 @@ +import axios from 'axios'; +import { Airport } from './airport.types'; +import { Metar } from './metar.types'; + +export async function getMetars(airports: Airport[]): Promise { + const stationICAOs: string = airports.map((airport) => airport.icao).join(','); + const url = `http://localhost:5000/metars/${stationICAOs}`; + const response = await axios.get(url).catch((error) => console.error(error)); + return response?.data; +} diff --git a/weather-ui/src/js/api/metar.types.ts b/weather-ui/src/js/api/metar.types.ts new file mode 100644 index 0000000..0a87cec --- /dev/null +++ b/weather-ui/src/js/api/metar.types.ts @@ -0,0 +1,30 @@ +export interface Metar { + raw_text: string; + station_id: string; + observation_time: string; + latitude: number; + longitude: number; + temp_c: number; + dewpoint_c: number; + wind_dir_degrees: string; + wind_speed_kt: number; + visibility_statute_mi: string; + altim_in_hg: number; + sea_level_pressure_mb: number; + quality_control_flags: { + auto: boolean; + auto_station: boolean; + }; + wx_string: string; + sky_condition: { + sky_cover: string; + cloud_base_ft_agl: number; + }[]; + flight_category: string; + three_hr_pressure_tendency_mb: number; + metar_type: string; + maxT_c: number; + minT_c: number; + precip_in: number; + elevation_m: number; +} diff --git a/weather-ui/src/js/state.ts b/weather-ui/src/js/state.ts deleted file mode 100644 index a604f0b..0000000 --- a/weather-ui/src/js/state.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Airport } from "./airport"; - -const airports: Map = new Map(); - -export function setAirport(icao: string, airport: Airport) { - airports.set(icao, airport); -} - -export function getAirport(icao: string): Airport | undefined { - return airports.get(icao); -} - -export function getAirports(): Airport[] { - return [...airports.values()]; -} \ No newline at end of file diff --git a/weather-ui/src/js/weather.ts b/weather-ui/src/js/weather.ts deleted file mode 100644 index 954eafd..0000000 --- a/weather-ui/src/js/weather.ts +++ /dev/null @@ -1,116 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unsafe-argument */ -/* eslint-disable @typescript-eslint/no-unsafe-assignment */ -/* eslint-disable @typescript-eslint/no-unsafe-member-access */ -import axios from 'axios'; -// import { xml2json } from 'xml-js'; -import { Airport } from './airport'; - -// const base_url = 'https://beta.aviationweather.gov/cgi-bin/data'; - -export async function getMetars(airports: Airport[]): Promise { - const stationICAOs: string = airports - .map((airport) => airport.icao) - .join(','); - const url = `http://localhost:5000/metars/KHEF`; - const response = await axios.get(url).catch((error) => console.error(error)); - console.log(response); - return []; -} - -// export async function getMetars(airports: Airport[]): Promise { -// const stationICAOs: string = airports -// .map((airport) => airport.icao) -// .join(','); -// const url = `${base_url}/metar.php?ids=${stationICAOs}&format=xml`; -// const response = await axios -// .get(`${url}`) -// .catch((error) => console.error(`${error}`)); -// const metars: Metar[] = []; -// if (response != null && response != undefined) { -// const json = xml2json(response.data, { compact: true }); -// const jsonObject = JSON.parse(json); -// let metarData = jsonObject?.response?.data?.METAR; -// if (!Array.isArray(metarData)) { -// metarData = [metarData]; -// } -// for (const data of metarData) { -// const sky_condition: { -// sky_cover: string; -// cloud_base_ft_agl: number; -// }[] = []; -// if (Array.isArray(data.sky_condition)) { -// for (const sc of data.sky_condition) { -// sky_condition.push({ -// sky_cover: sc.sky_cover, -// cloud_base_ft_agl: Number(sc.cloud_base_ft_agl) -// }) -// } -// } else { -// sky_condition.push({ -// sky_cover: data.sky_condition?.sky_cover, -// cloud_base_ft_agl: Number(data.sky_condition?.cloud_base_ft_agl) -// }) -// } -// const metar: Metar = { -// raw_text: data.raw_text._text, -// station_id: data.station_id._text, -// observation_time: data.observation_time._text, -// latitude: Number(data.latitude._text), -// longitude: Number(data.longitude._text), -// temp_c: Number(data.temp_c._text), -// dewpoint_c: Number(data.dewpoint_c._text), -// wind_dir_degrees: data.wind_dir_degrees._text, -// wind_speed_kt: Number(data.wind_speed_kt._text), -// visibility_statute_mi: data.visibility_statute_mi?._text, -// altim_in_hg: Number(data.altim_in_hg?._text), -// sea_level_pressure_mb: data.sea_level_pressure_mb?._text, -// quality_control_flags: { -// auto: data.quality_control_flags?.auto?._text == 'TRUE', -// auto_station: data.quality_control_flags?.auto_station?._text == 'TRUE', -// }, -// wx_string: data.wx_string?._text, -// sky_condition: sky_condition, -// flight_category: data.flight_category._text, -// three_hr_pressure_tendency_mb: data.three_hr_pressure_tendency_mb?._text, -// metar_type: data.metar_type._text, -// maxT_c: Number(data.maxT_c?._text), -// minT_c: Number(data.minT_c?._text), -// precip_in: Number(data.precip_in?._text), -// elevation_m: Number(data.elevation_m._text), -// }; -// metars.push(metar); -// } -// } -// return metars; -// } - -export interface Metar { - raw_text: string; - station_id: string; - observation_time: string; - latitude: number; - longitude: number; - temp_c: number; - dewpoint_c: number; - wind_dir_degrees: string; - wind_speed_kt: number; - visibility_statute_mi: string; - altim_in_hg: number; - sea_level_pressure_mb: number; - quality_control_flags: { - auto: boolean; - auto_station: boolean; - }; - wx_string: string; - sky_condition: { - sky_cover: string; - cloud_base_ft_agl: number; - }[]; - flight_category: string; - three_hr_pressure_tendency_mb: number; - metar_type: string; - maxT_c: number; - minT_c: number; - precip_in: number; - elevation_m: number; -} diff --git a/weather-ui/tailwind.config.js b/weather-ui/tailwind.config.js index 00f5ada..64070ab 100644 --- a/weather-ui/tailwind.config.js +++ b/weather-ui/tailwind.config.js @@ -1,11 +1,8 @@ /** @type {import('tailwindcss').Config} */ module.exports = { - content: [ - "./src/**/*.{js,ts,jsx,tsx,mdx}", - ], + content: ['./src/**/*.{js,ts,jsx,tsx,mdx}'], theme: { - extend: {}, + extend: {} }, - plugins: [], -} - + plugins: [] +}; diff --git a/weather-ui/tsconfig.json b/weather-ui/tsconfig.json index 27f266e..b4ff779 100755 --- a/weather-ui/tsconfig.json +++ b/weather-ui/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "ES2015", + "target": "ESNext", "downlevelIteration": true, "lib": [ "dom",