aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/App.js2
-rw-r--r--src/classes/brand.js12
-rw-r--r--src/classes/item.js2
-rw-r--r--src/components/editors/brand-editor.js79
-rw-r--r--src/components/editors/item-editor.js2
-rw-r--r--src/components/editors/scss/brand-editor.scss22
-rw-r--r--src/components/tables/brand-table.js54
-rw-r--r--src/components/tables/client-table.js4
-rw-r--r--src/components/tables/scss/_colors.scss16
-rw-r--r--src/components/tables/scss/brand-table.scss37
-rw-r--r--src/components/tables/scss/client-table.scss14
-rw-r--r--src/views/manage/brands.js44
12 files changed, 269 insertions, 19 deletions
diff --git a/src/App.js b/src/App.js
index 91beeb6..6e90a3d 100644
--- a/src/App.js
+++ b/src/App.js
@@ -19,6 +19,7 @@ import './App.scss';
import { BrowserRouter, Route, Routes } from "react-router-dom";
import ManageItemsPage from './views/manage/items';
import ManageClientsPage from './views/manage/clients';
+import ManageBrandsPage from './views/manage/brands';
const App = () => {
return (
@@ -27,6 +28,7 @@ const App = () => {
<Routes>
<Route exact path="/manage/items" element={<ManageItemsPage/>}/>
<Route exact path="/manage/clients" element={<ManageClientsPage/>}/>
+ <Route exact path="/manage/brands" element={<ManageBrandsPage/>}/>
<Route path="*" element={<h1>404</h1>}/>
</Routes>
</main>
diff --git a/src/classes/brand.js b/src/classes/brand.js
index 48bc974..967f9a1 100644
--- a/src/classes/brand.js
+++ b/src/classes/brand.js
@@ -32,9 +32,9 @@ export class Brand {
}
export const deleteBrand = (id, ok, fail) => {
- axios.delete(`/brand/${id}`)
- .then(res => ok())
- .catch(err => fail())
+ axios.delete(`/brand/${id}`)
+ .then(res => ok())
+ .catch(err => fail())
}
export const getAllBrands = (ok, fail) => {
@@ -42,3 +42,9 @@ export const getAllBrands = (ok, fail) => {
.then(res => ok(res.data))
.catch(err => fail())
}
+
+export const saveBrand = (brand, ok, fail) => {
+ axios.post("/brand/new", brand)
+ .then(res => ok())
+ .catch((err) => fail())
+}
diff --git a/src/classes/item.js b/src/classes/item.js
index 3985e9d..1c59992 100644
--- a/src/classes/item.js
+++ b/src/classes/item.js
@@ -50,7 +50,7 @@ export class InvoiceItem extends Item {
export const saveItem = (item, ok, fail) => {
axios.post("/item/new", item)
- .then(res => { console.log(res);ok()})
+ .then(res => ok())
.catch((err) => fail())
}
diff --git a/src/components/editors/brand-editor.js b/src/components/editors/brand-editor.js
new file mode 100644
index 0000000..801a790
--- /dev/null
+++ b/src/components/editors/brand-editor.js
@@ -0,0 +1,79 @@
+/* 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 { Brand, saveBrand } from './../../classes/brand'
+import './scss/brand-editor.scss'
+
+import { useState, useEffect } from 'react';
+
+const BrandEditor = (props) => {
+ const [name, setName] = useState("");
+
+ const handleSubmit = (e) => {
+ e.preventDefault();
+
+ const brand = new Brand();
+ brand.Name = name;
+
+ // TODO: Save is for new brands. implement modification too
+ saveBrand(brand, handleSuccess, handleFail);
+ }
+
+ const handleSuccess = () => {
+ clearAll();
+ props.callback();
+ }
+
+ const handleFail = () => {
+ alert("fail");
+ }
+
+ const clearAll = () => {
+ setName("");
+ }
+
+ 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>{props.heading}</p>
+ <form onSubmit={handleSubmit} className={"editor brand-editor"}>
+ <label>
+ Brand Name:
+ <input
+ type="text" name="name"
+ value={name} onChange={(e) => setName(e.target.value)} />
+ </label>
+
+ <span className={"buttons"}>
+ <input type="button" value="Clear" onClick={clearAll}/>
+ <input type="submit" value="Save" />
+ </span>
+ </form>
+ </div>
+ );
+}
+
+export default BrandEditor;
diff --git a/src/components/editors/item-editor.js b/src/components/editors/item-editor.js
index 19fa7e2..6c5e976 100644
--- a/src/components/editors/item-editor.js
+++ b/src/components/editors/item-editor.js
@@ -154,6 +154,7 @@ const ItemEditor = (props) => {
value={maxQty} onChange={(e) => validateFloatInput(e, setMaxQty)} />
</label>
+ {savedBrands && savedBrands.length > 0 &&
<label>
Brand:
<select value={brand.Id ? brand.Id : ""} onChange={handleBrandSelect}>
@@ -163,6 +164,7 @@ const ItemEditor = (props) => {
{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}/>
diff --git a/src/components/editors/scss/brand-editor.scss b/src/components/editors/scss/brand-editor.scss
new file mode 100644
index 0000000..05b05a7
--- /dev/null
+++ b/src/components/editors/scss/brand-editor.scss
@@ -0,0 +1,22 @@
+/* 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 "editor";
+
+.brand-editor .buttons {
+ width: 9.5rem;
+}
diff --git a/src/components/tables/brand-table.js b/src/components/tables/brand-table.js
new file mode 100644
index 0000000..4b361a1
--- /dev/null
+++ b/src/components/tables/brand-table.js
@@ -0,0 +1,54 @@
+/* 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/brand-table.scss';
+import { deleteBrand } from './../../classes/brand';
+
+const BrandTable = (props) => {
+ const handleEdit = (i) => {
+ alert("editing coming soon")
+ }
+
+ const handleDelete = (b) => {
+ // TODO: add confirmation prompt
+ deleteBrand(b.Id, handleDelSuccess, handleDelFail);
+ }
+
+ const handleDelSuccess = () => {
+ props.refresh();
+ }
+
+ const handleDelFail = () => {
+ alert("fail")
+ }
+
+ return (
+ <div className={"brand-table"}>
+ {props.brands && props.brands.map(i =>
+ <div className={"brand"}>
+ <p className={"brand-name"}>{i.Name}</p>
+ <div className={"buttons"}>
+ <input type="button" value="Edit" onClick={() => handleEdit(i)}/>
+ <input type="button" value="Delete" onClick={() => handleDelete(i)}/>
+ </div>
+ </div>
+ )}
+ </div>
+ );
+}
+
+export default BrandTable;
diff --git a/src/components/tables/client-table.js b/src/components/tables/client-table.js
index 0060184..466316a 100644
--- a/src/components/tables/client-table.js
+++ b/src/components/tables/client-table.js
@@ -23,9 +23,9 @@ const ClientTable = (props) => {
alert("editing coming soon")
}
- const handleDelete = (i) => {
+ const handleDelete = (c) => {
// TODO: add confirmation prompt
- deleteClient(i.Id, handleDelSuccess, handleDelFail);
+ deleteClient(c.Id, handleDelSuccess, handleDelFail);
}
const handleDelSuccess = () => {
diff --git a/src/components/tables/scss/_colors.scss b/src/components/tables/scss/_colors.scss
index 98634bb..a4a8ba4 100644
--- a/src/components/tables/scss/_colors.scss
+++ b/src/components/tables/scss/_colors.scss
@@ -27,3 +27,19 @@ $fgColorDisabled: lightgray;
$inputBackgroundColor: #00000000;
$warningColor: #ed4683;
+
+@mixin button {
+ input[type=button] {
+ padding: 0.2rem 0;
+ width: 4rem;
+ background-color: $inputBackgroundColor;
+ border: 1px solid $primaryAccentColor;
+ color: $fgColor;
+ border-radius: 4px;
+ transition: background-color 0.4s, color 0.4s;
+ }
+ input[type=button]:hover {
+ background-color: $primaryAccentColor;
+ color: $fgColorAlt;
+ }
+}
diff --git a/src/components/tables/scss/brand-table.scss b/src/components/tables/scss/brand-table.scss
new file mode 100644
index 0000000..ba994c4
--- /dev/null
+++ b/src/components/tables/scss/brand-table.scss
@@ -0,0 +1,37 @@
+/* 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 "colors";
+
+.brand-table {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ .brand {
+ display: flex;
+ min-width: 22rem;
+ justify-content: space-between;
+ border-bottom: 1px dashed $primaryAccentColor;
+ }
+ .buttons {
+ display: flex;
+ justify-content: space-between;
+ width: 8.5rem;
+ @include button;
+ margin: auto 0;
+ }
+}
diff --git a/src/components/tables/scss/client-table.scss b/src/components/tables/scss/client-table.scss
index 68b7e39..fc8f22c 100644
--- a/src/components/tables/scss/client-table.scss
+++ b/src/components/tables/scss/client-table.scss
@@ -46,19 +46,7 @@
display: flex;
justify-content: space-between;
width: 8.7rem;
- input {
- padding: 0.2rem 0;
- width: 4rem;
- background-color: $inputBackgroundColor;
- border: 1px solid $primaryAccentColor;
- color: $fgColor;
- border-radius: 4px;
- transition: background-color 0.4s, color 0.4s;
- }
- input:hover {
- background-color: $primaryAccentColor;
- color: $fgColorAlt;
- }
+ @include button;
bottom: 2rem;
right: 2rem;
margin: auto;
diff --git a/src/views/manage/brands.js b/src/views/manage/brands.js
new file mode 100644
index 0000000..61afe16
--- /dev/null
+++ b/src/views/manage/brands.js
@@ -0,0 +1,44 @@
+/* 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 { useState, useEffect } from 'react';
+
+import './scss/management-page.scss'
+import { getAllBrands } from '../../classes/brand';
+import BrandEditor from './../../components/editors/brand-editor';
+import BrandTable from './../../components/tables/brand-table';
+
+const ManageBrandsPage = () => {
+ const [allBrands, setAllBrands] = useState([]);
+ // TODO: handle error
+ const updateList = () =>
+ getAllBrands(setAllBrands, () => {});
+
+ useEffect(() => {
+ updateList();
+ }, []);
+
+ return (
+ <>
+ <BrandEditor heading={"Add New Brand"} callback={updateList}/>
+ <hr/>
+ <BrandTable refresh={updateList} brands={allBrands}/>
+ </>
+ );
+}
+
+export default ManageBrandsPage;