Browse Source

WIP - demo project

master
Rick Watson 5 years ago
parent
commit
a0d6524180
  1. 6
      interface/.env
  2. 2
      interface/.env.development
  3. 5
      interface/src/AppRouting.js
  4. 3
      interface/src/authentication/Authentication.js
  5. 10
      interface/src/components/MenuAppBar.js
  6. 9
      interface/src/components/SectionContent.js
  7. 1
      interface/src/constants/App.js
  8. 2
      interface/src/constants/Env.js
  9. 4
      interface/src/containers/APStatus.js
  10. 2
      interface/src/containers/ManageUsers.js
  11. 4
      interface/src/containers/SignInPage.js
  12. 22
      interface/src/project/DemoController.js
  13. 99
      interface/src/project/DemoInformation.js
  14. 37
      interface/src/project/DemoProject.js
  15. 31
      interface/src/project/ProjectMenu.js
  16. 32
      interface/src/project/ProjectRouting.js
  17. 1
      interface/src/sections/NetworkTime.js

6
interface/.env

@ -1 +1,5 @@
REACT_APP_NAME=ESP8266 React
# This is the name of your project. It appears on the sign-in page and in the menu bar.
REACT_APP_PROJECT_NAME=ESP8266 React
# This is the url path your project will be exposed under.
REACT_APP_PROJECT_PATH=project

2
interface/.env.development

@ -1 +1 @@
REACT_APP_ENDPOINT_ROOT=http://192.168.0.11/rest/
REACT_APP_ENDPOINT_ROOT=http://192.168.0.19/rest/

5
interface/src/AppRouting.js

