From 02a4d840e05970bb93a5a7f7f5e1813d8e08c128 Mon Sep 17 00:00:00 2001 From: Ben Sherriff Date: Fri, 22 Sep 2023 16:44:30 -0400 Subject: [PATCH] Migrate front end to Mantine --- weather-service/Makefile | 13 +++-- weather-service/docker-compose.yml | 23 ++++++-- weather-service/src/main.rs | 4 +- weather-ui/.prettierrc.json | 12 ++--- weather-ui/package.json | 9 ++-- weather-ui/postcss.config.js | 3 +- weather-ui/src/app/airport/[icao]/page.tsx | 4 +- weather-ui/src/app/layout.tsx | 22 ++++---- weather-ui/src/app/user/page.tsx | 3 -- weather-ui/src/components/Metars/MapTiles.tsx | 4 +- .../{MetarDialog.tsx => MetarModal.tsx} | 30 +++++------ weather-ui/src/components/Sidebar/index.tsx | 2 + weather-ui/src/components/Topbar/index.tsx | 52 +++++++++---------- weather-ui/src/js/theme.ts | 5 ++ weather-ui/src/lib/AntdRegistry.tsx | 14 ----- weather-ui/styles/globals.css | 4 -- weather-ui/tailwind.config.js | 11 ---- 17 files changed, 102 insertions(+), 113 deletions(-) delete mode 100644 weather-ui/src/app/user/page.tsx rename weather-ui/src/components/Metars/{MetarDialog.tsx => MetarModal.tsx} (91%) create mode 100644 weather-ui/src/js/theme.ts delete mode 100644 weather-ui/src/lib/AntdRegistry.tsx delete mode 100644 weather-ui/tailwind.config.js diff --git a/weather-service/Makefile b/weather-service/Makefile index d6c6e35..22a9c81 100644 --- a/weather-service/Makefile +++ b/weather-service/Makefile @@ -11,22 +11,25 @@ help: ## This info @cat Makefile | grep -E '^[a-zA-Z\/_-]+:.*?## .*$$' | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' @echo -up: +build: ## Build Docker service container + docker compose build + +up: ## Start Docker service containers docker compose up -d -down: +down: ## Stop Docker service containers docker compose down -connect: +connect: ## Connect to the Weather DB docker exec -it aviation_weather_db psql -U postgres lint: ## Run the linter npm run lint -clean: +clean: ## Clean up the service rm -rf target -clean-db: ## Remove database and Cargo packages +clean-db: ## Remove database docker exec -i ${DATABASE_CONTAINER} sh -c 'PGPASSWORD=${DATABASE_PASSWORD} psql -U ${DATABASE_USER} -d postgres -c "DROP DATABASE IF EXISTS \"${DATABASE_NAME}\";"' docker exec -i ${DATABASE_CONTAINER} sh -c 'PGPASSWORD=${DATABASE_PASSWORD} psql -U ${DATABASE_USER} -d postgres -c "CREATE DATABASE \"${DATABASE_NAME}\";"' || true diff --git a/weather-service/docker-compose.yml b/weather-service/docker-compose.yml index 15aa6c1..fb49d06 100644 --- a/weather-service/docker-compose.yml +++ b/weather-service/docker-compose.yml @@ -1,9 +1,10 @@ version: '3' +name: weather services: - weather-db: + db: image: postgis/postgis:latest - container_name: weather.db + container_name: weather-db env_file: - .env environment: @@ -17,6 +18,22 @@ services: - "${DATABASE_PORT}:5432" restart: unless-stopped + service: + container_name: weather-service + env_file: + - .env + ports: + - "${SERVICE_PORT}:${SERVICE_PORT}" + build: + context: ./ + depends_on: + - db + restart: unless-stopped + volumes: db: - db_logs: \ No newline at end of file + db_logs: + +networks: + default: + name: weather-backend \ No newline at end of file diff --git a/weather-service/src/main.rs b/weather-service/src/main.rs index 58ef191..88153c9 100644 --- a/weather-service/src/main.rs +++ b/weather-service/src/main.rs @@ -44,8 +44,8 @@ async fn main() -> std::io::Result<()> { server = match listenfd.take_tcp_listener(0)? { Some(listener) => server.listen(listener)?, None => { - let host = std::env::var("HOST").expect("Please set host in .env"); - let port = std::env::var("PORT").expect("Please set port in .env"); + let host = std::env::var("SERVICE_HOST").expect("Please set host in .env"); + let port = std::env::var("SERVICE_PORT").expect("Please set port in .env"); debug!("Binding server to {}:{}", host, port); server.bind(format!("{}:{}", host, port))? } diff --git a/weather-ui/.prettierrc.json b/weather-ui/.prettierrc.json index 56ccdc9..2396656 100644 --- a/weather-ui/.prettierrc.json +++ b/weather-ui/.prettierrc.json @@ -1,8 +1,8 @@ { - "trailingComma": "none", - "tabWidth": 2, - "semi": true, - "singleQuote": true, - "jsxSingleQuote": true, - "printWidth": 120 + "trailingComma": "none", + "tabWidth": 2, + "semi": true, + "singleQuote": true, + "jsxSingleQuote": true, + "printWidth": 120 } \ No newline at end of file diff --git a/weather-ui/package.json b/weather-ui/package.json index 1d7c666..3635b9f 100644 --- a/weather-ui/package.json +++ b/weather-ui/package.json @@ -9,9 +9,9 @@ "lint": "next lint" }, "dependencies": { - "@ant-design/cssinjs": "^1.17.0", - "@blueprintjs/core": "^5.3.0", - "antd": "^5.9.0", + "@mantine/core": "^7.0.0", + "@mantine/hooks": "^7.0.0", + "@mantine/modals": "^7.0.0", "axios": "^1.4.0", "leaflet": "^1.9.4", "next": "^13.4.19", @@ -34,8 +34,9 @@ "eslint-config-prettier": "^9.0.0", "eslint-plugin-prettier": "^5.0.0", "postcss": "^8.4.28", + "postcss-import": "^15.1.0", + "postcss-preset-mantine": "^1.7.0", "prettier": "^3.0.0", - "tailwindcss": "^3.3.3", "typescript": "5.1.6" } } diff --git a/weather-ui/postcss.config.js b/weather-ui/postcss.config.js index b063a5f..7a4f139 100644 --- a/weather-ui/postcss.config.js +++ b/weather-ui/postcss.config.js @@ -1,8 +1,7 @@ module.exports = { plugins: { + 'postcss-preset-mantine': {}, 'postcss-import': {}, - 'tailwindcss/nesting': {}, - tailwindcss: {}, autoprefixer: {} } }; diff --git a/weather-ui/src/app/airport/[icao]/page.tsx b/weather-ui/src/app/airport/[icao]/page.tsx index 20a440f..6aad27f 100644 --- a/weather-ui/src/app/airport/[icao]/page.tsx +++ b/weather-ui/src/app/airport/[icao]/page.tsx @@ -5,8 +5,8 @@ export default async function Page({ params }: { params: { icao: string } }) { const { data: airport } = await getAirport({ icao: params.icao }); return ( <> -
-

