-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added a list of vehicles #43
Changes from 4 commits
66b04fb
65b53c9
32eaf10
3defbb8
9203259
d7f7c4c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import '../../components/globals.css' | ||
import Header from "@/app/components/header"; | ||
import Footer from "@/app/components/footer"; | ||
|
||
export default function Layout({ | ||
children, | ||
}: { | ||
children: React.ReactNode | ||
}) { | ||
return ( | ||
<div className='h-full min-h-screen flex flex-initial flex-col'> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To organize the styling between the different files all the stylings should be structured into .css files and only referenced by their class here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. WON'T FIX: this sort of styling is only used for this component. There is absolutely nothing gained by defining a custom CSS class I would argue, that it also helps with maintainability, as there are no 'orphaned' CSS styles hanging around in a CSS file somewhere, that might still be in use However, (not in this case, but maybe for some other thing) I should move some duplicated layout things into a component or a |
||
<Header/> | ||
{children} | ||
<Footer/> | ||
</div> | ||
) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,18 @@ | ||
import RootLayout from "@/components/layout" | ||
import Layout from "@/app/components/layout_base" | ||
import {inter, meta_info} from "@/lib/common"; | ||
|
||
export const metadata = { | ||
title: 'Create Next App', | ||
description: 'Generated by create next app', | ||
} | ||
export const metadata = meta_info; | ||
|
||
export default RootLayout; | ||
export default function RootLayout({children,}: { children: React.ReactNode }) { | ||
return ( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Naming here seems inconsistent: the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Files named However I agree that naming things is hard |
||
<html lang="en"> | ||
<body className={inter.className}> | ||
<Layout> | ||
{children} | ||
</Layout> | ||
</body> | ||
</html> | ||
) | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
|
||
import {cookies} from 'next/headers'; | ||
import {getInitData, getVehicleData} from '@/lib/data'; | ||
import LoginWrapper from "@/components/login_wrap"; | ||
import {InitResponse, Vehicle} from "@/lib/api.website"; | ||
import DynamicList from "@/components/dynlist"; | ||
|
||
export default async function Home() { | ||
|
||
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 && track_selected) ? await getInitData(token, track_id) : undefined; | ||
server_vehicles = (token && track_selected) ? await getVehicleData(token, track_id) : []; | ||
} catch (e) { | ||
console.error('Catched e:', e); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Error messages should be a bit more informative about the context in which they occurred. |
||
init_data = undefined; | ||
server_vehicles = [] | ||
} | ||
|
||
console.log("server vehicles", server_vehicles) | ||
return ( | ||
<main className="container mx-auto max-w-4xl grow"> | ||
<div className={'bg-white p-4 rounded'}> | ||
<LoginWrapper logged_in={token !== undefined} track_selected={track_selected} map_conf={ | ||
{ | ||
position: {lat: 54.2333, lng: 10.6024}, | ||
zoom_level: 11, | ||
server_vehicles, | ||
init_data, | ||
track_id | ||
} | ||
} child={DynamicList}/> | ||
</div> | ||
</main> | ||
) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
"use client"; | ||
|
||
import {IMapRefreshConfig, RevalidateError} from "@/lib/types"; | ||
import {Vehicle} from "@/lib/api.website"; | ||
import useSWR from "swr"; | ||
import {batteryLevelFormatter, coordinateFormatter} from "@/lib/helpers"; | ||
import Link from "next/link"; | ||
|
||
var i = 0 | ||
const fetcher = ([url, track_id]: [url: string, track_id: number]) => { | ||
return fetch(url, {method: 'post', body: JSON.stringify({track_id})}).then( | ||
async (res: Response) => { | ||
if (!res.ok) { | ||
// console.log('not ok!'); | ||
throw new RevalidateError('Re-Fetching unsuccessful', res.status); | ||
} | ||
//console.log('ok') | ||
return res; | ||
} | ||
).then(res => res.json()) | ||
.then(res => { | ||
// console.log(res); | ||
const test_vehicle: Vehicle = { | ||
id: 0, | ||
pos: { | ||
lat: 54.17 + 0.05 * Math.cos(i * Math.PI / 180), | ||
lng: 10.56 + 0.085 * Math.sin(i * Math.PI / 180) | ||
}, | ||
heading: (i + 90) % 360, | ||
name: 'foo', | ||
batteryLevel: 0.5 | ||
}; | ||
// {id: 42, pos: {lat: 54.2 + 0.05 * Math.cos((i.current + 180) * Math.PI / 180), lng: 10.56 + 0.085 * Math.sin((i.current + 180) * Math.PI / 180) }, heading: i.current - 90, name: 'bar', batteryLevel: 1} | ||
// ]; | ||
i += 5.1; | ||
return res.concat([test_vehicle]) | ||
}); | ||
}; | ||
|
||
export default function DynamicList(props: IMapRefreshConfig) { | ||
|
||
const {server_vehicles, track_id, logged_in} = props; | ||
// console.log(props) | ||
|
||
// const [vehicles, setVehicles] = useState(server_vehicles) | ||
// const timeoutRef = useRef(undefined as NodeJS.Timeout | undefined); | ||
|
||
const {data, error, isLoading} = useSWR((logged_in && track_id) ? ['/webapi/update', track_id] : null, fetcher, { | ||
refreshInterval: 1000, | ||
}) | ||
|
||
// console.log(data, error, isLoading); | ||
|
||
const vehicles: Vehicle[] = (isLoading || error || !logged_in || !track_id) ? server_vehicles : data; | ||
const sorted_vehicles = vehicles.sort((a, b) => a.id - b.id); | ||
|
||
if (logged_in && error) { | ||
if (error instanceof RevalidateError && error.statusCode == 401) { | ||
console.log('Invalid token'); | ||
window.location.reload(); | ||
} | ||
console.log("revalidate error", error) | ||
} | ||
|
||
return ( | ||
<> | ||
<h2>{`Fahrzeuge der Strecke ${undefined}`}</h2> | ||
<table className={'table-auto border-collapse w-full'}> | ||
<thead> | ||
<tr className={'my-2'}> | ||
<th className={'mx-2 border-b-black border-b px-2'}>Name</th> | ||
<th className={'mx-2 border-b-black border-b px-2'}>geog. Breite</th> | ||
<th className={'mx-2 border-b-black border-b px-2'}>geog. Länge</th> | ||
<th className={'mx-2 border-b-black border-b px-2'}>Richtung</th> | ||
<th className={'mx-2 border-b-black border-b px-2'}>Batterieladung</th> | ||
<th className={'mx-2 border-b-black border-b px-2'}>Auf Karte anzeigen</th> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
{sorted_vehicles.map((v) => ( | ||
<tr key={v.id} className={'my-2'}> | ||
<td className={'mx-2 px-2 text-center'}>{v.name}</td> | ||
<td className={'mx-2 px-2 text-center'}>{coordinateFormatter.format(v.pos.lat)} N</td> | ||
<td className={'mx-2 px-2 text-center'}>{coordinateFormatter.format(v.pos.lng)} E</td> | ||
<td className={'mx-2 px-2 text-center'}>{v.heading ? coordinateFormatter.format(v.heading) : 'unbekannt'}</td> | ||
<td className={'mx-2 px-2 text-center'}>{batteryLevelFormatter.format(v.batteryLevel)}</td> | ||
<td className={'mx-2 px-2 text-center'}><Link className="text-blue-600 visited:text-purple-700" href={`/map?focus=${v.id}`}>Link</Link></td> | ||
</tr> | ||
))} | ||
</tbody> | ||
</table> | ||
</> | ||
) | ||
|
||
} |
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A quick look through this shows me that there are practically no comments in the code and no documentation for the public API. That makes it a lot harder to understand and also review code such as this. Please comment your code.