@ -2,18 +2,18 @@ import React, { Component } from 'react';
import { Redirect, Switch } from 'react-router';
import { PROJECT_PATH } from './constants/Env';
import * as Authentication from './authentication/Authentication';
import AuthenticationWrapper from './authentication/AuthenticationWrapper';
import AuthenticatedRoute from './authentication/AuthenticatedRoute';
import UnauthenticatedRoute from './authentication/UnauthenticatedRoute';
import SignInPage from './containers/SignInPage';
import WiFiConnection from './sections/WiFiConnection';
import AccessPoint from './sections/AccessPoint';
import NetworkTime from './sections/NetworkTime';
import Security from './sections/Security';
import System from './sections/System';
import ProjectRouting from './project/ProjectRouting';
class AppRouting extends Component {
@ -31,6 +31,7 @@ class AppRouting extends Component {
<AuthenticatedRoute exact path="/ntp/*" component={NetworkTime} />
<AuthenticatedRoute exact path="/security/*" component={Security} />
<AuthenticatedRoute exact path="/system/*" component={System} />
<AuthenticatedRoute exact path={`/${PROJECT_PATH}/*`} component={ProjectRouting} />
<Redirect to="/" />
</Switch>
</AuthenticationWrapper>

3
interface/src/authentication/Authentication.js

@ -1,4 +1,5 @@
import history from '../history';
import { PROJECT_PATH } from '../constants/Env';
export const ACCESS_TOKEN = 'access_token';
export const LOGIN_PATHNAME = 'loginPathname';
@ -21,7 +22,7 @@ export function fetchLoginRedirect() {
const loginSearch = localStorage.getItem(LOGIN_SEARCH);
clearLoginRedirect();
return {
pathname: loginPathname || "/wifi/",
pathname: loginPathname || `/${PROJECT_PATH}/`,
search: (loginPathname && loginSearch) || undefined
};
}

10
interface/src/components/MenuAppBar.js

@ -30,7 +30,8 @@ import CardContent from '@material-ui/core/CardContent';
import CardActions from '@material-ui/core/CardActions';
import Avatar from '@material-ui/core/Avatar';
import { APP_NAME } from '../constants/App';
import ProjectMenu from '../project/ProjectMenu';
import { PROJECT_NAME } from '../constants/Env';
import { withAuthenticationContext } from '../authentication/Context.js';
const drawerWidth = 290;
@ -65,8 +66,7 @@ const styles = theme => ({
width: drawerWidth,
},
content: {
flexGrow: 1,
padding: theme.spacing(),
flexGrow: 1
},
authMenu: {
zIndex: theme.zIndex.tooltip,
@ -112,11 +112,13 @@ class MenuAppBar extends React.Component {
<div>
<Toolbar>
<Typography variant="h6" color="primary">
{APP_NAME}
{PROJECT_NAME}
</Typography>
<Divider absolute />
</Toolbar>
<Divider />
<ProjectMenu />
<Divider />
<List>
<ListItem to='/wifi/' selected={path.startsWith('/wifi/')} button component={Link}>
<ListItemIcon>

9
interface/src/components/SectionContent.js

@ -8,15 +8,15 @@ import Typography from '@material-ui/core/Typography';
const styles = theme => ({
content: {
padding: theme.spacing(2),
margin: theme.spacing(2),
margin: theme.spacing(3),
}
});
function SectionContent(props) {
const { children, classes, title } = props;
const { children, classes, title, titleGutter } = props;
return (
<Paper className={classes.content}>
<Typography variant="h6">
<Typography variant="h6" gutterBottom={titleGutter}>
{title}
</Typography>
{children}
@ -30,7 +30,8 @@ SectionContent.propTypes = {
PropTypes.arrayOf(PropTypes.node),
PropTypes.node
]).isRequired,
title: PropTypes.string.isRequired
title: PropTypes.string.isRequired,
titleGutter: PropTypes.bool
};
export default withStyles(styles)(SectionContent);

1
interface/src/constants/App.js

@ -1 +0,0 @@
export const APP_NAME = process.env.REACT_APP_NAME;

2
interface/src/constants/Env.js

@ -0,0 +1,2 @@
export const PROJECT_NAME = process.env.REACT_APP_PROJECT_NAME;
export const PROJECT_PATH = process.env.REACT_APP_PROJECT_PATH;

4
interface/src/containers/APStatus.js

@ -96,9 +96,7 @@ class APStatus extends Component {
return (
<div>
<List>
<Fragment>
{this.createListItems(data, classes)}
</Fragment>
{this.createListItems(data, classes)}
</List>
<Button variant="contained" color="secondary" className={classes.button} onClick={this.props.loadData}>
Refresh

2
interface/src/containers/ManageUsers.js

@ -14,7 +14,7 @@ class ManageUsers extends Component {
render() {
const { data, fetched, errorMessage } = this.props;
return (
<SectionContent title="Manage Users">
<SectionContent title="Manage Users" titleGutter>
<ManageUsersForm
userData={data}
userDataFetched={fetched}

4
interface/src/containers/SignInPage.js

@ -4,7 +4,7 @@ import { TextValidator, ValidatorForm } from 'react-material-ui-form-validator';
import Paper from '@material-ui/core/Paper';
import Typography from '@material-ui/core/Typography';
import Fab from '@material-ui/core/Fab';
import { APP_NAME } from '../constants/App';
import { PROJECT_NAME } from '../constants/Env';
import ForwardIcon from '@material-ui/icons/Forward';
import { withNotifier } from '../components/SnackbarNotification';
import { SIGN_IN_ENDPOINT } from '../constants/Endpoints';
@ -95,7 +95,7 @@ class SignInPage extends Component {
return (
<div className={classes.loginPage}>
<Paper className={classes.loginPanel}>
<Typography variant="h4">{APP_NAME}</Typography>
<Typography variant="h4">{PROJECT_NAME}</Typography>
<ValidatorForm onSubmit={this.onSubmit}>
<TextValidator
disabled={processing}

22
interface/src/project/DemoController.js

@ -0,0 +1,22 @@
import React, { Component } from 'react';
import { withStyles } from '@material-ui/core/styles';
import SectionContent from '../components/SectionContent';
const styles = theme => ({
});
class DemoController extends Component {
render() {
return (
<SectionContent title="Controller" titleGutter>
TODO - This will contain a form which controls the speed of the built in LED.
</SectionContent>
)
}
}
export default withStyles(styles)(DemoController);

99
interface/src/project/DemoInformation.js

@ -0,0 +1,99 @@
import React, { Component } from 'react';
import { withStyles } from '@material-ui/core/styles';
import Table from '@material-ui/core/Table';
import TableHead from '@material-ui/core/TableHead';
import TableCell from '@material-ui/core/TableCell';
import TableBody from '@material-ui/core/TableBody';
import TableRow from '@material-ui/core/TableRow';
import Typography from '@material-ui/core/Typography';
import SectionContent from '../components/SectionContent';
const styles = theme => ({
fileTable: {
marginBottom: theme.spacing(2)
}
});
class DemoInformation extends Component {
render() {
const { classes } = this.props;
return (
<SectionContent title="Demo Project - Blink Speed Controller" titleGutter>
<Typography variant="body1" paragraph>
This simple demo project allows you to control the blink speed of the built-in LED.
It demonstrates how the esp8266-react framework may be extended for your own IoT project.
</Typography>
<Typography variant="body1" paragraph>
It is recommended that you keep your project interface code under the 'project' directory.
This serves to isolate your project code from the from the rest of the user interface which should
simplify merges should you wish to update your project with future framework changes.
</Typography>
<Typography variant="body1" paragraph>
The demo project interface code is structured as follows:
</Typography>
<Table className={classes.fileTable}>
<TableHead>
<TableRow>
<TableCell>
File
</TableCell>
<TableCell>
Description
</TableCell>
</TableRow>
</TableHead>
<TableBody>
<TableRow>
<TableCell>
project/ProjectMenu.js
</TableCell>
<TableCell>
You can add your project's screens to the side bar here.
</TableCell>
</TableRow>
<TableRow>
<TableCell>
project/ProjectRouting.js
</TableCell>
<TableCell>
The routing which controls the screens of your project.
</TableCell>
</TableRow>
<TableRow>
<TableCell>
project/DemoProject.js
</TableCell>
<TableCell>
This screen, with tabs and tab routing.
</TableCell>
</TableRow>
<TableRow>
<TableCell>
project/DemoInformation.js
</TableCell>
<TableCell>
The demo information tab.
</TableCell>
</TableRow>
<TableRow>
<TableCell>
project/DemoController.js
</TableCell>
<TableCell>
The demo controller tab, to control the built-in LED.
</TableCell>
</TableRow>
</TableBody>
</Table>
<Typography variant="body1" paragraph>
See the project <a href="https://github.com/rjwats/esp8266-react/">README</a> for a full description of the demo project.
</Typography>
</SectionContent>
)
}
}
export default withStyles(styles)(DemoInformation);

37
interface/src/project/DemoProject.js

@ -0,0 +1,37 @@
import React, { Component } from 'react';
import { Redirect, Switch } from 'react-router-dom'
import { PROJECT_PATH } from '../constants/Env';
import MenuAppBar from '../components/MenuAppBar';
import AuthenticatedRoute from '../authentication/AuthenticatedRoute';
import DemoInformation from './DemoInformation';
import DemoController from './DemoController';
import Tabs from '@material-ui/core/Tabs';
import Tab from '@material-ui/core/Tab';
class DemoProject extends Component {
handleTabChange = (event, path) => {
this.props.history.push(path);
};
render() {
return (
<MenuAppBar sectionTitle="Demo Project">
<Tabs value={this.props.match.url} onChange={this.handleTabChange} indicatorColor="primary" textColor="primary" variant="fullWidth">
<Tab value={`/${PROJECT_PATH}/demo/information`} label="Information" />
<Tab value={`/${PROJECT_PATH}/demo/controller`} label="Controller" />
</Tabs>
<Switch>
<AuthenticatedRoute exact path={`/${PROJECT_PATH}/demo/information`} component={DemoInformation} />
<AuthenticatedRoute exact path={`/${PROJECT_PATH}/demo/controller`} component={DemoController} />
<Redirect to={`/${PROJECT_PATH}/demo/information`} />
</Switch>
</MenuAppBar>
)
}
}
export default DemoProject;

31
interface/src/project/ProjectMenu.js

@ -0,0 +1,31 @@
import React, { Component } from 'react';
import { Link, withRouter } from 'react-router-dom';
import { PROJECT_PATH } from '../constants/Env';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
import ListItemIcon from '@material-ui/core/ListItemIcon';
import ListItemText from '@material-ui/core/ListItemText';
import SettingsRemoteIcon from '@material-ui/icons/SettingsRemote';
import Divider from '@material-ui/core/Divider';
class ProjectMenu extends Component {
render() {
const path = this.props.match.url;
return (
<List>
<ListItem to={`/${PROJECT_PATH}/demo/`} selected={path.startsWith(`/${PROJECT_PATH}/demo/`)} button component={Link}>
<ListItemIcon>
<SettingsRemoteIcon />
</ListItemIcon>
<ListItemText primary="Demo Project" />
</ListItem>
</List>
)
}
}
export default withRouter(ProjectMenu);

32
interface/src/project/ProjectRouting.js

@ -0,0 +1,32 @@
import React, { Component } from 'react';
import { Redirect, Switch } from 'react-router';
import { PROJECT_PATH } from '../constants/Env';
import AuthenticatedRoute from '../authentication/AuthenticatedRoute';
import DemoProject from './DemoProject';
class ProjectRouting extends Component {
render() {
return (
<Switch>
{
/*
* Add your project page routing below.
*/
}
<AuthenticatedRoute exact path={`/${PROJECT_PATH}/demo/*`} component={DemoProject} />
{
/*
* The redirect below caters for the default project route and redirecting invalid paths.
* The "to" property must match one of the routes above for this to work correctly.
*/
}
<Redirect to={`/${PROJECT_PATH}/demo/`} />
</Switch>
)
}
}
export default ProjectRouting;

1
interface/src/sections/NetworkTime.js

@ -32,6 +32,7 @@ class NetworkTime extends Component {
</MenuAppBar>
)
}
}
export default withAuthenticationContext(NetworkTime)
Loading…
Cancel
Save