From f6070e2803a6a94bc8959860b26e24418d3d5b35 Mon Sep 17 00:00:00 2001
From: meskio <meskio@sindominio.net>
Date: Mon, 4 Jan 2021 13:54:30 +0100
Subject: [PATCH] Add a price editor component

---
 src/PriceEditor.js  | 55 ++++++++++++++++++++++++++
 src/ProductAdder.js | 96 +++++++++++++++++++--------------------------
 src/Topup.js        | 19 +++------
 3 files changed, 100 insertions(+), 70 deletions(-)
 create mode 100644 src/PriceEditor.js

diff --git a/src/PriceEditor.js b/src/PriceEditor.js
new file mode 100644
index 0000000..eccbdf8
--- /dev/null
+++ b/src/PriceEditor.js
@@ -0,0 +1,55 @@
+import React, { useState } from "react";
+import { Form } from "react-bootstrap";
+
+function str2price(str) {
+  let value = str.split(",");
+  let cents = 0;
+
+  if (value.length > 2) {
+    return NaN;
+  }
+
+  if (value.length === 1) {
+    value = str.split(".");
+  }
+
+  if (value.length === 2) {
+    if (value[1].length > 2) {
+      return NaN;
+    }
+
+    cents = parseInt(value[1]);
+    if (value[1].length === 1) {
+      cents = cents * 10;
+    }
+    if (cents > 99) {
+      return NaN;
+    }
+  }
+
+  return parseInt(value[0]) * 100 + cents;
+}
+
+function PriceEditor(props) {
+  const [value, setValue] = useState("0,00");
+  const [invalid, setInvalid] = useState(false);
+
+  if (!isNaN(props.value) && str2price(value) !== props.value) {
+    let centStr = (props.value % 100).toString();
+    if (centStr.length === 1) {
+      centStr = "0" + centStr;
+    }
+    setValue(Math.floor(props.value / 100) + "," + centStr);
+  }
+
+  const change = (e) => {
+    setValue(e.target.value);
+    const price = str2price(e.target.value);
+    props.onChange(price);
+    setInvalid(isNaN(price));
+  };
+
+  return <Form.Control value={value} onChange={change} isInvalid={invalid} />;
+}
+
+export default PriceEditor;
diff --git a/src/ProductAdder.js b/src/ProductAdder.js
index 4791361..186db84 100644
--- a/src/ProductAdder.js
+++ b/src/ProductAdder.js
@@ -1,80 +1,64 @@
 import React, { useState } from "react";
-import { Form, InputGroup, Col, Row, Button } from "react-bootstrap";
+import { Form, Button } from "react-bootstrap";
+import PriceEditor from "./PriceEditor";
 
 function ProductAdder(props) {
-  const [code, setCode] = useState();
+  const [code, setCode] = useState("");
   const [name, setName] = useState("");
-  const [eur, setEur] = useState(0);
-  const [cents, setCents] = useState(0);
+  const [price, setPrice] = useState(0);
   const [stock, setStock] = useState(0);
 
   const add = (e) => {
     e.preventDefault();
     props.addProduct({
       code: parseInt(code),
-      price: parseInt(eur) * 100 + parseInt(cents),
+      price: price,
       stock: parseInt(stock),
       name,
     });
     setCode("");
     setName("");
-    setEur("");
-    setCents("");
+    setPrice(0);
     setStock("");
   };
 
+  const disabled = isNaN(price) || isNaN(parseInt(code)) || !name;
+
   return (
     <Form onSubmit={add}>
-      <Form.Group as={Row}>
-        <Col>
-          <Form.Control
-            type="number"
-            placeholder="codigo"
-            value={code}
-            onChange={(e) => setCode(e.target.value)}
-          />
-        </Col>
-        <Col>
-          <Form.Control
-            placeholder="nombre"
-            value={name}
-            onChange={(e) => setName(e.target.value)}
-          />
-        </Col>
-        <Col sm={3}>
-          <InputGroup>
-            <Form.Control
-              placeholder="euros"
-              value={eur}
-              onChange={(e) => setEur(e.target.value)}
-            />
-            <InputGroup.Append>
-              <InputGroup.Text>.</InputGroup.Text>
-            </InputGroup.Append>
-            <Form.Control
-              placeholder="centimos"
-              value={cents}
-              onChange={(e) => setCents(e.target.value)}
-              min="0"
-              max="99"
-            />
-            <InputGroup.Append>
-              <InputGroup.Text>€</InputGroup.Text>
-            </InputGroup.Append>
-          </InputGroup>
-        </Col>
-        <Col>
-          <Form.Control
-            type="number"
-            placeholder="cantidad"
-            value={stock}
-            onChange={(e) => setStock(e.target.value)}
-          />
-        </Col>
-        <Col sm={1}>
-          <Button type="submit">+</Button>
-        </Col>
+      <Form.Group>
+        <Form.Label>Codigo:</Form.Label>
+        <Form.Control
+          type="number"
+          placeholder="codigo"
+          value={code}
+          onChange={(e) => setCode(e.target.value)}
+        />
+      </Form.Group>
+      <Form.Group>
+        <Form.Label>Nombre:</Form.Label>
+        <Form.Control
+          placeholder="nombre"
+          value={name}
+          onChange={(e) => setName(e.target.value)}
+        />
+      </Form.Group>
+      <Form.Group>
+        <Form.Label>Precio:</Form.Label>
+        <PriceEditor value={price} onChange={setPrice} />
+      </Form.Group>
+      <Form.Group>
+        <Form.Label>Cantidad:</Form.Label>
+        <Form.Control
+          type="number"
+          placeholder="cantidad"
+          value={stock}
+          onChange={(e) => setStock(e.target.value)}
+        />
       </Form.Group>
+      <Button disabled={disabled} type="submit">
+        Añadir
+      </Button>
     </Form>
   );
 }
diff --git a/src/Topup.js b/src/Topup.js
index 6614acd..51b21f8 100644
--- a/src/Topup.js
+++ b/src/Topup.js
@@ -1,8 +1,9 @@
 import React, { useState } from "react";
 import { useParams, Redirect } from "react-router-dom";
 import MemberPicker from "./member/MemberPicker";
-import { Form, Col, Row, Button, InputGroup } from "react-bootstrap";
+import { Form, Col, Row, Button } from "react-bootstrap";
 import Sender from "./Sender";
+import PriceEditor from "./PriceEditor";
 
 function Topup() {
   const { num } = useParams();
@@ -21,7 +22,7 @@ function Topup() {
     }
     return {
       member: member.num,
-      amount: parseInt(amount) * 100,
+      amount: amount,
       comment,
     };
   };
@@ -34,17 +35,7 @@ function Topup() {
           Recarga
         </Form.Label>
         <Col sm={10}>
-          <InputGroup>
-            <Form.Control
-              type="number"
-              placeholder="euros"
-              value={amount}
-              onChange={(e) => setAmount(e.target.value)}
-            />
-            <InputGroup.Append>
-              <InputGroup.Text>.00 €</InputGroup.Text>
-            </InputGroup.Append>
-          </InputGroup>
+          <PriceEditor value={amount} onChange={setAmount} />
         </Col>
       </Form.Group>
       <Form.Group as={Row}>
@@ -61,7 +52,7 @@ function Topup() {
       </Form.Group>
       <Form.Group as={Row}>
         <Col sm={{ span: 10, offset: 2 }}>
-          <Button type="submit" disabled={member === null}>
+          <Button type="submit" disabled={member === null || isNaN(amount)}>
             Recarga
           </Button>
         </Col>
-- 
GitLab