diff options
Diffstat (limited to 'src/components/Form')
-rw-r--r-- | src/components/Form/Document/DocumentInfoForm.js | 206 | ||||
-rw-r--r-- | src/components/Form/Items/AddNewItemForm.js | 12 | ||||
-rw-r--r-- | src/components/Form/People/RegisterPersonForm.js | 87 |
3 files changed, 303 insertions, 2 deletions
diff --git a/src/components/Form/Document/DocumentInfoForm.js b/src/components/Form/Document/DocumentInfoForm.js new file mode 100644 index 0000000..a3f70b7 --- /dev/null +++ b/src/components/Form/Document/DocumentInfoForm.js @@ -0,0 +1,206 @@ +/* + * OpenBills - Self hosted browser app to generate and keep track of simple invoices + * Version - 0 + * Licensed under the MIT license - https://opensource.org/licenses/MIT + * + * Copyright (c) 2021 Vidhu Kant Sharma +*/ + +import React, { useState } from "react"; +import "./../Form.scss"; + + +const AddNewItemForm = (props) => { + const [itemNameValue, setItemNameValue] = useState(""); + const [itemDescValue, setItemDescValue] = useState(""); + const [itemPriceValue, setItemPriceValue] = useState(0.00); + const [itemDiscountValue, setItemDiscountValue] = useState(0.00); + const [itemGSTValue, setItemGSTValue] = useState(props.defGSTValue); + const [itemQtyValue, setItemQtyValue] = useState(1); + const [itemHSNValue, setItemHSNValue] = useState(0); + + const [itemToAdd, setItemToAdd] = useState({}); + + const enterItemNamePrompt = "start typing here"; + const registerItemPrompt = "add new"; + const emptyItemNames = [enterItemNamePrompt, registerItemPrompt, ""]; + + // Extract the model names from savedItems + let savedItemNames= []; + if (props.savedItems !== null) { + for (let i = 0; i < props.savedItems.length; i++) { + savedItemNames.push(props.savedItems[i].Model); + } + } + + // set description and price + // when item is entered + const setItemInfo = (itemName) => { + for (let i = 0; i < props.savedItems.length; i++) { + const mod = props.savedItems[i].Model.toLowerCase(); + const desc = props.savedItems[i].Description; + const price = props.savedItems[i].Price; + const hsn = props.savedItems[i].HSN; + const gst = props.savedItems[i].GST; + + if (mod === itemName) { + setItemDescValue(desc); + setItemPriceValue(price); + setItemHSNValue(hsn); + setItemGSTValue(gst); + break; + } + } + } + + const resetAllValues = () => { + setItemNameValue(""); + setItemDescValue(""); + setItemQtyValue(1); + setItemPriceValue(1); + setItemDiscountValue(0); + setItemHSNValue(0); + setItemGSTValue(props.defGSTValue); + } + + return ( + <div className={"formContainer"}> + <form className={"threePaneForm"} onSubmit={ + (event) => { + event.preventDefault(); + const newInvoiceItem = { + "Model": itemNameValue, + "Description": itemDescValue, + "Quantity": parseInt(itemQtyValue), + "UnitPrice": parseFloat(itemPriceValue), + "TotalPrice": parseFloat(itemPriceValue * itemQtyValue), + "Discount": parseInt(itemDiscountValue), + "HSN": parseInt(itemHSNValue), + "GST": parseInt(itemGSTValue) + }; + props.addItem(newInvoiceItem); + resetAllValues(); + } + }> + <div className={"widePane"}> + <label> + Item/Service: + <select + className={"selectInputBox"} + value={itemNameValue} + onChange={ + (event) => { + setItemNameValue(event.target.value); + setItemInfo(event.target.value.toLowerCase()); + } + }> + <option key={enterItemNamePrompt}>{enterItemNamePrompt}</option> + {savedItemNames.map( + (i) => { + return <option key={i}>{i}</option> + } + )} + <option key={registerItemPrompt}>{registerItemPrompt}</option> + </select> + </label> + + <label> + Description: + <input className={"wideInputBox"} type="text" value={itemDescValue} + onChange={ + (event) => { + setItemDescValue(event.target.value); + } + } + /> + </label> + </div> + + <div className={"widePane"}> + <label> + Quantity: + <input className={"smallInputBox"} type="number" min="1" value={itemQtyValue} + onInput={ + (event) => { + const value = event.target.value; + setItemQtyValue(value); + } + } + required /> + </label> + + <label> + Price: + <input className={"smallInputBox"} type="number" min="1.00" step="0.001" value={itemPriceValue} + onChange={ + (event) => { + const value = event.target.value; + setItemPriceValue(value); + } + } + required /> + </label> + + <label> + Discount: + <input className={"smallInputBox"} type="number" min="0" step="0.001" value={itemDiscountValue} + onChange={ + (event) => { + const value = event.target.value; + setItemDiscountValue(value); + } + } + /> + </label> + + <label> + HSN: + <input className={"smallInputBox"} type="number" min="0" value={itemHSNValue} + onChange={ + (event) => { + const value = event.target.value; + setItemHSNValue(value); + } + } + required /> + </label> + + <label> + GST: + <input className={"smallInputBox"} type="number" min="0" value={itemGSTValue} + onChange={ + (event) => { + const value = event.target.value; + setItemGSTValue(value); + } + } + required /> + </label> + </div> + + <div className={"smallPane"}> + <input type="button" + value="Register New Item" + onClick={() => props.registerFormVisibility(true)} + /> + + <input type="button" value="Placeholder1" /> + <input type="button" value="Placeholder2" /> + <input type="submit" value="Force Add" /> + + <input type="submit" value="add" + disabled={ + (emptyItemNames.includes(itemNameValue) + || itemQtyValue <= 0 + || itemPriceValue <= 0 + || itemGSTValue <= 0 + ) ? "disabled" : "" + } + /> + </div> + </form> + </div> + ) +} + +export default AddNewItemForm; diff --git a/src/components/Form/Items/AddNewItemForm.js b/src/components/Form/Items/AddNewItemForm.js index 6bce2ab..4eaea7d 100644 --- a/src/components/Form/Items/AddNewItemForm.js +++ b/src/components/Form/Items/AddNewItemForm.js @@ -47,6 +47,8 @@ const AddNewItemForm = (props) => { setItemHSNValue(hsn); setItemGSTValue(gst); break; + } else if (itemName === registerItemPrompt) { + props.registerItemFormVisibility(true); } } } @@ -65,6 +67,7 @@ const AddNewItemForm = (props) => { <div className={"formContainer"}> <form className={"threePaneForm"} onSubmit={ (event) => { + alert("submit") event.preventDefault(); const newInvoiceItem = { "Model": itemNameValue, @@ -103,7 +106,7 @@ const AddNewItemForm = (props) => { </label> <label> - Description: + Description: <input className={"wideInputBox"} type="text" value={itemDescValue} onChange={ (event) => { @@ -179,7 +182,12 @@ const AddNewItemForm = (props) => { <div className={"smallPane"}> <input type="button" value="Register New Item" - onClick={() => props.registerFormVisibility(true)} + onClick={() => props.registerItemFormVisibility(true)} + /> + + <input type="button" + value="Register New Person" + onClick={() => props.registerPersonFormVisibility(true)} /> <input type="button" value="Placeholder1" /> diff --git a/src/components/Form/People/RegisterPersonForm.js b/src/components/Form/People/RegisterPersonForm.js new file mode 100644 index 0000000..bca3bde --- /dev/null +++ b/src/components/Form/People/RegisterPersonForm.js @@ -0,0 +1,87 @@ +/* + * OpenBills - Self hosted browser app to generate and keep track of simple invoices + * Version - 0 + * Licensed under the MIT license - https://opensource.org/licenses/MIT + * + * Copyright (c) 2021 Vidhu Kant Sharma +*/ + +// TODO: Code isn't tested properly +// I'd be surprised if it < 10 bugs + +// TODO: Implement override protection + +import React, { useState } from "react"; +import axios from "axios"; +import "./../Form.scss"; + + +const RegisterPersonForm = (props) => { + const [newPersonName, setNewPersonName] = useState(""); + const [newPersonPhone, setNewPersonPhone] = useState(""); + const [newPersonEmail, setNewPersonEmail] = useState(""); + + const hideSelf = () => props.setVisibility(false); + + const closeOnBGClicked = (event) => + event.target.className === "floatingMenuBG" && hideSelf(); + + const postForm = (event) => { + event.preventDefault(); + // TODO: show confirmation before being invisible + axios.post( + `/api/people/` + + `?name=${newPersonName}` + + `&phone=${newPersonPhone}` + + `&email=${newPersonEmail}` + ) + .then((res) => { + console.log(res); + props.setVisibility(false); + }) + .catch((err) => { + console.log(err); + }); + } + + + return ( + <div className={"floatingMenuBG"} onClick={closeOnBGClicked}> + <div className={"floatingMenu"}> + <div className={"formContainer"}> + <form className={"floatingForm"} onSubmit={postForm}> + <div className={"wideForm"}> + <label> + Client Name: <input className={"wideInputBox"} type="text" value={newPersonName} onChange={ + (event) => { + setNewPersonName(event.target.value); + } + } required /> + </label> + + <label> + Phone: <input className={"wideInputBox"} type="text" value={newPersonPhone} onChange={ + (event) => { + setNewPersonPhone(event.target.value); + } + } /> + </label> + + <label> + Email: <input className={"wideInputBox"} type="text" value={newPersonEmail} onChange={ + (event) => { + setNewPersonEmail(event.target.value); + } + } /> + </label> + + <input type="submit" value="submit"/> + </div> + </form> + </div> + </div> + </div> + ); +} + +export default RegisterPersonForm; |