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