diff options
Diffstat (limited to 'web/simple/index.html')
-rw-r--r-- | web/simple/index.html | 238 |
1 files changed, 0 insertions, 238 deletions
diff --git a/web/simple/index.html b/web/simple/index.html deleted file mode 100644 index 4df77259..00000000 --- a/web/simple/index.html +++ /dev/null @@ -1,238 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -<head> -<meta charset="UTF-8"> -<meta name="viewport" content="width=device-width, initial-scale=1"> -<title>Traccar</title> -<link href="https://unpkg.com/@picocss/pico@2.0.6/css/pico.min.css" rel="stylesheet"> -<link href="https://unpkg.com/maplibre-gl@4.1.2/dist/maplibre-gl.css" rel="stylesheet"> -</head> -<body style="margin: 0; padding: 0;"> -<div id="content" style="width: 100%; height: 100%; position:fixed;"></div> -<script src="https://unpkg.com/react@17/umd/react.development.js"></script> -<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> -<script src="https://unpkg.com/maplibre-gl@4.1.2/dist/maplibre-gl.js"></script> -<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> -<script type="text/babel"> - - const LoginScreen = ({ server, setServer, setUser }) => { - const [email, setEmail] = React.useState(''); - const [password, setPassword] = React.useState(''); - - const handleSubmit = (event) => { - event.preventDefault(); - const fetchData = async () => { - if (server.newServer) { - const response = await fetch('/api/users', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ name: email, email, password }), - }); - if (response.ok) { - setServer({ ...server, newServer: false }); - } - } else { - const query = `email=${encodeURIComponent(email)}&password=${encodeURIComponent(password)}`; - const response = await fetch('/api/session', { - method: 'POST', - body: new URLSearchParams(query), - }); - if (response.ok) { - setUser(await response.json()); - } - } - } - fetchData(); - }; - - const formStyle = { - width: '320px', - margin: '32px', - display: 'flex', - flexDirection: 'column', - }; - - return ( - <form onSubmit={handleSubmit} style={formStyle}> - <input - value={email} - onChange={(e) => setEmail(e.target.value)} - placeholder="Email" - /> - <input - password={password} - onChange={(e) => setPassword(e.target.value)} - placeholder="Password" - type="password" - /> - <button type="submit"> - {server.newServer ? 'Register' : 'Login'} - </button> - </form> - ); - }; - - const MainScreen = ({ setUser }) => { - const mapContainer = React.useRef(); - const map = React.useRef(); - - React.useEffect(() => { - map.current = new maplibregl.Map({ - container: mapContainer.current, - style: 'https://demotiles.maplibre.org/style.json', - center: [0, 0], - zoom: 1, - }); - }, []); - - const [devices, setDevices] = React.useState([]); - - React.useEffect(() => { - const fetchData = async () => { - const devicesResponse = await fetch('/api/devices'); - if (devicesResponse.ok) { - setDevices(await devicesResponse.json()); - } - } - fetchData(); - }, []); - - const [initialized, setInitialized] = React.useState(false); - const [positions, setPositions] = React.useState({}); - - React.useEffect(() => { - if (initialized) { - const url = window.location.protocol + '//' + window.location.host; - const socket = new WebSocket('ws' + url.substring(4) + '/api/socket'); - socket.onmessage = (event) => { - const data = JSON.parse(event.data); - const updatedPositions = {}; - data.positions?.forEach((p) => updatedPositions[p.deviceId] = p); - setPositions({ ...positions, ...updatedPositions }) - }; - } - }, [initialized]); - - const handleAddDevice = (event) => { - event.preventDefault(); - const fetchData = async () => { - const id = prompt('Enter device id'); - const response = await fetch('/api/devices', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - name: id, - uniqueId: id, - }), - }); - if (response.ok) { - setDevices([...devices, await response.json()]); - } - } - fetchData(); - }; - - const handleLogout = (event) => { - event.preventDefault(); - const fetchData = async () => { - await fetch('/api/session', { method: 'DELETE' }); - setUser(null); - } - fetchData(); - }; - - React.useEffect(() => { - map.current.on('load', () => { - map.current.addSource('points', { - type: 'geojson', - data: { - type: 'FeatureCollection', - features: [], - }, - }); - map.current.addLayer({ - id: 'points', - type: 'circle', - source: 'points', - }); - setInitialized(true); - }); - }, []); - - React.useEffect(() => { - map.current.getSource('points')?.setData({ - type: 'FeatureCollection', - features: Object.values(positions).map((position) => ({ - type: 'Feature', - geometry: { - type: 'Point', - coordinates: [position.longitude, position.latitude], - }, - })), - }); - }, [positions]); - - const containerStyle = { - width: '100%', - height: '100%', - display: 'flex', - }; - const deviceStyle = { - width: '320px', - marginTop: '16px', - }; - const mapStyle = { - height: '100%', - flexGrow: 1, - }; - - return ( - <div style={containerStyle}> - <div style={deviceStyle}> - <ul> - {devices?.map((device) => (<li key={device.id}>{device.name}</li>))} - <li><a href="#" onClick={handleAddDevice}>Add device</a></li> - <li><a href="#" onClick={handleLogout}>Logout</a></li> - </ul> - </div> - <div style={mapStyle} ref={mapContainer}></div> - </div> - ); - }; - - const App = () => { - const [server, setServer] = React.useState(); - const [user, setUser] = React.useState(); - - React.useEffect(() => { - const fetchData = async () => { - const serverResponse = await fetch('/api/server'); - if (serverResponse.ok) { - setServer(await serverResponse.json()); - } - const sessionResponse = await fetch('/api/session'); - if (sessionResponse.ok) { - setUser(await sessionResponse.json()); - } - } - fetchData(); - }, []); - - return user ? ( - <MainScreen - setUser={setUser} - /> - ) : server ? ( - <LoginScreen - server={server} - setServer={setServer} - setUser={setUser} - /> - ) : ''; - }; - - ReactDOM.render(<App />, document.getElementById('content')); - -</script> -</body> -</html> |