diff --git a/src/Components/Api/Api.tsx b/src/Components/Api/Api.tsx index 2c89ce1..026a6c3 100644 --- a/src/Components/Api/Api.tsx +++ b/src/Components/Api/Api.tsx @@ -35,15 +35,20 @@ export function GetProduct(id: number) { }); } -export function UpdateProduct(note: UpdateProductParams) { +export function UpdateProduct(product: UpdateProductParams) { const token = JSON.parse(localStorage.getItem("token") || "{}"); return axios - .patch("http://localhost:8000/api/v1/products/" + note.id + "/", note, { - headers: { - Authorization: "Token " + token, - }, - }) + .patch( + "http://localhost:8000/api/v1/products/" + product.id + "/", + product, + { + headers: { + Authorization: "Token " + token, + }, + } + ) .then((response) => { + console.log("Product update successful", response.data); return response.data; }) .catch((error) => { diff --git a/src/Components/InventoryPage/RowRenderer/RowRenderer.tsx b/src/Components/InventoryPage/RowRenderer/RowRenderer.tsx new file mode 100644 index 0000000..82e92a6 --- /dev/null +++ b/src/Components/InventoryPage/RowRenderer/RowRenderer.tsx @@ -0,0 +1,35 @@ +import * as React from "react"; +import { ProductList } from "../../../Interfaces/Interfaces"; +import styles from "../../../styles"; +import { TableBody, TableRow, TableCell } from "@mui/material"; +import StockRenderer from "../StockRenderer/StockRenderer"; + +export default function RowRenderer(props: ProductList) { + if (props.Products.length === 0) { + return ( +
+

+ No products yet. Add one! +

+
+ ); + } + return ( + + {props.Products.map((row) => ( + + + {row.id} + + + {row.name} + + {StockRenderer(row)} + + ))} + + ); +} diff --git a/src/Components/InventoryPage/StockRenderer/StockRenderer.tsx b/src/Components/InventoryPage/StockRenderer/StockRenderer.tsx index e81b975..8e79b18 100644 --- a/src/Components/InventoryPage/StockRenderer/StockRenderer.tsx +++ b/src/Components/InventoryPage/StockRenderer/StockRenderer.tsx @@ -1,63 +1,73 @@ -import { TableCell } from "@mui/material"; -import { useState } from "react"; +import { Button, TableCell } from "@mui/material"; +import { useEffect, useState } from "react"; import styles from "../../../styles"; import IsNumber from "../IsNumber/IsNumber"; +import { UpdateProduct } from "../../Api/Api"; +import { useQueryClient, useMutation } from "react-query"; +import { Product } from "../../../Interfaces/Interfaces"; -export default function StockRenderer(in_stock: number) { - const [stock, setStock] = useState(in_stock); - if (stock >= 0 && stock <= 3) { - return ( - - ) => { - if (IsNumber(e.target.value)) { - setStock(parseInt(e.target.value)); - } - }} - /> - - ); - } else if (stock >= 4 && stock < 9) { - return ( - - ) => { - if (IsNumber(e.target.value)) { - setStock(parseInt(e.target.value)); - } - }} - /> - - ); - } else { - return ( - - ) => { - if (IsNumber(e.target.value)) { - setStock(parseInt(e.target.value)); - } - }} - /> - - ); +export default function StockRenderer(product: Product) { + const [stock, setStock] = useState(product.quantity); + const [valueChanged, setValueChanged] = useState(false); + const queryClient = useQueryClient(); + const mutation = useMutation({ + mutationFn: UpdateProduct, + onSuccess: () => { + queryClient.invalidateQueries("products"); + }, + }); + + function updateQuantity() { + mutation.mutate({ + id: product.id, + name: product.name, + quantity: stock, + }); + setValueChanged(false); } + useEffect(() => { + if (stock !== product.quantity) { + setValueChanged(true); + } else if (stock === product.quantity) { + setValueChanged(false); + } + }, [stock]); + let style; + if (stock >= 0 && stock <= 3) { + style = styles.text_red; + } else if (stock >= 4 && stock < 9) { + style = styles.text_orange; + } else { + style = styles.text_green; + } + return ( + +
+ ) => { + if (IsNumber(e.target.value)) { + setStock(parseInt(e.target.value)); + } + }} + /> +
+ +
+ + ); } diff --git a/src/Interfaces/Interfaces.tsx b/src/Interfaces/Interfaces.tsx index 35ce41a..0fa4d8c 100644 --- a/src/Interfaces/Interfaces.tsx +++ b/src/Interfaces/Interfaces.tsx @@ -6,6 +6,7 @@ export interface Product { id: number; name: string; date_added: string; + quantity: number; } // Redux Interfaces @@ -63,5 +64,5 @@ export interface AddProductParams { export interface UpdateProductParams { id: number; name: string; - quantity: string; + quantity: number; } diff --git a/src/routes/Inventory/Inventory.tsx b/src/routes/Inventory/Inventory.tsx index c9f5004..1cc56f9 100644 --- a/src/routes/Inventory/Inventory.tsx +++ b/src/routes/Inventory/Inventory.tsx @@ -12,8 +12,59 @@ import { import { SampleInventoryData } from "../../Components/SampleData/SampleData"; import StockRenderer from "../../Components/InventoryPage/StockRenderer/StockRenderer"; import LoginChecker from "../../Components/LoginChecker/LoginChecker"; +import { GetProducts, UpdateProduct } from "../../Components/Api/Api"; +import { useMutation, useQuery, useQueryClient } from "react-query"; +import RowRenderer from "../../Components/InventoryPage/RowRenderer/RowRenderer"; export default function Inventory() { + const { + data: products, + isLoading, + error, + } = useQuery("products", GetProducts, { retry: 0 }); + + if (isLoading) { + return ( +
+ +
+
+
+ +

+ Inventory +

+
+
+
+
+

+ Loading inventory... +

+
+
+ ); + } else if (error) { + return ( +
+
+
+
+ +

+ Inventory +

+
+
+
+
+

+ Error loading inventory +

+
+
+ ); + } return (
@@ -41,22 +92,7 @@ export default function Inventory() { - - {SampleInventoryData.map((row) => ( - - - {row.id} - - - {row.name} - - {StockRenderer(row.in_stock)} - - ))} - +