From aa5ac7f41220bd46003dcf3ebafe606fe5bb369e Mon Sep 17 00:00:00 2001 From: Annwan Date: Wed, 17 Sep 2025 12:15:13 +0200 Subject: [PATCH] Added UI for log --- README.md | 2 - bun.lock | 22 +++++++ package.json | 4 +- src/App.tsx | 134 ++++++++++++++++++++++++++++++----------- src/index.tsx | 19 +++--- static/legend/city.svg | 9 ++- 6 files changed, 135 insertions(+), 55 deletions(-) diff --git a/README.md b/README.md index ab800a7..54968e8 100644 --- a/README.md +++ b/README.md @@ -22,5 +22,3 @@ bun devscripts/optimise_assets.ts threadcount bun build bun start ``` - -This project was created using `bun init` in bun v1.2.21. [Bun](https://bun.com) is a fast all-in-one JavaScript runtime. diff --git a/bun.lock b/bun.lock index ee0162f..b3c49a6 100644 --- a/bun.lock +++ b/bun.lock @@ -6,10 +6,12 @@ "dependencies": { "@types/leaflet": "^1.9.20", "@types/react-leaflet": "^3.0.0", + "@types/react-modal": "^3.16.3", "leaflet": "^1.9.4", "react": "^19", "react-dom": "^19", "react-leaflet": "^5.0.0", + "react-modal": "^3.16.3", }, "devDependencies": { "@types/bun": "latest", @@ -35,20 +37,40 @@ "@types/react-leaflet": ["@types/react-leaflet@3.0.0", "", { "dependencies": { "react-leaflet": "*" } }, "sha512-p8R9mVKbCDDqOdW+M6GyJJuFn6q+IgDFYavFiOIvaWHuOe5kIHZEtCy1pfM43JIA6JiB3D/aDoby7C51eO+XSg=="], + "@types/react-modal": ["@types/react-modal@3.16.3", "", { "dependencies": { "@types/react": "*" } }, "sha512-xXuGavyEGaFQDgBv4UVm8/ZsG+qxeQ7f77yNrW3n+1J6XAstUy5rYHeIHPh1KzsGc6IkCIdu6lQ2xWzu1jBTLg=="], + "bun-types": ["bun-types@1.2.21", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-sa2Tj77Ijc/NTLS0/Odjq/qngmEPZfbfnOERi0KRUYhT9R8M4VBioWVmMWE5GrYbKMc+5lVybXygLdibHaqVqw=="], "csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="], + "exenv": ["exenv@1.2.2", "", {}, "sha512-Z+ktTxTwv9ILfgKCk32OX3n/doe+OcLTRtqK9pcL+JsP3J1/VW8Uvl4ZjLlKqeW4rzK4oesDOGMEMRIZqtP4Iw=="], + + "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], + "leaflet": ["leaflet@1.9.4", "", {}, "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA=="], + "loose-envify": ["loose-envify@1.4.0", "", { "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, "bin": { "loose-envify": "cli.js" } }, "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q=="], + + "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], + + "prop-types": ["prop-types@15.8.1", "", { "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" } }, "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg=="], + "react": ["react@19.1.1", "", {}, "sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ=="], "react-dom": ["react-dom@19.1.1", "", { "dependencies": { "scheduler": "^0.26.0" }, "peerDependencies": { "react": "^19.1.1" } }, "sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw=="], + "react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="], + "react-leaflet": ["react-leaflet@5.0.0", "", { "dependencies": { "@react-leaflet/core": "^3.0.0" }, "peerDependencies": { "leaflet": "^1.9.0", "react": "^19.0.0", "react-dom": "^19.0.0" } }, "sha512-CWbTpr5vcHw5bt9i4zSlPEVQdTVcML390TjeDG0cK59z1ylexpqC6M1PJFjV8jD7CF+ACBFsLIDs6DRMoLEofw=="], + "react-lifecycles-compat": ["react-lifecycles-compat@3.0.4", "", {}, "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="], + + "react-modal": ["react-modal@3.16.3", "", { "dependencies": { "exenv": "^1.2.0", "prop-types": "^15.7.2", "react-lifecycles-compat": "^3.0.0", "warning": "^4.0.3" }, "peerDependencies": { "react": "^0.14.0 || ^15.0.0 || ^16 || ^17 || ^18 || ^19", "react-dom": "^0.14.0 || ^15.0.0 || ^16 || ^17 || ^18 || ^19" } }, "sha512-yCYRJB5YkeQDQlTt17WGAgFJ7jr2QYcWa1SHqZ3PluDmnKJ/7+tVU+E6uKyZ0nODaeEj+xCpK4LcSnKXLMC0Nw=="], + "scheduler": ["scheduler@0.26.0", "", {}, "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA=="], "undici-types": ["undici-types@7.11.0", "", {}, "sha512-kt1ZriHTi7MU+Z/r9DOdAI3ONdaR3M3csEaRc6ewa4f4dTvX4cQCbJ4NkEn0ohE4hHtq85+PhPSTY+pO/1PwgA=="], + + "warning": ["warning@4.0.3", "", { "dependencies": { "loose-envify": "^1.0.0" } }, "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w=="], } } diff --git a/package.json b/package.json index d7da543..8da80f8 100644 --- a/package.json +++ b/package.json @@ -11,10 +11,12 @@ "dependencies": { "@types/leaflet": "^1.9.20", "@types/react-leaflet": "^3.0.0", + "@types/react-modal": "^3.16.3", "leaflet": "^1.9.4", "react": "^19", "react-dom": "^19", - "react-leaflet": "^5.0.0" + "react-leaflet": "^5.0.0", + "react-modal": "^3.16.3" }, "devDependencies": { "@types/react": "^19", diff --git a/src/App.tsx b/src/App.tsx index 847a12d..e8bcd79 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,46 +1,108 @@ -import { MapContainer, Marker, TileLayer, Tooltip } from "react-leaflet"; -import L, { marker } from "leaflet"; +import { MapContainer, Marker, Rectangle, TileLayer, Tooltip } from "react-leaflet"; +import L from "leaflet"; import { useCallback, useState } from "react"; +import Modal from 'react-modal'; import "./index.css"; +type SetState = React.Dispatch>; +type StateInit = [T, SetState]; -export function App() { - const [coords, set_coords] = useState({x:0, y:0}) - const [next_label, set_next_label] = useState("") - const [markers, set_markers] = useState([ - {label: "Spawn", x: 0, y: 0} - ]) +function Login(params: { modal: StateInit, login: StateInit; }) { + const {modal, login} = params; + const customStyles = { + content: { + top: '50%', + left: '50%', + right: 'auto', + bottom: 'auto', + marginRight: '-50%', + transform: 'translate(-50%, -50%)', + }, + }; - let map = useCallback((it: L.Map|null) => { - if (it == null) return; - it.on('mousemove', (e) => {set_coords({x: Math.round(e.latlng.lng), y: Math.round(e.latlng.lat)})}) - it.on('click', (e) => set_markers([...markers, {label: next_label, x: Math.round(e.latlng.lng), y: Math.round(e.latlng.lat)}])) - }, [coords, markers, next_label]) - + const openModal = () => modal[1](true) + const afterOpenModal = () => { } + const closeModal = () => modal[1](false) return (<> - - - { - markers.map((it, i) => ( - - {it.label} - - )) - } - -

Mouse is at {coords.x}, {-coords.y}

- - set_next_label(e.target.value)} value={next_label} /> + + +

Authentification

+
{ + // TODO Check Auth + const l = e.get("login") + if (l == null) return; + closeModal() + login[1](l.toString()) + }}> +
+
+ +
+
) +} + +function Toolbar(params: { logged_in: [boolean,] }) { } +export function App() { + const [modalIsOpen, setModalIsOpen]: StateInit = useState(false); + const [coords, setCoords]: StateInit<{ x: number; y: number }> = useState({ x: 0, y: 0 }) + const [nextLabel, setNextLabel]: StateInit = useState("") + const [currentZoom, setCurrentZoom]: StateInit = useState(0) + const [markers, setMarkers]: StateInit<{ label: string; x: number; y: number }[]> = useState([ + { label: "Spawn", x: 0, y: 0 } + ]) + const [login, setLogin]: StateInit = useState() + + let map = useCallback((it: L.Map | null) => { + if (it == null) return; + it.on('mousemove', (e) => { setCoords({ x: Math.round(e.latlng.lng), y: Math.round(e.latlng.lat) }) }) + it.on('zoomend', (_) => setCurrentZoom(it.getZoom())) + it.on('click', (e) => setMarkers([...markers, { label: nextLabel, x: Math.round(e.latlng.lng), y: Math.round(e.latlng.lat) }])) + }, [coords, markers, nextLabel]) + + return (<>{ (!modalIsOpen) ? + + + + {(currentZoom > -2) ? markers.map((it, i) => ( + + {it.label} + + )) : null + } + + : <> } { + (login) ? + <> +

Mouse is at {coords.x}, {-coords.y}

+ + setNextLabel(e.target.value)} value={nextLabel} /> +

Hello {login}!

+ + + : } + + ) +} + export default App; diff --git a/src/index.tsx b/src/index.tsx index c6db1d0..0df5eb6 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,21 +1,18 @@ import { serve, file, type BunRequest } from "bun"; import index from "./index.html"; +import { statSync, } from "node:fs"; const server = serve({ routes: { // Serve index.html for all unmatched routes. "/": index, - "/tiles/:z/:x/:y": (req : BunRequest<"/tiles/:z/:x/:y">) => { - const { z, x, y} = req.params; - return new Response(file(`./static/tiles/${z}/${x}_${y}.png`), { - headers: { - "Content-Type": "image/png" - } - }) - }, - "/legend/:item": (req: BunRequest<"/legend/:item">) => { - const {item} = req.params - return new Response(file(`./static/legend/${item}`)) + "/static/*": (req : BunRequest<"/static/*">) => { + const path = "." + new URL(req.url).pathname + if (statSync(path).isFile()) { + return new Response(file(path)) + } else { + return new Response(`${path} not found`, {status: 404}) + } } }, diff --git a/static/legend/city.svg b/static/legend/city.svg index 6d4765c..8d0ffa3 100644 --- a/static/legend/city.svg +++ b/static/legend/city.svg @@ -1,11 +1,10 @@ - - + \ No newline at end of file