diff --git a/src/App.js b/src/App.js
index 6b9a96560db66ca8fb5dc8e02909581afe5f1b02..44d69df44aa02156e250fb82f73dd197f077f849 100644
--- a/src/App.js
+++ b/src/App.js
@@ -1,6 +1,7 @@
 import React from 'react';
 import { BrowserRouter, Switch, Route } from 'react-router-dom';
 import MemberList from './member';
+import ProductList from './ProductList';
 import Dashboard from './Dashboard';
 import AuthContext from './AuthContext';
 import SignIn from './SignIn';
@@ -15,6 +16,9 @@ function Panel(props) {
                 <Route path="/members">
                     <MemberList />
                 </Route>
+                <Route path="/products">
+                    <ProductList />
+                </Route>
                 <Route path="/">
                     <Dashboard />
                 </Route>
diff --git a/src/Dashboard.js b/src/Dashboard.js
index 104ba0cbaad0d00ca62ebdc3e41b005b4ea145ec..4273d3ff511f33fe9fc09981dbce3677adddca19 100644
--- a/src/Dashboard.js
+++ b/src/Dashboard.js
@@ -1,6 +1,7 @@
 import React from 'react';
 import AuthContext from './AuthContext';
 import { Container, Spinner, Alert, Row } from 'react-bootstrap';
+import printMoney from './util';
 
 class Dashboard extends React.Component {
     static contextType = AuthContext;
@@ -50,7 +51,7 @@ class Dashboard extends React.Component {
         return (
             <Container>
                 <h1>{this.state.name}</h1>
-                <p>Saldo: {(this.state.balance/100).toFixed(2)}</p>
+                <p>Saldo: {printMoney(this.state.balance)}</p>
             </Container>
         );
     }
diff --git a/src/Head.js b/src/Head.js
index f9a141d824d7de44f2ff1e846f3a5f8b9f3118eb..7422b9a003f5662ac92da4c84d88f05038ab476a 100644
--- a/src/Head.js
+++ b/src/Head.js
@@ -12,6 +12,7 @@ function Head(props) {
             <Navbar.Collapse id="basic-navbar-nav">
                 <Nav className="mr-auto">
                     <Nav.Link href="/">Dashboard</Nav.Link>
+                    <Nav.Link href="/products">Productos</Nav.Link>
                     <Nav.Link href="/members">Socias</Nav.Link>
                 </Nav>
                 <Form inline>
diff --git a/src/ProductList.js b/src/ProductList.js
new file mode 100644
index 0000000000000000000000000000000000000000..2eb7f970cf99d16491681d2f481f59ae4c9dad3c
--- /dev/null
+++ b/src/ProductList.js
@@ -0,0 +1,79 @@
+import React from 'react';
+import { Table, Spinner, Alert, Row } from 'react-bootstrap';
+import AuthContext from './AuthContext';
+import printMoney from './util';
+
+class ProductList extends React.Component {
+    static contextType = AuthContext;
+
+    constructor(props) {
+        super(props);
+        this.state = {
+            products: [],
+            isLoading: false,
+            error: null
+        };
+    }
+
+    componentDidMount() {
+        this.setState({ isLoading: true });
+
+        fetch('/api/product', { headers: { 'x-authentication': this.context.token }})
+            .then(response => {
+                if (!response.ok) {
+                    throw new Error(response.status.toString()+' '+response.statusText);
+                }
+                return response.json();
+            })
+            .then(products => this.setState({ products, isLoading: false }))
+            .catch(e => this.setState({ error: e.message, isLoading: false }));
+    }
+
+    render() {
+        if (this.state.isLoading) {
+            return (
+              <Row className="justify-content-md-center">
+                <Spinner animation="border" />
+              </Row>
+            );
+        }
+
+        if (this.state.error != null) {
+            console.log(this.state.error);
+            return (
+                <Alert variant="danger">
+                   Ha ocurrido un error cargando el listado de productos: {this.state.error}
+                </Alert>
+            );
+        }
+
+        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 (
+            <Table striped bordered hover>
+                <thead>
+                    <tr>
+                        <th>codigo</th>
+                        <th>Nombre</th>
+                        <th>Precio</th>
+                        <th>Existencias</th>
+                    </tr>
+                </thead>
+                <tbody>
+                    {entries}
+                </tbody>
+            </Table>
+        );
+    }
+}
+
+export default ProductList;
diff --git a/src/member.js b/src/member.js
index e39b4cdba29812622a1346ab14b6aff1dcea7d57..6fda8cc58d5a52a82d00664fd4a4be9e2c71567a 100644
--- a/src/member.js
+++ b/src/member.js
@@ -1,6 +1,7 @@
 import React from 'react';
 import { Table, Spinner, Alert, Row } from 'react-bootstrap';
 import AuthContext from './AuthContext';
+import printMoney from './util';
 
 class MemberList extends React.Component {
     static contextType = AuthContext;
@@ -52,7 +53,7 @@ class MemberList extends React.Component {
                     <td>{member.num}</td>
                     <td>{member.name}</td>
                     <td>{member.email}</td>
-                    <td>{(member.balance/100).toFixed(2)}</td>
+                    <td>{printMoney(member.balance)}</td>
                 </tr>
             )
         });
diff --git a/src/util.js b/src/util.js
new file mode 100644
index 0000000000000000000000000000000000000000..c55886327228085ddd487173c59b33dcbd545a59
--- /dev/null
+++ b/src/util.js
@@ -0,0 +1,5 @@
+function printMoney(money) {
+    return (money/100).toFixed(2);
+}
+
+export default printMoney;