From 5329b1fd16d0b8940f9526b523676dfb1cdbf317 Mon Sep 17 00:00:00 2001
From: MikunoNaka <bokuwakanojogahoshii@yahoo.com>
Date: Thu, 24 Jun 2021 15:53:42 +0530
Subject: switching to typescript

---
 server/database/people.go                     |   5 +-
 server/main.go                                |   2 +
 server/router/router.go                       |   3 -
 src/components/Form/Document/MetaInfoForm.tsx |  38 +++++
 src/components/Form/Items/AddNewItemForm.js   | 203 ------------------------
 src/components/Form/Items/AddNewItemForm.tsx  | 219 ++++++++++++++++++++++++++
 src/components/Form/MetaInfoForm.js           |  22 ---
 src/components/Pages/BillingPage.js           |  93 -----------
 src/components/Pages/BillingPage.tsx          |  96 +++++++++++
 src/interfaces.ts                             |  21 +++
 tsconfig.json                                 |  26 +++
 11 files changed, 405 insertions(+), 323 deletions(-)
 create mode 100644 src/components/Form/Document/MetaInfoForm.tsx
 delete mode 100644 src/components/Form/Items/AddNewItemForm.js
 create mode 100644 src/components/Form/Items/AddNewItemForm.tsx
 delete mode 100644 src/components/Form/MetaInfoForm.js
 delete mode 100644 src/components/Pages/BillingPage.js
 create mode 100644 src/components/Pages/BillingPage.tsx
 create mode 100644 src/interfaces.ts
 create mode 100644 tsconfig.json

