Merge branch 'develop' of https://git.it.hs-heilbronn.de/volkmann/smart_garden_server into auribest_dev
This commit is contained in:
commit
3ae342ad3c
@ -1,9 +1,36 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
import { Container, Row, Col} from 'react-bootstrap';
|
||||||
|
|
||||||
|
|
||||||
export default function About() {
|
export default function About() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<>
|
||||||
About
|
<Container>
|
||||||
</div>
|
<Row className="justify-content-md-center">
|
||||||
|
<Col md="auto">
|
||||||
|
<h1>About</h1>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row className="justify-content-md-center">
|
||||||
|
<a>This is the frontend for the SmartGarden project in Embedded Systems.</a>
|
||||||
|
</Row>
|
||||||
|
|
||||||
|
<hr style={{
|
||||||
|
color: '#000000',
|
||||||
|
backgroundColor: '#000000',
|
||||||
|
height: .5,
|
||||||
|
borderColor : '#000000'
|
||||||
|
}}/>
|
||||||
|
|
||||||
|
<Row className="justify-content-md-center">
|
||||||
|
<a>Created by</a>
|
||||||
|
</Row>
|
||||||
|
<Row className="justify-content-md-center">
|
||||||
|
<a>Timo Volkmann, Andrés Uribe Stengel, Sebastian Herzog and Maximilian Seyfried</a>
|
||||||
|
</Row>
|
||||||
|
|
||||||
|
|
||||||
|
</Container>
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
85
imports/ui/ActivatePlant.jsx
Normal file
85
imports/ui/ActivatePlant.jsx
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { Button, Form} from 'react-bootstrap';
|
||||||
|
|
||||||
|
class ActivatePlant extends React.Component{
|
||||||
|
|
||||||
|
constructor(props){
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
name: '',
|
||||||
|
isActivationButtonDisabled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleChange = (e) => {
|
||||||
|
// console.log(e.target.id, e.target.value);
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (activePlant !== 'undefined'){
|
||||||
|
if (activePlant !== this.state.name) {
|
||||||
|
this.setState({
|
||||||
|
isActivationButtonDisabled: false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
[e.target.id]: e.target.value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// search for arrow function for further syntax knowledge
|
||||||
|
handleActivation = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
let activatedPlant
|
||||||
|
this.props.plants.map(plant =>{
|
||||||
|
if (plant.name === this.state.name){
|
||||||
|
activatedPlant = plant
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// activePlant = activatedPlant.name
|
||||||
|
|
||||||
|
this.props.activatePlant(activatedPlant)
|
||||||
|
|
||||||
|
/*
|
||||||
|
this.setState({
|
||||||
|
isActivationButtonDisabled: true
|
||||||
|
})*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
render (){
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{
|
||||||
|
this.props.plants.length !== 0 ?
|
||||||
|
<Form onSubmit={this.handleActivation}>
|
||||||
|
<Form.Group>
|
||||||
|
<Form.Label>Active plant:</Form.Label>
|
||||||
|
<Form.Control
|
||||||
|
as="select"
|
||||||
|
type="text"
|
||||||
|
id="name"
|
||||||
|
value={this.state.name}
|
||||||
|
onChange={this.handleChange}
|
||||||
|
>
|
||||||
|
<option></option>
|
||||||
|
{this.props.plants.map((plant, index) =>{
|
||||||
|
return <option key={index} value={plant.name}>{plant.name}</option>
|
||||||
|
})}
|
||||||
|
</Form.Control>
|
||||||
|
</Form.Group>
|
||||||
|
<Button type={"submit"} disabled={this.state.isActivationButtonDisabled}>Activate</Button>
|
||||||
|
</Form>
|
||||||
|
:null
|
||||||
|
}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ActivatePlant;
|
||||||
|
|
||||||
73
imports/ui/AddPlant.jsx
Normal file
73
imports/ui/AddPlant.jsx
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { Button, Form, Container, Row, Col, Table } from 'react-bootstrap';
|
||||||
|
|
||||||
|
class AddPlant extends React.Component{
|
||||||
|
|
||||||
|
constructor(props){
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
name: '',
|
||||||
|
type: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleChange = (e) => {
|
||||||
|
// console.log(e.target.id, e.target.value); // e.target.id reference to the state which is changed
|
||||||
|
this.setState({
|
||||||
|
[e.target.id]: e.target.value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// search for arrow function for further syntax knowledge
|
||||||
|
handleSubmit = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
//console.log(this.state)
|
||||||
|
|
||||||
|
this.props.addPlant(this.state)
|
||||||
|
|
||||||
|
this.setState({ // reset state
|
||||||
|
name: '',
|
||||||
|
type: ''
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
render (){
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Form onSubmit={this.handleSubmit}>
|
||||||
|
<Form.Group>
|
||||||
|
<Form.Label>Name:</Form.Label>
|
||||||
|
<Form.Control
|
||||||
|
type="text"
|
||||||
|
id="name"
|
||||||
|
value={this.state.name}
|
||||||
|
autoFocus ref={(input) => {this.nameInput=(input)}}
|
||||||
|
placeholder="plant"
|
||||||
|
onChange={this.handleChange} />
|
||||||
|
</Form.Group>
|
||||||
|
<Form.Group>
|
||||||
|
<Form.Label>Type:</Form.Label>
|
||||||
|
<Form.Control
|
||||||
|
as="select"
|
||||||
|
type="text"
|
||||||
|
id="type"
|
||||||
|
value={this.state.type}
|
||||||
|
onChange={this.handleChange}
|
||||||
|
>
|
||||||
|
<option></option>
|
||||||
|
{this.props.typeArray.map((type, index) =>{
|
||||||
|
return <option key={index} value={type}>{type}</option>
|
||||||
|
})}
|
||||||
|
</Form.Control>
|
||||||
|
</Form.Group>
|
||||||
|
<Button type={"submit"}>Submit</Button>
|
||||||
|
</Form>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AddPlant;
|
||||||
|
|
||||||
@ -24,7 +24,9 @@ function App() {
|
|||||||
<Route path="/" exact>
|
<Route path="/" exact>
|
||||||
<Home dummyData={exampleData}></Home>
|
<Home dummyData={exampleData}></Home>
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/settings" component={Settings}></Route>
|
<Route path="/settings">
|
||||||
|
<Settings></Settings>
|
||||||
|
</Route>
|
||||||
<Route path="/about" component={About}></Route>
|
<Route path="/about" component={About}></Route>
|
||||||
</Switch>
|
</Switch>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
|
|||||||
@ -1,18 +1,23 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { Navbar, Nav, NavDropdown } from 'react-bootstrap';
|
import { Navbar, Nav, NavDropdown } from 'react-bootstrap';
|
||||||
|
|
||||||
|
//import logo from '../../client/public/SmartGarden.svg';
|
||||||
|
|
||||||
export default function NavigationBar() {
|
export default function NavigationBar() {
|
||||||
return (
|
return (
|
||||||
<Navbar collapseOnSelect expand="lg" bg="light" variant="light">
|
<Navbar collapseOnSelect expand="lg" bg="light" variant="light">
|
||||||
<Navbar.Brand href="/">
|
<Navbar.Brand href="/">
|
||||||
|
{/* NOT POSSIBLE IN METEOR, only from the DB -> https://forums.meteor.com/t/importing-assets-image/30266/2
|
||||||
|
|
||||||
<img
|
<img
|
||||||
src="SmartGarden.svg"
|
src={logo}
|
||||||
width="30"
|
width="30"
|
||||||
height="30"
|
height="30"
|
||||||
className="d-inline-block align-top"
|
className="d-inline-block align-top"
|
||||||
rounded="true"
|
rounded="true"
|
||||||
alt="SmartGarden"
|
alt="SmartGarden"
|
||||||
/>{' '}
|
/>{' '}
|
||||||
|
*/}
|
||||||
SmartGarden
|
SmartGarden
|
||||||
</Navbar.Brand>
|
</Navbar.Brand>
|
||||||
<Navbar.Toggle aria-controls="responsive-navbar-nav" />
|
<Navbar.Toggle aria-controls="responsive-navbar-nav" />
|
||||||
@ -20,13 +25,16 @@ export default function NavigationBar() {
|
|||||||
<Nav className="mr-auto">
|
<Nav className="mr-auto">
|
||||||
<Nav.Link href="/settings">Settings</Nav.Link>
|
<Nav.Link href="/settings">Settings</Nav.Link>
|
||||||
<Nav.Link href="/about">About</Nav.Link>
|
<Nav.Link href="/about">About</Nav.Link>
|
||||||
|
{
|
||||||
|
/*
|
||||||
<NavDropdown title="Dropdown" id="collasible-nav-dropdown">
|
<NavDropdown title="Dropdown" id="collasible-nav-dropdown">
|
||||||
<NavDropdown.Item href="#action/3.1">Action</NavDropdown.Item>
|
<NavDropdown.Item href="#action/3.1">Action</NavDropdown.Item>
|
||||||
<NavDropdown.Item href="#action/3.2">Another action</NavDropdown.Item>
|
<NavDropdown.Item href="#action/3.2">Another action</NavDropdown.Item>
|
||||||
<NavDropdown.Item href="#action/3.3">Something</NavDropdown.Item>
|
<NavDropdown.Item href="#action/3.3">Something</NavDropdown.Item>
|
||||||
<NavDropdown.Divider />
|
<NavDropdown.Divider />
|
||||||
<NavDropdown.Item href="#action/3.4">Separated link</NavDropdown.Item>
|
<NavDropdown.Item href="#action/3.4">Separated link</NavDropdown.Item>
|
||||||
</NavDropdown>
|
</NavDropdown>*/
|
||||||
|
}
|
||||||
</Nav>
|
</Nav>
|
||||||
</Navbar.Collapse>
|
</Navbar.Collapse>
|
||||||
</Navbar>
|
</Navbar>
|
||||||
|
|||||||
37
imports/ui/Plants.jsx
Normal file
37
imports/ui/Plants.jsx
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { Table, Button } from 'react-bootstrap';
|
||||||
|
|
||||||
|
const Plants = ({plants, deletePlant}) => {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{
|
||||||
|
plants.length !== 0 ?
|
||||||
|
<Table striped bordered hover>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Plant name</th>
|
||||||
|
<th>Plant type</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{
|
||||||
|
plants.map((plant, index) => {
|
||||||
|
return <tr key={index}>
|
||||||
|
<td>{plant.name}</td>
|
||||||
|
<td>{plant.type}</td>
|
||||||
|
<td><Button onClick={()=>{deletePlant(plant.id)}}>Delete</Button></td>
|
||||||
|
</tr>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
</Table>
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Plants
|
||||||
@ -1,26 +1,43 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
import { Container, Row, Col} from 'react-bootstrap';
|
||||||
|
|
||||||
import { Button, Form, Container, Row, Col, Table } from 'react-bootstrap';
|
import AddPlant from './AddPlant'
|
||||||
|
import Plants from './Plants'
|
||||||
|
import ActivatePlant from './ActivatePlant'
|
||||||
|
|
||||||
class Settings extends React.Component{
|
class Settings extends React.Component{
|
||||||
|
|
||||||
constructor(props){
|
constructor(props){
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
name: '',
|
|
||||||
type: '',
|
|
||||||
dirt: '',
|
|
||||||
plants: [],
|
plants: [],
|
||||||
types: ['Chile', 'Mint'], // hardcoded for now
|
types: ['Chile', 'Mint'], // hardcoded for now
|
||||||
dirts: ['Vegetable Soil', 'Potting Soil'], // hardcoded for now
|
|
||||||
updateId: -1,
|
|
||||||
btnName: 'submit'
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount(){
|
// pass this function to the addplant comp as a prop
|
||||||
// fetch data from db here
|
addPlant = (plant) => {
|
||||||
|
plant.id = this.state.plants.length + 1 // TODO rework
|
||||||
|
|
||||||
|
let plants = [...this.state.plants, plant]; // create a copy of the array and add the new plant to it
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
plants: plants
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
deletePlant = (id) => {
|
||||||
|
let plants = this.state.plants.filter(plant =>{ // callback function
|
||||||
|
return plant.id !== id // when it returns false (the id is the same), it filters this object out of the array
|
||||||
|
})
|
||||||
|
this.setState({
|
||||||
|
plants: plants
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
activatePlant = (plant) => {
|
||||||
|
console.log('The plant ' + plant.name + ' will be monitored')
|
||||||
|
// TODO head for activate logic
|
||||||
}
|
}
|
||||||
|
|
||||||
render(){
|
render(){
|
||||||
@ -38,50 +55,10 @@ class Settings extends React.Component{
|
|||||||
|
|
||||||
<br></br>
|
<br></br>
|
||||||
|
|
||||||
{
|
<AddPlant
|
||||||
this.state.updateId >= 0 | this.state.plants.length === 0? // show the form only if we edit the plant or there is no plant set yet
|
addPlant={this.addPlant}
|
||||||
<Form onSubmit={this.handleSubmit}>
|
typeArray={this.state.types}
|
||||||
<Form.Group controlId="exampleForm.ControlInput1">
|
></AddPlant>
|
||||||
<Form.Label>Name</Form.Label>
|
|
||||||
<Form.Control
|
|
||||||
type="text"
|
|
||||||
value={this.state.name}
|
|
||||||
autoFocus ref={(input) => {this.nameInput=(input)}}
|
|
||||||
placeholder="plant"
|
|
||||||
onChange={(e)=>this.setState({name:e.target.value})} />
|
|
||||||
</Form.Group>
|
|
||||||
<Form.Group controlId="exampleForm.ControlSelect1">
|
|
||||||
<Form.Label>Type</Form.Label>
|
|
||||||
<Form.Control
|
|
||||||
as="select"
|
|
||||||
type="text"
|
|
||||||
value={this.state.type}
|
|
||||||
onChange={(e)=>this.setState({type:e.target.value})}
|
|
||||||
>
|
|
||||||
<option></option>
|
|
||||||
{this.state.types.map((type, index) => {
|
|
||||||
return <option key={index} value={type}>{type}</option>
|
|
||||||
})}
|
|
||||||
</Form.Control>
|
|
||||||
</Form.Group>
|
|
||||||
<Form.Group controlId="exampleForm.ControlSelect1">
|
|
||||||
<Form.Label>Dirt</Form.Label>
|
|
||||||
<Form.Control
|
|
||||||
as="select"
|
|
||||||
type="text"
|
|
||||||
value={this.state.dirt}
|
|
||||||
onChange={(e)=>this.setState({dirt:e.target.value})}
|
|
||||||
>
|
|
||||||
<option></option>
|
|
||||||
{this.state.dirts.map((dirt, index) => {
|
|
||||||
return <option key={index}>{dirt}</option>
|
|
||||||
})}
|
|
||||||
</Form.Control>
|
|
||||||
</Form.Group>
|
|
||||||
<Button type={"submit"}>{this.state.btnName}</Button>
|
|
||||||
</Form>
|
|
||||||
:null
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
<Row className="justify-content-md-center">
|
<Row className="justify-content-md-center">
|
||||||
@ -90,34 +67,16 @@ class Settings extends React.Component{
|
|||||||
|
|
||||||
<br></br>
|
<br></br>
|
||||||
|
|
||||||
{
|
<Plants
|
||||||
this.state.plants.length !== 0?
|
plants={this.state.plants}
|
||||||
<Table striped bordered hover>
|
deletePlant={this.deletePlant}
|
||||||
<thead>
|
></Plants>
|
||||||
<tr>
|
|
||||||
<th>Plant name</th>
|
<ActivatePlant
|
||||||
<th>Plant type</th>
|
plants={this.state.plants}
|
||||||
<th>Dirt type</th>
|
activatePlant={this.activatePlant}
|
||||||
<th></th>
|
>
|
||||||
<th></th>
|
</ActivatePlant>
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{
|
|
||||||
this.state.plants.map((plant, index) => {
|
|
||||||
return <tr key={index}>
|
|
||||||
<td>{plant[0]}</td>
|
|
||||||
<td>{plant[1]}</td>
|
|
||||||
<td>{plant[2]}</td>
|
|
||||||
<td><Button type={"button"} onClick={() => this.editItem(plant[0], plant[1], plant[2], index)}>Edit</Button></td>
|
|
||||||
<td><Button type={"button"} onClick={() => this.removeItem(plant)}>Delete</Button></td>
|
|
||||||
</tr>
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</tbody>
|
|
||||||
</Table>
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
|
|
||||||
</Container>
|
</Container>
|
||||||
|
|
||||||
@ -125,57 +84,6 @@ class Settings extends React.Component{
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// search for arrow function for further syntax knowledge
|
|
||||||
handleSubmit = (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
if (this.state.updateId >= 0) { // check if it is in edit mode
|
|
||||||
this.state.plants[this.state.updateId][0] = this.state.name;
|
|
||||||
this.state.plants[this.state.updateId][1] = this.state.type;
|
|
||||||
this.state.plants[this.state.updateId][2] = this.state.dirt; // updates the name of the plant
|
|
||||||
this.setState({
|
|
||||||
updateId:-1, // Todo check docu
|
|
||||||
name:'', // reset inputtext again
|
|
||||||
btnName:'submit' // reset button to submit again
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
let newDataElement = [
|
|
||||||
this.state.name,
|
|
||||||
this.state.type,
|
|
||||||
this.state.dirt
|
|
||||||
]
|
|
||||||
console.log("name " + newDataElement[0])
|
|
||||||
console.log("type " + newDataElement[1])
|
|
||||||
console.log("dirt " + newDataElement[2])
|
|
||||||
this.setState(prevState =>({
|
|
||||||
plants:[...prevState.plants, newDataElement], // adds a new plant array
|
|
||||||
name:'' //to reset the inputfield
|
|
||||||
}))
|
|
||||||
return this.state.plants;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
removeItem = (value) => {
|
|
||||||
this.setState({
|
|
||||||
plants:this.state.plants.filter((plant) => { // filter function add docu
|
|
||||||
return plant !== value;
|
|
||||||
}),
|
|
||||||
name:''
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
editItem = (editedName, editedType, editedDirt, index) => {
|
|
||||||
this.setState({
|
|
||||||
name:editedName,
|
|
||||||
type:editedType,
|
|
||||||
dirt:editedDirt,
|
|
||||||
btnName:'update',
|
|
||||||
updateId:index // should be edited to a boolean
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Settings;
|
export default Settings;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user