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 { Container, Row, Col} from 'react-bootstrap';
|
||||
|
||||
|
||||
export default function About() {
|
||||
return (
|
||||
<div>
|
||||
About
|
||||
</div>
|
||||
<>
|
||||
<Container>
|
||||
<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>
|
||||
<Home dummyData={exampleData}></Home>
|
||||
</Route>
|
||||
<Route path="/settings" component={Settings}></Route>
|
||||
<Route path="/settings">
|
||||
<Settings></Settings>
|
||||
</Route>
|
||||
<Route path="/about" component={About}></Route>
|
||||
</Switch>
|
||||
</Suspense>
|
||||
|
||||
@ -1,18 +1,23 @@
|
||||
import React from 'react'
|
||||
import { Navbar, Nav, NavDropdown } from 'react-bootstrap';
|
||||
|
||||
//import logo from '../../client/public/SmartGarden.svg';
|
||||
|
||||
export default function NavigationBar() {
|
||||
return (
|
||||
<Navbar collapseOnSelect expand="lg" bg="light" variant="light">
|
||||
<Navbar.Brand href="/">
|
||||
<img
|
||||
src="SmartGarden.svg"
|
||||
{/* NOT POSSIBLE IN METEOR, only from the DB -> https://forums.meteor.com/t/importing-assets-image/30266/2
|
||||
|
||||
<img
|
||||
src={logo}
|
||||
width="30"
|
||||
height="30"
|
||||
className="d-inline-block align-top"
|
||||
rounded="true"
|
||||
alt="SmartGarden"
|
||||
/>{' '}
|
||||
/>{' '}
|
||||
*/}
|
||||
SmartGarden
|
||||
</Navbar.Brand>
|
||||
<Navbar.Toggle aria-controls="responsive-navbar-nav" />
|
||||
@ -20,13 +25,16 @@ export default function NavigationBar() {
|
||||
<Nav className="mr-auto">
|
||||
<Nav.Link href="/settings">Settings</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.2">Another action</NavDropdown.Item>
|
||||
<NavDropdown.Item href="#action/3.3">Something</NavDropdown.Item>
|
||||
<NavDropdown.Divider />
|
||||
<NavDropdown.Item href="#action/3.4">Separated link</NavDropdown.Item>
|
||||
</NavDropdown>
|
||||
</NavDropdown>*/
|
||||
}
|
||||
</Nav>
|
||||
</Navbar.Collapse>
|
||||
</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 { 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{
|
||||
|
||||
constructor(props){
|
||||
super(props);
|
||||
this.state = {
|
||||
name: '',
|
||||
type: '',
|
||||
dirt: '',
|
||||
plants: [],
|
||||
types: ['Chile', 'Mint'], // hardcoded for now
|
||||
dirts: ['Vegetable Soil', 'Potting Soil'], // hardcoded for now
|
||||
updateId: -1,
|
||||
btnName: 'submit'
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount(){
|
||||
// fetch data from db here
|
||||
|
||||
// pass this function to the addplant comp as a prop
|
||||
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(){
|
||||
@ -38,50 +55,10 @@ class Settings extends React.Component{
|
||||
|
||||
<br></br>
|
||||
|
||||
{
|
||||
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
|
||||
<Form onSubmit={this.handleSubmit}>
|
||||
<Form.Group controlId="exampleForm.ControlInput1">
|
||||
<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
|
||||
}
|
||||
<AddPlant
|
||||
addPlant={this.addPlant}
|
||||
typeArray={this.state.types}
|
||||
></AddPlant>
|
||||
|
||||
|
||||
<Row className="justify-content-md-center">
|
||||
@ -90,34 +67,16 @@ class Settings extends React.Component{
|
||||
|
||||
<br></br>
|
||||
|
||||
{
|
||||
this.state.plants.length !== 0?
|
||||
<Table striped bordered hover>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Plant name</th>
|
||||
<th>Plant type</th>
|
||||
<th>Dirt type</th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
</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
|
||||
}
|
||||
<Plants
|
||||
plants={this.state.plants}
|
||||
deletePlant={this.deletePlant}
|
||||
></Plants>
|
||||
|
||||
<ActivatePlant
|
||||
plants={this.state.plants}
|
||||
activatePlant={this.activatePlant}
|
||||
>
|
||||
</ActivatePlant>
|
||||
|
||||
</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;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user