Skip to content

Commit

Permalink
Formatted
Browse files Browse the repository at this point in the history
  • Loading branch information
williamwoldum committed Oct 31, 2024
1 parent 86c6693 commit 94be72e
Show file tree
Hide file tree
Showing 34 changed files with 328 additions and 249 deletions.
10 changes: 5 additions & 5 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"singleQuote": true,
"semi": false,
"trailingComma": "es5",
"printWidth": 120
}
"singleQuote": true,
"semi": false,
"trailingComma": "es5",
"printWidth": 120
}
7 changes: 2 additions & 5 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,7 @@ export default tseslint.config(
},
rules: {
...reactHooks.configs.recommended.rules,
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
'react-refresh/only-export-components': ['warn', { allowConstantExport: true }],
},
},
}
)
11 changes: 7 additions & 4 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Gabarito:[email protected]&family=Roboto+Mono:ital,wght@0,100..700;1,100..700&display=swap" rel="stylesheet">
<link rel="icon" href="/FaviconAIS.png">
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Gabarito:[email protected]&family=Roboto+Mono:ital,wght@0,100..700;1,100..700&display=swap"
rel="stylesheet"
/>
<link rel="icon" href="/FaviconAIS.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Suspicios Vessel Finder</title>
</head>
Expand Down
15 changes: 15 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"dev:all": "concurrently \"npm run proxy\" \"npm run dev\"",
"build": "tsc -b && vite build",
"lint": "eslint .",
"format": "prettier --write src",
"preview": "vite preview",
"build:protos:mac": "protoc --plugin=./node_modules/.bin/protoc-gen-ts_proto --ts_proto_opt=outputClientImpl=grpc-web --ts_proto_out=./proto ./AIS-protobuf/ais.proto",
"build:protos:win": "protoc --plugin=./node_modules/.bin/protoc-gen-ts_proto.cmd --ts_proto_opt=outputClientImpl=grpc-web --ts_proto_out=./proto ./AIS-protobuf/ais.proto",
Expand All @@ -22,6 +23,7 @@
"leaflet": "^1.9.4",
"leaflet-pixi-overlay": "^1.9.4",
"pixi.js": "^7.4.2",
"prettier": "^3.3.3",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-leaflet": "^4.2.1",
Expand All @@ -48,4 +50,4 @@
"typescript-eslint": "^8.0.1",
"vite": "^5.4.1"
}
}
}
16 changes: 9 additions & 7 deletions src/components/monitoringMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ export default function MonitoringMenu({ monitoredVessels, children }: IMonitori
<div className="flex flex-col h-full rounded-lg bg-gray-200 px-2 shadow-xl">
<div className={`flex flex-row justify-between items-center ${!isCollapsed && 'border-b-2'} gap-4 p-2`}>
<h1 className="text-xl font-bold">Monitored vessels</h1>
<p className="text-sm rounded-md bg-gray-300 py-1 px-2">{monitoredVessels.length} {monitoredVessels.length == 1 ? "vessel" : "vessels"}</p>
<p className="text-sm rounded-md bg-gray-300 py-1 px-2">
{monitoredVessels.length} {monitoredVessels.length == 1 ? 'vessel' : 'vessels'}
</p>
</div>
{!isCollapsed && (
<>
Expand All @@ -34,12 +36,12 @@ export default function MonitoringMenu({ monitoredVessels, children }: IMonitori
</div>
</>
)}
<button title="Show/hide list of monitored vessels" onClick={() => setIsCollapsed(!isCollapsed)} className="w-full flex flex-cols items-center justify-center bottom-0">
{isCollapsed ? (
<ChevronSVG />
) : (
<ChevronSVG rotate={180}/>
)}
<button
title="Show/hide list of monitored vessels"
onClick={() => setIsCollapsed(!isCollapsed)}
className="w-full flex flex-cols items-center justify-center bottom-0"
>
{isCollapsed ? <ChevronSVG /> : <ChevronSVG rotate={180} />}
</button>
</div>
)
Expand Down
12 changes: 9 additions & 3 deletions src/components/monitoringMenuRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,15 @@ export default function MonitoringMenuRow({ isSelected, monitoredVessel, zoomToC
return (
<span className={`${isSelected && 'font-bold'} grid grid-cols-4 gap-4`}>
<p className="text-left font-mono">{monitoredVessel.mmsi}</p>
<p className="text-right font-mono">{(Math.round(monitoredVessel.trustworthiness*1000)/10).toFixed(2)}%</p>
<p title={monitoredVessel.reason} className="text-left text-ellipsis">{monitoredVessel.reason}</p>
<button title="Go to vessel" className="flex items-center justify-center transition-all hover:scale-110" onClick={handleClick}>
<p className="text-right font-mono">{(Math.round(monitoredVessel.trustworthiness * 1000) / 10).toFixed(2)}%</p>
<p title={monitoredVessel.reason} className="text-left text-ellipsis">
{monitoredVessel.reason}
</p>
<button
title="Go to vessel"
className="flex items-center justify-center transition-all hover:scale-110"
onClick={handleClick}
>
<EyeSVG />
</button>
</span>
Expand Down
123 changes: 70 additions & 53 deletions src/components/navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,60 +1,77 @@
import { useState } from "react"
import { useAppContext } from "../contexts/appcontext"
import FaviconSVG from "../svgs/faviconSVG"
import HamburgerSVG from "../svgs/hamburgerSVG"
import CloseSVG from "../svgs/closeSVG"
import { useState } from 'react'
import { useAppContext } from '../contexts/appcontext'
import FaviconSVG from '../svgs/faviconSVG'
import HamburgerSVG from '../svgs/hamburgerSVG'
import CloseSVG from '../svgs/closeSVG'

interface INavbar {
interface INavbar {}

}

export default function Navbar({ }: INavbar) {
const [opened, setOpened] = useState<boolean>(false)
const { myDateTime, myClockSpeed, setMyDateTime, setMyClockSpeed } = useAppContext()
const convertedMyDateTime = `${myDateTime.getFullYear()}-${myDateTime.getMonth().toString().padStart(2, "0")}-${myDateTime.getDate().toString().padStart(2, "0")}T${myDateTime.getHours().toString().padStart(2, "0")}:${myDateTime.getMinutes().toString().padStart(2, "0")}`
export default function Navbar({}: INavbar) {
const [opened, setOpened] = useState<boolean>(false)
const { myDateTime, myClockSpeed, setMyDateTime, setMyClockSpeed } = useAppContext()
const convertedMyDateTime = `${myDateTime.getFullYear()}-${myDateTime.getMonth().toString().padStart(2, '0')}-${myDateTime.getDate().toString().padStart(2, '0')}T${myDateTime.getHours().toString().padStart(2, '0')}:${myDateTime.getMinutes().toString().padStart(2, '0')}`

function manageSpeedChange(val: string) {
try {
const parsed = parseInt(val)
setMyClockSpeed(parsed)
} catch (e) {
console.error(e)
setMyClockSpeed(1)
}
function manageSpeedChange(val: string) {
try {
const parsed = parseInt(val)
setMyClockSpeed(parsed)
} catch (e) {
console.error(e)
setMyClockSpeed(1)
}
}

function manageDateChange(val: string) {
const parsed = new Date(val)
setMyDateTime(parsed)
}
function manageDateChange(val: string) {
const parsed = new Date(val)
setMyDateTime(parsed)
}

return (
<div className="w-fit">
<div id="navbar" className="relative px-5 flex flex-row gap-4 flex-nowrap items-center w-full bg-gray-700 text-white rounded-lg p-4">
<FaviconSVG></FaviconSVG>
<h1 className="text-xl font-bold">Suspicios Vessel Finder</h1>
{ opened &&
<div id="settings-container" className="absolute left-[101%] top-0 bg-gray-200 text-gray-800 flex flex-col gap-4 p-4 w-fit rounded-md shadow-lg">
<h2 className="text-lg font-bold">Simulation settings</h2>

<div className="flex flex-row justify-between gap-4">
<label className="font-medium whitespace-nowrap" htmlFor="my-speed">Simulated Speed</label>
<input id="my-speed" className="w-20 text-right bg-transparent" type="number" step="1" onChange={(e) => manageSpeedChange(e.target.value)} value={myClockSpeed} />
</div>
<div className="flex flex-row justify-between gap-4">
<label className="font-medium whitespace-nowrap" htmlFor='date-picker'>Simulated Date</label>
<input id='date-picker' className="w-40 text-right bg-transparent" type="datetime-local" onChange={(e) => manageDateChange(e.target.value)} value={convertedMyDateTime} />
</div>
</div>
}
<button id="menu-icon" title="Show/hide simulation settings" className="" onClick={() => setOpened(!opened)}>
{ !opened ?
<HamburgerSVG/>
:
<CloseSVG/>
}
</button>
return (
<div className="w-fit">
<div
id="navbar"
className="relative px-5 flex flex-row gap-4 flex-nowrap items-center w-full bg-gray-700 text-white rounded-lg p-4"
>
<FaviconSVG></FaviconSVG>
<h1 className="text-xl font-bold">Suspicios Vessel Finder</h1>
{opened && (
<div
id="settings-container"
className="absolute left-[101%] top-0 bg-gray-200 text-gray-800 flex flex-col gap-4 p-4 w-fit rounded-md shadow-lg"
>
<h2 className="text-lg font-bold">Simulation settings</h2>

<div className="flex flex-row justify-between gap-4">
<label className="font-medium whitespace-nowrap" htmlFor="my-speed">
Simulated Speed
</label>
<input
id="my-speed"
className="w-20 text-right bg-transparent"
type="number"
step="1"
onChange={(e) => manageSpeedChange(e.target.value)}
value={myClockSpeed}
/>
</div>
<div className="flex flex-row justify-between gap-4">
<label className="font-medium whitespace-nowrap" htmlFor="date-picker">
Simulated Date
</label>
<input
id="date-picker"
className="w-40 text-right bg-transparent"
type="datetime-local"
onChange={(e) => manageDateChange(e.target.value)}
value={convertedMyDateTime}
/>
</div>
</div>
)
}
</div>
)}
<button id="menu-icon" title="Show/hide simulation settings" className="" onClick={() => setOpened(!opened)}>
{!opened ? <HamburgerSVG /> : <CloseSVG />}
</button>
</div>
</div>
)
}
30 changes: 15 additions & 15 deletions src/components/path.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,34 @@
import { useEffect } from 'react';
import { useVesselGuiContext } from '../contexts/vesselGuiContext';
import { ILocation } from '../models/location';
import L from "leaflet"
import { useEffect } from 'react'
import { useVesselGuiContext } from '../contexts/vesselGuiContext'
import { ILocation } from '../models/location'
import L from 'leaflet'

interface IPathProps {
path: ILocation[];
path: ILocation[]
map: L.Map
}

export default function Path({ path, map }: IPathProps) {
useEffect(() => {
const points = path.map(loc => L.latLng(loc.point.lat, loc.point.lon))
const points = path.map((loc) => L.latLng(loc.point.lat, loc.point.lon))

const polyline = new L.Polyline(points, {
color: 'red',
weight: 3,
opacity: 0.5,
smoothFactor: 1
});
polyline.addTo(map);
smoothFactor: 1,
})

polyline.addTo(map)

return () => {
map.eachLayer(layer => {
if(layer instanceof L.Polyline) {
map.eachLayer((layer) => {
if (layer instanceof L.Polyline) {
map.removeLayer(layer)
}
})
})
}
}, [path])

return null
return null
}
12 changes: 8 additions & 4 deletions src/components/timeline.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useEffect, useState } from 'react'
import { useVesselGuiContext } from '../contexts/vesselGuiContext'
interface ITimelineProps {
timestamps: Date[];
onChange(index: number): void;
timestamps: Date[]
onChange(index: number): void
}

export default function Timeline({ timestamps, onChange }: ITimelineProps) {
Expand All @@ -29,11 +29,15 @@ export default function Timeline({ timestamps, onChange }: ITimelineProps) {
<div className="bg-neutral_2 rounded-xl mx-4 px-4 py-2 shadow">
<div className="w-full flex items-center relative">
<p className="absolute left-1/2 transform -translate-x-1/2 font-bold text-center">
Timestamp: {timelineVal && timestamps[timelineVal] ? timestamps[timelineVal].toISOString().replace("T", " ").replace("Z", "").slice(0, 19) : "unknown"}
Timestamp:{' '}
{timelineVal && timestamps[timelineVal]
? timestamps[timelineVal].toISOString().replace('T', ' ').replace('Z', '').slice(0, 19)
: 'unknown'}
</p>
<button
onClick={closePath}
className="ml-auto text-bold rounded-md bg-blue-600 hover:bg-blue-400 px-2 text-white">
className="ml-auto text-bold rounded-md bg-blue-600 hover:bg-blue-400 px-2 text-white"
>
Close
</button>
</div>
Expand Down
Loading

0 comments on commit 94be72e

Please sign in to comment.