diff --git a/server/database/people.go b/server/database/people.go
index 5fc3bf5..4817139 100644
--- a/server/database/people.go
+++ b/server/database/people.go
@@ -14,7 +14,7 @@ import (
   _ "github.com/mattn/go-sqlite3"
 )
 type Person struct {
-  ID      string
+  ID      int
   Name    string
   Address string
   Phone   string
@@ -28,7 +28,8 @@ func GetAllPeople() []Person {
   )
 
   var (
-    id, name, address, phone, email string
+    id int
+    name, address, phone, email string
   )
 
   for rows.Next() {
diff --git a/server/main.go b/server/main.go
index 2f0d87f..287e4cc 100644
--- a/server/main.go
+++ b/server/main.go
@@ -13,8 +13,10 @@ package main
 
 import (
   router "github.com/MikunoNaka/openbills/router"
+  db "github.com/MikunoNaka/openbills/database"
 )
 
 func main() {
+  db.InitDB()
   router.InitRouter()
 }
diff --git a/server/router/router.go b/server/router/router.go
index 80e9dfc..7729dd2 100644
--- a/server/router/router.go
+++ b/server/router/router.go
@@ -11,12 +11,9 @@ package router
 import (
   "github.com/gin-gonic/gin"
   "github.com/gin-gonic/contrib/static"
-
-  db "github.com/MikunoNaka/openbills/database"
 )
 
 func InitRouter() {
-  db.InitDB()
   myRouter := gin.New()
   myRouter.Use(gin.Logger())
 
diff --git a/src/components/Form/Document/MetaInfoForm.tsx b/src/components/Form/Document/MetaInfoForm.tsx
new file mode 100644
index 0000000..da484ab
--- /dev/null
+++ b/src/components/Form/Document/MetaInfoForm.tsx
@@ -0,0 +1,38 @@
+/*
+ * 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 from "react";
+import "./../Form.scss";
+
+interface Transport {
+  name:       string,
+  vehicleNum: string, 
+  method:     string, // shipment method
+  gstin:      string,
+  builty:     string // goods receipt
+}
+
+const MetaInfoForm: React.FC = () => {
+  // don't push it to github!
+  const sampleTransport: Transport = {
+    name: "Own Vehicle",
+    vehicleNum: "HR61C9220",
+    method: "By Road",
+    gstin: "",
+    builty: ""
+  }
+  console.log(sampleTransport);
+  return (
+    <div className={"MetaInfoForm"}>
+      <form>
+      </form>
+    </div>
+  );
+}
+
+export default MetaInfoForm;
diff --git a/src/components/Form/Items/AddNewItemForm.js b/src/components/Form/Items/AddNewItemForm.js
deleted file mode 100644
index 37167fd..0000000
--- a/src/components/Form/Items/AddNewItemForm.js
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * 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);
-
-  // to be handled by DocumentInfo
-  // check if client is in same state
-  // and apply cgst+sgst or igst accordingly
-  const inState = true;
-
-  const enterItemNamePrompt = "start typing here";
-  const registerItemPrompt = "add new";
-  const emptyItemNames = [enterItemNamePrompt, registerItemPrompt, ""];
-
-  // set description and price if match found in DB
-  const applyItemInfo = (i) => {
-    setItemDescValue(i.Description);
-    setItemPriceValue(i.Price);
-    setItemHSNValue(i.HSN);
-    setItemGSTValue(i.GST);
-  }
-
-  // check the item name value and do stuff accordingly
-  const setItemInfo = (itemName) =>
-    (props.savedItems === null || itemName === registerItemPrompt)
-      ? props.registerItemFormVisibility(true)
-      : props.savedItems.some((i) => 
-        itemName === i.Model.toLowerCase() && applyItemInfo(i))
-
-  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),
-
-            // this also checks if igst applies or not
-            "sgst": inState ? parseInt(itemGSTValue) / 2 : "",
-            "cgst": inState ? parseInt(itemGSTValue) / 2 : "",
-            "igst": inState ? "" :  parseInt(itemGSTValue)
-          };
-          console.log(newInvoiceItem);
-          props.addItem(newInvoiceItem);
-          resetAllValues();
-        }
-      }>
-        <div className={"widePane formPane"}>
-          <label>
-            Item/Service: 
-              <select
-                className={"selectInputBox"}
-                value={itemNameValue} 
-                onChange={
-                  (event) => {
-                    setItemNameValue(event.target.value);
-                    setItemInfo(event.target.value.toLowerCase());
-                  }
-                }>
-                <option key={enterItemNamePrompt}>{enterItemNamePrompt}</option>
-                {props.savedItems !== null && props.savedItems.map(
-                  (i) => <option key={i.Model}>{i.Model}</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 formPane"}>
-          <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 formPane"}>
-          <input type="button" 
-            value="Register New Client" 
-            onClick={() => props.registerPersonFormVisibility(true)}
-          />
-
-          <input type="button" 
-            value="Register New Item" 
-            onClick={() => props.registerItemFormVisibility(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.tsx b/src/components/Form/Items/AddNewItemForm.tsx
new file mode 100644
index 0000000..283d779
--- /dev/null
+++ b/src/components/Form/Items/AddNewItemForm.tsx
@@ -0,0 +1,219 @@
+/*
+ * 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";
+import { Item } from "../../../interfaces";
+
+interface props {
+  savedItems: Item[]
+  addItem: (item: Item) => void
+  defGSTValue: number,
+  registerItemFormVisibility: any,
+  registerPersonFormVisibility: any
+}
+
+const AddNewItemForm: React.FC<props> = (props) => {
+  console.log(props)
+  const [itemNameValue, setItemNameValue] = useState<string>("");
+  const [itemDescValue, setItemDescValue] = useState<string>("");
+  const [itemPriceValue, setItemPriceValue] = useState<number>(0.00);
+  const [itemDiscountValue, setItemDiscountValue] = useState<number>(0.00);
+  const [itemGSTValue, setItemGSTValue] = useState<number>(props.defGSTValue);
+  const [itemQTYValue, setItemQTYValue] = useState<number>(1);
+  const [itemHSNValue, setItemHSNValue] = useState<number>(0);
+
+  // to be handled by DocumentInfo
+  // check if client is in same state
+  // and apply cgst+sgst or igst accordingly
+  // const inState: boolean = true;
+
+  const enterItemNamePrompt: string = "start typing here";
+  const registerItemPrompt: string = "add new";
+  const emptyItemNames: any[] = [enterItemNamePrompt, registerItemPrompt, ""];
+
+  // set description and price if match found in DB
+  const applyItemInfo = (i: any) => {
+    setItemDescValue(i.Description);
+    setItemPriceValue(i.Price);
+    setItemHSNValue(i.HSN);
+    setItemGSTValue(i.GST);
+  }
+
+  // check the item name value and do stuff accordingly
+  const setItemInfo = (itemName: any) =>
+    (props.savedItems === null || itemName === registerItemPrompt)
+      ? props.registerItemFormVisibility(true)
+      : props.savedItems.some((i) => 
+        itemName === i.Model.toLowerCase() && applyItemInfo(i))
+
+  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();
+
+          // TODO: maybe move calculation of GST and Discount here
+          const newInvoiceItem: Item = {
+            Model: itemNameValue,
+            Description: itemDescValue,
+            Quantity: itemQTYValue,
+            UnitPrice: itemPriceValue,
+            TotalValue: (itemPriceValue * itemQTYValue),
+            Discount: itemDiscountValue,
+            HSN: itemHSNValue,
+
+            // this also checks if igst applies or not
+            // TODO: fix this
+            sgst: 0,
+            cgst: 0,
+            igst: 0
+            // sgst: inState ? parseInt(itemGSTValue) / 2 : "",
+            // cgst: inState ? parseInt(itemGSTValue) / 2 : "",
+            // igst: inState ? "" :  parseInt(itemGSTValue)
+          }
+          props.addItem(newInvoiceItem);
+
+          resetAllValues();
+        }
+      }>
+        <div className={"widePane formPane"}>
+          <label>
+            Item/Service: 
+              <select
+                className={"selectInputBox"}
+                value={itemNameValue} 
+                onChange={
+                  (event) => {
+                    setItemNameValue(event.target.value);
+                    setItemInfo(event.target.value.toLowerCase());
+                  }
+                }>
+                <option key={enterItemNamePrompt}>{enterItemNamePrompt}</option>
+                {props.savedItems !== null && props.savedItems.map(
+                  (i) => <option key={i.Model}>{i.Model}</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 formPane"}>
+          <label>
+            Quantity: 
+              <input className={"smallInputBox"} type="number" min="1" value={itemQTYValue} 
+                onInput={
+                  (event: React.FormEvent<HTMLInputElement>) => {
+                    const value: number = parseInt(event.currentTarget.value);
+                    setItemQTYValue(value);
+                  }
+                } 
+              required />
+          </label>
+
+          <label>
+            Price: 
+              <input className={"smallInputBox"} type="number" min="1.00" step="0.001" value={itemPriceValue} 
+                onInput={
+                  (event: React.FormEvent<HTMLInputElement>) => {
+                    const value: number = parseFloat(event.currentTarget.value);
+                    setItemPriceValue(value);
+                  }
+                } 
+              required />
+          </label>
+
+          <label>
+            Discount: 
+              <input className={"smallInputBox"} type="number" min="0" step="0.001" value={itemDiscountValue} 
+                onInput={
+                  (event: React.FormEvent<HTMLInputElement>) => {
+                    const value: number = parseInt(event.currentTarget.value);
+                    setItemDiscountValue(value);
+                  }
+                } 
+              />
+          </label>
+
+          <label>
+            HSN: 
+              <input className={"smallInputBox"} type="number" min="0" value={itemHSNValue} 
+                onInput={
+                  (event: React.FormEvent<HTMLInputElement>) => {
+                    const value: number = parseInt(event.currentTarget.value);
+                    setItemHSNValue(value);
+                  }
+                } 
+              required />
+          </label>
+
+          <label>
+            GST: 
+              <input className={"smallInputBox"} type="number" min="0" value={itemGSTValue} 
+                onInput={
+                  (event: React.FormEvent<HTMLInputElement>) => {
+                    const value: number = parseInt(event.currentTarget.value);
+                    setItemGSTValue(value);
+                  }
+                } 
+              required />
+          </label>
+        </div>
+
+        <div className={"smallPane formPane"}>
+          <input type="button" 
+            value="Register New Client" 
+            onClick={() => props.registerPersonFormVisibility(true)}
+          />
+
+          <input type="button" 
+            value="Register New Item" 
+            onClick={() => props.registerItemFormVisibility(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
+              ) ? true : false
+            }
+          />
+        </div>
+      </form>
+    </div>
+  )
+}
+
+export default AddNewItemForm;
diff --git a/src/components/Form/MetaInfoForm.js b/src/components/Form/MetaInfoForm.js
deleted file mode 100644
index 5d9e3c3..0000000
--- a/src/components/Form/MetaInfoForm.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * 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 MetaInfoForm = () => {
-  return (
-    <div className={"MetaInfoForm"}>
-      <h1>This section of the app is missing</h1>
-      <p>Please look at this waifu instead.</p>
-      <img height="300" width="230" src="https://i.redd.it/te8tbxl1r9v61.jpg" alt="Shit where is the waifu"></img>
-    </div>
-  )
-}
-
-export default MetaInfoForm;
diff --git a/src/components/Pages/BillingPage.js b/src/components/Pages/BillingPage.js
deleted file mode 100644
index abb7b7d..0000000
--- a/src/components/Pages/BillingPage.js
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * 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, useEffect } from "react";
-import axios from "axios";
-
-import AddNewItemForm from "./../Form/Items/AddNewItemForm";
-import RegisterItemForm from "./../Form/Items/RegisterItemForm";
-
-import RegisterPersonForm from "./../Form/People/RegisterPersonForm";
-
-import DocumentInfoForm from "./../Form/Document/DocumentInfoForm";
-import MetaInfoForm from "./../Form/MetaInfoForm";
-
-import ItemsDisplay from "./../Display/ItemsDisplay";
-import SummaryDisplay from "./../Display/SummaryDisplay"; 
-
-const BillingPage = () => {
-  const [savedItems, getSavedItems] = useState([]);
-  const [savedPeople, getSavedPeople] = useState([]);
-  const [registerItemFormVisibility, setRegisterItemFormVisibility] = useState(false);
-  const [registerPersonFormVisibility, setRegisterPersonFormVisibility] = useState(false);
-  const [items, setItems] = useState([]);
-
-  const getRegisteredItems = () =>
-    axios.get(`/api/items/get-all`)
-      .then((res) => getSavedItems(res.data))
-      .catch((res) => console.log(res));
-
-  const getRegisteredPeople = () => 
-    axios.get(`/api/people/get-all`)
-      .then((res) => getSavedPeople(res.data))
-      .catch((res) => console.log(res));
-
-  // get data from server on startup
-  useEffect(() => {
-    getRegisteredItems();
-    getRegisteredPeople();
-  }, []);
-  // TODO: to be handled by backend
-  const defGSTValue = 18;
-
-  // update the items from AddNewItemForm
-  const getItems = (item) => setItems([...items, item]);
-
-  return (
-    <>
-      {registerItemFormVisibility &&
-        <RegisterItemForm 
-          defGSTValue={defGSTValue}
-          updateItemsList={getRegisteredItems} 
-          setVisibility={setRegisterItemFormVisibility}
-        />
-      }
-
-      {registerPersonFormVisibility &&
-        <RegisterPersonForm 
-          updateItemsList={getRegisteredItems} 
-          setVisibility={setRegisterPersonFormVisibility}
-        />
-      }
-
-      <DocumentInfoForm 
-        savedPeople={savedPeople}
-      />
-
-      <AddNewItemForm 
-        savedItems={savedItems} 
-        addItem={getItems} 
-        defGSTValue={defGSTValue}
-        registerItemFormVisibility={setRegisterItemFormVisibility}
-        registerPersonFormVisibility={setRegisterPersonFormVisibility}
-      />
-
-      <ItemsDisplay 
-        items={items} 
-        defGSTValue={defGSTValue}
-      />
-
-      <div className={"BillingPageFlex"}>
-        <MetaInfoForm/>
-        <SummaryDisplay items={items}/>
-      </div>
-    </>
-  );
-}
-
-export default BillingPage;
diff --git a/src/components/Pages/BillingPage.tsx b/src/components/Pages/BillingPage.tsx
new file mode 100644
index 0000000..9697a24
--- /dev/null
+++ b/src/components/Pages/BillingPage.tsx
@@ -0,0 +1,96 @@
+/*
+ * 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, useEffect } from "react";
+import axios from "axios";
+
+import { Item } from "../../interfaces";
+
+import AddNewItemForm from "./../Form/Items/AddNewItemForm";
+import RegisterItemForm from "./../Form/Items/RegisterItemForm";
+
+import RegisterPersonForm from "./../Form/People/RegisterPersonForm";
+
+import DocumentInfoForm from "./../Form/Document/DocumentInfoForm";
+import MetaInfoForm from "./../Form/Document/MetaInfoForm";
+
+import ItemsDisplay from "./../Display/ItemsDisplay";
+import SummaryDisplay from "./../Display/SummaryDisplay"; 
+
+const BillingPage: React.FC = () => {
+  const [savedItems, getSavedItems] = useState<Item[]>([]);
+  const [savedPeople, getSavedPeople] = useState([]);
+  const [registerItemFormVisibility, setRegisterItemFormVisibility] = useState<boolean>(false);
+  const [registerPersonFormVisibility, setRegisterPersonFormVisibility] = useState<boolean>(false);
+  const [items, setItems] = useState<Item[]>([]);
+
+  const getRegisteredItems = () =>
+    axios.get(`/api/items/get-all`)
+      .then((res) => getSavedItems(res.data))
+      .catch((res) => console.log(res));
+
+  const getRegisteredPeople = () => 
+    axios.get(`/api/people/get-all`)
+      .then((res) => getSavedPeople(res.data))
+      .catch((res) => console.log(res));
+
+  // get data from server on startup
+  useEffect(() => {
+    getRegisteredItems();
+    getRegisteredPeople();
+  }, []);
+
+  // TODO: to be handled by backend
+  const defGSTValue = 18;
+
+  // update the items from AddNewItemForm
+  const getItems = (item: Item) => setItems([...items, item]);
+
+  return (
+    <>
+      {registerItemFormVisibility &&
+        <RegisterItemForm 
+          defGSTValue={defGSTValue}
+          updateItemsList={getRegisteredItems} 
+          setVisibility={setRegisterItemFormVisibility}
+        />
+      }
+
+      {registerPersonFormVisibility &&
+        <RegisterPersonForm 
+          updateItemsList={getRegisteredItems} 
+          setVisibility={setRegisterPersonFormVisibility}
+        />
+      }
+
+      <DocumentInfoForm 
+        savedPeople={savedPeople}
+      />
+
+      <AddNewItemForm 
+        savedItems={savedItems} 
+        addItem={getItems} 
+        defGSTValue={defGSTValue}
+        registerItemFormVisibility={setRegisterItemFormVisibility}
+        registerPersonFormVisibility={setRegisterPersonFormVisibility}
+      />
+
+      <ItemsDisplay 
+        items={items} 
+        defGSTValue={defGSTValue}
+      />
+
+      <div className={"BillingPageFlex"}>
+        <MetaInfoForm/>
+        <SummaryDisplay items={items}/>
+      </div>
+    </>
+  );
+}
+
+export default BillingPage;
diff --git a/src/interfaces.ts b/src/interfaces.ts
new file mode 100644
index 0000000..7090907
--- /dev/null
+++ b/src/interfaces.ts
@@ -0,0 +1,21 @@
+export interface Transport {
+  name: string,
+  vehicleNum: string,
+  method: string,
+  gstin: string,
+  builty: string
+}
+
+export interface Item {
+  Model: string,
+  Description: string,
+  Quantity: number,
+  UnitPrice: number,
+  TotalValue: number, // UnitPrice * Quantity
+  Discount: number,
+  HSN: number, // string??
+
+  sgst: number,
+  cgst: number,
+  igst: number
+}
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..a273b0c
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,26 @@
+{
+  "compilerOptions": {
+    "target": "es5",
+    "lib": [
+      "dom",
+      "dom.iterable",
+      "esnext"
+    ],
+    "allowJs": true,
+    "skipLibCheck": true,
+    "esModuleInterop": true,
+    "allowSyntheticDefaultImports": true,
+    "strict": true,
+    "forceConsistentCasingInFileNames": true,
+    "noFallthroughCasesInSwitch": true,
+    "module": "esnext",
+    "moduleResolution": "node",
+    "resolveJsonModule": true,
+    "isolatedModules": true,
+    "noEmit": true,
+    "jsx": "react-jsx"
+  },
+  "include": [
+    "src"
+  ]
+}
-- 
cgit v1.2.3