import React, { useState, useEffect } from 'react';
import * as leaflet from 'leaflet';
import { MapContainer, Polyline, TileLayer, useMap } from 'react-leaflet';
import Datetime from 'react-datetime';
import 'react-datetime/css/react-datetime.css';
import axios from 'axios';
import moment from 'moment-timezone';
import RangeSlider from 'react-range-slider-input';
import './App.css';
import 'leaflet/dist/leaflet.css';
import 'react-range-slider-input/dist/style.css';
let tzcache = {};
// num: number of steps per duration
// secs: number of seconds per step
const durations = [
{id: 0, len: 'Day', win: '1m', full: '1 min', delta: [1, 'days'], format: 'HH', num: 1440, secs: 60},
{id: 1, len: 'Week', win: '3m', full: '3 min', delta: [7, 'days'], format: 'HH', num: 3360, secs: 180},
{id: 2, len: 'Month', win: '10m', full: '10 min', delta: [1, 'months'], format: 'D', num: 4380, secs: 600},
{id: 3, len: 'Year', win: '2h', full: '2 hour', delta: [1, 'years'], format: 'M/D', num: 4380, secs: 7200},
];
function useSensor(measurement, name, end, duration) {
const [data, setData] = useState(false);
const [loading, setLoading] = useState(false);
useEffect(() => {
const get = async() => {
setLoading(true);
try {
const api_key = localStorage.getItem('api_key', 'null');
const params = { end: end.unix(), duration: duration.len.toLowerCase(), window: duration.win, api_key: api_key };
const res = await axios.get(
'https://sensors-api.dns.t0.vc/history/'+measurement+'/'+name,
{ params: params },
);
setData((d) => (res.data));
setLoading(false);
} catch (error) {
console.log(error);
}
};
get();
}, [end, duration]);
return [data, loading];
};
function Owntracks({end, duration, range}) {
const [data, loading] = useSensor('owntracks', 'OwnTracks', end, duration);
const coords = data.length ? data.filter(x => !range || (x.time >= range[0] && x.time <= range[1])).map(({ lat, lon }) => [lat, lon]).filter(([lat, lon]) => lat !== null || lon !== null) : [];
const handleSubmit = (e) => {
e.preventDefault();
const api_key = e.target[0].value;
localStorage.setItem('api_key', api_key);
}
return (
<>
{loading ?
Loading...
:
coords.length ?
:
<>
No data
>
}
>
);
}
function Graphs({end, duration, range}) {
return (
);
}
function Menu({duration, setDuration, end, setEnd, range, setRange}) {
const [submenu, setSubmenu] = useState(false);
const [showRange, setShowRange] = useState(false);
const chooseDuration = (x) => {
setSubmenu(false);
setRange(false);
setDuration(x);
};
const chooseEnd = (x) => {
setSubmenu(false);
const newEnd = x.add(...duration.delta);
setRange(false);
setEnd(newEnd);
};
const chooseNow = (x) => {
setSubmenu(false);
setRange(false);
setEnd(moment());
};
const next = () => {
setSubmenu(false);
setRange(false);
setEnd(prevEnd => moment(prevEnd).add(...duration.delta));
}
const prev = () => {
setSubmenu(false);
setRange(false);
setEnd(prevEnd => moment(prevEnd).subtract(...duration.delta));
}
const onSlider = (slider) => {
console.log(slider);
// good luck remembering how this works
const lowOffset = slider[0] * duration.secs - duration.num * duration.secs;
const highOffset = slider[1] * duration.secs - duration.num * duration.secs;
const low = moment.unix(end.unix() + lowOffset);
const high = moment.unix(end.unix() + highOffset);
const lowStr = low.utc().format('YYYY-MM-DDTHH:mm:ss[Z]');
const highStr = high.utc().format('YYYY-MM-DDTHH:mm:ss[Z]');
console.log(lowStr, highStr);
setRange([lowStr, highStr]);
}
return (
{showRange &&
{moment(range[0]).format('lll')} - {moment(range[1]).format('lll')}
}
{submenu ?
{submenu === 'end' &&
<>
Choose start date:
chooseEnd(x)}
/>
>
}
{submenu === 'duration' &&
<>
Choose duration:
{durations.map(x =>
)}
>
}
:
setShowRange(true)}
onThumbDragEnd={() => setShowRange(false)}
onRangeDragStart={() => setShowRange(true)}
onRangeDragEnd={() => setShowRange(false)}
/>
}
);
}
function App() {
const [duration, setDuration] = useState(durations[0]);
const [end, setEnd] = useState(moment());
const [range, setRange] = useState(false);
return (
);
}
export default App;