{airport.full_name}

+
+

{airport.full_name}

Back
diff --git a/weather-ui/src/app/layout.tsx b/weather-ui/src/app/layout.tsx index 7b416f9..214c16a 100644 --- a/weather-ui/src/app/layout.tsx +++ b/weather-ui/src/app/layout.tsx @@ -2,18 +2,20 @@ import React from 'react'; import RecoilRootWrapper from '@app/recoil-root-wrapper'; import Sidebar from '@/components/Sidebar'; import Topbar from '@/components/Topbar'; +import { Inter } from 'next/font/google'; +import { MantineProvider } from '@mantine/core'; +import { ModalsProvider } from '@mantine/modals'; import 'styles/globals.css'; import 'styles/leaflet.css'; -import StyledComponentsRegistry from '@/lib/AntdRegistry'; -import { Inter } from 'next/font/google'; - -const inter = Inter({ subsets: ['latin'] }); +import '@mantine/core/styles.css'; export const metadata = { title: 'Aviation Weather', description: '' }; +const inter = Inter({ subsets: ['latin'] }); + export default function RootLayout({ children }: { children: React.ReactNode }) { return ( @@ -22,11 +24,13 @@ export default function RootLayout({ children }: { children: React.ReactNode }) - - - - {children} - + + + + + {children} + + diff --git a/weather-ui/src/app/user/page.tsx b/weather-ui/src/app/user/page.tsx deleted file mode 100644 index 2deac63..0000000 --- a/weather-ui/src/app/user/page.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export default function Profile() { - return <>; -} diff --git a/weather-ui/src/components/Metars/MapTiles.tsx b/weather-ui/src/components/Metars/MapTiles.tsx index 7aa51cd..136da94 100644 --- a/weather-ui/src/components/Metars/MapTiles.tsx +++ b/weather-ui/src/components/Metars/MapTiles.tsx @@ -7,7 +7,7 @@ import { DivIcon, LatLngBounds } from 'leaflet'; import { useEffect, useState } from 'react'; import ReactDOMServer from 'react-dom/server'; import { Marker, TileLayer, Tooltip, useMap, useMapEvents } from 'react-leaflet'; -import MetarDialog from './MetarDialog'; +import MetarModal from './MetarModal'; import { BsCircle, BsCircleFill } from 'react-icons/bs'; export default function MapTiles() { @@ -133,7 +133,7 @@ export default function MapTiles() { return ( <> - {selectedAirport && setIsOpen(false)} airport={selectedAirport} />} + {selectedAirport && setIsOpen(false)} airport={selectedAirport} />} } - open={isOpen} - onCancel={onClose} - closable={false} - footer={[]} + opened={isOpen} + onClose={onClose} className='select-none' >
@@ -131,8 +129,8 @@ function MetarInfo({ metar }: { metar: Metar }) { return (

{metar.raw_text}

- - + + {metar.flight_category ? metar.flight_category : 'UNKN'} - - + + {metar.wx_string && metar.wx_string.split(' ').map((wx) => )} - - - Compass TBD Compass TBD Compass TBD Compass TBD Compass TB - - - + +
); } @@ -215,7 +209,7 @@ function MetarIcon({ wx }: { wx: string }) { // color = ''; // } return ( - + {icon} ); diff --git a/weather-ui/src/components/Sidebar/index.tsx b/weather-ui/src/components/Sidebar/index.tsx index fe98409..f57c603 100644 --- a/weather-ui/src/components/Sidebar/index.tsx +++ b/weather-ui/src/components/Sidebar/index.tsx @@ -1,3 +1,5 @@ +'use client'; + import './Sidebar.css'; export default function Sidebar() { diff --git a/weather-ui/src/components/Topbar/index.tsx b/weather-ui/src/components/Topbar/index.tsx index ba418c2..17df695 100644 --- a/weather-ui/src/components/Topbar/index.tsx +++ b/weather-ui/src/components/Topbar/index.tsx @@ -1,20 +1,18 @@ 'use client'; -import { AutoComplete, Avatar } from 'antd'; import Link from 'next/link'; import { AiOutlineUser } from 'react-icons/ai'; import { useState } from 'react'; import { getAirports } from '@/api/airport'; import { useRouter } from 'next/navigation'; - -const DEFAULT_ICON_SIZE = 40; +import { Autocomplete, Avatar } from '@mantine/core'; export default function Topbar() { const [searchValue, setSearchValue] = useState(''); const [airports, setAirports] = useState<{ key: string; value: string; label: string }[]>([]); const router = useRouter(); - async function onSearch(value: string) { + async function onChange(value: string) { setSearchValue(value); const airportData = await getAirports({ filter: value }); setAirports( @@ -26,34 +24,32 @@ export default function Topbar() { ); } - function onSelect(value: string) { - setSearchValue(''); + function onClick(value: string) { router.push(`/airport/${value}`); } return ( - <> -
+ + + + + + ); } diff --git a/weather-ui/src/js/theme.ts b/weather-ui/src/js/theme.ts new file mode 100644 index 0000000..cdc2cb2 --- /dev/null +++ b/weather-ui/src/js/theme.ts @@ -0,0 +1,5 @@ +'use client'; + +import { createTheme } from '@mantine/core'; + +export const theme = createTheme({}); diff --git a/weather-ui/src/lib/AntdRegistry.tsx b/weather-ui/src/lib/AntdRegistry.tsx deleted file mode 100644 index 289a635..0000000 --- a/weather-ui/src/lib/AntdRegistry.tsx +++ /dev/null @@ -1,14 +0,0 @@ -'use client'; - -import React from 'react'; -import { createCache, extractStyle, StyleProvider } from '@ant-design/cssinjs'; -import type Entity from '@ant-design/cssinjs/es/Cache'; -import { useServerInsertedHTML } from 'next/navigation'; - -const StyledComponentsRegistry = ({ children }: { children: React.ReactNode }) => { - const cache = React.useMemo(() => createCache(), [createCache]); - useServerInsertedHTML(() =>