From ab35c30f1caaebdede30aa382f06d62c99b4daf9 Mon Sep 17 00:00:00 2001
From: meskio <meskio@sindominio.net>
Date: Fri, 23 Oct 2020 19:13:27 +0200
Subject: [PATCH] Edit members

---
 setup.sh            |   2 +-
 src/EditableCell.js |   6 +-
 src/MemberList.js   | 137 +++++++++++++++++++++++++++++++++++++++++---
 src/ProductList.js  |   2 +
 4 files changed, 137 insertions(+), 10 deletions(-)

diff --git a/setup.sh b/setup.sh
index 5e3d79b..95491aa 100755
--- a/setup.sh
+++ b/setup.sh
@@ -5,7 +5,7 @@ ADDR="localhost:8080"
 
 # set up members
 curl -H "x-authentication: $TOKEN" -X "POST" -d '{"num": 900, "login": "admin", "name": "Administradora", "email": "admin@example.com", "phone": "654321123", "password": "admin", "role": "admin", "balance": 10000}' $ADDR/api/member
-curl -H "x-authentication: $TOKEN" -X "POST" -d '{"num": 901, "login": "socia", "name": "Socia Aicos", "email": "socia@example.com", "phone": "678900123", "password": "socia", "balance": 10000}' $ADDR/api/member
+curl -H "x-authentication: $TOKEN" -X "POST" -d '{"num": 901, "login": "socia", "name": "Socia Aicos", "email": "socia@example.com", "phone": "678900123", "password": "socia", "role": "member", "balance": 10000}' $ADDR/api/member
 
 # set up products
 curl -H "x-authentication: $TOKEN" -X "POST" -d '{"code": 234, "name": "aceite", "price": 1700, "stock": 35}' $ADDR/api/product
diff --git a/src/EditableCell.js b/src/EditableCell.js
index 566b7d1..d54c937 100644
--- a/src/EditableCell.js
+++ b/src/EditableCell.js
@@ -18,7 +18,11 @@ function EditableCell(props) {
   return (
     <td>
       <Form onSubmit={submit}>
-        <Form.Control value={data} onChange={(e) => setData(e.target.value)} />
+        <Form.Control
+          value={data}
+          onChange={(e) => setData(e.target.value)}
+          onBlur={() => setEditing(false)}
+        />
       </Form>
     </td>
   );
diff --git a/src/MemberList.js b/src/MemberList.js
index ebd52ee..eb3bd39 100644
--- a/src/MemberList.js
+++ b/src/MemberList.js
@@ -1,42 +1,163 @@
 import React from "react";
-import { Table } from "react-bootstrap";
+import { Table, Alert, Form, Button } from "react-bootstrap";
 import Fetcher from "./Fetcher";
+import EditableCell from "./EditableCell";
+import AuthContext from "./AuthContext";
 import { printMoney } from "./util";
 
 class MemberList extends React.Component {
+  static contextType = AuthContext;
+
   constructor(props) {
     super(props);
     this.state = {
       members: [],
+      error: null,
     };
   }
 
+  update(row, key, value) {
+    this.setState({ error: null });
+
+    let members = this.state.members;
+    const num = members[row].num;
+
+    if (key === "num") {
+      value = parseInt(value);
+    }
+    members[row][key] = value;
+    this.setState({ members });
+
+    let update = {};
+    update[key] = value;
+    const body = JSON.stringify(update);
+    fetch("/api/member/" + num, {
+      headers: { "x-authentication": this.context.token },
+      method: "PUT",
+      body,
+    }).then((response) => {
+      if (!response.ok) {
+        this.setState({
+          error: response.status.toString() + " " + response.statusText,
+        });
+      }
+    });
+  }
+
+  setAdmin(row, checked) {
+    const role = checked ? "admin" : "member";
+    this.update(row, "role", role);
+  }
+
+  delMember(num) {
+    let members = this.state.members;
+    const index = members.findIndex((m) => m.num === num);
+    members.splice(index, 1);
+    this.setState({ members });
+
+    fetch("/api/member/" + num, {
+      headers: { "x-authentication": this.context.token },
+      method: "DELETE",
+    }).then((response) => {
+      if (!response.ok) {
+        this.setState({
+          error: response.status.toString() + " " + response.statusText,
+        });
+      }
+    });
+  }
+
+  addMember(member) {
+    let members = this.state.members;
+    members.push(member);
+    this.setState({ members });
+
+    const body = JSON.stringify(member);
+    fetch("/api/member", {
+      headers: { "x-authentication": this.context.token },
+      method: "POST",
+      body,
+    }).then((response) => {
+      if (!response.ok) {
+        this.setState({
+          error: response.status.toString() + " " + response.statusText,
+        });
+      }
+    });
+  }
+
   render() {
-    const entries = this.state.members.map((member) => {
+    let alert = null;
+    if (this.state.error !== null) {
+      alert = (
+        <Alert variant="danger">
+          Ha ocurrido un error enviando cambios: {this.state.error}
+        </Alert>
+      );
+    }
+
+    const entries = this.state.members.map((member, row) => {
       return (
         <tr key={member.num}>
-          <td>{member.num}</td>
-          <td>{member.name}</td>
-          <td>{member.email}</td>
-          <td>{member.phone}</td>
-          <td>{printMoney(member.balance)} €</td>
+          <EditableCell
+            onChange={(v) => this.update(row, "num", v)}
+            value={member.num}
+          />
+          <EditableCell
+            onChange={(v) => this.update(row, "login", v)}
+            value={member.login}
+          />
+          <EditableCell
+            onChange={(v) => this.update(row, "name", v)}
+            value={member.name}
+          />
+          <EditableCell
+            onChange={(v) => this.update(row, "email", v)}
+            value={member.email}
+          />
+          <EditableCell
+            onChange={(v) => this.update(row, "phone", v)}
+            value={member.phone}
+          />
+          <td>{printMoney(member.balance)}€</td>
+          <td sm={1}>
+            <Form>
+              <Form.Check
+                type="switch"
+                id={"admin-" + member.num}
+                label=""
+                checked={member.role === "admin"}
+                onChange={(e) => this.setAdmin(row, e.target.checked)}
+              />
+            </Form>
+          </td>
+          <td sm={1}>
+            <Button variant="danger" onClick={() => this.delMember(member.num)}>
+              -
+            </Button>
+          </td>
         </tr>
       );
     });
 
+    // TODO: add member
     return (
       <Fetcher
         url="/api/member"
         onFetch={(members) => this.setState({ members })}
       >
+        {alert}
         <Table striped bordered hover>
           <thead>
             <tr>
-              <th>Numero</th>
+              <th></th>
+              <th>Login</th>
               <th>Nombre</th>
               <th>Email</th>
               <th>Telefono</th>
               <th>Saldo</th>
+              <th sm={1}>Admin</th>
+              <th sm={1}></th>
             </tr>
           </thead>
           <tbody>{entries}</tbody>
diff --git a/src/ProductList.js b/src/ProductList.js
index e3bd6fd..02f7001 100644
--- a/src/ProductList.js
+++ b/src/ProductList.js
@@ -31,6 +31,8 @@ class ProductList extends React.Component {
       case "price":
         value = value * 100;
         break;
+      default:
+        break;
     }
     products[row][key] = value;
     this.setState({ products });
-- 
GitLab