-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactored and commented some components
(cherry picked from commit d7f7c4c)
- Loading branch information
Showing
29 changed files
with
368 additions
and
258 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import './globals.css' | ||
import Header from "@/app/components/header"; | ||
import Footer from "@/app/components/footer"; | ||
|
||
/** | ||
* The general layout for this site to be used both for pages | ||
* using the app-router and the legacy pages-router. | ||
* | ||
* This will ensure that each page has a header and a footer. | ||
* | ||
* Because this is a flex-layout, children can use the `grow` | ||
* class to grow to take up the remaining space on the page. | ||
* | ||
* @param children The actual page this layout should wrap. In JSX, these are the | ||
* children of this element. | ||
* @constructor | ||
*/ | ||
export default function BaseLayout({ | ||
children, | ||
}: { | ||
children: React.ReactNode | ||
}) { | ||
return ( | ||
// inline styling using tailwind will keep styling information in the same | ||
// file as the markup information. | ||
<div className='h-full min-h-screen flex flex-initial flex-col'> | ||
<Header/> | ||
{children} | ||
<Footer/> | ||
</div> | ||
) | ||
} |
6 changes: 3 additions & 3 deletions
6
Website/src/components/dynmap.tsx → Website/src/app/components/dynmap.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import React from "react"; | ||
|
||
/** | ||
* A component that wraps any Form, giving them a consistent appearance. | ||
* | ||
* @param children The actual page this layout should wrap. In JSX, these are the | ||
* children of this element. | ||
* @constructor | ||
*/ | ||
export function FormWrapper({children}: { children: React.ReactNode }) { | ||
return ( | ||
<main className="mx-auto max-w-2xl grow"> | ||
<div className={'bg-white dark:bg-slate-800 dark:text-white p-4 rounded'}> | ||
{children} | ||
</div> | ||
</main> | ||
) | ||
} | ||
|
||
// TODO: create a component for a form in a dialog to replace/refactor | ||
// the LoginDialog and SelectionDialog components. |
File renamed without changes.
File renamed without changes.
File renamed without changes.
6 changes: 3 additions & 3 deletions
6
Website/src/components/login_wrap.tsx → Website/src/app/components/login_wrap.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
"use client"; | ||
import L from "leaflet" | ||
import "leaflet-rotatedmarker" | ||
import 'leaflet/dist/leaflet.css' | ||
import {useEffect, useMemo, useRef, useState} from "react"; | ||
import {IMapConfig} from '@/utils/types' | ||
import {batteryLevelFormatter, coordinateFormatter} from "@/utils/helpers"; | ||
import assert from "assert"; | ||
import {createPortal} from "react-dom"; | ||
|
||
function Map(props: IMapConfig) { | ||
|
||
// console.log('props', props); | ||
|
||
const {position: initial_position, zoom_level, server_vehicles: vehicles, init_data, focus: initial_focus} = props; | ||
|
||
const mapRef = useRef(undefined as L.Map | undefined); | ||
const markerRef = useRef([] as L.Marker[]) | ||
const mapContainerRef = useRef(null as HTMLDivElement | null) | ||
const [position, setPosition] = useState(initial_position) | ||
const [focus, setFocus] = useState(initial_focus); | ||
const [popupContainer, setPopupContainer] = useState(undefined as undefined | HTMLDivElement); | ||
const markerIcon = useMemo(() => new L.Icon({ | ||
iconUrl: "generic_rail_bound_vehicle.svg", | ||
iconSize: L.point(45, 45) | ||
}), []); | ||
|
||
const vehicleInFocus = vehicles.find((v) => v.id == focus); | ||
|
||
// debugger; | ||
|
||
function insertMap() { | ||
// debugger; | ||
// console.log(mapRef, mapRef.current); | ||
assert(mapContainerRef.current, "Error: Ref to Map Container not populated"); | ||
assert(mapRef.current == undefined, "Error: Trying to insert map more than once"); | ||
mapRef.current = L.map(mapContainerRef.current); | ||
|
||
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', { | ||
maxZoom: 19, | ||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>' | ||
}).addTo(mapRef.current); | ||
|
||
/*const openrailwaymap = L.tileLayer('http://{s}.tiles.openrailwaymap.org/standard/{z}/{x}/{y}.png', | ||
{ | ||
attribution: '<a href="https://www.openstreetmap.org/copyright">© OpenStreetMap contributors</a>, Style: <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA 2.0</a> <a href="http://www.openrailwaymap.org/">OpenRailwayMap</a> and OpenStreetMap', | ||
minZoom: 2, | ||
maxZoom: 19, | ||
tileSize: 256 | ||
}).addTo(mapRef.current);*/ | ||
|
||
} | ||
|
||
function setMapZoom() { | ||
assert(mapRef.current != undefined, "Error: Map not ready!"); | ||
|
||
mapRef.current.setZoom(zoom_level); | ||
} | ||
|
||
function setMapPosition() { | ||
assert(mapRef.current != undefined, "Error: Map not ready!"); | ||
assert(!Number.isNaN(mapRef.current?.getZoom()), "Error: ZoomLevel MUST be set before position is set!") | ||
|
||
mapRef.current.setView(position); | ||
} | ||
|
||
|
||
function addTrackPath() { | ||
assert(mapRef.current != undefined, "Error: Map not ready!"); | ||
|
||
const trackPath = L.geoJSON(init_data?.trackPath, {style: {color: 'red'}}) | ||
trackPath.addTo(mapRef.current) | ||
|
||
// Add a callback to remove the track path to remove the track path in case of a re-render. | ||
return () => { | ||
trackPath.remove(); | ||
} | ||
} | ||
|
||
function updateMarkers() { | ||
|
||
assert(mapRef.current != undefined, "Error: Map not ready!"); | ||
|
||
while (markerRef.current.length > vehicles.length) { | ||
const m = markerRef.current.pop() | ||
if (m) { | ||
m.remove() | ||
} else { | ||
break; | ||
} | ||
} | ||
vehicles.forEach((v, i) => { | ||
if (i >= markerRef.current.length) { | ||
if (mapRef.current) { | ||
const m = L.marker(vehicles[i].pos, { | ||
icon: markerIcon, | ||
rotationOrigin: "center" | ||
}).addTo(mapRef.current); | ||
markerRef.current.push(m); | ||
} | ||
} | ||
const m = markerRef.current[i]; | ||
m.setLatLng(vehicles[i].pos) | ||
// m.setPopupContent(popupContent(vehicles[i])) | ||
m.setRotationAngle(vehicles[i].heading || 0) | ||
|
||
if (v.id === focus) { | ||
const current_popup = m.getPopup() | ||
if (current_popup == undefined) { | ||
// create a div element to contain the popup content. | ||
// We can then use a React portal to place content in there. | ||
const popupElement = document.createElement('div'); | ||
popupElement.className = "w-64 flex p-1.5 flex-row flex-wrap"; | ||
m.bindPopup(popupElement); | ||
setPopupContainer(popupElement); | ||
// unset the focussed element on popup closing. | ||
m.on('popupclose', () => { | ||
setFocus(undefined) | ||
}) | ||
} | ||
m.openPopup(); | ||
setPosition(vehicles[i].pos); | ||
} else { | ||
m.closePopup(); | ||
m.unbindPopup(); | ||
} | ||
m.on('click', () => { | ||
// set the vehicle as the focussed vehicle if it is clicked. | ||
setFocus(v.id) | ||
}) | ||
|
||
} | ||
) | ||
} | ||
|
||
useEffect(insertMap, []); | ||
useEffect(setMapZoom, [zoom_level]); | ||
useEffect(setMapPosition, [position]); | ||
useEffect(addTrackPath, [init_data?.trackPath]); | ||
useEffect(updateMarkers, [focus, markerIcon, vehicles]); | ||
|
||
return ( | ||
<> | ||
<div id='map' className="h-full" ref={mapContainerRef}/> | ||
{popupContainer && createPortal(vehicleInFocus ? | ||
<> | ||
<h4 className={'col-span-2 basis-full text-xl text-center'}>Vehicle "{vehicleInFocus?.name}"</h4> | ||
<div className={'basis-1/2'}>Tracker-Level:</div> | ||
<div | ||
className={'basis-1/2'}>{vehicleInFocus ? batteryLevelFormatter.format(vehicleInFocus.batteryLevel) : 'unbekannt'}</div> | ||
<div className={'basis-1/2'}>Position:</div> | ||
<div | ||
className={'basis-1/2'}>{ | ||
vehicleInFocus | ||
? <>{coordinateFormatter.format(vehicleInFocus?.pos.lat)} N {coordinateFormatter.format(vehicleInFocus?.pos.lng)} E</> | ||
: 'unbekannt'} | ||
</div> | ||
</> : <div/>, popupContainer | ||
)} | ||
</> | ||
); | ||
} | ||
|
||
|
||
export default Map |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,22 @@ | ||
import RootLayout from "@/components/layout" | ||
import BaseLayout from "@/app/components/base_layout" | ||
import {inter, meta_info} from "@/utils/common"; | ||
|
||
export const metadata = { | ||
title: 'Create Next App', | ||
description: 'Generated by create next app', | ||
} | ||
export const metadata = meta_info; | ||
|
||
export default RootLayout; | ||
/** | ||
* The Layout to use on all pages in the app-directory. | ||
* Effectively defers to BaseLayout with minimal adjustments. | ||
*/ | ||
export default function RootLayout({children,}: { children: React.ReactNode }) { | ||
return ( | ||
<html lang="en"> | ||
<body className={inter.className}> | ||
<BaseLayout> | ||
{children} | ||
</BaseLayout> | ||
</body> | ||
</html> | ||
) | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,12 @@ | ||
import Login from "@/components/login"; | ||
import Login from "@/app/components/login"; | ||
import {FormWrapper} from "@/app/components/form"; | ||
|
||
|
||
export default function Home(x: any) { | ||
export default function LoginPage() { | ||
|
||
return ( | ||
// <div className='h-full min-h-screen'> | ||
<main className="container mx-auto max-w-2xl grow"> | ||
<div className={'bg-white p-4 rounded'}> | ||
<Login/> | ||
</div> | ||
</main> | ||
//</div> | ||
<FormWrapper> | ||
<Login/> | ||
</FormWrapper> | ||
) | ||
} | ||
} |
Oops, something went wrong.