From 8085c38ed24ef17a879a482fb35c961f01979bd1 Mon Sep 17 00:00:00 2001 From: meskio <meskio@sindominio.net> Date: Fri, 9 Oct 2020 15:30:38 +0200 Subject: [PATCH] Format code with prettier --- .prettierrc.json | 1 + package-lock.json | 6 + package.json | 5 +- src/App.js | 289 +++++++++++++++++---------------- src/App.test.js | 8 +- src/AuthContext.js | 8 +- src/Dashboard.js | 83 +++++----- src/Fetcher.js | 116 +++++++------- src/Head.js | 83 +++++----- src/MemberList.js | 79 ++++----- src/ProductList.js | 79 ++++----- src/ProductPicker.js | 235 +++++++++++++-------------- src/ShowTransaction.js | 68 ++++---- src/SignIn.js | 218 +++++++++++++------------ src/Topup.js | 300 +++++++++++++++++++---------------- src/TransactionList.js | 120 +++++++------- src/index.js | 16 +- src/order/CreateOrder.js | 240 +++++++++++++++------------- src/order/OrderList.js | 42 +++-- src/order/PurchaseOrder.js | 241 +++++++++++++++------------- src/order/ShowOrder.js | 233 ++++++++++++++------------- src/purchase/Purchase.js | 197 ++++++++++++----------- src/purchase/ShowPurchase.js | 30 ++-- src/serviceWorker.js | 44 ++--- src/setupTests.js | 2 +- src/util.js | 4 +- 26 files changed, 1438 insertions(+), 1309 deletions(-) create mode 100644 .prettierrc.json diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1 @@ +{} diff --git a/package-lock.json b/package-lock.json index 55a2fea..af3b5fa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10206,6 +10206,12 @@ "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" }, + "prettier": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.1.2.tgz", + "integrity": "sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg==", + "dev": true + }, "pretty-bytes": { "version": "5.4.1", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.4.1.tgz", diff --git a/package.json b/package.json index 8421366..d8fc919 100644 --- a/package.json +++ b/package.json @@ -38,5 +38,8 @@ "last 1 safari version" ] }, - "proxy": "http://localhost:8080" + "proxy": "http://localhost:8080", + "devDependencies": { + "prettier": "2.1.2" + } } diff --git a/src/App.js b/src/App.js index 8bb0589..6c04689 100644 --- a/src/App.js +++ b/src/App.js @@ -1,169 +1,176 @@ -import React from 'react'; -import { BrowserRouter, Switch, Route } from 'react-router-dom'; -import MemberList from './MemberList'; -import ProductList from './ProductList'; -import Dashboard from './Dashboard'; -import Purchase from './purchase/Purchase'; -import Topup from './Topup'; -import ShowTransaction from './ShowTransaction'; -import ShowOrder from './order/ShowOrder'; -import CreateOrder from './order/CreateOrder'; -import AuthContext from './AuthContext'; -import SignIn from './SignIn'; -import Head from './Head'; +import React from "react"; +import { BrowserRouter, Switch, Route } from "react-router-dom"; +import MemberList from "./MemberList"; +import ProductList from "./ProductList"; +import Dashboard from "./Dashboard"; +import Purchase from "./purchase/Purchase"; +import Topup from "./Topup"; +import ShowTransaction from "./ShowTransaction"; +import ShowOrder from "./order/ShowOrder"; +import CreateOrder from "./order/CreateOrder"; +import AuthContext from "./AuthContext"; +import SignIn from "./SignIn"; +import Head from "./Head"; function Panel(props) { - return ( - <div> - <BrowserRouter> - <Head onLogout={props.onLogout} /> - <Switch> - <Route path="/members"> - <MemberList /> - </Route> - <Route path="/products"> - <ProductList /> - </Route> - <Route path="/transaction/:id"> - <ShowTransaction /> - </Route> - <Route path="/purchase"> - <Purchase /> - </Route> - <Route path="/topup"> - <Topup /> - </Route> - <Route path="/order/create"> - <CreateOrder /> - </Route> - <Route path="/order/:id" component={ShowOrder} /> - <Route path="/"> - <Dashboard /> - </Route> - </Switch> - </BrowserRouter> - </div> - ); + return ( + <div> + <BrowserRouter> + <Head onLogout={props.onLogout} /> + <Switch> + <Route path="/members"> + <MemberList /> + </Route> + <Route path="/products"> + <ProductList /> + </Route> + <Route path="/transaction/:id"> + <ShowTransaction /> + </Route> + <Route path="/purchase"> + <Purchase /> + </Route> + <Route path="/topup"> + <Topup /> + </Route> + <Route path="/order/create"> + <CreateOrder /> + </Route> + <Route path="/order/:id" component={ShowOrder} /> + <Route path="/"> + <Dashboard /> + </Route> + </Switch> + </BrowserRouter> + </div> + ); } function getClaims(token) { - const base64Url = token.split('.')[1]; - const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/'); - const jsonPayload = decodeURIComponent(atob(base64).split('').map(function(c) { - return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); - }).join('')); + const base64Url = token.split(".")[1]; + const base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/"); + const jsonPayload = decodeURIComponent( + atob(base64) + .split("") + .map(function (c) { + return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2); + }) + .join("") + ); - return JSON.parse(jsonPayload); + return JSON.parse(jsonPayload); } class App extends React.Component { - constructor(props) { - super(props); - this.state = { - num: null, - role: null, - token: null - }; + constructor(props) { + super(props); + this.state = { + num: null, + role: null, + token: null, + }; - this.logout = this.logout.bind(this); - this.login = this.login.bind(this); - } + this.logout = this.logout.bind(this); + this.login = this.login.bind(this); + } - componentDidMount() { - const token = localStorage.getItem("token"); - if (token) { - const num = localStorage.getItem("num"); - const role = localStorage.getItem("role"); - this.setState({ num, role, token }); - if (getClaims(token)["exp"] !== undefined) { - this.timerID = setInterval( - () => this.renewToken(), - 60000 // every minute - ); - } - } + componentDidMount() { + const token = localStorage.getItem("token"); + if (token) { + const num = localStorage.getItem("num"); + const role = localStorage.getItem("role"); + this.setState({ num, role, token }); + if (getClaims(token)["exp"] !== undefined) { + this.timerID = setInterval( + () => this.renewToken(), + 60000 // every minute + ); + } } + } - componentWillUnmount() { - if (this.timeID) { - clearInterval(this.timerID); - } + componentWillUnmount() { + if (this.timeID) { + clearInterval(this.timerID); } + } - storeState(token, num, role) { - localStorage.setItem("token", token); - localStorage.setItem("num", num); - localStorage.setItem("role", role); - } + storeState(token, num, role) { + localStorage.setItem("token", token); + localStorage.setItem("num", num); + localStorage.setItem("role", role); + } - login(token, member) { - this.setState({ - num: member.num, - role: member.role, - token: token - }); - this.storeState(token, member.num, member.role); - if (getClaims(token)["exp"] !== undefined) { - this.timerID = setInterval( - () => this.renewToken(), - 60000 // every minute - ); - } + login(token, member) { + this.setState({ + num: member.num, + role: member.role, + token: token, + }); + this.storeState(token, member.num, member.role); + if (getClaims(token)["exp"] !== undefined) { + this.timerID = setInterval( + () => this.renewToken(), + 60000 // every minute + ); } + } - logout() { - if (this.timeID) { - clearInterval(this.timerID); - } - this.setState({ - num: null, - role: null, - token: null - }); - this.storeState("", "", ""); + logout() { + if (this.timeID) { + clearInterval(this.timerID); } + this.setState({ + num: null, + role: null, + token: null, + }); + this.storeState("", "", ""); + } - isLoged() { - if (!this.state.token) { - return false; - } - const claims = getClaims(this.state.token); - if (claims["exp"] === undefined) { - return true; - } - return claims["exp"] > Date.now()/1000; - }; - - renewToken() { - fetch("/api/token", { headers: { 'x-authentication': this.state.token } }) - .then(response => { - if (!response.ok) { - throw new Error(response.status.toString()+' '+response.statusText); - } - return response.json(); - }) - .then(data => { - const token = data.token; - this.setState({token}); - localStorage.setItem("token", token); - }) - .catch(error => { - console.log("Error renewing token: " + error.message) - }); + isLoged() { + if (!this.state.token) { + return false; } + const claims = getClaims(this.state.token); + if (claims["exp"] === undefined) { + return true; + } + return claims["exp"] > Date.now() / 1000; + } - render() { - let component = <Panel onLogout={this.logout} />; - if (!this.isLoged()) { - component = <SignIn onLogin={this.login} />; + renewToken() { + fetch("/api/token", { headers: { "x-authentication": this.state.token } }) + .then((response) => { + if (!response.ok) { + throw new Error( + response.status.toString() + " " + response.statusText + ); } + return response.json(); + }) + .then((data) => { + const token = data.token; + this.setState({ token }); + localStorage.setItem("token", token); + }) + .catch((error) => { + console.log("Error renewing token: " + error.message); + }); + } - return ( - <AuthContext.Provider value={this.state}> - {component} - </AuthContext.Provider> - ); + render() { + let component = <Panel onLogout={this.logout} />; + if (!this.isLoged()) { + component = <SignIn onLogin={this.login} />; } + + return ( + <AuthContext.Provider value={this.state}> + {component} + </AuthContext.Provider> + ); + } } export default App; diff --git a/src/App.test.js b/src/App.test.js index 4db7ebc..352d7b8 100644 --- a/src/App.test.js +++ b/src/App.test.js @@ -1,8 +1,8 @@ -import React from 'react'; -import { render } from '@testing-library/react'; -import App from './App'; +import React from "react"; +import { render } from "@testing-library/react"; +import App from "./App"; -test('renders learn react link', () => { +test("renders learn react link", () => { const { getByText } = render(<App />); const linkElement = getByText(/learn react/i); expect(linkElement).toBeInTheDocument(); diff --git a/src/AuthContext.js b/src/AuthContext.js index 74c76a2..b170a4f 100644 --- a/src/AuthContext.js +++ b/src/AuthContext.js @@ -1,9 +1,9 @@ -import { createContext } from 'react'; +import { createContext } from "react"; export const AuthContext = createContext({ - num: 0, - role: "", - token: null, + num: 0, + role: "", + token: null, }); export default AuthContext; diff --git a/src/Dashboard.js b/src/Dashboard.js index 42377cb..d827c4c 100644 --- a/src/Dashboard.js +++ b/src/Dashboard.js @@ -1,46 +1,51 @@ -import React from 'react'; -import { Container, Row, Col, Button } from 'react-bootstrap'; -import AuthContext from './AuthContext'; -import Fetcher from './Fetcher'; -import OrderList from './order/OrderList'; -import TransactionList from './TransactionList'; -import { printMoney } from './util'; +import React from "react"; +import { Container, Row, Col, Button } from "react-bootstrap"; +import AuthContext from "./AuthContext"; +import Fetcher from "./Fetcher"; +import OrderList from "./order/OrderList"; +import TransactionList from "./TransactionList"; +import { printMoney } from "./util"; class Dashboard extends React.Component { - static contextType = AuthContext; + static contextType = AuthContext; - constructor(props) { - super(props); - this.state = { - name: null, - balance: null - }; - } + constructor(props) { + super(props); + this.state = { + name: null, + balance: null, + }; + } - render() { - return ( - <Container> - <Fetcher - url={"/api/member/me"} - onFetch={member => this.setState({ balance: member.balance, name: member.name})} > - <Row> - <Col xs> - <div className="text-right"> - <h6>{this.state.name}</h6> - <h1>{printMoney(this.state.balance)}€</h1> - </div> - </Col> - <Col xs={{ offset: 0 }} md={{ offset: 1 }}> - <br /> - <Button variant="success" href="/purchase">Comprar</Button> - </Col> - </Row> - <OrderList /> - <TransactionList /> - </Fetcher> - </Container> - ); - } + render() { + return ( + <Container> + <Fetcher + url={"/api/member/me"} + onFetch={(member) => + this.setState({ balance: member.balance, name: member.name }) + } + > + <Row> + <Col xs> + <div className="text-right"> + <h6>{this.state.name}</h6> + <h1>{printMoney(this.state.balance)}€</h1> + </div> + </Col> + <Col xs={{ offset: 0 }} md={{ offset: 1 }}> + <br /> + <Button variant="success" href="/purchase"> + Comprar + </Button> + </Col> + </Row> + <OrderList /> + <TransactionList /> + </Fetcher> + </Container> + ); + } } export default Dashboard; diff --git a/src/Fetcher.js b/src/Fetcher.js index 657c5b6..b1115eb 100644 --- a/src/Fetcher.js +++ b/src/Fetcher.js @@ -1,71 +1,75 @@ -import React from 'react'; -import { Spinner, Alert, Row } from 'react-bootstrap'; -import AuthContext from './AuthContext'; +import React from "react"; +import { Spinner, Alert, Row } from "react-bootstrap"; +import AuthContext from "./AuthContext"; class Fetcher extends React.Component { - static contextType = AuthContext; + static contextType = AuthContext; - constructor(props) { - super(props); - this.state = { - isLoading: false, - error: null - }; - } + constructor(props) { + super(props); + this.state = { + isLoading: false, + error: null, + }; + } - componentDidMount() { - this.setState({ isLoading: true }); - this.fetch(); - this.timerID = setInterval( - () => this.fetch(), - 10000 // every 10 seconds - ); - } + componentDidMount() { + this.setState({ isLoading: true }); + this.fetch(); + this.timerID = setInterval( + () => this.fetch(), + 10000 // every 10 seconds + ); + } - compomentWillUnmount() { - clearInterval(this.timerID); - } + compomentWillUnmount() { + clearInterval(this.timerID); + } - fetch() { - if (this.state.error) { - this.setState({ error: null }); - } - fetch(this.props.url, { headers: { 'x-authentication': this.context.token } }) - .then(response => { - if (!response.ok) { - throw new Error(response.status.toString()+' '+response.statusText); - } - return response.json(); - }) - .then(data => { - if (this.state.isLoading) { - this.setState({ isLoading: false }); - } - this.props.onFetch(data); - }) - .catch(e => this.setState({ error: e.message, isLoading: false })); + fetch() { + if (this.state.error) { + this.setState({ error: null }); } - - render() { + fetch(this.props.url, { + headers: { "x-authentication": this.context.token }, + }) + .then((response) => { + if (!response.ok) { + throw new Error( + response.status.toString() + " " + response.statusText + ); + } + return response.json(); + }) + .then((data) => { if (this.state.isLoading) { - return ( - <Row className="justify-content-md-center"> - <Spinner animation="border" /> - </Row> - ); + this.setState({ isLoading: false }); } + this.props.onFetch(data); + }) + .catch((e) => this.setState({ error: e.message, isLoading: false })); + } - if (this.state.error != null) { - console.log(this.state.error); - return ( - <Alert variant="danger"> - Ha ocurrido un error cargando datos: {this.state.error} - </Alert> - ); - } + render() { + if (this.state.isLoading) { + return ( + <Row className="justify-content-md-center"> + <Spinner animation="border" /> + </Row> + ); + } - return this.props.children; + if (this.state.error != null) { + console.log(this.state.error); + return ( + <Alert variant="danger"> + Ha ocurrido un error cargando datos: {this.state.error} + </Alert> + ); } + + return this.props.children; + } } export default Fetcher; diff --git a/src/Head.js b/src/Head.js index b47ff38..63d4582 100644 --- a/src/Head.js +++ b/src/Head.js @@ -1,46 +1,49 @@ -import React, { useContext } from 'react'; -import { Navbar, Nav, NavDropdown, Button, Form } from 'react-bootstrap'; -import { useLocation } from 'react-router-dom'; -import mano from './mano.svg'; -import AuthContext from './AuthContext'; +import React, { useContext } from "react"; +import { Navbar, Nav, NavDropdown, Button, Form } from "react-bootstrap"; +import { useLocation } from "react-router-dom"; +import mano from "./mano.svg"; +import AuthContext from "./AuthContext"; function Head(props) { - const auth = useContext(AuthContext); - let location = useLocation(); + const auth = useContext(AuthContext); + let location = useLocation(); - let adminNav; - if (auth.role === "admin") { - adminNav = ( - <NavDropdown title="Admin" id="admin"> - <Nav.Link href="/members">Socias</Nav.Link> - <Nav.Link href="/topup">Recarga</Nav.Link> - </NavDropdown> - ); - } - return ( - <Navbar bg="light"> - <Navbar.Brand href="/"> - <img src={mano} width="30" height="30" className="d-inline-block align-top" alt="Garbanzo Negro" /> - </Navbar.Brand> - <Navbar.Toggle aria-controls="basic-navbar-nav" /> - <Navbar.Collapse id="basic-navbar-nav"> - <Nav className="mr-auto" activeKey={location.pathname}> - <Nav.Link href="/products">Productos</Nav.Link> - <Nav.Link href="/purchase">Comprar</Nav.Link> - <Nav.Link href="/order/create">Abrir pedido</Nav.Link> - </Nav> - {adminNav} - <Form inline> - <Button - variant="outline-success" - onClick={props.onLogout} - > - Salir - </Button> - </Form> - </Navbar.Collapse> - </Navbar> - ) + let adminNav; + if (auth.role === "admin") { + adminNav = ( + <NavDropdown title="Admin" id="admin"> + <Nav.Link href="/members">Socias</Nav.Link> + <Nav.Link href="/topup">Recarga</Nav.Link> + </NavDropdown> + ); + } + return ( + <Navbar bg="light"> + <Navbar.Brand href="/"> + <img + src={mano} + width="30" + height="30" + className="d-inline-block align-top" + alt="Garbanzo Negro" + /> + </Navbar.Brand> + <Navbar.Toggle aria-controls="basic-navbar-nav" /> + <Navbar.Collapse id="basic-navbar-nav"> + <Nav className="mr-auto" activeKey={location.pathname}> + <Nav.Link href="/products">Productos</Nav.Link> + <Nav.Link href="/purchase">Comprar</Nav.Link> + <Nav.Link href="/order/create">Abrir pedido</Nav.Link> + </Nav> + {adminNav} + <Form inline> + <Button variant="outline-success" onClick={props.onLogout}> + Salir + </Button> + </Form> + </Navbar.Collapse> + </Navbar> + ); } export default Head; diff --git a/src/MemberList.js b/src/MemberList.js index 69f955a..7300c02 100644 --- a/src/MemberList.js +++ b/src/MemberList.js @@ -1,46 +1,47 @@ -import React from 'react'; -import { Table } from 'react-bootstrap'; -import Fetcher from './Fetcher'; -import { printMoney } from './util'; +import React from "react"; +import { Table } from "react-bootstrap"; +import Fetcher from "./Fetcher"; +import { printMoney } from "./util"; class MemberList extends React.Component { - constructor(props) { - super(props); - this.state = { - members: [], - }; - } + constructor(props) { + super(props); + this.state = { + members: [], + }; + } - render() { - const entries = this.state.members.map((member) => { - return ( - <tr key={member.num}> - <td>{member.num}</td> - <td>{member.name}</td> - <td>{member.email}</td> - <td>{printMoney(member.balance)} €</td> - </tr> - ) - }); + render() { + const entries = this.state.members.map((member) => { + return ( + <tr key={member.num}> + <td>{member.num}</td> + <td>{member.name}</td> + <td>{member.email}</td> + <td>{printMoney(member.balance)} €</td> + </tr> + ); + }); - return ( - <Fetcher url="/api/member" onFetch={members => this.setState({ members })} > - <Table striped bordered hover> - <thead> - <tr> - <th>Numero</th> - <th>Nombre</th> - <th>Email</th> - <th>Saldo</th> - </tr> - </thead> - <tbody> - {entries} - </tbody> - </Table> - </Fetcher> - ); - } + return ( + <Fetcher + url="/api/member" + onFetch={(members) => this.setState({ members })} + > + <Table striped bordered hover> + <thead> + <tr> + <th>Numero</th> + <th>Nombre</th> + <th>Email</th> + <th>Saldo</th> + </tr> + </thead> + <tbody>{entries}</tbody> + </Table> + </Fetcher> + ); + } } export default MemberList; diff --git a/src/ProductList.js b/src/ProductList.js index 840ff62..015cd35 100644 --- a/src/ProductList.js +++ b/src/ProductList.js @@ -1,46 +1,47 @@ -import React from 'react'; -import { Table } from 'react-bootstrap'; -import Fetcher from './Fetcher'; -import { printMoney } from './util'; +import React from "react"; +import { Table } from "react-bootstrap"; +import Fetcher from "./Fetcher"; +import { printMoney } from "./util"; class ProductList extends React.Component { - constructor(props) { - super(props); - this.state = { - products: [], - }; - } + constructor(props) { + super(props); + this.state = { + products: [], + }; + } - render() { - const entries = this.state.products.map((product) => { - return ( - <tr key={product.code}> - <td>{product.code}</td> - <td>{product.name}</td> - <td>{printMoney(product.price)}</td> - <td>{product.stock}</td> - </tr> - ) - }); + render() { + const entries = this.state.products.map((product) => { + return ( + <tr key={product.code}> + <td>{product.code}</td> + <td>{product.name}</td> + <td>{printMoney(product.price)}</td> + <td>{product.stock}</td> + </tr> + ); + }); - return ( - <Fetcher url="/api/product" onFetch={products => this.setState({ products })} > - <Table striped bordered hover> - <thead> - <tr> - <th>codigo</th> - <th>Nombre</th> - <th>Precio</th> - <th>Existencias</th> - </tr> - </thead> - <tbody> - {entries} - </tbody> - </Table> - </Fetcher> - ); - } + return ( + <Fetcher + url="/api/product" + onFetch={(products) => this.setState({ products })} + > + <Table striped bordered hover> + <thead> + <tr> + <th>codigo</th> + <th>Nombre</th> + <th>Precio</th> + <th>Existencias</th> + </tr> + </thead> + <tbody>{entries}</tbody> + </Table> + </Fetcher> + ); + } } export default ProductList; diff --git a/src/ProductPicker.js b/src/ProductPicker.js index 1dd21e0..105ea5a 100644 --- a/src/ProductPicker.js +++ b/src/ProductPicker.js @@ -1,129 +1,130 @@ -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'; +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: [], - }; - } + constructor(props) { + super(props); + this.state = { + code: "", + products: [], + }; + } - delPick(index) { - let picks = this.props.picks; - picks.splice(index, 1); - this.props.setPicks(picks); - } + delPick(index) { + let picks = this.props.picks; + picks.splice(index, 1); + this.props.setPicks(picks); + } - setAmount(index, amount) { - let picks = this.props.picks; - picks[index].amount = parseInt(amount); - this.props.setPicks(picks); - } + setAmount(index, amount) { + let picks = this.props.picks; + picks[index].amount = parseInt(amount); + 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); - } + 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, - amount: 1 - }); - this.props.setPicks(picks); - this.setState({ code: "" }); - } + pickProduct(product) { + let picks = this.props.picks; + picks.push({ + code: product.code, + name: product.name, + price: product.price, + amount: 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.amount && - <Col> - <Form.Control - type="number" min="1" - placeholder="cantidad" - value={p.amount} - onChange={e => this.setAmount(i, e.target.value)} - /> - </Col> - } - <Col sm={1}> - <Button variant="danger" onClick={() => this.delPick(i)}>-</Button> - </Col> - </Form.Group> - ) - }); + 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.amount && ( + <Col> + <Form.Control + type="number" + min="1" + placeholder="cantidad" + value={p.amount} + onChange={(e) => this.setAmount(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.amount && - <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.amount && - <Col></Col> - } - <Col sm={1}></Col> - </Form.Group> - </Fetcher> - ); - } + 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.amount && ( + <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.amount && <Col></Col>} + <Col sm={1}></Col> + </Form.Group> + </Fetcher> + ); + } } export default ProductPicker; diff --git a/src/ShowTransaction.js b/src/ShowTransaction.js index 6a48ae1..a94c66b 100644 --- a/src/ShowTransaction.js +++ b/src/ShowTransaction.js @@ -1,41 +1,41 @@ -import React, { useState } from 'react'; -import { useParams } from 'react-router-dom'; -import { Container, Row, Col } from 'react-bootstrap'; -import Fetcher from './Fetcher'; -import ShowPurchase from './purchase/ShowPurchase'; -import { printMoney, printDate } from './util'; +import React, { useState } from "react"; +import { useParams } from "react-router-dom"; +import { Container, Row, Col } from "react-bootstrap"; +import Fetcher from "./Fetcher"; +import ShowPurchase from "./purchase/ShowPurchase"; +import { printMoney, printDate } from "./util"; function ShowTransaction() { - const { id } = useParams(); - const [transaction, setTransaction] = useState({}); + const { id } = useParams(); + const [transaction, setTransaction] = useState({}); - let show_list; - switch (transaction.type) { - case "purchase": - show_list = <ShowPurchase purchase={transaction.purchase} />; - break; - case "topup": - show_list = <p>{transaction.topup.comment}</p>; - break; - default: - show_list = null; - } + let show_list; + switch (transaction.type) { + case "purchase": + show_list = <ShowPurchase purchase={transaction.purchase} />; + break; + case "topup": + show_list = <p>{transaction.topup.comment}</p>; + break; + default: + show_list = null; + } - return ( - <Fetcher url={"/api/transaction/"+id} onFetch={setTransaction} > - <Container> - {show_list} - <Row> - <Col> - <h3>Total: {printMoney(transaction.total)}€</h3> - </Col> - <Col> - <p className="text-right">{printDate(transaction.date)}</p> - </Col> - </Row> - </Container> - </Fetcher> - ); + return ( + <Fetcher url={"/api/transaction/" + id} onFetch={setTransaction}> + <Container> + {show_list} + <Row> + <Col> + <h3>Total: {printMoney(transaction.total)}€</h3> + </Col> + <Col> + <p className="text-right">{printDate(transaction.date)}</p> + </Col> + </Row> + </Container> + </Fetcher> + ); } export default ShowTransaction; diff --git a/src/SignIn.js b/src/SignIn.js index 0a80d07..41157b6 100644 --- a/src/SignIn.js +++ b/src/SignIn.js @@ -1,127 +1,123 @@ -import React from 'react'; -import logo from './logo.svg'; -import { Form, Button, Container, Row, Spinner, Alert } from 'react-bootstrap'; +import React from "react"; +import logo from "./logo.svg"; +import { Form, Button, Container, Row, Spinner, Alert } from "react-bootstrap"; class SignIn extends React.Component { - constructor (props) { - super(props); - this.state = { - name: "", - password: "", - noExpire: false, - isLoading: false, - badAuth: false, - error: null - }; + constructor(props) { + super(props); + this.state = { + name: "", + password: "", + noExpire: false, + isLoading: false, + badAuth: false, + error: null, + }; - this.onFormSubmit = this.onFormSubmit.bind(this); - } + this.onFormSubmit = this.onFormSubmit.bind(this); + } - onFormSubmit(e) { - e.preventDefault(); + onFormSubmit(e) { + e.preventDefault(); - this.setState({isLoading: true, error: null}); - const body = JSON.stringify({ - name: this.state.name, - password: this.state.password, - noExpire: this.state.noExpire - }); + this.setState({ isLoading: true, error: null }); + const body = JSON.stringify({ + name: this.state.name, + password: this.state.password, + noExpire: this.state.noExpire, + }); - fetch("/api/signin", {method: "POST", body}) - .then(response => { - if (response.status === 400) { - var error = new Error("Bad auth"); - error.name ="bad-auth"; - throw error; - } else if (!response.ok) { - throw new Error(response.status.toString()+' '+response.statusText); - } - return response.json(); - }) - .then(data => { - this.setState({isLoading: false, error: null, badAuth: false}); - this.props.onLogin(data.token, data.member); - }) - .catch(error => { - if (error.name === "bad-auth") { - this.setState({isLoading: false, error: null, badAuth: true}); - } else { - this.setState({isLoading: false, error: error.message}) - } - }); - } + fetch("/api/signin", { method: "POST", body }) + .then((response) => { + if (response.status === 400) { + var error = new Error("Bad auth"); + error.name = "bad-auth"; + throw error; + } else if (!response.ok) { + throw new Error( + response.status.toString() + " " + response.statusText + ); + } + return response.json(); + }) + .then((data) => { + this.setState({ isLoading: false, error: null, badAuth: false }); + this.props.onLogin(data.token, data.member); + }) + .catch((error) => { + if (error.name === "bad-auth") { + this.setState({ isLoading: false, error: null, badAuth: true }); + } else { + this.setState({ isLoading: false, error: error.message }); + } + }); + } - render() { - let form = ( - <Form onSubmit={this.onFormSubmit}> - <Form.Group> - <Form.Label>Nombre</Form.Label> - <Form.Control - placeholder="Nombre" - value={this.state.name} - onChange={e => this.setState({name: e.target.value})} - isInvalid={this.state.badAuth} - /> - </Form.Group> + render() { + let form = ( + <Form onSubmit={this.onFormSubmit}> + <Form.Group> + <Form.Label>Nombre</Form.Label> + <Form.Control + placeholder="Nombre" + value={this.state.name} + onChange={(e) => this.setState({ name: e.target.value })} + isInvalid={this.state.badAuth} + /> + </Form.Group> - <Form.Group> - <Form.Label>Contraseña</Form.Label> - <Form.Control - type="password" - placeholder="Contraseña" - value={this.state.password} - onChange={e => this.setState({password: e.target.value}) } - isInvalid={this.state.badAuth} - /> - <Form.Control.Feedback type="invalid"> - Nombre o contraseña invalidos. - </Form.Control.Feedback> - </Form.Group> + <Form.Group> + <Form.Label>Contraseña</Form.Label> + <Form.Control + type="password" + placeholder="Contraseña" + value={this.state.password} + onChange={(e) => this.setState({ password: e.target.value })} + isInvalid={this.state.badAuth} + /> + <Form.Control.Feedback type="invalid"> + Nombre o contraseña invalidos. + </Form.Control.Feedback> + </Form.Group> - <Form.Group> - <Form.Check - type="switch" - id="noExpire" - label="Permanecer conectada con este navegador" - onChange={e => this.setState({noExpire: e.target.checked}) } - /> - </Form.Group> + <Form.Group> + <Form.Check + type="switch" + id="noExpire" + label="Permanecer conectada con este navegador" + onChange={(e) => this.setState({ noExpire: e.target.checked })} + /> + </Form.Group> - <Button - variant="primary" - type="submit" - className="w-100 mt-3" - > - Entra - </Button> - </Form> - ); + <Button variant="primary" type="submit" className="w-100 mt-3"> + Entra + </Button> + </Form> + ); - if (this.state.isLoading) { - form = <Spinner animation="border" />; - } - - let alert; - if (this.state.error != null) { - alert = ( - <Alert variant="danger"> - Ha ocurrido un error iniciando sesión: {this.state.error} - </Alert> - ); - } + if (this.state.isLoading) { + form = <Spinner animation="border" />; + } - return ( - <Container> - <Row className="justify-content-center"> - <img src={logo} alt="Garbanzo Negro" /> - </Row> - {alert} - <Row className="justify-content-center"> - {form} - </Row> - </Container> - ); + let alert; + if (this.state.error != null) { + alert = ( + <Alert variant="danger"> + Ha ocurrido un error iniciando sesión: {this.state.error} + </Alert> + ); } + + return ( + <Container> + <Row className="justify-content-center"> + <img src={logo} alt="Garbanzo Negro" /> + </Row> + {alert} + <Row className="justify-content-center">{form}</Row> + </Container> + ); + } } export default SignIn; diff --git a/src/Topup.js b/src/Topup.js index b427600..af549de 100644 --- a/src/Topup.js +++ b/src/Topup.js @@ -1,153 +1,177 @@ -import React from 'react'; -import { Redirect } from 'react-router-dom'; -import Fetcher from './Fetcher'; -import { Container, Form, Col, Row, Button, Alert, Spinner, InputGroup } from 'react-bootstrap'; -import { Typeahead } from 'react-bootstrap-typeahead'; -import AuthContext from './AuthContext'; +import React from "react"; +import { Redirect } from "react-router-dom"; +import Fetcher from "./Fetcher"; +import { + Container, + Form, + Col, + Row, + Button, + Alert, + Spinner, + InputGroup, +} from "react-bootstrap"; +import { Typeahead } from "react-bootstrap-typeahead"; +import AuthContext from "./AuthContext"; class Topup extends React.Component { - static contextType = AuthContext; + static contextType = AuthContext; - constructor(props) { - super(props); - this.state = { - members: [], - numInvalid: false, - amount: 0, - num: null, - name: "", - comment: "", - transactionId: null, - isLoading: false, - badAuth: false, - error: null - }; - } + constructor(props) { + super(props); + this.state = { + members: [], + numInvalid: false, + amount: 0, + num: null, + name: "", + comment: "", + transactionId: null, + isLoading: false, + badAuth: false, + error: null, + }; + } - setNum(numStr) { - const num = parseInt(numStr); - const member = this.state.members.find(p => p.num === num); - let name = ""; - if (member) { - name = member.name; - } - this.setState({ - num: numStr, - name: name, - numInvalid: name === undefined - }); + setNum(numStr) { + const num = parseInt(numStr); + const member = this.state.members.find((p) => p.num === num); + let name = ""; + if (member) { + name = member.name; } + this.setState({ + num: numStr, + name: name, + numInvalid: name === undefined, + }); + } - setName(member) { - this.setState({ - num: member.num, - name: member.name, - numInvalid: false, - }); - } + setName(member) { + this.setState({ + num: member.num, + name: member.name, + numInvalid: false, + }); + } - send(e) { - e.preventDefault(); - - this.setState({isLoading: true, error: null}); - const body = JSON.stringify({ - member: parseInt(this.state.num), - comment: this.state.comment, - amount: parseInt(this.state.amount)*100 - }); - fetch("/api/topup", {headers: {'x-authentication': this.context.token}, method: "POST", body}) - .then(response => { - if (!response.ok) { - throw new Error(response.status.toString()+' '+response.statusText); - } - return response.json(); - }) - .then(transaction => { - this.setState({transactionId: transaction.ID, isLoading: false}); - }) - .catch(error => { - this.setState({isLoading: false, error: error.message}); - }); - } + send(e) { + e.preventDefault(); - render() { - if (this.state.isLoading) { - return <Spinner animation="border" />; + this.setState({ isLoading: true, error: null }); + const body = JSON.stringify({ + member: parseInt(this.state.num), + comment: this.state.comment, + amount: parseInt(this.state.amount) * 100, + }); + fetch("/api/topup", { + headers: { "x-authentication": this.context.token }, + method: "POST", + body, + }) + .then((response) => { + if (!response.ok) { + throw new Error( + response.status.toString() + " " + response.statusText + ); } + return response.json(); + }) + .then((transaction) => { + this.setState({ transactionId: transaction.ID, isLoading: false }); + }) + .catch((error) => { + this.setState({ isLoading: false, error: error.message }); + }); + } - let alert; - if (this.state.error != null) { - alert = ( - <Alert variant="danger"> - Ha ocurrido un error enviando la compra: {this.state.error} - </Alert> - ); - } - if (this.state.transactionId !== null) { - return <Redirect to={"/transaction/"+this.state.transactionId} />; - } + render() { + if (this.state.isLoading) { + return <Spinner animation="border" />; + } - return ( - <Fetcher url="/api/member" onFetch={members => this.setState({ members })} > - <Container> - {alert} - <Form onSubmit={e => this.send(e)}> - <Form.Group as={Row}> - <Form.Label as="legend" column sm={2}>Socia</Form.Label> - <Col sm={5}> - <Form.Control - placeholder="numero de socia" - value={this.state.num} - onChange={e => this.setNum(e.target.value)} - isInvalid={this.state.numInvalid} - /> - </Col> - <Col sm={5}> - <Typeahead - id="name" - labelKey="name" - options={this.state.members} - onChange={m => this.setName(m[0])} - selected={this.state.name? [this.state.name]:[]} - /> - </Col> - </Form.Group> - <Form.Group as={Row}> - <Form.Label as="legend" column sm={2}>Recarga</Form.Label> - <Col sm={10}> - <InputGroup> - <Form.Control - type="number" - placeholder="euros" - value={this.state.amount} - onChange={e => this.setState({amount: e.target.value})} - /> - <InputGroup.Append> - <InputGroup.Text>.00 €</InputGroup.Text> - </InputGroup.Append> - </InputGroup> - </Col> - </Form.Group> - <Form.Group as={Row}> - <Form.Label as="legend" column sm={2}>Comentario</Form.Label> - <Col sm={10}> - <Form.Control - placeholder="..." - value={this.state.comment} - onChange={e => this.setState({comment: e.target.value})} - /> - </Col> - </Form.Group> - <Form.Group as={Row}> - <Col sm={{ span: 10, offset: 2 }}> - <Button type="submit">Recarga</Button> - </Col> - </Form.Group> - </Form> - </Container> - </Fetcher> - ); + let alert; + if (this.state.error != null) { + alert = ( + <Alert variant="danger"> + Ha ocurrido un error enviando la compra: {this.state.error} + </Alert> + ); } + if (this.state.transactionId !== null) { + return <Redirect to={"/transaction/" + this.state.transactionId} />; + } + + return ( + <Fetcher + url="/api/member" + onFetch={(members) => this.setState({ members })} + > + <Container> + {alert} + <Form onSubmit={(e) => this.send(e)}> + <Form.Group as={Row}> + <Form.Label as="legend" column sm={2}> + Socia + </Form.Label> + <Col sm={5}> + <Form.Control + placeholder="numero de socia" + value={this.state.num} + onChange={(e) => this.setNum(e.target.value)} + isInvalid={this.state.numInvalid} + /> + </Col> + <Col sm={5}> + <Typeahead + id="name" + labelKey="name" + options={this.state.members} + onChange={(m) => this.setName(m[0])} + selected={this.state.name ? [this.state.name] : []} + /> + </Col> + </Form.Group> + <Form.Group as={Row}> + <Form.Label as="legend" column sm={2}> + Recarga + </Form.Label> + <Col sm={10}> + <InputGroup> + <Form.Control + type="number" + placeholder="euros" + value={this.state.amount} + onChange={(e) => this.setState({ amount: e.target.value })} + /> + <InputGroup.Append> + <InputGroup.Text>.00 €</InputGroup.Text> + </InputGroup.Append> + </InputGroup> + </Col> + </Form.Group> + <Form.Group as={Row}> + <Form.Label as="legend" column sm={2}> + Comentario + </Form.Label> + <Col sm={10}> + <Form.Control + placeholder="..." + value={this.state.comment} + onChange={(e) => this.setState({ comment: e.target.value })} + /> + </Col> + </Form.Group> + <Form.Group as={Row}> + <Col sm={{ span: 10, offset: 2 }}> + <Button type="submit">Recarga</Button> + </Col> + </Form.Group> + </Form> + </Container> + </Fetcher> + ); + } } export default Topup; diff --git a/src/TransactionList.js b/src/TransactionList.js index 74d1002..cdb656f 100644 --- a/src/TransactionList.js +++ b/src/TransactionList.js @@ -1,69 +1,79 @@ -import React, { useState } from 'react'; -import { Redirect } from 'react-router-dom'; -import BootstrapTable from 'react-bootstrap-table-next'; -import { FaShoppingBasket, FaMoneyBillAlt } from 'react-icons/fa'; -import { GiPayMoney, GiReceiveMoney } from 'react-icons/gi'; -import { HiClipboardCopy, HiClipboardList } from 'react-icons/hi'; -import Fetcher from './Fetcher'; -import { printMoney, printDate } from './util'; +import React, { useState } from "react"; +import { Redirect } from "react-router-dom"; +import BootstrapTable from "react-bootstrap-table-next"; +import { FaShoppingBasket, FaMoneyBillAlt } from "react-icons/fa"; +import { GiPayMoney, GiReceiveMoney } from "react-icons/gi"; +import { HiClipboardCopy, HiClipboardList } from "react-icons/hi"; +import Fetcher from "./Fetcher"; +import { printMoney, printDate } from "./util"; const columns = [ - {dataField: 'type', text: '', align: 'center', - formatter: (cell, row) => { - switch (cell) { - case "purchase": - return <FaShoppingBasket />; - case "topup": - if (row.total < 0) { - return <GiReceiveMoney />; - } - return <GiPayMoney />; - case "order": - return <HiClipboardList />; - case "refund": - return <HiClipboardCopy />; - default: - return <FaMoneyBillAlt />; - }; - }}, - {dataField: 'date', text: 'Fecha', formatter: printDate}, - {dataField: 'total', text: 'Cantidad', formatter: cell => printMoney(cell)+" €"}, -] + { + dataField: "type", + text: "", + align: "center", + formatter: (cell, row) => { + switch (cell) { + case "purchase": + return <FaShoppingBasket />; + case "topup": + if (row.total < 0) { + return <GiReceiveMoney />; + } + return <GiPayMoney />; + case "order": + return <HiClipboardList />; + case "refund": + return <HiClipboardCopy />; + default: + return <FaMoneyBillAlt />; + } + }, + }, + { dataField: "date", text: "Fecha", formatter: printDate }, + { + dataField: "total", + text: "Cantidad", + formatter: (cell) => printMoney(cell) + " €", + }, +]; function rowStyle(row) { - if (row.total < 0) { - return { - backgroundColor: "#fcbabf" - }; - } + if (row.total < 0) { return { - backgroundColor: "#c4fcba" + backgroundColor: "#fcbabf", }; + } + return { + backgroundColor: "#c4fcba", + }; } function TransactionList() { - const [transactions, setTransactions] = useState([]); - const [clickID, setClicID] = useState(null); + const [transactions, setTransactions] = useState([]); + const [clickID, setClicID] = useState(null); - if (clickID) { - return <Redirect to={"/transaction/"+clickID} push />; - } + if (clickID) { + return <Redirect to={"/transaction/" + clickID} push />; + } - return ( - <Fetcher url="/api/transaction/mine" onFetch={setTransactions} > - <BootstrapTable - keyField="ID" - data={ transactions } - columns={ columns } - rowEvents={{ - onClick: (_, row) => setClicID(row.ID) - }} - rowStyle={rowStyle} - classes="stripped" - bordered={ false } - /> - </Fetcher> - ); + // TODO: useEffect to disable fetcher... + + return ( + <Fetcher url="/api/transaction/mine" onFetch={setTransactions}> + <BootstrapTable + keyField="ID" + data={transactions} + columns={columns} + rowEvents={{ + onClick: (_, row) => setClicID(row.ID), + }} + rowStyle={rowStyle} + classes="stripped" + bordered={false} + /> + </Fetcher> + ); } export default TransactionList; diff --git a/src/index.js b/src/index.js index a9db757..4f0ecf1 100644 --- a/src/index.js +++ b/src/index.js @@ -1,16 +1,16 @@ -import React from 'react'; -import ReactDOM from 'react-dom'; -import App from './App'; -import * as serviceWorker from './serviceWorker'; -import 'bootstrap/dist/css/bootstrap.min.css'; -import 'react-bootstrap-table-next/dist/react-bootstrap-table2.min.css'; -import 'react-bootstrap-typeahead/css/Typeahead.css'; +import React from "react"; +import ReactDOM from "react-dom"; +import App from "./App"; +import * as serviceWorker from "./serviceWorker"; +import "bootstrap/dist/css/bootstrap.min.css"; +import "react-bootstrap-table-next/dist/react-bootstrap-table2.min.css"; +import "react-bootstrap-typeahead/css/Typeahead.css"; ReactDOM.render( <React.StrictMode> <App /> </React.StrictMode>, - document.getElementById('root') + document.getElementById("root") ); // If you want your app to work offline and load faster, you can change diff --git a/src/order/CreateOrder.js b/src/order/CreateOrder.js index 740021e..5cffff6 100644 --- a/src/order/CreateOrder.js +++ b/src/order/CreateOrder.js @@ -1,126 +1,150 @@ -import React from 'react'; -import { Redirect } from 'react-router-dom'; -import { Container, Form, Row, Col, Button, Alert, Spinner } from 'react-bootstrap'; -import ProductPicker from '../ProductPicker'; -import AuthContext from '../AuthContext'; +import React from "react"; +import { Redirect } from "react-router-dom"; +import { + Container, + Form, + Row, + Col, + Button, + Alert, + Spinner, +} from "react-bootstrap"; +import ProductPicker from "../ProductPicker"; +import AuthContext from "../AuthContext"; function date2string(date) { - return date.toISOString().split("T")[0]; + return date.toISOString().split("T")[0]; } function daysAfterNow(days) { - let date = new Date(); - date.setDate(date.getDate() + days); - return date; + let date = new Date(); + date.setDate(date.getDate() + days); + return date; } class CreateOrder extends React.Component { - static contextType = AuthContext; + static contextType = AuthContext; - constructor(props) { - super(props); - this.state = { - products: [], - name: "", - description: "", - deadline: daysAfterNow(3), - orderId: null, - isLoading: false, - error: null - }; - } + constructor(props) { + super(props); + this.state = { + products: [], + name: "", + description: "", + deadline: daysAfterNow(3), + orderId: null, + isLoading: false, + error: null, + }; + } - submit(e) { - e.preventDefault(); + submit(e) { + e.preventDefault(); - this.setState({isLoading: true, error: null, noMoney: false}); - const products = this.state.products.map(p => { - return { code: p.code }; - }); - const body = JSON.stringify({ - name: this.state.name, - description: this.state.description, - deadline: this.state.deadline, - products - }); - fetch("/api/order", {headers: {'x-authentication': this.context.token}, method: "POST", body}) - .then(response => { - if (!response.ok) { - throw new Error(response.status.toString()+' '+response.statusText); - } - return response.json(); - }) - .then(o => this.setState({orderId: o.ID, isLoading: false})) - .catch(error => this.setState({isLoading: false, error: error.message})); - } - - render() { - if (this.state.isLoading) { - return <Spinner animation="border" />; + this.setState({ isLoading: true, error: null, noMoney: false }); + const products = this.state.products.map((p) => { + return { code: p.code }; + }); + const body = JSON.stringify({ + name: this.state.name, + description: this.state.description, + deadline: this.state.deadline, + products, + }); + fetch("/api/order", { + headers: { "x-authentication": this.context.token }, + method: "POST", + body, + }) + .then((response) => { + if (!response.ok) { + throw new Error( + response.status.toString() + " " + response.statusText + ); } + return response.json(); + }) + .then((o) => this.setState({ orderId: o.ID, isLoading: false })) + .catch((error) => + this.setState({ isLoading: false, error: error.message }) + ); + } - let alert; - if (this.state.error != null) { - alert = ( - <Alert variant="danger"> - Ha ocurrido un error creando el pedido: {this.state.error} - </Alert> - ); - } - if (this.state.orderId !== null) { - return <Redirect to={"/order/"+this.state.orderId} />; - } + render() { + if (this.state.isLoading) { + return <Spinner animation="border" />; + } - return ( - <Container> - {alert} - <Form onSubmit={e => this.submit(e)}> - <Form.Group as={Row}> - <Form.Label as="legend" column sm={3}>Nombre</Form.Label> - <Col sm={9}> - <Form.Control - placeholder="nombre del pedido" - value={this.state.name} - onChange={e => this.setState({name: e.target.value})} - /> - </Col> - </Form.Group> - <Form.Group as={Row}> - <Form.Label as="legend" column sm={3}>Descripción</Form.Label> - <Col sm={9}> - <Form.Control - as='textarea' - value={this.state.description} - onChange={e => this.setState({description: e.target.value})} - /> - </Col> - </Form.Group> - <Form.Group as={Row}> - <Form.Label as="legend" column sm={3}>Fecha límite</Form.Label> - <Col sm={9}> - <Form.Control - type='date' - value={date2string(this.state.deadline)} - onChange={e => this.setState({deadline: Date(e.target.value)})} - min={date2string(daysAfterNow(1))} - /> - </Col> - </Form.Group> - <ProductPicker - picks={this.state.products} - setPicks={products => this.setState({ products })} - /> - <Form.Group as={Row}> - <Col> - <div className="text-right"> - <Button type="submit">Abrir pedido</Button> - </div> - </Col> - </Form.Group> - </Form> - </Container> - ); + let alert; + if (this.state.error != null) { + alert = ( + <Alert variant="danger"> + Ha ocurrido un error creando el pedido: {this.state.error} + </Alert> + ); + } + if (this.state.orderId !== null) { + return <Redirect to={"/order/" + this.state.orderId} />; } + + return ( + <Container> + {alert} + <Form onSubmit={(e) => this.submit(e)}> + <Form.Group as={Row}> + <Form.Label as="legend" column sm={3}> + Nombre + </Form.Label> + <Col sm={9}> + <Form.Control + placeholder="nombre del pedido" + value={this.state.name} + onChange={(e) => this.setState({ name: e.target.value })} + /> + </Col> + </Form.Group> + <Form.Group as={Row}> + <Form.Label as="legend" column sm={3}> + Descripción + </Form.Label> + <Col sm={9}> + <Form.Control + as="textarea" + value={this.state.description} + onChange={(e) => this.setState({ description: e.target.value })} + /> + </Col> + </Form.Group> + <Form.Group as={Row}> + <Form.Label as="legend" column sm={3}> + Fecha límite + </Form.Label> + <Col sm={9}> + <Form.Control + type="date" + value={date2string(this.state.deadline)} + onChange={(e) => + this.setState({ deadline: Date(e.target.value) }) + } + min={date2string(daysAfterNow(1))} + /> + </Col> + </Form.Group> + <ProductPicker + picks={this.state.products} + setPicks={(products) => this.setState({ products })} + /> + <Form.Group as={Row}> + <Col> + <div className="text-right"> + <Button type="submit">Abrir pedido</Button> + </div> + </Col> + </Form.Group> + </Form> + </Container> + ); + } } export default CreateOrder; diff --git a/src/order/OrderList.js b/src/order/OrderList.js index b6eaade..46507ae 100644 --- a/src/order/OrderList.js +++ b/src/order/OrderList.js @@ -1,27 +1,25 @@ -import React, { useState } from 'react'; -import Fetcher from '../Fetcher'; -import { Container, Card, Row, Col, Button } from 'react-bootstrap'; +import React, { useState } from "react"; +import Fetcher from "../Fetcher"; +import { Container, Card, Row, Col, Button } from "react-bootstrap"; function OrderList() { - const [ orders, setOrders ] = useState([]); - const order_list = orders.map(o => - <Card as={Col} sm={4}> - <Card.Body> - <Card.Title>{o.name}</Card.Title> - <Card.Text>{o.description}</Card.Text> - <Button href={"/order/"+o.ID}>Realizar pedido</Button> - </Card.Body> - </Card> - ); - return ( - <Container> - <Fetcher url={"/api/order/active"} onFetch={setOrders} > - <Row> - {order_list} - </Row> - </Fetcher> - </Container> - ); + const [orders, setOrders] = useState([]); + const order_list = orders.map((o) => ( + <Card as={Col} sm={4}> + <Card.Body> + <Card.Title>{o.name}</Card.Title> + <Card.Text>{o.description}</Card.Text> + <Button href={"/order/" + o.ID}>Realizar pedido</Button> + </Card.Body> + </Card> + )); + return ( + <Container> + <Fetcher url={"/api/order/active"} onFetch={setOrders}> + <Row>{order_list}</Row> + </Fetcher> + </Container> + ); } export default OrderList; diff --git a/src/order/PurchaseOrder.js b/src/order/PurchaseOrder.js index ea3ef20..3adb7ae 100644 --- a/src/order/PurchaseOrder.js +++ b/src/order/PurchaseOrder.js @@ -1,129 +1,144 @@ -import React from 'react'; -import { Alert, Spinner, Form, InputGroup, Button, Col, Row } from 'react-bootstrap'; -import AuthContext from '../AuthContext'; -import { printMoney } from '../util'; +import React from "react"; +import { + Alert, + Spinner, + Form, + InputGroup, + Button, + Col, + Row, +} from "react-bootstrap"; +import AuthContext from "../AuthContext"; +import { printMoney } from "../util"; class PurchaseOrder extends React.Component { - static contextType = AuthContext; + static contextType = AuthContext; - constructor(props) { - super(props); - let order = props.order.products; - order = order.map(p => { - p.amount = 0; - p.purchased = 0; - return p; - }); - props.order.transactions.forEach(t => { - t.order_purchase.forEach(purchase => { - const i = order.findIndex(p => p.code === purchase.product_code); - if (i) { - order[i].purchased += purchase.amount; - } - }); - }); - this.state = { - order: order, - total: 0, - isLoading: false, - noMoney: false, - error: null - }; - } + constructor(props) { + super(props); + let order = props.order.products; + order = order.map((p) => { + p.amount = 0; + p.purchased = 0; + return p; + }); + props.order.transactions.forEach((t) => { + t.order_purchase.forEach((purchase) => { + const i = order.findIndex((p) => p.code === purchase.product_code); + if (i) { + order[i].purchased += purchase.amount; + } + }); + }); + this.state = { + order: order, + total: 0, + isLoading: false, + noMoney: false, + error: null, + }; + } - send(e) { - e.preventDefault(); + send(e) { + e.preventDefault(); - this.setState({isLoading: true, error: null, noMoney: false}); - const purchase = this.state.order.map(p => { - return { - product_code: p.code, - amount: parseInt(p.amount) - }; - }); - const body = JSON.stringify({ - order: this.props.order.ID, - purchase + this.setState({ isLoading: true, error: null, noMoney: false }); + const purchase = this.state.order.map((p) => { + return { + product_code: p.code, + amount: parseInt(p.amount), + }; + }); + const body = JSON.stringify({ + order: this.props.order.ID, + purchase, + }); + console.log(body); + fetch("/api/order/purchase", { + headers: { "x-authentication": this.context.token }, + method: "POST", + body, + }).then((response) => { + if (response.status === 400) { + this.setState({ isLoading: false, noMoney: true }); + } else if (!response.ok) { + this.setState({ + isLoading: false, + error: response.status.toString() + " " + response.statusText, }); - console.log(body); - fetch("/api/order/purchase", {headers: {'x-authentication': this.context.token}, method: "POST", body}) - .then(response => { - if (response.status === 400) { - this.setState({isLoading: false, noMoney: true}); - } else if (!response.ok) { - this.setState({isLoading: false, error: response.status.toString()+' '+response.statusText}) - } else { - this.props.onSend(this.state.order, this.state.total); - } - }) - } + } else { + this.props.onSend(this.state.order, this.state.total); + } + }); + } - setAmount(index, amount) { - let order = this.state.order; - order[index].amount = amount; + setAmount(index, amount) { + let order = this.state.order; + order[index].amount = amount; - const add = (acc, p) => acc + (p.price*p.amount); - const total = order.reduce(add, 0); + const add = (acc, p) => acc + p.price * p.amount; + const total = order.reduce(add, 0); - this.setState({ order, total }); - } + this.setState({ order, total }); + } - render() { - if (this.state.isLoading) { - return <Spinner animation="border" />; - } + render() { + if (this.state.isLoading) { + return <Spinner animation="border" />; + } - let alert; - if (this.state.noMoney) { - alert = ( - <Alert variant="warning"> - No tienes suficiente dinero para realizar este pedido. - </Alert> - ); - } else if (this.state.error != null) { - alert = ( - <Alert variant="danger"> - Ha ocurrido un error enviando el pedido: {this.state.error} - </Alert> - ); - } + let alert; + if (this.state.noMoney) { + alert = ( + <Alert variant="warning"> + No tienes suficiente dinero para realizar este pedido. + </Alert> + ); + } else if (this.state.error != null) { + alert = ( + <Alert variant="danger"> + Ha ocurrido un error enviando el pedido: {this.state.error} + </Alert> + ); + } - const formEntries = this.state.order.map((p, i) => - <Form.Group key={p.code} as={Row}> - <Form.Label column className="text-right"> - {p.name} ({p.code}): - </Form.Label> - <Col> - <InputGroup> - <Form.Control - type="number" min="0" - placeholder="cantidad" - value={p.amount} - onChange={e => this.setAmount(i, e.target.value)} - /> - <InputGroup.Append> - <InputGroup.Text>{printMoney(p.price)}€</InputGroup.Text> - </InputGroup.Append> - </InputGroup> - </Col> - </Form.Group> - ); + const formEntries = this.state.order.map((p, i) => ( + <Form.Group key={p.code} as={Row}> + <Form.Label column className="text-right"> + {p.name} ({p.code}): + </Form.Label> + <Col> + <InputGroup> + <Form.Control + type="number" + min="0" + placeholder="cantidad" + value={p.amount} + onChange={(e) => this.setAmount(i, e.target.value)} + /> + <InputGroup.Append> + <InputGroup.Text>{printMoney(p.price)}€</InputGroup.Text> + </InputGroup.Append> + </InputGroup> + </Col> + </Form.Group> + )); - return ( - <Form onSubmit={e => this.send(e)}> - {alert} - {formEntries} - <Form.Group as={Row}> - <Col className="text-right"> - <Button type="submit">Realizar pedido</Button> - </Col> - <Col> - <h3>Total: {printMoney(this.state.total)}€</h3> - </Col> - </Form.Group> - </Form> - ); - } + return ( + <Form onSubmit={(e) => this.send(e)}> + {alert} + {formEntries} + <Form.Group as={Row}> + <Col className="text-right"> + <Button type="submit">Realizar pedido</Button> + </Col> + <Col> + <h3>Total: {printMoney(this.state.total)}€</h3> + </Col> + </Form.Group> + </Form> + ); + } } export default PurchaseOrder; diff --git a/src/order/ShowOrder.js b/src/order/ShowOrder.js index 723c3bb..dbafbd7 100644 --- a/src/order/ShowOrder.js +++ b/src/order/ShowOrder.js @@ -1,130 +1,151 @@ -import React from 'react'; -import Fetcher from '../Fetcher'; -import { Container, Row, Col, Badge } from 'react-bootstrap'; -import PurchaseOrder from './PurchaseOrder'; -import { printDate } from '../util'; -import AuthContext from '../AuthContext'; -import { printMoney } from '../util'; +import React from "react"; +import Fetcher from "../Fetcher"; +import { Container, Row, Col, Badge } from "react-bootstrap"; +import PurchaseOrder from "./PurchaseOrder"; +import { printDate } from "../util"; +import AuthContext from "../AuthContext"; +import { printMoney } from "../util"; function ShowOrderTransaction(props) { - const list = props.transaction.order_purchase.map(o => - <li key={o.product.code}> - {o.product.name} ({o.product.code}): {o.amount} - </li> - ); - return ( - <div> - <h3>Mi pedido</h3> - <ul> - {list} - </ul> - <p>Total: {printMoney(-props.transaction.total)} €</p> - </div> - ); + const list = props.transaction.order_purchase.map((o) => ( + <li key={o.product.code}> + {o.product.name} ({o.product.code}): {o.amount} + </li> + )); + return ( + <div> + <h3>Mi pedido</h3> + <ul>{list}</ul> + <p>Total: {printMoney(-props.transaction.total)} €</p> + </div> + ); } function ShowOrderResults(props) { - let products = props.order.products.map(p => { - p.amount = 0; - return p; - }); - const transactions = props.order.transactions.map(t => { - const list = t.order_purchase.map(purchase => { - const i = products.findIndex(p => p.code === purchase.product_code); - if (!i) { - return null; - } - products[i].amount += purchase.amount; - if (purchase.amount) { - const key = t.member.num.toString() + "-" + purchase.product_code.toString(); - return <li key={key}>{products[i].name} {purchase.amount}</li>; - } - return null; - }); + let products = props.order.products.map((p) => { + p.amount = 0; + return p; + }); + const transactions = props.order.transactions.map((t) => { + const list = t.order_purchase.map((purchase) => { + const i = products.findIndex((p) => p.code === purchase.product_code); + if (!i) { + return null; + } + products[i].amount += purchase.amount; + if (purchase.amount) { + const key = + t.member.num.toString() + "-" + purchase.product_code.toString(); return ( - <li key={t.member.num}> - {t.member.name} ({t.member.num}): - <ul> - {list} - </ul> - </li> + <li key={key}> + {products[i].name} {purchase.amount} + </li> ); + } + return null; }); - - const product_list = products.map(p => <li key={p.code}>{p.name}: {p.amount}</li>); return ( - <div> - <h3>Productos pedidos</h3> - <ul>{product_list}</ul> - - <h3>Pedidos</h3> - <ul>{transactions}</ul> - </div> + <li key={t.member.num}> + {t.member.name} ({t.member.num}): + <ul>{list}</ul> + </li> ); + }); + + const product_list = products.map((p) => ( + <li key={p.code}> + {p.name}: {p.amount} + </li> + )); + return ( + <div> + <h3>Productos pedidos</h3> + <ul>{product_list}</ul> + + <h3>Pedidos</h3> + <ul>{transactions}</ul> + </div> + ); } class ShowOrder extends React.Component { - static contextType = AuthContext; + static contextType = AuthContext; - constructor(props) { - super(props); - this.state = { - order: { - products: [], - transactions: [] - }, - transaction: null - }; - } + constructor(props) { + super(props); + this.state = { + order: { + products: [], + transactions: [], + }, + transaction: null, + }; + } - onSend(purchase, total) { - const order_purchase = purchase.map(p => { - p.product = p; - return p; - }); - const transaction = { order_purchase, total: -total }; - this.setState({ transaction }); - } + onSend(purchase, total) { + const order_purchase = purchase.map((p) => { + p.product = p; + return p; + }); + const transaction = { order_purchase, total: -total }; + this.setState({ transaction }); + } - showTransaction() { - if (this.state.transaction) { - return <ShowOrderTransaction order={this.state.order} transaction={this.state.transaction} />; - } - if (this.state.order.active) { - return <PurchaseOrder order={this.state.order} onSend={(p, t) => this.onSend(p, t)}/> - } + showTransaction() { + if (this.state.transaction) { + return ( + <ShowOrderTransaction + order={this.state.order} + transaction={this.state.transaction} + /> + ); } - - setData(data) { - this.setState({ order: data.order, transaction: data.transaction }); + if (this.state.order.active) { + return ( + <PurchaseOrder + order={this.state.order} + onSend={(p, t) => this.onSend(p, t)} + /> + ); } + } - render() { - let expired; - if (!this.state.order.active) { - expired = <Badge variant="info">finalizado</Badge> - } + setData(data) { + this.setState({ order: data.order, transaction: data.transaction }); + } - const { id } = this.props.match.params; - return ( - <Container> - <Fetcher url={"/api/order/"+id} onFetch={data => this.setData(data)} > - <Row> - <Col> - <h1>{this.state.order.name}</h1> - </Col> - <Col> - <p className="text-right">Fecha limite: {printDate(this.state.order.deadline)}{expired}</p> - </Col> - </Row> - <p>{this.state.order.description}</p> - - {this.showTransaction()} - <ShowOrderResults order={this.state.order} /> - </Fetcher> - </Container> - ); + render() { + let expired; + if (!this.state.order.active) { + expired = <Badge variant="info">finalizado</Badge>; } + + const { id } = this.props.match.params; + return ( + <Container> + <Fetcher + url={"/api/order/" + id} + onFetch={(data) => this.setData(data)} + > + <Row> + <Col> + <h1>{this.state.order.name}</h1> + </Col> + <Col> + <p className="text-right"> + Fecha limite: {printDate(this.state.order.deadline)} + {expired} + </p> + </Col> + </Row> + <p>{this.state.order.description}</p> + + {this.showTransaction()} + <ShowOrderResults order={this.state.order} /> + </Fetcher> + </Container> + ); + } } export default ShowOrder; diff --git a/src/purchase/Purchase.js b/src/purchase/Purchase.js index 0dac522..24b5981 100644 --- a/src/purchase/Purchase.js +++ b/src/purchase/Purchase.js @@ -1,106 +1,115 @@ -import React from 'react'; -import { Redirect } from 'react-router-dom'; -import { Container, Row, Col, Button, Alert, Spinner } from 'react-bootstrap'; -import ProductPicker from '../ProductPicker'; -import AuthContext from '../AuthContext'; -import { printMoney } from '../util'; +import React from "react"; +import { Redirect } from "react-router-dom"; +import { Container, Row, Col, Button, Alert, Spinner } from "react-bootstrap"; +import ProductPicker from "../ProductPicker"; +import AuthContext from "../AuthContext"; +import { printMoney } from "../util"; class Purchase extends React.Component { - static contextType = AuthContext; + static contextType = AuthContext; - constructor(props) { - super(props); - this.state = { - purchase: [], - total: 0, - transactionId: null, - isLoading: false, - noMoney: false, - error: null - }; - } - - setPurchase(purchase) { - const add = (acc, p) => acc + (p.price*p.amount); - const total = purchase.reduce(add, 0); - this.setState({ purchase, total }); - } - - send() { - this.setState({isLoading: true, error: null, noMoney: false}); - const body = JSON.stringify(this.state.purchase.map(p => { - return { - code: p.code, - amount: p.amount - }; - })); - fetch("/api/purchase", {headers: {'x-authentication': this.context.token}, method: "POST", body}) - .then(response => { - if (response.status === 400) { - var error = new Error("Not enough money"); - error.name ="not-money"; - throw error; - } else if (!response.ok) { - throw new Error(response.status.toString()+' '+response.statusText); - } - return response.json(); - }) - .then(p => { - this.setState({transactionId: p.ID, isLoading: false}); - }) - .catch(error => { - if (error.name === "not-money") { - this.setState({isLoading: false, noMoney: true}); - } else { - this.setState({isLoading: false, error: error.message}) - } - }); - } + constructor(props) { + super(props); + this.state = { + purchase: [], + total: 0, + transactionId: null, + isLoading: false, + noMoney: false, + error: null, + }; + } - render() { - if (this.state.isLoading) { - return <Spinner animation="border" />; - } + setPurchase(purchase) { + const add = (acc, p) => acc + p.price * p.amount; + const total = purchase.reduce(add, 0); + this.setState({ purchase, total }); + } - let alert; - if (this.state.noMoney) { - alert = ( - <Alert variant="warning"> - No tienes suficiente dinero para realizar esta compra. - </Alert> - ); - } else if (this.state.error != null) { - alert = ( - <Alert variant="danger"> - Ha ocurrido un error enviando la compra: {this.state.error} - </Alert> - ); + send() { + this.setState({ isLoading: true, error: null, noMoney: false }); + const body = JSON.stringify( + this.state.purchase.map((p) => { + return { + code: p.code, + amount: p.amount, + }; + }) + ); + fetch("/api/purchase", { + headers: { "x-authentication": this.context.token }, + method: "POST", + body, + }) + .then((response) => { + if (response.status === 400) { + var error = new Error("Not enough money"); + error.name = "not-money"; + throw error; + } else if (!response.ok) { + throw new Error( + response.status.toString() + " " + response.statusText + ); } - if (this.state.transactionId !== null) { - return <Redirect to={"/transaction/"+this.state.transactionId} />; + return response.json(); + }) + .then((p) => { + this.setState({ transactionId: p.ID, isLoading: false }); + }) + .catch((error) => { + if (error.name === "not-money") { + this.setState({ isLoading: false, noMoney: true }); + } else { + this.setState({ isLoading: false, error: error.message }); } + }); + } + + render() { + if (this.state.isLoading) { + return <Spinner animation="border" />; + } - return ( - <Container> - {alert} - <ProductPicker amount - picks={this.state.purchase} - setPicks={purchase => this.setPurchase(purchase)} - /> - <br /> - <Row> - <Col> - <h3>Total: {printMoney(this.state.total)}€</h3> - </Col> - <Col> - <div className="text-right"> - <Button onClick={() => this.send()}>Finalizar compra</Button> - </div> - </Col> - </Row> - </Container> - ); + let alert; + if (this.state.noMoney) { + alert = ( + <Alert variant="warning"> + No tienes suficiente dinero para realizar esta compra. + </Alert> + ); + } else if (this.state.error != null) { + alert = ( + <Alert variant="danger"> + Ha ocurrido un error enviando la compra: {this.state.error} + </Alert> + ); + } + if (this.state.transactionId !== null) { + return <Redirect to={"/transaction/" + this.state.transactionId} />; } + + return ( + <Container> + {alert} + <ProductPicker + amount + picks={this.state.purchase} + setPicks={(purchase) => this.setPurchase(purchase)} + /> + <br /> + <Row> + <Col> + <h3>Total: {printMoney(this.state.total)}€</h3> + </Col> + <Col> + <div className="text-right"> + <Button onClick={() => this.send()}>Finalizar compra</Button> + </div> + </Col> + </Row> + </Container> + ); + } } export default Purchase; diff --git a/src/purchase/ShowPurchase.js b/src/purchase/ShowPurchase.js index 0a0da36..9ce53b6 100644 --- a/src/purchase/ShowPurchase.js +++ b/src/purchase/ShowPurchase.js @@ -1,22 +1,22 @@ -import React from 'react'; -import BootstrapTable from 'react-bootstrap-table-next'; -import { printMoney } from '../util'; +import React from "react"; +import BootstrapTable from "react-bootstrap-table-next"; +import { printMoney } from "../util"; const columns = [ - {dataField: 'code', text: 'Codigo'}, - {dataField: 'product.name', text: 'Nombre'}, - {dataField: 'price', text: 'Precio', formatter: cell => printMoney(cell)+" €"}, - {dataField: 'amount', text: 'Cantidad'}, -] + { dataField: "code", text: "Codigo" }, + { dataField: "product.name", text: "Nombre" }, + { + dataField: "price", + text: "Precio", + formatter: (cell) => printMoney(cell) + " €", + }, + { dataField: "amount", text: "Cantidad" }, +]; function ShowPurchase(props) { - return ( - <BootstrapTable - keyField="code" - data={ props.purchase } - columns={ columns } - /> - ) + return ( + <BootstrapTable keyField="code" data={props.purchase} columns={columns} /> + ); } export default ShowPurchase; diff --git a/src/serviceWorker.js b/src/serviceWorker.js index b04b771..c7cd666 100644 --- a/src/serviceWorker.js +++ b/src/serviceWorker.js @@ -11,9 +11,9 @@ // opt-in, read https://bit.ly/CRA-PWA const isLocalhost = Boolean( - window.location.hostname === 'localhost' || + window.location.hostname === "localhost" || // [::1] is the IPv6 localhost address. - window.location.hostname === '[::1]' || + window.location.hostname === "[::1]" || // 127.0.0.0/8 are considered localhost for IPv4. window.location.hostname.match( /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ @@ -21,7 +21,7 @@ const isLocalhost = Boolean( ); export function register(config) { - if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { + if (process.env.NODE_ENV === "production" && "serviceWorker" in navigator) { // The URL constructor is available in all browsers that support SW. const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href); if (publicUrl.origin !== window.location.origin) { @@ -31,7 +31,7 @@ export function register(config) { return; } - window.addEventListener('load', () => { + window.addEventListener("load", () => { const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; if (isLocalhost) { @@ -42,8 +42,8 @@ export function register(config) { // service worker/PWA documentation. navigator.serviceWorker.ready.then(() => { console.log( - 'This web app is being served cache-first by a service ' + - 'worker. To learn more, visit https://bit.ly/CRA-PWA' + "This web app is being served cache-first by a service " + + "worker. To learn more, visit https://bit.ly/CRA-PWA" ); }); } else { @@ -57,21 +57,21 @@ export function register(config) { function registerValidSW(swUrl, config) { navigator.serviceWorker .register(swUrl) - .then(registration => { + .then((registration) => { registration.onupdatefound = () => { const installingWorker = registration.installing; if (installingWorker == null) { return; } installingWorker.onstatechange = () => { - if (installingWorker.state === 'installed') { + if (installingWorker.state === "installed") { if (navigator.serviceWorker.controller) { // At this point, the updated precached content has been fetched, // but the previous service worker will still serve the older // content until all client tabs are closed. console.log( - 'New content is available and will be used when all ' + - 'tabs for this page are closed. See https://bit.ly/CRA-PWA.' + "New content is available and will be used when all " + + "tabs for this page are closed. See https://bit.ly/CRA-PWA." ); // Execute callback @@ -82,7 +82,7 @@ function registerValidSW(swUrl, config) { // At this point, everything has been precached. // It's the perfect time to display a // "Content is cached for offline use." message. - console.log('Content is cached for offline use.'); + console.log("Content is cached for offline use."); // Execute callback if (config && config.onSuccess) { @@ -93,25 +93,25 @@ function registerValidSW(swUrl, config) { }; }; }) - .catch(error => { - console.error('Error during service worker registration:', error); + .catch((error) => { + console.error("Error during service worker registration:", error); }); } function checkValidServiceWorker(swUrl, config) { // Check if the service worker can be found. If it can't reload the page. fetch(swUrl, { - headers: { 'Service-Worker': 'script' }, + headers: { "Service-Worker": "script" }, }) - .then(response => { + .then((response) => { // Ensure service worker exists, and that we really are getting a JS file. - const contentType = response.headers.get('content-type'); + const contentType = response.headers.get("content-type"); if ( response.status === 404 || - (contentType != null && contentType.indexOf('javascript') === -1) + (contentType != null && contentType.indexOf("javascript") === -1) ) { // No service worker found. Probably a different app. Reload the page. - navigator.serviceWorker.ready.then(registration => { + navigator.serviceWorker.ready.then((registration) => { registration.unregister().then(() => { window.location.reload(); }); @@ -123,18 +123,18 @@ function checkValidServiceWorker(swUrl, config) { }) .catch(() => { console.log( - 'No internet connection found. App is running in offline mode.' + "No internet connection found. App is running in offline mode." ); }); } export function unregister() { - if ('serviceWorker' in navigator) { + if ("serviceWorker" in navigator) { navigator.serviceWorker.ready - .then(registration => { + .then((registration) => { registration.unregister(); }) - .catch(error => { + .catch((error) => { console.error(error.message); }); } diff --git a/src/setupTests.js b/src/setupTests.js index 74b1a27..5fdf001 100644 --- a/src/setupTests.js +++ b/src/setupTests.js @@ -2,4 +2,4 @@ // allows you to do things like: // expect(element).toHaveTextContent(/react/i) // learn more: https://github.com/testing-library/jest-dom -import '@testing-library/jest-dom/extend-expect'; +import "@testing-library/jest-dom/extend-expect"; diff --git a/src/util.js b/src/util.js index 11b6c56..4bbe1da 100644 --- a/src/util.js +++ b/src/util.js @@ -1,9 +1,9 @@ function printMoney(money) { - return (money/100).toFixed(2); + return (money / 100).toFixed(2); } function printDate(date) { - return new Date(date).toLocaleDateString(); + return new Date(date).toLocaleDateString(); } export { printMoney, printDate }; -- GitLab