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;