aboutsummaryrefslogtreecommitdiff
path: root/src/components
diff options
context:
space:
mode:
authorVidhu Kant Sharma <vidhukant@vidhukant.xyz>2022-09-26 20:00:09 +0530
committerVidhu Kant Sharma <vidhukant@vidhukant.xyz>2022-09-26 20:00:09 +0530
commitdb693ab4000405f5b02e71dfaf78efe6884b775b (patch)
tree169712dca42359a1575f9a889a1e60556932ada4 /src/components
parentecff3ce21dc1fb68cbe62533a1798bc7b4c061ba (diff)
First Commit
Diffstat (limited to 'src/components')
-rw-r--r--src/components/editors/item-editor.js177
-rw-r--r--src/components/editors/scss/item-editor.scss88
-rw-r--r--src/components/tables/item-table.js78
-rw-r--r--src/components/tables/scss/table.scss49
4 files changed, 392 insertions, 0 deletions
diff --git a/src/components/editors/item-editor.js b/src/components/editors/item-editor.js
new file mode 100644
index 0000000..af505ac
--- /dev/null
+++ b/src/components/editors/item-editor.js
@@ -0,0 +1,177 @@
+/* OpenBills-web - Web based libre billing software
+ * Copyright (C) 2022 Vidhu Kant Sharma <vidhukant@vidhukant.xyz>
+
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import { Item, saveItem } from './../../classes/item'
+import { Brand, getAllBrands } from './../../classes/brand'
+import './scss/item-editor.scss'
+
+import { useState, useEffect } from 'react';
+
+const ItemEditor = (props) => {
+ const [name, setName] = useState("");
+ const [desc, setDesc] = useState("");
+ const [HSN, setHSN] = useState("");
+ const [unit, setUnit] = useState("");
+ const [unitPrice, setUnitPrice] = useState(0.00);
+ const [gstP, setGSTP] = useState(0.00);
+ const [minQty, setMinQty] = useState(0.00);
+ const [maxQty, setMaxQty] = useState(0.00);
+ const [brand, setBrand] = useState(new Brand());
+ const [savedBrands, setSavedBrands] = useState([]);
+
+ // get saved brands from API
+ // needed by the brands dropdown menu
+ useEffect(() => {
+ // TODO: handle error
+ getAllBrands(setSavedBrands, () => {});
+ }, [])
+
+ const handleSubmit = (e) => {
+ e.preventDefault();
+
+ const item = new Item();
+ item.Name = name;
+ item.Description = desc;
+ item.HSN = HSN;
+ item.UnitOfMeasure = unit;
+ item.UnitPrice = unitPrice;
+ item.GSTPercentage = gstP;
+ item.MinQuantity = minQty;
+ item.MaxQuantity = maxQty;
+ item.Brand = brand;
+
+ // TODO: Save is for new items. implement modification too
+ saveItem(item, handleSuccess, handleFail);
+ }
+
+ const handleSuccess = () => {
+ clearAll();
+ props.callback();
+ }
+
+ const handleFail = () => {
+ alert("fail");
+ }
+
+ const handleBrandSelect = (e) => {
+ const b = savedBrands.filter(i => i.Id === e.target.value )[0];
+ setBrand(b ? b : new Brand());
+ }
+
+ const clearAll = () => {
+ setName("");
+ setDesc("");
+ setHSN("");
+ setUnit("");
+ setUnitPrice(0.00);
+ setGSTP(0.00);
+ setMinQty(0.00);
+ setMaxQty(0.00);
+ setBrand(new Brand())
+ }
+
+ const handleCancel = () => {
+ // TODO: hide this component or something
+ clearAll();
+ }
+
+ const validateFloatInput = (e, callback) => {
+ const f = parseFloat(e.target.value);
+ f && callback(f)
+ }
+
+ return (
+ <div className={"editor-wrapper"}>
+ <p>Add New Item</p>
+ <form onSubmit={handleSubmit} className={"editor"}>
+ <label>
+ Product/Service:
+ <input
+ type="text" name="name"
+ value={name} onChange={(e) => setName(e.target.value)} />
+ </label>
+
+ <label>
+ Description:
+ <input
+ type="text" name="desc"
+ value={desc} onChange={(e) => setDesc(e.target.value)} />
+ </label>
+
+ <label>
+ HSN:
+ <input
+ type="text" name="hsn"
+ value={HSN} onChange={(e) => setHSN(e.target.value)} />
+ </label>
+
+ <label>
+ Unit of Measurement:
+ <input
+ type="text" name="unit"
+ value={unit} onChange={(e) => setUnit(e.target.value)} />
+ </label>
+
+ <label>
+ Unit Price:
+ <input
+ type="number" name="unitprice"
+ value={unitPrice} onChange={(e) => validateFloatInput(e, setUnitPrice)} />
+ </label>
+
+ <label>
+ GST %:
+ <input
+ type="number" name="gstp"
+ value={gstP} onChange={(e) => validateFloatInput(e, setGSTP)} />
+ </label>
+
+ <label>
+ Minimum Quantity:
+ <input
+ type="number" name="minqty"
+ value={minQty} onChange={(e) => validateFloatInput(e, setMinQty)} />
+ </label>
+
+ <label>
+ Maximum Quantity:
+ <input
+ type="number" name="maxqty"
+ value={maxQty} onChange={(e) => validateFloatInput(e, setMaxQty)} />
+ </label>
+
+ <label>
+ Brand:
+ <select value={brand.Id ? brand.Id : ""} onChange={handleBrandSelect}>
+ <option key="placeholder" value={""}>
+ {brand.Id == null ? "Select a Brand (optional)" : "None"}
+ </option>
+ {savedBrands.map(i => <option key={i.Id} value={i.Id}>{i.Name}</option>)}
+ </select>
+ </label>
+
+ <span className={"buttons"}>
+ <input type="button" value="Clear" onClick={clearAll}/>
+ <input type="button" value="Cancel" onClick={handleCancel}/>
+ <input type="submit" value="Save" />
+ </span>
+ </form>
+ </div>
+ );
+}
+
+export default ItemEditor;
diff --git a/src/components/editors/scss/item-editor.scss b/src/components/editors/scss/item-editor.scss
new file mode 100644
index 0000000..968795a
--- /dev/null
+++ b/src/components/editors/scss/item-editor.scss
@@ -0,0 +1,88 @@
+/* OpenBills-web - Web based libre billing software
+ * Copyright (C) 2022 Vidhu Kant Sharma <vidhukant@vidhukant.xyz>
+
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+.editor-wrapper {
+ width: 100%;
+ margin: auto;
+ padding: 0;
+ margin: 0;
+ position: relative;
+ p {
+ text-align: center;
+ font-weight: bold;
+ font-size: 1.7rem;
+ color: #bd93f9;
+ }
+}
+
+.editor {
+ padding-bottom: 2.5rem;
+ margin: auto;
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ justify-content: space-evenly;
+ align-items: center;
+ min-width: 90%;
+
+ label {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: space-between;
+ align-items: center;
+ max-width: 24rem;
+ width: 90%;
+ padding: 0.3rem 0.1rem;
+ border-bottom: 1px dotted #d0afff;
+
+ select,input {
+ padding: 0.2rem;
+ max-width: 13rem;
+ width: 90%;
+ box-sizing: border-box;
+ background-color: #00000000;
+ border: 1px solid #bd93f9;
+ color: white;
+ border-radius: 4px;
+ outline: 0;
+ }
+ }
+
+ .buttons {
+ position: absolute;
+ display: flex;
+ justify-content: space-between;
+ width: 13.5rem;
+ input {
+ padding: 0.2rem 0;
+ width: 4rem;
+ background-color: #00000000;
+ border: 1px solid #bd93f9;
+ color: white;
+ border-radius: 4px;
+ transition: background-color 0.4s, color 0.4s;
+ }
+ input:hover {
+ background-color: #bd93f9;
+ color: black;
+ }
+ bottom: 0;
+ left: 0;
+ right: 0;
+ margin: auto;
+ }
+}
diff --git a/src/components/tables/item-table.js b/src/components/tables/item-table.js
new file mode 100644
index 0000000..c1115c1
--- /dev/null
+++ b/src/components/tables/item-table.js
@@ -0,0 +1,78 @@
+/* OpenBills-web - Web based libre billing software
+ * Copyright (C) 2022 Vidhu Kant Sharma <vidhukant@vidhukant.xyz>
+
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import './scss/table.scss';
+import { deleteItem } from './../../classes/item';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
+import { faPencil, faTrashCan } from '@fortawesome/free-solid-svg-icons'
+
+const ItemTable = (props) => {
+ const handleDelete = (i) => {
+ // TODO: add confirmation prompt
+ deleteItem(i.Id, handleDelSuccess, handleDelFail);
+ }
+
+ const handleDelSuccess = () => {
+ props.refresh();
+ }
+
+ const handleDelFail = () => {
+ alert("fail")
+ }
+
+ return (
+ <table>
+ <thead>
+ <tr>
+ <th>S. No</th>
+ <th>Name</th>
+ <th>Description</th>
+ <th>Brand Name</th>
+ <th>UOM</th>
+ <th>HSN</th>
+ <th>Unit Price</th>
+ <th>GST %</th>
+ <th>Min Qty</th>
+ <th>Max Qty</th>
+ <th></th>
+ </tr>
+ </thead>
+ <tbody>
+ {props.items && props.items.map((i, id=id+1) => (
+ <tr key={id}>
+ <td>{id+1}</td>
+ <td className={i.Name === "" ? "empty" : ""}>{i.Name}</td>
+ <td className={i.Description === "" ? "empty" : ""}>{i.Description}</td>
+ <td className={i.Brand.Name === "" ? "empty" : ""}>{i.Brand.Name}</td>
+ <td className={i.UnitOfMeasure === "" ? "empty" : ""}>{i.UnitOfMeasure}</td>
+ <td className={i.HSN === "" ? "empty" : ""}>{i.HSN}</td>
+ <td className={i.UnitPrice === 0.0 ? "empty" : ""}>{i.UnitPrice}</td>
+ <td className={i.GSTPercentage === 0.0 ? "empty" : ""}>{i.GSTPercentage}</td>
+ <td className={i.MinQuantity === 0.0 ? "empty" : ""}>{i.MinQuantity}</td>
+ <td className={i.MaxQuantity === 0.0 ? "empty" : ""}>{i.MaxQuantity}</td>
+ <td className={"buttons"}>
+ <FontAwesomeIcon icon={faPencil} onClick={() => alert("editing coming soon")}/>
+ <FontAwesomeIcon icon={faTrashCan} onClick={() => handleDelete(i)}/>
+ </td>
+ </tr>
+ ))}
+ </tbody>
+ </table>
+ );
+}
+
+export default ItemTable;
diff --git a/src/components/tables/scss/table.scss b/src/components/tables/scss/table.scss
new file mode 100644
index 0000000..44d7f57
--- /dev/null
+++ b/src/components/tables/scss/table.scss
@@ -0,0 +1,49 @@
+/* OpenBills-web - Web based libre billing software
+ * Copyright (C) 2022 Vidhu Kant Sharma <vidhukant@vidhukant.xyz>
+
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+table {
+ width: 90%;
+ margin: auto;
+
+ th {
+ box-sizing: border-box;
+ background-color: #383a59;
+ font-weight: normal;
+ text-align: left;
+ padding-left: 0.3rem;
+ }
+
+ tr:hover {
+ background-color: rgba(#383a59, 0.4);
+ }
+
+ td {
+ border-bottom: 1px solid white;
+ }
+
+ td.empty {
+ border-bottom: 1px solid gray;
+ }
+
+ td.buttons {
+ display: flex;
+ justify-content: space-evenly;
+ align-items: center;
+ border: none;
+ height: 1.4rem;
+ }
+}