Skip to content

Commit

Permalink
Improved fetching behavior and prepared for list view
Browse files Browse the repository at this point in the history
  • Loading branch information
n1kPLV committed Jul 24, 2023
1 parent 29e4bb1 commit d069f76
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 55 deletions.
49 changes: 27 additions & 22 deletions Website/src/app/map/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,40 @@ import DynamicMap from '@/components/dynmap';
import {cookies} from 'next/headers';
import {getInitData, getVehicleData} from '@/lib/data';
import {LoginDialog} from "@/components/login";
import LoginMapWrapper from "@/components/login_map";
import LoginWrapper from "@/components/login_wrap";
import {InitResponse, Vehicle} from "@/lib/api.website";
import {nanToUndefined} from "@/lib/helpers";

export default async function Home() {
export default async function Home({searchParams}: { searchParams: { focus?: string, success?: string } }) {

const token = cookies().get("token")?.value;
const track_id = parseInt(cookies().get("track_id")?.value ?? '', 10)
let server_vehicles: Vehicle[];
let init_data: InitResponse | undefined;
console.log('params', searchParams);

const token = cookies().get("token")?.value;
const track_id = parseInt(cookies().get("track_id")?.value ?? '', 10)
const track_selected = !isNaN(track_id);
let server_vehicles: Vehicle[];
let init_data: InitResponse | undefined;
try {
init_data = token ? await getInitData(token, track_id) : undefined;
server_vehicles = token ? await getVehicleData(token, track_id) : [];
init_data = (token && track_selected) ? await getInitData(token, track_id) : undefined;
server_vehicles = (token && track_selected) ? await getVehicleData(token, track_id) : [];
} catch (e) {
console.log('Catched e');
console.log('Catched e:', e);
init_data = undefined;
server_vehicles = []
}
const focus = nanToUndefined(parseInt(searchParams.focus ?? '', 10));


console.log("server vehicles", server_vehicles)
return (
<LoginMapWrapper logged_in={token !== undefined} track_selected={!isNaN(track_id)} map_conf={
{
position: {lat: 54.2333, lng: 10.6024},
zoom_level: 11,
server_vehicles,
track_id,
init_data
}
} />
)
console.log("server vehicles", server_vehicles)
return (
<LoginWrapper logged_in={token !== undefined} track_selected={track_selected} map_conf={
{
position: {lat: 54.2333, lng: 10.6024},
zoom_level: 11,
server_vehicles,
track_id,
init_data,
focus
}
} child={DynamicMap}/>
)
}
14 changes: 5 additions & 9 deletions Website/src/components/dynmap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,25 +44,21 @@ const fetcher = ([url, track_id]: [url: string, track_id: number]) => {
});
};

