Skip to content
Snippets Groups Projects
Commit 54508466 authored by meskio's avatar meskio :tent:
Browse files

Improve the product picker

parent b209ab4e
Branches
Tags
No related merge requests found
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;
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>
);
}
}
......
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;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment