diff --git a/src/ProductPicker.js b/src/ProductPicker.js new file mode 100644 index 0000000000000000000000000000000000000000..e4fe1e794c5470aaae18e91c77a1cea536631f0d --- /dev/null +++ b/src/ProductPicker.js @@ -0,0 +1,129 @@ +import React from 'react'; +import { Form, Row, Col, Button } from 'react-bootstrap'; +import { Typeahead } from 'react-bootstrap-typeahead'; +import Fetcher from './Fetcher'; +import { printMoney } from './util'; + +class ProductPicker extends React.Component { + constructor(props) { + super(props); + this.state = { + code: "", + products: [], + }; + } + + delPick(index) { + let picks = this.props.picks; + picks.splice(index, 1); + this.props.setPicks(picks); + } + + setAmmount(index, ammount) { + let picks = this.props.picks; + picks[index].ammount = parseInt(ammount); + this.props.setPicks(picks); + } + + setCode(codeStr) { + const code = parseInt(codeStr); + const product = this.state.products.find(p => p.code === code); + if (product === undefined) { + this.setState({ code: codeStr }); + } else { + this.pickProduct(product); + } + } + + pickProduct(product) { + let picks = this.props.picks; + picks.push({ + code: product.code, + name: product.name, + price: product.price, + ammount: 1 + }); + this.props.setPicks(picks); + this.setState({ code: "" }); + } + + render() { + const rows = this.props.picks.map((p, i) => { + return ( + <Form.Group key={p.code} as={Row}> + <Col> + <p>{p.code}</p> + </Col> + <Col sm={4}> + <p>{p.name}</p> + </Col> + <Col> + {printMoney(p.price)+"€"} + </Col> + {this.props.ammount && + <Col> + <Form.Control + type="number" min="1" + placeholder="cantidad" + value={p.ammount} + onChange={e => this.setAmmount(i, e.target.value)} + /> + </Col> + } + <Col sm={1}> + <Button variant="danger" onClick={() => this.delPick(i)}>-</Button> + </Col> + </Form.Group> + ) + }); + + return ( + <Fetcher url="/api/product" onFetch={products => this.setState({ products })} > + <Row> + <Col> + <h6>Código</h6> + </Col> + <Col sm={4}> + <h6>Nombre</h6> + </Col> + <Col> + <h6>Precio</h6> + </Col> + {this.props.ammount && + <Col> + <h6>Cantidad</h6> + </Col> + } + <Col sm={1}> + </Col> + </Row> + {rows} + <Form.Group as={Row}> + <Col> + <Form.Control + placeholder="codigo" + value={this.state.code} + onChange={e => this.setCode(e.target.value)} + /> + </Col> + <Col sm={4}> + <Typeahead + id="product-name" + labelKey="name" + options={this.state.products} + onChange={name => this.pickProduct(name[0])} + selected={[]} + /> + </Col> + <Col></Col> + {this.props.ammount && + <Col></Col> + } + <Col sm={1}></Col> + </Form.Group> + </Fetcher> + ); + } +} + +export default ProductPicker; diff --git a/src/purchase/Purchase.js b/src/purchase/Purchase.js index 7b7ca43ef8fda867f08a8345ca66b8b5fe4e5a49..115e254882d28d0e32feca3fc8bc5e0095415079 100644 --- a/src/purchase/Purchase.js +++ b/src/purchase/Purchase.js @@ -1,80 +1,37 @@ import React from 'react'; import { Redirect } from 'react-router-dom'; -import Fetcher from '../Fetcher'; -import PurchaseForm from './PurchaseForm'; -import { Row, Col, Button, Alert, Spinner } from 'react-bootstrap'; -import BootstrapTable from 'react-bootstrap-table-next'; -import cellEditFactory from 'react-bootstrap-table2-editor'; +import { Container, Row, Col, Button, Alert, Spinner } from 'react-bootstrap'; +import ProductPicker from '../ProductPicker'; import AuthContext from '../AuthContext'; import { printMoney } from '../util'; -const columns = [ - {dataField: 'code', text: 'codigo', editable: false}, - {dataField: 'name', text: 'nombre', editable: false}, - {dataField: 'priceStr', text: 'precio', editable: false}, - {dataField: 'ammount', text: 'cantidad', validator: v => { - if (isNaN(v)) { - return { - valid: false, - message: "no es un numero" - }; - } - return true; - }}, - {dataField: 'del', text: '', editable: false}, -] - class Purchase extends React.Component { static contextType = AuthContext; constructor(props) { super(props); this.state = { - products: [], purchase: [], total: 0, - purchaseId: null, + transactionId: null, isLoading: false, - badAuth: false, + noMoney: false, error: null }; } - addProduct(product) { - const code = product.code; - if (this.state.purchase.find(p => p.code === code) !== undefined) { - return false; - } - - product.priceStr = printMoney(product.price)+"€"; - product.del = <Button onClick={() => this.delProduct(code)}>-</Button>; - let purchase = this.state.purchase; - purchase.push(product); - this.setState({ purchase }); - this.updateTotal(purchase); - return true; - } - - delProduct(code) { - const i = this.state.purchase.findIndex(p => p.code === code); - let purchase = this.state.purchase; - purchase.splice(i,1); - this.setState({purchase}); - this.updateTotal(purchase); - } - - updateTotal(purchase) { + setPurchase(purchase) { const add = (acc, p) => acc + (p.price*p.ammount); const total = purchase.reduce(add, 0); - this.setState({total}); + this.setState({ purchase, total }); } send() { this.setState({isLoading: true, error: null, noMoney: false}); const body = JSON.stringify(this.state.purchase.map(p => { return { - code: parseInt(p.code), - ammount: parseInt(p.ammount) + code: p.code, + ammount: p.ammount }; })); fetch("/api/purchase", {headers: {'x-authentication': this.context.token}, method: "POST", body}) @@ -89,7 +46,7 @@ class Purchase extends React.Component { return response.json(); }) .then(p => { - this.setState({purchaseId: p.ID, isLoading: false}); + this.setState({transactionId: p.ID, isLoading: false}); }) .catch(error => { if (error.name === "not-money") { @@ -119,23 +76,17 @@ class Purchase extends React.Component { </Alert> ); } - if (this.state.purchaseId !== null) { - return <Redirect to={"/transaction/"+this.state.purchaseId} />; + if (this.state.transactionId !== null) { + return <Redirect to={"/transaction/"+this.state.transactionId} />; } - const purchase = this.state.purchase; return ( - <Fetcher url="/api/product" onFetch={products => this.setState({ products })} > + <Container> {alert} - <BootstrapTable - keyField="code" - data={ purchase } - columns={ columns } - cellEdit={ cellEditFactory({ - mode: 'click', - afterSaveCell: () => this.updateTotal(this.state.purchase) - }) } /> - <PurchaseForm products={this.state.products} onSubmit={p => this.addProduct(p)} /> + <ProductPicker ammount + picks={this.state.purchase} + setPicks={purchase => this.setPurchase(purchase)} + /> <br /> <Row> <Col> @@ -143,11 +94,11 @@ class Purchase extends React.Component { </Col> <Col> <div className="text-right"> - <Button onClick={() => this.send()}>Enviar</Button> + <Button onClick={() => this.send()}>Finalizar compra</Button> </div> </Col> </Row> - </Fetcher> + </Container> ); } } diff --git a/src/purchase/PurchaseForm.js b/src/purchase/PurchaseForm.js deleted file mode 100644 index cad441838c3f46ca4412cb14138a8d6b3e422513..0000000000000000000000000000000000000000 --- a/src/purchase/PurchaseForm.js +++ /dev/null @@ -1,100 +0,0 @@ -import React from 'react'; -import { Col, Form, Button } from 'react-bootstrap'; -import { Typeahead } from 'react-bootstrap-typeahead'; -import { printMoney } from '../util'; - - -class PurchaseForm extends React.Component { - constructor(props) { - super(props); - this.state = { - codeInvalid: false, - code: "", - product: null, - ammount: 1 - }; - } - - setCode(codeStr) { - const code = parseInt(codeStr); - const product = this.props.products.find(p => p.code === code); - this.setState({ - code: codeStr, - product: product, - codeInvalid: product === undefined - }); - } - - setName(product) { - this.setState({ - product, - code: product.code, - codeInvalid: false, - }); - } - - submit(e) { - e.preventDefault(); - if (!this.state.product) { - return - } - let product = this.state.product; - product.ammount = this.state.ammount; - if (this.props.onSubmit(product)) { - this.setState({ - code: "", - product: null, - ammount: 1, - codeInvalid: false - }); - } else { - this.setState({ codeInvalid: true }); - } - } - - render() { - if (this.props.products.length === 0) { - return null; - } - return ( - <Form onSubmit={e => this.submit(e)}> - <Form.Row> - <Col> - <Form.Control - placeholder="codigo" - value={this.state.code} - onChange={e => this.setCode(e.target.value)} - isInvalid={this.state.codeInvalid} - /> - </Col> - <Col> - <Typeahead - id="product-name" - labelKey="name" - options={this.props.products} - onChange={name => this.setName(name[0])} - selected={this.state.product? [this.state.product]:[]} - /> - </Col> - <Col> - {this.state.product? printMoney(this.state.product.price)+"€":"0.00€"} - </Col> - <Col> - <Form.Control - type="number" min="1" - placeholder="cantidad" - value={this.state.ammount} - onChange={e => this.setState({ammount: e.target.value})} - /> - </Col> - <Col> - <Button type="submit">+</Button> - </Col> - </Form.Row> - </Form> - ); - } - -} - -export default PurchaseForm;