diff --git a/package-lock.json b/package-lock.json index f2fcfb9..1744336 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,6 +28,7 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-fast-marquee": "^1.3.5", + "react-moment": "^1.1.3", "react-query": "^3.39.3", "react-redux": "^8.0.5", "react-router-dom": "^6.8.1", @@ -12592,6 +12593,15 @@ "mkdirp": "bin/cmd.js" } }, + "node_modules/moment": { + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", + "peer": true, + "engines": { + "node": "*" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -14881,6 +14891,16 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, + "node_modules/react-moment": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/react-moment/-/react-moment-1.1.3.tgz", + "integrity": "sha512-8EPvlUL8u6EknPp1ISF5MQ3wx2OHJVXIP/iZc4wRh3iV3XozftZERDv9ANZeAtMlhNNQHdFoqcZHFUkBSTONfA==", + "peerDependencies": { + "moment": "^2.29.0", + "prop-types": "^15.7.0", + "react": "^16.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-query": { "version": "3.39.3", "resolved": "https://registry.npmjs.org/react-query/-/react-query-3.39.3.tgz", diff --git a/package.json b/package.json index 17997f8..9e40098 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-fast-marquee": "^1.3.5", + "react-moment": "^1.1.3", "react-query": "^3.39.3", "react-redux": "^8.0.5", "react-router-dom": "^6.8.1", diff --git a/src/App.tsx b/src/App.tsx index 1f8b4a5..567eb03 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -22,6 +22,7 @@ import Activation from "./Routes/Activation/Activation"; import { QueryClient, QueryClientProvider } from "react-query"; import NewProduct from "./Routes/NewProduct/NewProduct"; import Register from "./Routes/Register/Register"; +import DailyView from "./Routes/DailyView/DailyView"; const queryClient = new QueryClient(); @@ -103,6 +104,14 @@ const router = createHashRouter([ ), }, + { + path: "/ActivityToday", + element: ( + + + + ), + }, ]); export default function App() { diff --git a/src/Components/Api/Api.tsx b/src/Components/Api/Api.tsx index 0cfc1f5..db8d4fb 100644 --- a/src/Components/Api/Api.tsx +++ b/src/Components/Api/Api.tsx @@ -8,11 +8,14 @@ import { } from "../../Interfaces/Interfaces"; // Product APIs +const instance = axios.create({ + baseURL: "https://keannu125.pythonanywhere.com", +}); export function GetProducts() { const token = JSON.parse(localStorage.getItem("token") || "{}"); - return axios - .get("https://keannu125.pythonanywhere.com/api/v1/products/", { + return instance + .get("api/v1/products/", { headers: { Authorization: "Token " + token, }, @@ -24,8 +27,8 @@ export function GetProducts() { export function GetProduct(id: number) { const token = JSON.parse(localStorage.getItem("token") || "{}"); - return axios - .get("https://keannu125.pythonanywhere.com/api/v1/products/" + id + "/", { + return instance + .get("api/v1/products/" + id + "/", { headers: { Authorization: "Token " + token, }, @@ -37,18 +40,12 @@ export function GetProduct(id: number) { export function UpdateProduct(product: UpdateProductParams) { const token = JSON.parse(localStorage.getItem("token") || "{}"); - return axios - .patch( - "https://keannu125.pythonanywhere.com/api/v1/products/" + - product.id + - "/", - product, - { - headers: { - Authorization: "Token " + token, - }, - } - ) + return instance + .patch("api/v1/products/" + product.id + "/", product, { + headers: { + Authorization: "Token " + token, + }, + }) .then((response) => { console.log("Product update successful"); return response.data; @@ -61,8 +58,8 @@ export function UpdateProduct(product: UpdateProductParams) { export function GetLowestStockedProduct() { const token = JSON.parse(localStorage.getItem("token") || "{}"); - return axios - .get("https://keannu125.pythonanywhere.com/api/v1/lowest_stock_product/", { + return instance + .get("api/v1/lowest_stock_product/", { headers: { Authorization: "Token " + token, }, @@ -74,8 +71,8 @@ export function GetLowestStockedProduct() { export function GetLogs() { const token = JSON.parse(localStorage.getItem("token") || "{}"); - return axios - .get("https://keannu125.pythonanywhere.com/api/v1/logs/", { + return instance + .get("api/v1/logs/", { headers: { Authorization: "Token " + token, }, @@ -87,8 +84,8 @@ export function GetLogs() { export function AddProduct(note: AddProductParams) { const token = JSON.parse(localStorage.getItem("token") || "{}"); - return axios - .post("https://keannu125.pythonanywhere.com/api/v1/products/", note, { + return instance + .post("api/v1/products/", note, { headers: { Authorization: "Token " + token, }, @@ -104,15 +101,12 @@ export function AddProduct(note: AddProductParams) { export function DeleteProduct(id: number) { const token = JSON.parse(localStorage.getItem("token") || "{}"); - return axios - .delete( - "https://keannu125.pythonanywhere.com/api/v1/products/" + id + "/", - { - headers: { - Authorization: "Token " + token, - }, - } - ) + return instance + .delete("api/v1/products/" + id + "/", { + headers: { + Authorization: "Token " + token, + }, + }) .catch((error) => { console.log("Error deleting product"); return error; @@ -122,11 +116,8 @@ export function DeleteProduct(id: number) { // User APIs export function UserRegister(register: RegistrationParams) { - return axios - .post( - "https://keannu125.pythonanywhere.com/api/v1/accounts/users/", - register - ) + return instance + .post("api/v1/accounts/users/", register) .then(async (response) => { console.log(response.data); return true; @@ -138,11 +129,8 @@ export function UserRegister(register: RegistrationParams) { } export function UserLogin(user: LoginParams) { - return axios - .post( - "https://keannu125.pythonanywhere.com/api/v1/accounts/token/login/", - user - ) + return instance + .post("api/v1/accounts/token/login/", user) .then(async (response) => { localStorage.setItem("token", JSON.stringify(response.data.auth_token)); console.log("Login Success "); @@ -156,8 +144,8 @@ export function UserLogin(user: LoginParams) { export function UserInfo() { const token = JSON.parse(localStorage.getItem("token") || "{}"); - return axios - .get("https://keannu125.pythonanywhere.com/api/v1/accounts/users/me/", { + return instance + .get("api/v1/accounts/users/me/", { headers: { Authorization: "Token " + token, }, @@ -174,8 +162,8 @@ export function UserInfo() { export function QueryUser(id: number) { const token = JSON.parse(localStorage.getItem("token") || "{}"); - return axios - .get("https://keannu125.pythonanywhere.com/api/v1/user_list/" + id, { + return instance + .get("api/v1/user_list/" + id, { headers: { Authorization: "Token " + token, }, @@ -191,11 +179,8 @@ export function QueryUser(id: number) { } export function UserActivate(activation: ActivationParams) { - return axios - .post( - "https://keannu125.pythonanywhere.com/api/v1/accounts/users/activation/", - activation - ) + return instance + .post("api/v1/accounts/users/activation/", activation) .then(async (response) => { console.log("Activation Success"); return true; diff --git a/src/Components/DashboardPage/RecentTransactionsWidget/RecentTransactionsWidget.tsx b/src/Components/DashboardPage/RecentTransactionsWidget/RecentTransactionsWidget.tsx new file mode 100644 index 0000000..1465f57 --- /dev/null +++ b/src/Components/DashboardPage/RecentTransactionsWidget/RecentTransactionsWidget.tsx @@ -0,0 +1,42 @@ +import * as React from "react"; +import { ProductLog, ProductLogList } from "../../../Interfaces/Interfaces"; +import styles from "../../../styles"; +import LogsIcon from "../../Icons/LogsIcon/LogsIcon"; +import Moment from "react-moment"; + +export default function RecentTransactionsWidget(props: ProductLogList) { + return ( +
+
+
+ +
+

Recent

+

+ Transactions +

+
+
+ {props.ProductLogs.slice(0, 5).map((log: ProductLog, index: number) => { + return ( +
+
+

+ {log.name} +

+

+ Quantity: {log.quantity} +

+

+ {log.history_date} +

+

+ Transaction ID: {log.history_id} +

+
+ ); + })} +
+
+ ); +} diff --git a/src/Components/DashboardPage/SessionStatsWidget/SessionStatsWidget.tsx b/src/Components/DashboardPage/SessionStatsWidget/SessionStatsWidget.tsx index 900d1b5..32bf35c 100644 --- a/src/Components/DashboardPage/SessionStatsWidget/SessionStatsWidget.tsx +++ b/src/Components/DashboardPage/SessionStatsWidget/SessionStatsWidget.tsx @@ -3,16 +3,16 @@ 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"; +import { RootState } from "../../../Plugins/Redux/Store/Store"; export interface props {} export default function SessionStatsWidget() { const session_added = useSelector( - (state: SessionTransactions) => state.session_transactions.added + (state: RootState) => state.session_transactions.added ); const session_removed = useSelector( - (state: SessionTransactions) => state.session_transactions.removed + (state: RootState) => state.session_transactions.removed ); return (
+ + + + + + + + ); +} diff --git a/src/Components/Login/Login.tsx b/src/Components/Login/Login.tsx index 4b812b2..66a08ad 100644 --- a/src/Components/Login/Login.tsx +++ b/src/Components/Login/Login.tsx @@ -2,13 +2,12 @@ import { useSelector } from "react-redux"; import { Button } from "@mui/material"; import styles from "../../styles"; import { useNavigate } from "react-router-dom"; -import { LoggedInUserState } from "../../Interfaces/Interfaces"; -import { LoginState } from "../../Interfaces/Interfaces"; +import { RootState } from "../../Plugins/Redux/Store/Store"; export default function Login() { - const logged_in = useSelector((state: LoginState) => state.logged_in.value); + const logged_in = useSelector((state: RootState) => state.logged_in.value); const logged_in_user = useSelector( - (state: LoggedInUserState) => state.logged_in_user.value + (state: RootState) => state.logged_in_user.value ); const navigate = useNavigate(); if (logged_in) { diff --git a/src/Components/LoginChecker/LoginChecker.tsx b/src/Components/LoginChecker/LoginChecker.tsx index 07d8bed..c273127 100644 --- a/src/Components/LoginChecker/LoginChecker.tsx +++ b/src/Components/LoginChecker/LoginChecker.tsx @@ -2,14 +2,14 @@ import * as React from "react"; import { Navigate } from "react-router-dom"; import { useSelector } from "react-redux"; -import { LoginState, OldSessionState } from "../../Interfaces/Interfaces"; +import { RootState } from "../../Plugins/Redux/Store/Store"; export interface props {} export default function LoginChecker() { - const logged_in = useSelector((state: LoginState) => state.logged_in.value); + const logged_in = useSelector((state: RootState) => state.logged_in.value); const old_session_checked = useSelector( - (state: OldSessionState) => state.old_session_checked.value + (state: RootState) => state.old_session_checked.value ); if (!logged_in && !old_session_checked) { } else if (!logged_in && old_session_checked) { diff --git a/src/Components/PreviousSessionChecker/PreviousSessionChecker.tsx b/src/Components/PreviousSessionChecker/PreviousSessionChecker.tsx index d0945af..1513740 100644 --- a/src/Components/PreviousSessionChecker/PreviousSessionChecker.tsx +++ b/src/Components/PreviousSessionChecker/PreviousSessionChecker.tsx @@ -1,30 +1,32 @@ import * as React from "react"; -import { useEffect } from "react"; +import { useEffect, useCallback } from "react"; import { useDispatch, useSelector } from "react-redux"; import { UserInfo } from "../Api/Api"; import { toggle_login } from "../../Features/Redux/Slices/Login/LoginSlice"; import { SetUser } from "../../Features/Redux/Slices/LoggedInUserSlice/LoggedInUserSlice"; -import { LoginState } from "../../Interfaces/Interfaces"; import { set_checked } from "../../Features/Redux/Slices/OldSession/OldSessionSlice"; +import { RootState } from "../../Plugins/Redux/Store/Store"; export default function PreviousSessionChecker() { const dispatch = useDispatch(); - const logged_in = useSelector((state: LoginState) => state.logged_in.value); + const logged_in = useSelector((state: RootState) => state.logged_in.value); // Function to check for previous login session - useEffect(() => { - async function check() { - if (await UserInfo()) { - if (logged_in !== true) { - console.log("Previous session found. Restoring"); - await dispatch(toggle_login()); - await dispatch(SetUser(await UserInfo())); - } - } else { - console.log("No old session found"); - localStorage.removeItem("token"); + const check = useCallback(async () => { + if (await UserInfo()) { + if (logged_in !== true) { + console.log("Previous session found. Restoring"); + await dispatch(toggle_login()); + await dispatch(SetUser(await UserInfo())); } - await dispatch(set_checked()); + } else { + console.log("No old session found"); + localStorage.removeItem("token"); } - check(); - }, []); + await dispatch(set_checked()); + }, [dispatch, logged_in]); + useEffect(() => { + if (!logged_in) { + check(); + } + }, [check, logged_in]); return
; } diff --git a/src/Components/ProductsPage/BlobView/BlobView.tsx b/src/Components/ProductsPage/BlobView/BlobView.tsx index d318af9..e88e7e9 100644 --- a/src/Components/ProductsPage/BlobView/BlobView.tsx +++ b/src/Components/ProductsPage/BlobView/BlobView.tsx @@ -21,7 +21,7 @@ export default function BlobView({ Products }: ProductList) { padding: 16, }} > - +
))}
diff --git a/src/Components/Sidebar/Sidebar.tsx b/src/Components/Sidebar/Sidebar.tsx index f95da1f..b6c622e 100644 --- a/src/Components/Sidebar/Sidebar.tsx +++ b/src/Components/Sidebar/Sidebar.tsx @@ -9,97 +9,64 @@ import Logout from "../Logout/Logout"; import InventoryIcon from "../Icons/InventoryIcon/InventoryIcon"; import LogsIcon from "../Icons/LogsIcon/LogsIcon"; import LogoutIcon from "../Icons/LogoutIcon/LogoutIcon"; +import TodayIcon from "../Icons/TodayIcon/TodayIcon"; +import { RootState } from "../../Plugins/Redux/Store/Store"; -export interface state { - logged_in: { - value: boolean; - }; -} export default function Sidebar() { const navigate = useNavigate(); - const logged_in = useSelector((state: state) => state.logged_in.value); - if (!logged_in) { - return ( -
-
-
- navigate("/")} name="Dashboard"> - - - navigate("/Products")} - name="Products" - > - - - navigate("/Inventory")} - name="Inventory" - > - - - navigate("/Logs")} name="Logs"> - - -
-
-
- ); - } else { - return ( -
-
-
- navigate("/")} name="Dashboard"> - - - navigate("/Products")} - name="Products" - > - - - navigate("/Inventory")} - name="Inventory" - > - - - navigate("/Logs")} name="Logs"> - - - - - -
-
-
- ); + const logged_in = useSelector((state: RootState) => state.logged_in.value); + function LogoutButton() { + if (!logged_in) { + return
; + } else { + return ( + + + + ); + } } + return ( +
+
+
+ navigate("/")} name="Dashboard"> + + + navigate("/Products")} name="Products"> + + + navigate("/Inventory")} + name="Inventory" + > + + + navigate("/ActivityToday")} + name="Summary" + > + + + navigate("/Logs")} name="Logs"> + + + +
+
+
+ ); } diff --git a/src/Interfaces/Interfaces.tsx b/src/Interfaces/Interfaces.tsx index c831f44..5cb725c 100644 --- a/src/Interfaces/Interfaces.tsx +++ b/src/Interfaces/Interfaces.tsx @@ -7,6 +7,12 @@ export interface Product { name: string; date_added: string; quantity: number; + history: ProductHistoryEntry[]; +} + +export interface ProductHistoryEntry { + quantity: number; + history_date: string; } export interface ProductLogList { @@ -33,36 +39,6 @@ export interface ProductLog { history_user: string; } -// Redux Interfaces -export interface LoginState { - logged_in: { - value: boolean; - }; -} - -export interface OldSessionState { - old_session_checked: { - value: boolean; - }; -} - -export interface LoggedInUserState { - logged_in_user: { - value: { - email: string; - id: number; - username: string; - }; - }; -} - -export interface SessionTransactions { - session_transactions: { - added: number; - removed: number; - }; -} - // Component Props Interfaces export interface IconProps { diff --git a/src/Plugins/Redux/Store/Store.tsx b/src/Plugins/Redux/Store/Store.tsx index 1a1fdf9..d7d9c0e 100644 --- a/src/Plugins/Redux/Store/Store.tsx +++ b/src/Plugins/Redux/Store/Store.tsx @@ -4,7 +4,7 @@ import LoggedInUserReducer from "../../../Features/Redux/Slices/LoggedInUserSlic import OldSessionReducer from "../../../Features/Redux/Slices/OldSession/OldSessionSlice"; import TransactionsThisSessionReducer from "../../../Features/Redux/Slices/TransactionsThisSessionSlice/TransactionsThisSessionSlice"; -export default configureStore({ +const store = configureStore({ reducer: { logged_in: LoginReducer, logged_in_user: LoggedInUserReducer, @@ -12,3 +12,10 @@ export default configureStore({ session_transactions: TransactionsThisSessionReducer, }, }); + +export default store; + +// Infer the `RootState` and `AppDispatch` types from the store itself +export type RootState = ReturnType; +// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState} +export type AppDispatch = typeof store.dispatch; diff --git a/src/Routes/DailyView/DailyView.tsx b/src/Routes/DailyView/DailyView.tsx new file mode 100644 index 0000000..8f8e23f --- /dev/null +++ b/src/Routes/DailyView/DailyView.tsx @@ -0,0 +1,167 @@ +import React from "react"; +import "../../index.css"; +import styles from "../../styles"; +import LoginChecker from "../../Components/LoginChecker/LoginChecker"; +import { useQuery } from "react-query"; +import { + GetLogs, + GetLowestStockedProduct, + GetProducts, +} from "../../Components/Api/Api"; +import { Product } from "../../Interfaces/Interfaces"; +import { useSelector } from "react-redux"; +import TodayIcon from "../../Components/Icons/TodayIcon/TodayIcon"; +import moment from "moment"; +import GetToday from "../../Components/GetToday/GetToday"; +import Moment from "react-moment"; +import { useNavigate } from "react-router-dom"; +import { + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, +} from "@mui/material"; +import { RootState } from "../../Plugins/Redux/Store/Store"; + +export default function DailyView() { + const logs = useQuery("logs", GetLogs, { retry: 0 }); + const products = useQuery("products", GetProducts, { retry: 0 }); + const lowest_stock_product = useQuery( + "lowest_stock_product", + GetLowestStockedProduct, + { + retry: 0, + } + ); + const old_session_checked = useSelector( + (state: RootState) => state.old_session_checked.value + ); + const navigate = useNavigate(); + if ( + logs.isLoading || + products.isLoading || + lowest_stock_product.isLoading || + !old_session_checked + ) { + return ( +
+ +
+ +

Daily View

+
+
+

+ Loading today's summary... +

+
+
+ ); + } + if (logs.error || products.error || lowest_stock_product.isError) { +
+ +
+ +

Daily View

+
+
+

+ Error loading today's summary +

+
+
; + } + return ( +
+ +
+ +

+ Products Modified Today +

+
+
+ {products.data + .filter( + (Product: Product) => + moment(Product.history[0].history_date).format("MM-DD-YYYY") === + GetToday() + ) + .map((Product: Product) => ( + + ))} +
+
+ ); +} diff --git a/src/Routes/Dashboard/Dashboard.tsx b/src/Routes/Dashboard/Dashboard.tsx index 11e5df2..a9f2117 100644 --- a/src/Routes/Dashboard/Dashboard.tsx +++ b/src/Routes/Dashboard/Dashboard.tsx @@ -1,13 +1,7 @@ -import React, { useState } from "react"; -import TotalProductsIcon from "../../Components/Icons/TotalProductsIcon/TotalProductsIcon"; -import LowStockIcon from "../../Components/Icons/LowStockIcon/LowStockIcon"; -import StatsIcon from "../../Components/Icons/StatsIcon/StatsIcon"; -import LogsIcon from "../../Components/Icons/LogsIcon/LogsIcon"; +import React from "react"; import "../../index.css"; import styles from "../../styles"; import HomeIcon from "../../Components/Icons/HomeIcon/HomeIcon"; -import ColoredCube from "../../Components/ColoredCube/ColoredCube"; -import RecentlyAddedIcon from "../../Components/Icons/RecentlyAddedIcon/RecentlyAddedIcon"; import LoginChecker from "../../Components/LoginChecker/LoginChecker"; import { useQuery } from "react-query"; import { @@ -15,16 +9,13 @@ import { GetLowestStockedProduct, GetProducts, } from "../../Components/Api/Api"; -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"; +import RecentTransactionsWidget from "../../Components/DashboardPage/RecentTransactionsWidget/RecentTransactionsWidget"; +import { RootState } from "../../Plugins/Redux/Store/Store"; export default function Dashboard() { const logs = useQuery("logs", GetLogs, { retry: 0 }); @@ -37,7 +28,7 @@ export default function Dashboard() { } ); const old_session_checked = useSelector( - (state: OldSessionState) => state.old_session_checked.value + (state: RootState) => state.old_session_checked.value ); if ( logs.isLoading || @@ -107,38 +98,7 @@ export default function Dashboard() {
-
-
-
- -
-

Recent

-

- Transactions -

-
-
- {logs.data.slice(0, 5).map((log: ProductLog, index: number) => { - return ( -
-
-

- {log.name} -

-

- Quantity: {log.quantity} -

-

- Date: {log.history_date} -

-

- Transaction ID: {log.history_id} -

-
- ); - })} -
-
+
); diff --git a/src/Routes/Logs/Logs.tsx b/src/Routes/Logs/Logs.tsx index 7376047..9b47957 100644 --- a/src/Routes/Logs/Logs.tsx +++ b/src/Routes/Logs/Logs.tsx @@ -10,23 +10,19 @@ import { TableHead, TableRow, } 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, - ProductLogEntry, -} from "../../Interfaces/Interfaces"; +import { GetLogs } from "../../Components/Api/Api"; +import { ProductLog } from "../../Interfaces/Interfaces"; import { useState } from "react"; import { useSelector } from "react-redux"; import GetToday from "../../Components/LogsPage/GetToday/GetToday"; +import { RootState } from "../../Plugins/Redux/Store/Store"; export default function Logs() { const logs = useQuery("logs", GetLogs, { retry: 0 }); const old_session_checked = useSelector( - (state: OldSessionState) => state.old_session_checked.value + (state: RootState) => state.old_session_checked.value ); const [searchTerm, setSearchTerm] = useState(""); const [searchToday, setSearchToday] = useState(""); diff --git a/src/Routes/Product/Product.tsx b/src/Routes/Product/Product.tsx index f26a575..4f183d5 100644 --- a/src/Routes/Product/Product.tsx +++ b/src/Routes/Product/Product.tsx @@ -1,13 +1,22 @@ import * as React from "react"; import styles from "../../styles"; -import { Button } from "@mui/material"; +import { + Button, + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, +} from "@mui/material"; import { useNavigate, useParams } from "react-router-dom"; 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"; +import { ProductHistoryEntry } from "../../Interfaces/Interfaces"; +import moment from "moment"; +import { RootState } from "../../Plugins/Redux/Store/Store"; export default function Product() { const navigate = useNavigate(); @@ -30,7 +39,7 @@ export default function Product() { }, }); const old_session_checked = useSelector( - (state: OldSessionState) => state.old_session_checked.value + (state: RootState) => state.old_session_checked.value ); if (isLoading || !old_session_checked) { return ( @@ -91,6 +100,48 @@ export default function Product() { > Delete Product +

+ Individual Transaction Log +

+
+ + + + + Time + + + Quantity + + + + + {product.history.map( + (history_entry: ProductHistoryEntry, index: number) => ( + + + {moment(history_entry.history_date).format( + "MMMM DD, YYYY hh:mm A" + )} + + + {history_entry.quantity} + + + ) + )} + + +
); diff --git a/src/Routes/Products/Products.tsx b/src/Routes/Products/Products.tsx index a48a69a..23d1dc5 100644 --- a/src/Routes/Products/Products.tsx +++ b/src/Routes/Products/Products.tsx @@ -1,16 +1,15 @@ -import React, { useState } from "react"; +import React from "react"; import styles from "../../styles"; import { useNavigate } from "react-router-dom"; import ProductsIcon from "../../Components/Icons/ProductsIcon/ProductsIcon"; import AddIcon from "../../Components/Icons/AddIcon/AddIcon"; import { Button } from "@mui/material"; -import { SampleProducts } from "../../Components/SampleData/SampleData"; 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"; +import { RootState } from "../../Plugins/Redux/Store/Store"; export default function Products() { const navigate = useNavigate(); @@ -20,7 +19,7 @@ export default function Products() { error, } = useQuery("products", GetProducts, { retry: 0 }); const old_session_checked = useSelector( - (state: OldSessionState) => state.old_session_checked.value + (state: RootState) => state.old_session_checked.value ); if (isLoading || !old_session_checked) { return ( diff --git a/src/Routes/Register/Register.tsx b/src/Routes/Register/Register.tsx index 1224982..287d69b 100644 --- a/src/Routes/Register/Register.tsx +++ b/src/Routes/Register/Register.tsx @@ -1,14 +1,9 @@ import * as React from "react"; import styles from "../../styles"; -import LoginIcon from "../../Components/Icons/LoginIcon/LoginIcon"; import { Button } from "@mui/material"; -import { useDispatch } from "react-redux"; -import { useNavigate } from "react-router-dom"; import { useState } from "react"; import { UserRegister } from "../../Components/Api/Api"; export default function Register() { - const navigate = useNavigate(); - const dispatch = useDispatch(); const [user, setUser] = useState({ email: "", username: "", @@ -65,11 +60,6 @@ export default function Register() { style={styles.login_button} variant="contained" onClick={async () => { - setUser({ - email: "", - username: "", - password: "", - }); if (await UserRegister(user)) { setFeedback( "Registration success. Please check your email address for activation" @@ -77,6 +67,11 @@ export default function Register() { } else { setFeedback("Invalid credentials specified"); } + setUser({ + email: "", + username: "", + password: "", + }); }} > Register diff --git a/src/routes/Inventory/Inventory.tsx b/src/routes/Inventory/Inventory.tsx index 23b0803..a0aaa79 100644 --- a/src/routes/Inventory/Inventory.tsx +++ b/src/routes/Inventory/Inventory.tsx @@ -4,22 +4,19 @@ import InventoryIcon from "../../Components/Icons/InventoryIcon/InventoryIcon"; import { Button, Table, - TableBody, TableCell, TableContainer, TableHead, TableRow, } from "@mui/material"; -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 { GetProducts } from "../../Components/Api/Api"; +import { useQuery } 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"; +import { RootState } from "../../Plugins/Redux/Store/Store"; export default function Inventory() { const { @@ -29,7 +26,7 @@ export default function Inventory() { } = useQuery("products", GetProducts, { retry: 0 }); const navigate = useNavigate(); const old_session_checked = useSelector( - (state: OldSessionState) => state.old_session_checked.value + (state: RootState) => state.old_session_checked.value ); if (isLoading || !old_session_checked) { return (