diff --git a/src/Components/Api/Api.tsx b/src/Components/Api/Api.tsx
index bcfc084..0bee75c 100644
--- a/src/Components/Api/Api.tsx
+++ b/src/Components/Api/Api.tsx
@@ -164,6 +164,24 @@ export function UserInfo() {
});
}
+export function QueryUser(id: number) {
+ const token = JSON.parse(localStorage.getItem("token") || "{}");
+ return axios
+ .get("http://localhost:8000/api/v1/user_list/" + id, {
+ headers: {
+ Authorization: "Token " + token,
+ },
+ })
+ .then((response) => {
+ console.log("Querying one user...", response.data);
+ return response.data;
+ })
+ .catch((error) => {
+ console.log("Error retrieving single user data", error.response);
+ return false;
+ });
+}
+
export function UserActivate(activation: ActivationParams) {
return axios
.post("http://localhost:8000/api/v1/accounts/users/activation/", activation)
diff --git a/src/Components/DashboardPage/LowestStockWidget/LowestStockWidget.tsx b/src/Components/DashboardPage/LowestStockWidget/LowestStockWidget.tsx
new file mode 100644
index 0000000..538cbe6
--- /dev/null
+++ b/src/Components/DashboardPage/LowestStockWidget/LowestStockWidget.tsx
@@ -0,0 +1,49 @@
+import * as React from "react";
+import styles from "../../../styles";
+import LowStockIcon from "../../Icons/LowStockIcon/LowStockIcon";
+import { ProductList } from "../../../Interfaces/Interfaces";
+
+export interface props {}
+
+export default function LowestStockWidget(props: ProductList) {
+ if (!props.Products[0]) {
+ return (
+
+
+
+ There are no products yet...
+
+
+ No worries on running out!
+
+
+ );
+ }
+ return (
+
+
+
+ {props.Products[0].name}
+
+
+ In Stock: {props.Products[0].quantity}
+
+
+ );
+}
diff --git a/src/Components/DashboardPage/RecentlyAddedWidget/RecentlyAddedWidget.tsx b/src/Components/DashboardPage/RecentlyAddedWidget/RecentlyAddedWidget.tsx
new file mode 100644
index 0000000..ed58e7a
--- /dev/null
+++ b/src/Components/DashboardPage/RecentlyAddedWidget/RecentlyAddedWidget.tsx
@@ -0,0 +1,58 @@
+import * as React from "react";
+import styles from "../../../styles";
+import { ProductList } from "../../../Interfaces/Interfaces";
+import RecentlyAddedIcon from "../../Icons/RecentlyAddedIcon/RecentlyAddedIcon";
+
+export default function RecentlyAddedWidget(props: ProductList) {
+ if (!props.Products[0]) {
+ return (
+
+
+
+ Nothing recently added...
+
+
+ );
+ }
+ return (
+
+
+
+ {props.Products[0].name}
+
+
+ {props.Products[0].date_added}
+
+
+ );
+}
diff --git a/src/Components/DashboardPage/SessionStatsWidget/SessionStatsWidget.tsx b/src/Components/DashboardPage/SessionStatsWidget/SessionStatsWidget.tsx
new file mode 100644
index 0000000..900d1b5
--- /dev/null
+++ b/src/Components/DashboardPage/SessionStatsWidget/SessionStatsWidget.tsx
@@ -0,0 +1,44 @@
+import * as React from "react";
+import styles from "../../../styles";
+import ColoredCube from "../../ColoredCube/ColoredCube";
+import StatsIcon from "../../Icons/StatsIcon/StatsIcon";
+import { useSelector } from "react-redux";
+import { SessionTransactions } from "../../../Interfaces/Interfaces";
+
+export interface props {}
+
+export default function SessionStatsWidget() {
+ const session_added = useSelector(
+ (state: SessionTransactions) => state.session_transactions.added
+ );
+ const session_removed = useSelector(
+ (state: SessionTransactions) => state.session_transactions.removed
+ );
+ return (
+
+
+
+
+ Current Session
+
+
+
+
{session_added}
+
+
+ {session_removed}
+
+
+ );
+}
diff --git a/src/Components/DashboardPage/TotalProductsWidget/TotalProductsWidget.tsx b/src/Components/DashboardPage/TotalProductsWidget/TotalProductsWidget.tsx
new file mode 100644
index 0000000..c4a19e6
--- /dev/null
+++ b/src/Components/DashboardPage/TotalProductsWidget/TotalProductsWidget.tsx
@@ -0,0 +1,37 @@
+import * as React from "react";
+import styles from "../../../styles";
+import TotalProductsIcon from "../../Icons/TotalProductsIcon/TotalProductsIcon";
+import { Product, ProductList } from "../../../Interfaces/Interfaces";
+import { useEffect, useState } from "react";
+
+export interface props {}
+
+export default function TotalProductsWidget(props: ProductList) {
+ const [items, setItems] = useState("Loading...");
+ useEffect(() => {
+ if (props.Products.length === 0) {
+ setItems("No products");
+ } else if (props.Products.length === 1) {
+ setItems("1 product");
+ } else {
+ setItems(props.Products.length + " Unique Items");
+ }
+ }, []);
+ return (
+
+
+
{items}
+
In inventory
+
+ );
+}
diff --git a/src/Components/LogsPage/RowRenderer/RowRenderer.tsx b/src/Components/LogsPage/RowRenderer/RowRenderer.tsx
new file mode 100644
index 0000000..16196fd
--- /dev/null
+++ b/src/Components/LogsPage/RowRenderer/RowRenderer.tsx
@@ -0,0 +1,99 @@
+import * as React from "react";
+import {
+ OldSessionState,
+ ProductLogEntry,
+} from "../../../Interfaces/Interfaces";
+import styles from "../../../styles";
+import { TableBody, TableRow, TableCell } from "@mui/material";
+import { GetProduct, QueryUser } from "../../Api/Api";
+import { useState } from "react";
+import { useSelector } from "react-redux";
+import { useQuery } from "react-query";
+
+export default function RowRenderer(props: ProductLogEntry) {
+ const old_session_checked = useSelector(
+ (state: OldSessionState) => state.old_session_checked.value
+ );
+ const {
+ data: user,
+ isLoading,
+ error,
+ } = useQuery({
+ queryKey: ["user_select_id_" + props.Product.id, props.Product.id],
+ queryFn: () => QueryUser(props.Product.id),
+ });
+ if (isLoading || !old_session_checked) {
+
+
+ {props.Product.history_id}
+
+
+ {props.Product.id}
+
+
+ {props.Product.name}
+
+
+ {props.Product.quantity}
+
+
+ Loading...
+
+
+ {props.Product.history_date}
+
+ ;
+ } else if (error) {
+
+
+ {props.Product.history_id}
+
+
+ {props.Product.id}
+
+
+ {props.Product.name}
+
+
+ {props.Product.quantity}
+
+
+ Loading...
+
+
+ {props.Product.history_date}
+
+ ;
+ }
+ return (
+
+
+ {props.Product.history_id}
+
+
+ {props.Product.id}
+
+
+ {props.Product.name}
+
+
+ {props.Product.quantity}
+
+
+ {isLoading || user.username}
+
+
+ {props.Product.history_date}
+
+
+ );
+}
diff --git a/src/Interfaces/Interfaces.tsx b/src/Interfaces/Interfaces.tsx
index fa27e80..70025c2 100644
--- a/src/Interfaces/Interfaces.tsx
+++ b/src/Interfaces/Interfaces.tsx
@@ -13,11 +13,24 @@ export interface ProductLogList {
ProductLogs: ProductLog[];
}
+export interface ProductLogEntry {
+ Product: {
+ history_id: number;
+ id: number;
+ name: string;
+ quantity: string;
+ history_date: string;
+ history_user_id: number;
+ };
+}
+
export interface ProductLog {
history_id: number;
+ id: number;
name: string;
quantity: string;
history_date: string;
+ history_user_id: number;
}
// Redux Interfaces
diff --git a/src/Routes/Dashboard/Dashboard.tsx b/src/Routes/Dashboard/Dashboard.tsx
index f52b29f..11e5df2 100644
--- a/src/Routes/Dashboard/Dashboard.tsx
+++ b/src/Routes/Dashboard/Dashboard.tsx
@@ -15,8 +15,16 @@ import {
GetLowestStockedProduct,
GetProducts,
} from "../../Components/Api/Api";
-import { ProductLog, SessionTransactions } from "../../Interfaces/Interfaces";
+import {
+ OldSessionState,
+ ProductLog,
+ SessionTransactions,
+} from "../../Interfaces/Interfaces";
import { useSelector } from "react-redux";
+import LowestStockWidget from "../../Components/DashboardPage/LowestStockWidget/LowestStockWidget";
+import RecentlyAddedWidget from "../../Components/DashboardPage/RecentlyAddedWidget/RecentlyAddedWidget";
+import TotalProductsWidget from "../../Components/DashboardPage/TotalProductsWidget/TotalProductsWidget";
+import SessionStatsWidget from "../../Components/DashboardPage/SessionStatsWidget/SessionStatsWidget";
export default function Dashboard() {
const logs = useQuery("logs", GetLogs, { retry: 0 });
@@ -28,13 +36,15 @@ export default function Dashboard() {
retry: 0,
}
);
- const session_added = useSelector(
- (state: SessionTransactions) => state.session_transactions.added
+ const old_session_checked = useSelector(
+ (state: OldSessionState) => state.old_session_checked.value
);
- const session_removed = useSelector(
- (state: SessionTransactions) => state.session_transactions.removed
- );
- if (logs.isLoading || products.isLoading || lowest_stock_product.isLoading) {
+ if (
+ logs.isLoading ||
+ products.isLoading ||
+ lowest_stock_product.isLoading ||
+ !old_session_checked
+ ) {
return (
@@ -79,108 +89,20 @@ export default function Dashboard() {
>
-
-
-
- {products.data.length} Unique Item/s
-
-
- In inventory
-
-
+
-
-
-
-
- Current Session
-
-
-
-
- {session_added}
-
-
-
- {session_removed}
-
-
+
-
-
-
- {lowest_stock_product.data[0].name}
-
-
- In Stock: {lowest_stock_product.data[0].quantity}
-
-
-
-
-
- {products.data[0].name}
-
-
- {products.data[0].date_added}
-
-
+
+
diff --git a/src/Routes/Logs/Logs.tsx b/src/Routes/Logs/Logs.tsx
index 5ef42a2..90a86ac 100644
--- a/src/Routes/Logs/Logs.tsx
+++ b/src/Routes/Logs/Logs.tsx
@@ -11,8 +11,49 @@ import {
} from "@mui/material";
import { SampleLogData } from "../../Components/SampleData/SampleData";
import LoginChecker from "../../Components/LoginChecker/LoginChecker";
+import { useQuery } from "react-query";
+import { GetLogs, UserInfo } from "../../Components/Api/Api";
+import { OldSessionState, ProductLog } from "../../Interfaces/Interfaces";
+import { useState } from "react";
+import RowRenderer from "../../Components/LogsPage/RowRenderer/RowRenderer";
+import { useSelector } from "react-redux";
export default function Logs() {
+ const logs = useQuery("logs", GetLogs, { retry: 0 });
+ const old_session_checked = useSelector(
+ (state: OldSessionState) => state.old_session_checked.value
+ );
+ if (logs.isLoading || !old_session_checked) {
+ return (
+
+ );
+ } else if (logs.error) {
+ return (
+
+
+
+
+
+ Error loading logs
+
+
+
+ );
+ }
return (
@@ -39,7 +80,10 @@ export default function Logs() {
Product
- Amount Change
+ Quantity
+
+
+ User
Timestamp
@@ -47,34 +91,8 @@ export default function Logs() {
- {SampleLogData.map((row) => (
-
-
- {row.id}
-
-
- {row.p_id}
-
-
- {row.p_name}
-
-
- {row.amount_changed}
-
-
- {row.timestamp}
-
-
+ {logs.data.map((row: ProductLog, index: number) => (
+
))}
diff --git a/src/Routes/Product/Product.tsx b/src/Routes/Product/Product.tsx
index 5497a35..835c874 100644
--- a/src/Routes/Product/Product.tsx
+++ b/src/Routes/Product/Product.tsx
@@ -6,6 +6,8 @@ import LoginChecker from "../../Components/LoginChecker/LoginChecker";
import { DeleteProduct, GetProduct } from "../../Components/Api/Api";
import { useMutation, useQuery, useQueryClient } from "react-query";
import ProductIcon from "../../Components/Icons/ProductIcon/ProductIcon";
+import { useSelector } from "react-redux";
+import { OldSessionState } from "../../Interfaces/Interfaces";
export default function Product() {
const navigate = useNavigate();
@@ -25,7 +27,10 @@ export default function Product() {
queryClient.invalidateQueries("products");
},
});
- if (isLoading) {
+ const old_session_checked = useSelector(
+ (state: OldSessionState) => state.old_session_checked.value
+ );
+ if (isLoading || !old_session_checked) {
return (
diff --git a/src/Routes/Products/Products.tsx b/src/Routes/Products/Products.tsx
index 95e6a37..973896b 100644
--- a/src/Routes/Products/Products.tsx
+++ b/src/Routes/Products/Products.tsx
@@ -9,6 +9,8 @@ import ViewManager from "../../Components/ProductsPage/ViewManager";
import { useQuery } from "react-query";
import { GetProducts } from "../../Components/Api/Api";
import LoginChecker from "../../Components/LoginChecker/LoginChecker";
+import { useSelector } from "react-redux";
+import { OldSessionState } from "../../Interfaces/Interfaces";
export default function Products() {
const navigate = useNavigate();
@@ -17,7 +19,10 @@ export default function Products() {
isLoading,
error,
} = useQuery("products", GetProducts, { retry: 0 });
- if (isLoading) {
+ const old_session_checked = useSelector(
+ (state: OldSessionState) => state.old_session_checked.value
+ );
+ if (isLoading || !old_session_checked) {
return (
diff --git a/src/routes/Inventory/Inventory.tsx b/src/routes/Inventory/Inventory.tsx
index afb07ad..890f91b 100644
--- a/src/routes/Inventory/Inventory.tsx
+++ b/src/routes/Inventory/Inventory.tsx
@@ -18,6 +18,8 @@ import { useMutation, useQuery, useQueryClient } from "react-query";
import RowRenderer from "../../Components/InventoryPage/RowRenderer/RowRenderer";
import AddIcon from "../../Components/Icons/AddIcon/AddIcon";
import { useNavigate } from "react-router-dom";
+import { useSelector } from "react-redux";
+import { OldSessionState } from "../../Interfaces/Interfaces";
export default function Inventory() {
const {
@@ -26,8 +28,10 @@ export default function Inventory() {
error,
} = useQuery("products", GetProducts, { retry: 0 });
const navigate = useNavigate();
-
- if (isLoading) {
+ const old_session_checked = useSelector(
+ (state: OldSessionState) => state.old_session_checked.value
+ );
+ if (isLoading || !old_session_checked) {
return (