WIP - demo project
This commit is contained in:
		| @@ -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 | ||||
|   | ||||
| @@ -1 +1 @@ | ||||
| REACT_APP_ENDPOINT_ROOT=http://192.168.0.11/rest/ | ||||
| REACT_APP_ENDPOINT_ROOT=http://192.168.0.19/rest/ | ||||
|   | ||||
| @@ -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> | ||||
|   | ||||
| @@ -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 | ||||
|   }; | ||||
| } | ||||
|   | ||||
| @@ -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> | ||||
|   | ||||
| @@ -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 +0,0 @@ | ||||
| export const APP_NAME = process.env.REACT_APP_NAME; | ||||
							
								
								
									
										2
									
								
								interface/src/constants/Env.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								interface/src/constants/Env.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| export const PROJECT_NAME = process.env.REACT_APP_PROJECT_NAME; | ||||
| export const PROJECT_PATH = process.env.REACT_APP_PROJECT_PATH; | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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,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
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								interface/src/project/DemoController.js
									
									
									
									
									
										Normal file
									
								
							| @@ -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
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								interface/src/project/DemoInformation.js
									
									
									
									
									
										Normal file
									
								
							| @@ -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
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								interface/src/project/DemoProject.js
									
									
									
									
									
										Normal file
									
								
							| @@ -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
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								interface/src/project/ProjectMenu.js
									
									
									
									
									
										Normal file
									
								
							| @@ -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
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								interface/src/project/ProjectRouting.js
									
									
									
									
									
										Normal file
									
								
							| @@ -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; | ||||
| @@ -32,6 +32,7 @@ class NetworkTime extends Component { | ||||
|       </MenuAppBar> | ||||
|     ) | ||||
|   } | ||||
|  | ||||
| } | ||||
|  | ||||
| export default withAuthenticationContext(NetworkTime) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user