From bea8fc68950b3442904c6a8298c877d031533e43 Mon Sep 17 00:00:00 2001 From: Ben Sherriff Date: Sat, 26 Aug 2023 14:17:37 -0400 Subject: [PATCH] metar grid changes --- package-lock.json | 110 +++++++++++++++++++++++++++++--- package.json | 4 ++ src/app/airport/[icao]/page.tsx | 4 +- src/app/layout.tsx | 5 ++ src/app/page.tsx | 36 +++++------ src/atoms/index.ts | 7 ++ src/components/MetarCard.tsx | 46 ------------- src/components/MetarGrid.tsx | 73 +++++++++++++++++++++ src/js/state.ts | 18 ++++-- src/js/weather.ts | 4 +- 10 files changed, 224 insertions(+), 83 deletions(-) create mode 100644 src/atoms/index.ts delete mode 100644 src/components/MetarCard.tsx create mode 100644 src/components/MetarGrid.tsx diff --git a/package-lock.json b/package-lock.json index 2aa5ceb..a5ce05f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,10 @@ "name": "pcs-ui", "version": "0.1.0", "dependencies": { + "@fortawesome/fontawesome-svg-core": "^6.4.2", + "@fortawesome/free-regular-svg-icons": "^6.4.2", + "@fortawesome/free-solid-svg-icons": "^6.4.2", + "@fortawesome/react-fontawesome": "^0.2.0", "axios": "^1.4.0", "next": "13.4.12", "react": "18.2.0", @@ -121,6 +125,63 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@fortawesome/fontawesome-common-types": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.4.2.tgz", + "integrity": "sha512-1DgP7f+XQIJbLFCTX1V2QnxVmpLdKdzzo2k8EmvDOePfchaIGQ9eCHj2up3/jNEbZuBqel5OxiaOJf37TWauRA==", + "hasInstallScript": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/fontawesome-svg-core": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.4.2.tgz", + "integrity": "sha512-gjYDSKv3TrM2sLTOKBc5rH9ckje8Wrwgx1CxAPbN5N3Fm4prfi7NsJVWd1jklp7i5uSCVwhZS5qlhMXqLrpAIg==", + "hasInstallScript": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.4.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/free-regular-svg-icons": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.4.2.tgz", + "integrity": "sha512-0+sIUWnkgTVVXVAPQmW4vxb9ZTHv0WstOa3rBx9iPxrrrDH6bNLsDYuwXF9b6fGm+iR7DKQvQshUH/FJm3ed9Q==", + "hasInstallScript": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.4.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/free-solid-svg-icons": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.4.2.tgz", + "integrity": "sha512-sYwXurXUEQS32fZz9hVCUUv/xu49PEJEyUOsA51l6PU/qVgfbTb2glsTEaJngVVT8VqBATRIdh7XVgV1JF1LkA==", + "hasInstallScript": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.4.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/react-fontawesome": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.0.tgz", + "integrity": "sha512-uHg75Rb/XORTtVt7OS9WoK8uM276Ufi7gCzshVWkUJbHhh3svsUUeqXerrM96Wm7fRiDzfKRwSoahhMIkGAYHw==", + "dependencies": { + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "@fortawesome/fontawesome-svg-core": "~1 || ~6", + "react": ">=16.3" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", @@ -3447,7 +3508,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -3907,7 +3967,6 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -3974,8 +4033,7 @@ "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "node_modules/read-cache": { "version": "1.0.0", @@ -5065,6 +5123,43 @@ "integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==", "dev": true }, + "@fortawesome/fontawesome-common-types": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.4.2.tgz", + "integrity": "sha512-1DgP7f+XQIJbLFCTX1V2QnxVmpLdKdzzo2k8EmvDOePfchaIGQ9eCHj2up3/jNEbZuBqel5OxiaOJf37TWauRA==" + }, + "@fortawesome/fontawesome-svg-core": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.4.2.tgz", + "integrity": "sha512-gjYDSKv3TrM2sLTOKBc5rH9ckje8Wrwgx1CxAPbN5N3Fm4prfi7NsJVWd1jklp7i5uSCVwhZS5qlhMXqLrpAIg==", + "requires": { + "@fortawesome/fontawesome-common-types": "6.4.2" + } + }, + "@fortawesome/free-regular-svg-icons": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.4.2.tgz", + "integrity": "sha512-0+sIUWnkgTVVXVAPQmW4vxb9ZTHv0WstOa3rBx9iPxrrrDH6bNLsDYuwXF9b6fGm+iR7DKQvQshUH/FJm3ed9Q==", + "requires": { + "@fortawesome/fontawesome-common-types": "6.4.2" + } + }, + "@fortawesome/free-solid-svg-icons": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.4.2.tgz", + "integrity": "sha512-sYwXurXUEQS32fZz9hVCUUv/xu49PEJEyUOsA51l6PU/qVgfbTb2glsTEaJngVVT8VqBATRIdh7XVgV1JF1LkA==", + "requires": { + "@fortawesome/fontawesome-common-types": "6.4.2" + } + }, + "@fortawesome/react-fontawesome": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.0.tgz", + "integrity": "sha512-uHg75Rb/XORTtVt7OS9WoK8uM276Ufi7gCzshVWkUJbHhh3svsUUeqXerrM96Wm7fRiDzfKRwSoahhMIkGAYHw==", + "requires": { + "prop-types": "^15.8.1" + } + }, "@humanwhocodes/config-array": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", @@ -7351,8 +7446,7 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" }, "object-hash": { "version": "3.0.0", @@ -7642,7 +7736,6 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, "requires": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -7686,8 +7779,7 @@ "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "read-cache": { "version": "1.0.0", diff --git a/package.json b/package.json index ee0cb12..dfd2a45 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,10 @@ "lint": "next lint" }, "dependencies": { + "@fortawesome/fontawesome-svg-core": "^6.4.2", + "@fortawesome/free-regular-svg-icons": "^6.4.2", + "@fortawesome/free-solid-svg-icons": "^6.4.2", + "@fortawesome/react-fontawesome": "^0.2.0", "axios": "^1.4.0", "next": "13.4.12", "react": "18.2.0", diff --git a/src/app/airport/[icao]/page.tsx b/src/app/airport/[icao]/page.tsx index fb263b6..8cc02bb 100644 --- a/src/app/airport/[icao]/page.tsx +++ b/src/app/airport/[icao]/page.tsx @@ -1,9 +1,9 @@ -import { airports } from "@/js/state"; +import { getAirport } from "@/js/state"; import Link from "next/link"; export default function Page({ params }: { params: { icao: string } }) { - const airport = airports.get(params.icao); + const airport = getAirport(params.icao); return <>

{airport?.name}

diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 0b50073..af153a2 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,6 +1,11 @@ import React from 'react'; import RecoilRootWrapper from '@app/recoil-root-wrapper'; + +import '@fortawesome/fontawesome-svg-core/styles.css'; +// Prevent fontawesome from adding its CSS since we did it manually above: +import { config } from '@fortawesome/fontawesome-svg-core'; +config.autoAddCss = false; /* eslint-disable import/first */ import 'styles/globals.css'; export default function RootLayout({ children }: { children: React.ReactNode }) { diff --git a/src/app/page.tsx b/src/app/page.tsx index 55df61a..23cc836 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,30 +1,30 @@ import React from 'react'; -import { airports } from "@/js/state"; +import { setAirport } from "@/js/state"; import { Airport } from "@/js/airport"; -import MetarCard from '@/components/MetarCard'; +import MetarGrid from '@/components/MetarGrid'; -airports.set('KJYO', new Airport('Leesburg Executive Airport', 'KJYO')) -airports.set('KHEF', new Airport('Manassas Regional Airpoirt', 'KHEF')) -airports.set('KIAD', new Airport('Dulles International Airport', 'KIAD')) -airports.set('KFDK', new Airport('Frederick Municipal Airport', 'KFDK')) -airports.set('KMRB', new Airport('Eastern West Virginia Regional Airport', 'KMRB')) -airports.set('KOKV', new Airport('Winchester Regional Airport', 'KOKV')) -airports.set('KFRR', new Airport('Front Royal-Warren County Airport', 'KFRR')) -airports.set('KLUA', new Airport('Luray Caverns Airport', 'KLUA')) -airports.set('KSHD', new Airport('Shenandoah Valley Airport', 'KSHD')) -airports.set('KCHO', new Airport('Charlottesville-Albemarle Airport', 'KCHO')) -airports.set('KCJR', new Airport('Culpeper Regional Airport', 'KCJR')) -airports.set('KHWY', new Airport('Warrenton-Fauquier Airport', 'KHWY')) -airports.set('KRMN', new Airport('Stafford Regional Airport', 'KRMN')) -airports.set('KEZF', new Airport('Shannon Airport', 'KEZF')) +setAirport('KJYO', new Airport('Leesburg Executive Airport', 'KJYO')) +setAirport('KHEF', new Airport('Manassas Regional Airpoirt', 'KHEF')) +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')) +setAirport('KOKV', new Airport('Winchester Regional Airport', 'KOKV')) +setAirport('KFRR', new Airport('Front Royal-Warren County Airport', 'KFRR')) +setAirport('KLUA', new Airport('Luray Caverns Airport', 'KLUA')) +setAirport('KSHD', new Airport('Shenandoah Valley Airport', 'KSHD')) +setAirport('KCHO', new Airport('Charlottesville-Albemarle Airport', 'KCHO')) +setAirport('KCJR', new Airport('Culpeper Regional Airport', 'KCJR')) +setAirport('KHWY', new Airport('Warrenton-Fauquier Airport', 'KHWY')) +setAirport('KRMN', new Airport('Stafford Regional Airport', 'KRMN')) +setAirport('KEZF', new Airport('Shannon Airport', 'KEZF')) export default function Page() { return <>
-

Airports

+

Airports

- +
} diff --git a/src/atoms/index.ts b/src/atoms/index.ts new file mode 100644 index 0000000..46169d3 --- /dev/null +++ b/src/atoms/index.ts @@ -0,0 +1,7 @@ +export const airportsState = atom({ + key: 'airportsState', + default: [] as Airport[] +}); + +import { Airport } from "@/js/airport"; +import { atom } from "recoil"; \ No newline at end of file diff --git a/src/components/MetarCard.tsx b/src/components/MetarCard.tsx deleted file mode 100644 index 51ff963..0000000 --- a/src/components/MetarCard.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import { Airport } from "@/js/airport"; -import { Metar, getMetars } from "@/js/weather" -import Link from "next/link" - -export default async function MetarCard({airports}: {airports: Airport[]}) { - const metars = await getMetars(airports); - for (let i = 0; i < airports.length; i++) { - airports[i].metar = metars[i]; - } - - 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-red-600' - } else if (metar?.flight_category == 'LIFR') { - return 'bg-purple-600' - } else { - return 'bg-black' - } - } - - return ( -
- {airports.map((airport) => ( -
-
- -
-
- ))} -
- ) - } \ No newline at end of file diff --git a/src/components/MetarGrid.tsx b/src/components/MetarGrid.tsx new file mode 100644 index 0000000..faf87a9 --- /dev/null +++ b/src/components/MetarGrid.tsx @@ -0,0 +1,73 @@ +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 { faLocationArrow } from '@fortawesome/free-solid-svg-icons' + +export default async function MetarGrid() { + const airports: Airport[] = getAirports(); + + async function update() { + const airports: Airport[] = getAirports(); + const metars = await getMetars(airports); + for (let i = 0; i < airports.length; i++) { + airports[i].metar = metars[i]; + setAirport(airports[i].icao, airports[i]); + } + // setTimeout(update, 30 * 60 * 1000); + // setTimeout(update, 5000); + } + await update(); + + + return ( +
+ {airports.map((airport) => ( + + ))} +
+ ); +} + +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' + } + } + + return ( +
+
+ +
+
+ ); +} \ No newline at end of file diff --git a/src/js/state.ts b/src/js/state.ts index 8de603d..a604f0b 100644 --- a/src/js/state.ts +++ b/src/js/state.ts @@ -1,9 +1,15 @@ -// import { atom } from "recoil"; import { Airport } from "./airport"; -// export const airportsState = atom({ -// key: 'airportsState', -// default: [] as Airport[] -// }); +const airports: Map = new Map(); -export const airports: Map = new Map(); \ No newline at end of file +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/src/js/weather.ts b/src/js/weather.ts index a27c8a4..78b0fcc 100644 --- a/src/js/weather.ts +++ b/src/js/weather.ts @@ -52,8 +52,8 @@ export async function getMetars(airports: Airport[]): Promise { dewpoint_c: Number(data.dewpoint_c._text), wind_dir_degrees: Number(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), + 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',