From b75f41963e9efb3fd0d0f7c1ee9c9d0003899349 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 3 Sep 2018 20:46:57 +1200 Subject: Create initial React project --- modern/src/index.js | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 modern/src/index.js (limited to 'modern/src/index.js') diff --git a/modern/src/index.js b/modern/src/index.js new file mode 100644 index 00000000..fae3e350 --- /dev/null +++ b/modern/src/index.js @@ -0,0 +1,8 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import './index.css'; +import App from './App'; +import registerServiceWorker from './registerServiceWorker'; + +ReactDOM.render(, document.getElementById('root')); +registerServiceWorker(); -- cgit v1.2.3 From da578b6ac7ba43b8d437aebbfe36777278370e5e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 3 Sep 2018 22:51:20 +1200 Subject: First hacky implementation --- modern/package.json | 3 +++ modern/public/favicon.ico | Bin 3870 -> 15086 bytes modern/public/index.html | 33 +++++++------------------------- modern/src/App.css | 28 --------------------------- modern/src/App.js | 22 ++++++++++++---------- modern/src/MainMap.js | 29 ++++++++++++++++++++++++++++ modern/src/MainToolbar.js | 47 ++++++++++++++++++++++++++++++++++++++++++++++ modern/src/index.css | 5 ----- modern/src/index.js | 1 - modern/src/logo.svg | 7 ------- 10 files changed, 98 insertions(+), 77 deletions(-) delete mode 100644 modern/src/App.css create mode 100644 modern/src/MainMap.js create mode 100644 modern/src/MainToolbar.js delete mode 100644 modern/src/index.css delete mode 100644 modern/src/logo.svg (limited to 'modern/src/index.js') diff --git a/modern/package.json b/modern/package.json index 6dea9060..5dd4cb93 100644 --- a/modern/package.json +++ b/modern/package.json @@ -4,7 +4,10 @@ "private": true, "dependencies": { "@material-ui/core": "^3.0.1", + "@material-ui/icons": "^3.0.1", + "leaflet": "^1.3.4", "react": "^16.4.2", + "react-container-dimensions": "^1.4.1", "react-dom": "^16.4.2", "react-leaflet": "^2.0.1", "react-scripts": "1.1.5" diff --git a/modern/public/favicon.ico b/modern/public/favicon.ico index a11777cc..6be99dda 100644 Binary files a/modern/public/favicon.ico and b/modern/public/favicon.ico differ diff --git a/modern/public/index.html b/modern/public/index.html index ed0ebafa..ac6d8d5e 100644 --- a/modern/public/index.html +++ b/modern/public/index.html @@ -2,39 +2,20 @@ - + - - - React App + + + + + Traccar - +
- diff --git a/modern/src/App.css b/modern/src/App.css deleted file mode 100644 index c5c6e8a6..00000000 --- a/modern/src/App.css +++ /dev/null @@ -1,28 +0,0 @@ -.App { - text-align: center; -} - -.App-logo { - animation: App-logo-spin infinite 20s linear; - height: 80px; -} - -.App-header { - background-color: #222; - height: 150px; - padding: 20px; - color: white; -} - -.App-title { - font-size: 1.5em; -} - -.App-intro { - font-size: large; -} - -@keyframes App-logo-spin { - from { transform: rotate(0deg); } - to { transform: rotate(360deg); } -} diff --git a/modern/src/App.js b/modern/src/App.js index 203067e4..204c89ee 100644 --- a/modern/src/App.js +++ b/modern/src/App.js @@ -1,18 +1,20 @@ import React, { Component } from 'react'; -import logo from './logo.svg'; -import './App.css'; +import ContainerDimensions from 'react-container-dimensions'; +import MainToobar from './MainToolbar'; +import MainMap from './MainMap'; class App extends Component { render() { return ( -
-
- logo -

Welcome to React

-
-

- To get started, edit src/App.js and save to reload. -

+
+
+ +
+
+ + + +
); } diff --git a/modern/src/MainMap.js b/modern/src/MainMap.js new file mode 100644 index 00000000..27c58bca --- /dev/null +++ b/modern/src/MainMap.js @@ -0,0 +1,29 @@ +import React, { Component } from 'react'; +import { Map, TileLayer, Marker, Popup } from 'react-leaflet'; + +class MainMap extends Component { + state = { + lat: 51.505, + lng: -0.09, + zoom: 13, + } + + render() { + const position = [this.state.lat, this.state.lng] + return ( + + + + + A pretty CSS3 popup.
Easily customizable. +
+
+
+ ) + } +} + +export default MainMap; diff --git a/modern/src/MainToolbar.js b/modern/src/MainToolbar.js new file mode 100644 index 00000000..e8294ab1 --- /dev/null +++ b/modern/src/MainToolbar.js @@ -0,0 +1,47 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import AppBar from '@material-ui/core/AppBar'; +import Toolbar from '@material-ui/core/Toolbar'; +import Typography from '@material-ui/core/Typography'; +import Button from '@material-ui/core/Button'; +import IconButton from '@material-ui/core/IconButton'; +import MenuIcon from '@material-ui/icons/Menu'; + +const styles = { + root: { + flexGrow: 1, + }, + flex: { + flexGrow: 1, + }, + menuButton: { + marginLeft: -12, + marginRight: 20, + }, +}; + +function MainToobar(props) { + const { classes } = props; + return ( +
+ + + + + + + Traccar + + + + +
+ ); +} + +MainToobar.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(MainToobar); diff --git a/modern/src/index.css b/modern/src/index.css deleted file mode 100644 index b4cc7250..00000000 --- a/modern/src/index.css +++ /dev/null @@ -1,5 +0,0 @@ -body { - margin: 0; - padding: 0; - font-family: sans-serif; -} diff --git a/modern/src/index.js b/modern/src/index.js index fae3e350..917d6518 100644 --- a/modern/src/index.js +++ b/modern/src/index.js @@ -1,6 +1,5 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import './index.css'; import App from './App'; import registerServiceWorker from './registerServiceWorker'; diff --git a/modern/src/logo.svg b/modern/src/logo.svg deleted file mode 100644 index 6b60c104..00000000 --- a/modern/src/logo.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - -- cgit v1.2.3 From c821e4722da493c5408bcb505599239d687453c6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 4 Sep 2018 16:44:14 +1200 Subject: Implement login logic --- modern/package.json | 6 ++-- modern/src/App.js | 26 +++++++-------- modern/src/LoginPage.js | 87 +++++++++++++++++++++++++++++++++++++++++++++++++ modern/src/MainPage.js | 49 ++++++++++++++++++++++++++++ modern/src/index.js | 8 ++++- 5 files changed, 159 insertions(+), 17 deletions(-) create mode 100644 modern/src/LoginPage.js create mode 100644 modern/src/MainPage.js (limited to 'modern/src/index.js') diff --git a/modern/package.json b/modern/package.json index 5dd4cb93..94822a62 100644 --- a/modern/package.json +++ b/modern/package.json @@ -10,12 +10,14 @@ "react-container-dimensions": "^1.4.1", "react-dom": "^16.4.2", "react-leaflet": "^2.0.1", - "react-scripts": "1.1.5" + "react-router-dom": "^4.3.1", + "react-scripts": "^1.1.5" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test --env=jsdom", "eject": "react-scripts eject" - } + }, + "proxy": "http://localhost:8082" } diff --git a/modern/src/App.js b/modern/src/App.js index 204c89ee..31b8b69b 100644 --- a/modern/src/App.js +++ b/modern/src/App.js @@ -1,21 +1,19 @@ -import React, { Component } from 'react'; -import ContainerDimensions from 'react-container-dimensions'; -import MainToobar from './MainToolbar'; -import MainMap from './MainMap'; +import React, { Component, Fragment } from 'react'; +import { Switch, Route } from 'react-router-dom' +import CssBaseline from '@material-ui/core/CssBaseline'; +import MainPage from './MainPage'; +import LoginPage from './LoginPage'; class App extends Component { render() { return ( -
-
- -
-
- - - -
-
+ + + + + + + ); } } diff --git a/modern/src/LoginPage.js b/modern/src/LoginPage.js new file mode 100644 index 00000000..8b8401a8 --- /dev/null +++ b/modern/src/LoginPage.js @@ -0,0 +1,87 @@ +import React, { Component } from 'react'; +import Button from '@material-ui/core/Button'; +import FormControl from '@material-ui/core/FormControl'; +import Input from '@material-ui/core/Input'; +import InputLabel from '@material-ui/core/InputLabel'; +import Paper from '@material-ui/core/Paper'; +import Typography from '@material-ui/core/Typography'; +import withStyles from '@material-ui/core/styles/withStyles'; + +const styles = theme => ({ + layout: { + width: 'auto', + display: 'block', // Fix IE11 issue. + marginLeft: theme.spacing.unit * 3, + marginRight: theme.spacing.unit * 3, + [theme.breakpoints.up(400 + theme.spacing.unit * 3 * 2)]: { + width: 400, + marginLeft: 'auto', + marginRight: 'auto', + }, + }, + paper: { + marginTop: theme.spacing.unit * 8, + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + padding: `${theme.spacing.unit * 2}px ${theme.spacing.unit * 3}px ${theme.spacing.unit * 3}px`, + }, + submit: { + marginTop: theme.spacing.unit * 3, + }, +}); + +class LoginPage extends Component { + constructor(props) { + super(props); + this.state = { + failed: false + }; + this.handleSubmit = this.handleSubmit.bind(this); + } + + handleSubmit() { + console.log(); + fetch("/api/session", { + method: "POST", + body: new URLSearchParams(`email=admin&password=admin`) + }).then(response => { + if (response.ok) { + this.props.history.push('/'); // TODO avoid calling sessions twice + } else { + this.setState({ + failed: true + }); + } + }); + } + + render() { + const { classes } = this.props; + const { failed } = this.state; + return ( +
+ + Traccar + { + failed && + Login failed + } + + Email Address + + + + Password + + + + +
+ ); + } +} + +export default withStyles(styles)(LoginPage); diff --git a/modern/src/MainPage.js b/modern/src/MainPage.js new file mode 100644 index 00000000..02d98dca --- /dev/null +++ b/modern/src/MainPage.js @@ -0,0 +1,49 @@ +import React, { Component } from 'react'; +import ContainerDimensions from 'react-container-dimensions'; +import MainToobar from './MainToolbar'; +import MainMap from './MainMap'; + +class MainPage extends Component { + constructor(props) { + super(props); + this.state = { + loading: true + }; + } + + componentDidMount() { + fetch('/api/session').then(response => { + if (response.ok) { + this.setState({ + loading: false + }); + } else { + this.props.history.push('/login'); + } + }); + } + + render() { + const { loading } = this.state; + if (loading) { + return ( +
Loading...
+ ); + } else { + return ( +
+
+ +
+
+ + + +
+
+ ); + } + } +} + +export default MainPage; diff --git a/modern/src/index.js b/modern/src/index.js index 917d6518..016a4af1 100644 --- a/modern/src/index.js +++ b/modern/src/index.js @@ -1,7 +1,13 @@ import React from 'react'; import ReactDOM from 'react-dom'; +import { BrowserRouter } from 'react-router-dom' import App from './App'; import registerServiceWorker from './registerServiceWorker'; -ReactDOM.render(, document.getElementById('root')); +ReactDOM.render(( + + + +), document.getElementById('root')); + registerServiceWorker(); -- cgit v1.2.3 From 72aa50650203d6db0b17de59bfd98c9d5b06e3e7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 7 Sep 2018 16:09:01 +1200 Subject: Add redux and load positions --- modern/package.json | 4 +++- modern/src/MainMap.js | 28 +++++++++++++++++++--------- modern/src/SocketContoller.js | 7 ++++--- modern/src/actions/index.js | 14 ++++++++++++++ modern/src/index.js | 13 ++++++++++--- modern/src/reducers/index.js | 18 ++++++++++++++++++ 6 files changed, 68 insertions(+), 16 deletions(-) create mode 100644 modern/src/actions/index.js create mode 100644 modern/src/reducers/index.js (limited to 'modern/src/index.js') diff --git a/modern/package.json b/modern/package.json index 0c1a1cbb..457650c9 100644 --- a/modern/package.json +++ b/modern/package.json @@ -10,8 +10,10 @@ "react-container-dimensions": "^1.4.1", "react-dom": "^16.4.2", "react-leaflet": "^2.0.1", + "react-redux": "^5.0.7", "react-router-dom": "^4.3.1", - "react-scripts": "^1.1.5" + "react-scripts": "^1.1.5", + "redux": "^4.0.0" }, "scripts": { "start": "react-scripts start", diff --git a/modern/src/MainMap.js b/modern/src/MainMap.js index 3388d670..0e93ddba 100644 --- a/modern/src/MainMap.js +++ b/modern/src/MainMap.js @@ -1,28 +1,38 @@ import React, { Component } from 'react'; import { Map, TileLayer, Marker, Popup } from 'react-leaflet'; +import { connect } from 'react-redux' + +const mapStateToProps = state => ({ + positions: state.positions +}); class MainMap extends Component { state = { - lat: 51.505, - lng: -0.09, - zoom: 13, + lat: 0, + lng: 0, + zoom: 3, } render() { const position = [this.state.lat, this.state.lng] + + const markers = this.props.positions.map((position) => + + + A pretty CSS3 popup.
Easily customizable. +
+
+ ); + return ( - - - A pretty CSS3 popup.
Easily customizable. -
-
+ {markers}
) } } -export default MainMap; +export default connect(mapStateToProps)(MainMap); diff --git a/modern/src/SocketContoller.js b/modern/src/SocketContoller.js index c07fcff0..fe686ed8 100644 --- a/modern/src/SocketContoller.js +++ b/modern/src/SocketContoller.js @@ -1,4 +1,6 @@ import { Component } from 'react'; +import { connect } from 'react-redux'; +import { updatePositions } from './actions'; class SocketController extends Component { connectSocket() { @@ -12,8 +14,7 @@ class SocketController extends Component { socket.onmessage = (event) => { const data = JSON.parse(event.data); if (data.positions) { - // TODO update positions - console.log(data.positions); + this.props.dispatch(updatePositions(data.positions)); } } } @@ -27,4 +28,4 @@ class SocketController extends Component { } } -export default SocketController; +export default connect()(SocketController); diff --git a/modern/src/actions/index.js b/modern/src/actions/index.js new file mode 100644 index 00000000..8ef49fa8 --- /dev/null +++ b/modern/src/actions/index.js @@ -0,0 +1,14 @@ +export const updateDevices = devices => ({ + type: 'UPDATE_DEVICES', + devices +}) + +export const updatePositions = positions => ({ + type: 'UPDATE_POSITIONS', + positions +}); + +export const updateEvents = events => ({ + type: 'UPDATE_EVENTS', + events +}) diff --git a/modern/src/index.js b/modern/src/index.js index 016a4af1..66d3b048 100644 --- a/modern/src/index.js +++ b/modern/src/index.js @@ -1,13 +1,20 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { BrowserRouter } from 'react-router-dom' +import { Provider } from 'react-redux'; +import { createStore } from 'redux' +import rootReducer from './reducers'; import App from './App'; import registerServiceWorker from './registerServiceWorker'; +const store = createStore(rootReducer); + ReactDOM.render(( - - - + + + + + ), document.getElementById('root')); registerServiceWorker(); diff --git a/modern/src/reducers/index.js b/modern/src/reducers/index.js new file mode 100644 index 00000000..b9c94771 --- /dev/null +++ b/modern/src/reducers/index.js @@ -0,0 +1,18 @@ +const initialState = { + devices: [], + positions: [], + events: [] +}; + +function rootReducer(state = initialState, action) { + switch (action.type) { + case 'UPDATE_POSITIONS': + return Object.assign({}, { + positions: [...state.positions, ...action.positions] + }); + default: + return state; + } +} + +export default rootReducer -- cgit v1.2.3 From 268ec5bb5214ef0b1e1a1dcb837ae149fe9dcb83 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 22 Mar 2020 12:16:39 -0700 Subject: Include Roboto locally --- modern/package.json | 3 ++- modern/src/index.js | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'modern/src/index.js') diff --git a/modern/package.json b/modern/package.json index d4ce9550..04c1b4aa 100644 --- a/modern/package.json +++ b/modern/package.json @@ -14,7 +14,8 @@ "react-redux": "^7.2.0", "react-router-dom": "^5.1.2", "react-scripts": "^3.4.0", - "redux": "^4.0.5" + "redux": "^4.0.5", + "typeface-roboto": "0.0.75" }, "scripts": { "start": "react-scripts start", diff --git a/modern/src/index.js b/modern/src/index.js index 66d3b048..527a4d69 100644 --- a/modern/src/index.js +++ b/modern/src/index.js @@ -1,3 +1,4 @@ +import 'typeface-roboto' import React from 'react'; import ReactDOM from 'react-dom'; import { BrowserRouter } from 'react-router-dom' -- cgit v1.2.3