export default function DynamicMap(props: React.PropsWithChildren<IMapRefreshConfig & {
logged_in: boolean,
setLogin: (success: boolean) => void
}>) {
export default function DynamicMap(props: IMapRefreshConfig) {

const {position, zoom_level, server_vehicles, track_id, logged_in, init_data} = props;
const {position, zoom_level, server_vehicles, track_id, logged_in, init_data, focus} = props;
// console.log(props)

// const [vehicles, setVehicles] = useState(server_vehicles)
// const timeoutRef = useRef(undefined as NodeJS.Timeout | undefined);

const {data, error, isLoading} = useSWR(['/api/update', track_id], fetcher, {
const {data, error, isLoading} = useSWR((logged_in && track_id) ? ['/api/update', track_id] : null, fetcher, {
refreshInterval: 1000,
isOnline: () => logged_in
})

// console.log(data, error, isLoading);

const vehicles = (isLoading || error) ? server_vehicles : data;
const vehicles = (isLoading || error || !logged_in || !track_id) ? server_vehicles : data;

if (logged_in && error) {
if (error instanceof RevalidateError && error.statusCode == 401) {
Expand All @@ -75,7 +71,7 @@ export default function DynamicMap(props: React.PropsWithChildren<IMapRefreshCon
return (
<div className={'h-96 grow'}>
<_internal_DynamicMap
position={position} zoom_level={zoom_level} server_vehicles={vehicles} init_data={init_data}
position={position} zoom_level={zoom_level} server_vehicles={vehicles} init_data={init_data} focus={focus}
/>
</div>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,21 @@ import {LoginDialog} from "@/components/login";
import DynamicMap from "@/components/dynmap";
import {SelectionDialog} from "@/components/track_selection";

const LoginMapWrapper = ({logged_in, track_selected, map_conf}: PropsWithChildren<{logged_in: boolean, track_selected: boolean, map_conf: IMapRefreshConfig}>) => {
const LoginWrapper = ({logged_in, track_selected, map_conf, child}: {logged_in: boolean, track_selected: boolean, map_conf: IMapRefreshConfig, child: (conf: IMapRefreshConfig) => JSX.Element}) => {
const [loginState, setLogin] = useState(logged_in);

console.log('track selected', track_selected, map_conf.track_id)

return <>
{!loginState &&
<LoginDialog dst_url='/map' login_callback={setLogin}>
<LoginDialog login_callback={setLogin}>
<p className="mb-1.5">You need to log in!</p>
</LoginDialog>}
{loginState && !track_selected && <SelectionDialog dst_url='/map' login_callback={setLogin}>
{loginState && !track_selected && <SelectionDialog login_callback={setLogin}>
<p className="mb-1.5">Please select a track!</p>
</SelectionDialog> }
<DynamicMap {...map_conf} logged_in={loginState} setLogin={setLogin}/>
{child({...map_conf, logged_in: loginState, setLogin: setLogin})}
</>
}

export default LoginMapWrapper;
export default LoginWrapper;
29 changes: 14 additions & 15 deletions Website/src/components/map.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,7 @@ import {useEffect, useRef} from "react";
import {createRoot} from "react-dom/client";
import {IMapConfig} from '@/lib/types'
import {Vehicle} from "@/lib/api.website";

const batteryLevelFormatter = new Intl.NumberFormat('de-DE', {
notation: "standard",
style: 'unit',
unit: 'percent',
maximumFractionDigits: 1,
})

const coordinateFormatter = new Intl.NumberFormat('de-DE', {
notation: "standard",
style: 'unit',
unit: 'degree',
maximumFractionDigits: 2,
})
import {batteryLevelFormatter, coordinateFormatter} from "@/lib/helpers";

function popupContent({batteryLevel, name, pos}: Vehicle): L.Content {
const baseContainer = document.createElement('div')
Expand All @@ -44,7 +31,7 @@ function Map(props: IMapConfig) {

// console.log('props', props);

const {position, zoom_level, server_vehicles, init_data} = props;
const {position, zoom_level, server_vehicles, init_data, focus} = props;

const mapRef = useRef(undefined as L.Map | undefined);
const markerRef = useRef([] as L.Marker[])
Expand Down Expand Up @@ -89,6 +76,10 @@ function Map(props: IMapConfig) {
}).addTo(mapRef.current);
m.bindPopup(popupContent(v))
m.setRotationAngle(v.heading || 0)
if (v.id === focus) {
m.openPopup();
mapRef.current?.setView(m.getLatLng());
}
markerRef.current.push(m);
}
mapRef.current.setView(position, zoom_level);
Expand All @@ -114,6 +105,10 @@ function Map(props: IMapConfig) {
m.setLatLng(vehicles[i].pos)
m.setPopupContent(popupContent(vehicles[i]))
m.setRotationAngle(vehicles[i].heading || 0)
if (vehicles[i].id === focus) {
m.openPopup();
mapRef.current?.setView(m.getLatLng());
}
// L.circle(vehicles[i].pos, {radius: 0.5, color: '#009988'}).addTo(mapRef.current);
} else {
const m = L.marker(vehicles[i].pos, {
Expand All @@ -123,6 +118,10 @@ function Map(props: IMapConfig) {
markerRef.current.push(m);
m.bindPopup(popupContent(vehicles[i]))
m.setRotationAngle(vehicles[i].heading || 0)
if (vehicles[i].id === focus) {
m.openPopup();
mapRef.current?.setView(m.getLatLng());
}
}

}
Expand Down
4 changes: 2 additions & 2 deletions Website/src/components/track_selection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ export default function Selection({dst_url}: {dst_url?: Url}) {

return (
<form onSubmit={selectTrack} className="grid grid-cols-2 gap-y-1 mx-1.5 items-center">
{isLoading ? <p> Lädt... </p> : (<>
{isLoading ? <p> Lädt... </p> : (error ? <p> {error.toString()} </p> : (<>
<label htmlFor="track">Strecke: </label>
<select id={'track'} name={'track'}>
{data.map(({id, name}) => (<option value={id} key={id}>{name}</option>))}
</select>
<button type="submit" className="col-span-2 rounded-full bg-gray-700 text-white">Auswählen</button>
</>)}
</>))}
</form>
)
}
Expand Down
2 changes: 1 addition & 1 deletion Website/src/lib/api.website.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export interface VehicleCrU {
uid?: number, // Null, if creating vehicle, some other value otherwise
name: string, // The name, that is attached to the vehicle, e.g. "1" for "Draisine 1"
typeId: number, // The id of the type
trackerIds?: string[]// A unique id to identify the tracker belonging to that vehicle
trackerIds: string[]// A unique id to identify the tracker belonging to that vehicle
}

export interface VehicleTypeListItem {
Expand Down
23 changes: 22 additions & 1 deletion Website/src/lib/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,23 @@

export const async_sleep: (time: number) => Promise<null> = (time) => new Promise((resolve, reject) => setTimeout(() => resolve(null), time))
export const async_sleep: (time: number) => Promise<null> = (time) => new Promise((resolve, reject) => setTimeout(() => resolve(null), time))

export const batteryLevelFormatter = new Intl.NumberFormat('de-DE', {
notation: "standard",
style: 'unit',
unit: 'percent',
maximumFractionDigits: 1,
})

export const coordinateFormatter = new Intl.NumberFormat('de-DE', {
notation: "standard",
style: 'unit',
unit: 'degree',
maximumFractionDigits: 2,
})

export function nanToUndefined(x: number): number | undefined {
if (Number.isNaN(x))
return;
return x;

}
3 changes: 3 additions & 0 deletions Website/src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ export interface IMapConfig {
zoom_level: number,
server_vehicles: Vehicle[],
init_data?: InitResponse
focus?: number
}

export interface IMapRefreshConfig extends IMapConfig {
track_id: number
logged_in?: boolean,
setLogin?: (success: boolean) => void
}

export class UnauthorizedError extends Error {}
Expand Down

0 comments on commit d069f76

Please sign in to comment.