diff --git a/package-lock.json b/package-lock.json
index 4ad0668..40e9e5e 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-query": "^3.39.3",
"react-redux": "^8.0.5",
"react-router-dom": "^6.8.1",
"react-scripts": "5.0.1",
@@ -5614,6 +5615,14 @@
"node": ">= 8.0.0"
}
},
+ "node_modules/big-integer": {
+ "version": "1.6.51",
+ "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz",
+ "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
"node_modules/big.js": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
@@ -5726,6 +5735,21 @@
"node": ">=8"
}
},
+ "node_modules/broadcast-channel": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/broadcast-channel/-/broadcast-channel-3.7.0.tgz",
+ "integrity": "sha512-cIAKJXAxGJceNZGTZSBzMxzyOn72cVgPnKx4dc6LRjQgbaJUQqhy5rzL3zbMxkMWsGKkv2hSFkPRMEXfoMZ2Mg==",
+ "dependencies": {
+ "@babel/runtime": "^7.7.2",
+ "detect-node": "^2.1.0",
+ "js-sha3": "0.8.0",
+ "microseconds": "0.2.0",
+ "nano-time": "1.0.0",
+ "oblivious-set": "1.0.0",
+ "rimraf": "3.0.2",
+ "unload": "2.2.0"
+ }
+ },
"node_modules/browser-process-hrtime": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz",
@@ -11848,6 +11872,11 @@
"url": "https://opencollective.com/js-sdsl"
}
},
+ "node_modules/js-sha3": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz",
+ "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q=="
+ },
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -12278,6 +12307,11 @@
"node": ">=8.6"
}
},
+ "node_modules/microseconds": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/microseconds/-/microseconds-0.2.0.tgz",
+ "integrity": "sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA=="
+ },
"node_modules/mime": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
@@ -12443,6 +12477,14 @@
"multicast-dns": "cli.js"
}
},
+ "node_modules/nano-time": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/nano-time/-/nano-time-1.0.0.tgz",
+ "integrity": "sha512-flnngywOoQ0lLQOTRNexn2gGSNuM9bKj9RZAWSzhQ+UJYaAFG9bac4DW9VHjUAzrOaIcajHybCTHe/bkvozQqA==",
+ "dependencies": {
+ "big-integer": "^1.6.16"
+ }
+ },
"node_modules/nanoid": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
@@ -12704,6 +12746,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/oblivious-set": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/oblivious-set/-/oblivious-set-1.0.0.tgz",
+ "integrity": "sha512-z+pI07qxo4c2CulUHCDf9lcqDlMSo72N/4rLUpRXf6fu+q8vjt8y0xS+Tlf8NTJDdTXHbdeO1n3MlbctwEoXZw=="
+ },
"node_modules/obuf": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz",
@@ -14681,6 +14728,31 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
},
+ "node_modules/react-query": {
+ "version": "3.39.3",
+ "resolved": "https://registry.npmjs.org/react-query/-/react-query-3.39.3.tgz",
+ "integrity": "sha512-nLfLz7GiohKTJDuT4us4X3h/8unOh+00MLb2yJoGTPjxKs2bc1iDhkNx2bd5MKklXnOD3NrVZ+J2UXujA5In4g==",
+ "dependencies": {
+ "@babel/runtime": "^7.5.5",
+ "broadcast-channel": "^3.4.1",
+ "match-sorter": "^6.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ },
+ "peerDependenciesMeta": {
+ "react-dom": {
+ "optional": true
+ },
+ "react-native": {
+ "optional": true
+ }
+ }
+ },
"node_modules/react-redux": {
"version": "8.0.5",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.0.5.tgz",
@@ -16644,6 +16716,15 @@
"node": ">= 10.0.0"
}
},
+ "node_modules/unload": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/unload/-/unload-2.2.0.tgz",
+ "integrity": "sha512-B60uB5TNBLtN6/LsgAf3udH9saB5p7gqJwcFfbOEZ8BcBHnGwCf6G/TGiEqkRAxX7zAFIUtzdrXQSdL3Q/wqNA==",
+ "dependencies": {
+ "@babel/runtime": "^7.6.2",
+ "detect-node": "^2.0.4"
+ }
+ },
"node_modules/unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
diff --git a/package.json b/package.json
index 89af1bf..40d5e2c 100644
--- a/package.json
+++ b/package.json
@@ -23,6 +23,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-fast-marquee": "^1.3.5",
+ "react-query": "^3.39.3",
"react-redux": "^8.0.5",
"react-router-dom": "^6.8.1",
"react-scripts": "5.0.1",
diff --git a/src/App.tsx b/src/App.tsx
index 203be88..483aec2 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -9,6 +9,12 @@ import Store from "./Plugins/Redux/Store/Store";
import { Provider } from "react-redux";
import Inventory from "./Routes/Inventory/Inventory";
import Login from "./Routes/Login/Login";
+import Product from "./Routes/Product/Product";
+import Activation from "./Routes/Activation/Activation";
+import { QueryClient, QueryClientProvider } from "react-query";
+import NewProduct from "./Routes/NewProduct/NewProduct";
+
+const queryClient = new QueryClient();
const router = createBrowserRouter([
{
@@ -56,12 +62,38 @@ const router = createBrowserRouter([
),
},
+ {
+ path: "/Product/:id",
+ element: (
+
+
+
+ ),
+ },
+ {
+ path: "/Activation/:uid/:token",
+ element: (
+
+
+
+ ),
+ },
+ {
+ path: "/NewProduct",
+ element: (
+
+
+
+ ),
+ },
]);
export default function App() {
return (
-
+
+
+
);
}
diff --git a/src/Components/Api/Api.tsx b/src/Components/Api/Api.tsx
index bddfe1f..2c89ce1 100644
--- a/src/Components/Api/Api.tsx
+++ b/src/Components/Api/Api.tsx
@@ -6,11 +6,8 @@ import {
LoginParams,
RegistrationParams,
} from "../../Interfaces/Interfaces";
-import { useDispatch } from "react-redux";
-import { SetUser } from "../../Features/Redux/Slices/LoggedInUserSlice/LoggedInUserSlice";
-import { toggle_login } from "../../Features/Redux/Slices/Login/LoginSlice";
-// Note APIs
+// Product APIs
export function GetProducts() {
const token = JSON.parse(localStorage.getItem("token") || "{}");
@@ -25,7 +22,7 @@ export function GetProducts() {
});
}
-export function GetNote(id: number) {
+export function GetProduct(id: number) {
const token = JSON.parse(localStorage.getItem("token") || "{}");
return axios
.get("http://localhost:8000/api/v1/products/" + id + "/", {
@@ -156,7 +153,8 @@ export async function CheckSavedSession() {
console.log("Previous session found");
return true;
} else {
- console.log("Previous session found but expired");
+ console.log("Previous session found but expired. Clearing token");
+ localStorage.removeItem("token");
return false;
}
}
diff --git a/src/Components/Container/Container.tsx b/src/Components/Container/Container.tsx
index 906ffe1..99be824 100644
--- a/src/Components/Container/Container.tsx
+++ b/src/Components/Container/Container.tsx
@@ -5,33 +5,33 @@ import styles from "../../styles";
import { CheckSavedSession, UserInfo } from "../Api/Api";
import { toggle_login } from "../../Features/Redux/Slices/Login/LoginSlice";
import { SetUser } from "../../Features/Redux/Slices/LoggedInUserSlice/LoggedInUserSlice";
-import { useDispatch } from "react-redux";
+import { useDispatch, useSelector } from "react-redux";
+import { LoginState } from "../../Interfaces/Interfaces";
+import { useNavigate } from "react-router-dom";
+import PreviousSessionChecker from "../PreviousSessionChecker/PreviousSessionChecker";
export interface props {
children: React.ReactNode;
}
export default function Container(props: props) {
- const dispatch = useDispatch();
- // Function to check for previous login session
- async function CheckPreviousSession() {
- if (await CheckSavedSession()) {
- await dispatch(toggle_login());
- await dispatch(SetUser(await UserInfo()));
- }
- }
- useEffect(() => {
- CheckPreviousSession();
- }, []);
-
return (
+
- {props.children}
+
+ {props.children}
+
diff --git a/src/Components/Login/Login.tsx b/src/Components/Login/Login.tsx
index 0dbcc93..4b812b2 100644
--- a/src/Components/Login/Login.tsx
+++ b/src/Components/Login/Login.tsx
@@ -1,27 +1,16 @@
-import { useSelector, useDispatch } from "react-redux";
-import { toggle_login } from "../../Features/Redux/Slices/Login/LoginSlice";
+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";
-export interface state {
- logged_in: {
- value: boolean;
- };
-}
export default function Login() {
- const logged_in = useSelector((state: state) => state.logged_in.value);
+ const logged_in = useSelector((state: LoginState) => state.logged_in.value);
const logged_in_user = useSelector(
(state: LoggedInUserState) => state.logged_in_user.value
);
const navigate = useNavigate();
- const dispatch = useDispatch();
- async function login() {
- await dispatch(toggle_login());
- await console.log("Login State Toggled " + logged_in);
- }
-
if (logged_in) {
return (
diff --git a/src/Components/LoginChecker/LoginChecker.tsx b/src/Components/LoginChecker/LoginChecker.tsx
new file mode 100644
index 0000000..c99bee3
--- /dev/null
+++ b/src/Components/LoginChecker/LoginChecker.tsx
@@ -0,0 +1,19 @@
+import * as React from "react";
+import { Navigate } from "react-router-dom";
+
+import { useSelector } from "react-redux";
+import { LoginState, OldSessionState } from "../../Interfaces/Interfaces";
+
+export interface props {}
+
+export default function LoginChecker() {
+ const logged_in = useSelector((state: LoginState) => state.logged_in.value);
+ const old_session_checked = useSelector(
+ (state: OldSessionState) => state.old_session_checked.value
+ );
+ if (!logged_in && old_session_checked) {
+ console.log("Not logged in. Redirecting to login page");
+ return ;
+ }
+ return
;
+}
diff --git a/src/Components/Logout/Logout.tsx b/src/Components/Logout/Logout.tsx
index 036f478..3c10fed 100644
--- a/src/Components/Logout/Logout.tsx
+++ b/src/Components/Logout/Logout.tsx
@@ -20,6 +20,7 @@ export default function Logout(props: props) {
async function logout() {
await dispatch(toggle_login());
+ localStorage.removeItem("token");
navigate("/");
}
diff --git a/src/Components/PreviousSessionChecker/PreviousSessionChecker.tsx b/src/Components/PreviousSessionChecker/PreviousSessionChecker.tsx
new file mode 100644
index 0000000..d0945af
--- /dev/null
+++ b/src/Components/PreviousSessionChecker/PreviousSessionChecker.tsx
@@ -0,0 +1,30 @@
+import * as React from "react";
+import { useEffect } 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";
+export default function PreviousSessionChecker() {
+ const dispatch = useDispatch();
+ const logged_in = useSelector((state: LoginState) => 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");
+ }
+ await dispatch(set_checked());
+ }
+ check();
+ }, []);
+ return ;
+}
diff --git a/src/Components/ProductsPage/BlobView/BlobView.tsx b/src/Components/ProductsPage/BlobView/BlobView.tsx
index 5eddc30..d318af9 100644
--- a/src/Components/ProductsPage/BlobView/BlobView.tsx
+++ b/src/Components/ProductsPage/BlobView/BlobView.tsx
@@ -3,16 +3,17 @@ import * as React from "react";
import styles from "../../../styles";
import { ProductList } from "../../../Interfaces/Interfaces";
import ProductIcon from "../../Icons/ProductIcon/ProductIcon";
+import { Button } from "@mui/material";
+import { useNavigate } from "react-router-dom";
export default function BlobView({ Products }: ProductList) {
+ const navigate = useNavigate();
return (
{Products.map((row) => (
-
+
))}
diff --git a/src/Components/ProductsPage/TableView/TableView.tsx b/src/Components/ProductsPage/TableView/TableView.tsx
index 5550cc9..ef020ec 100644
--- a/src/Components/ProductsPage/TableView/TableView.tsx
+++ b/src/Components/ProductsPage/TableView/TableView.tsx
@@ -9,8 +9,10 @@ import {
} from "@mui/material";
import styles from "../../../styles";
import { ProductList } from "../../../Interfaces/Interfaces";
+import { useNavigate } from "react-router-dom";
export default function TableView({ Products }: ProductList) {
+ const navigate = useNavigate();
return (
- Last Modified
+ Date Added
@@ -36,7 +38,10 @@ export default function TableView({ Products }: ProductList) {
{Products.map((row) => (
navigate("/Product/" + row.id)}
>
{row.id}
@@ -45,7 +50,7 @@ export default function TableView({ Products }: ProductList) {
{row.name}
- {row.last_modified}
+ {row.date_added}
))}
diff --git a/src/Components/ProductsPage/ViewManager.tsx b/src/Components/ProductsPage/ViewManager.tsx
index 0ef4659..da535a6 100644
--- a/src/Components/ProductsPage/ViewManager.tsx
+++ b/src/Components/ProductsPage/ViewManager.tsx
@@ -4,11 +4,21 @@ import { Switch } from "@mui/material";
import TableView from "../../Components/ProductsPage/TableView/TableView";
import BlobView from "../../Components/ProductsPage/BlobView/BlobView";
import { ProductList } from "../../Interfaces/Interfaces";
+import styles from "../../styles";
export interface props {}
export default function ViewManager(props: ProductList) {
- const [tableView, toggleTableView] = useState(false);
+ const [tableView, toggleTableView] = useState(true);
+ if (props.Products.length === 0) {
+ return (
+
+
+ No products yet. Add one!
+
+
+ );
+ }
if (tableView) {
return (
diff --git a/src/Components/SampleData/SampleData.tsx b/src/Components/SampleData/SampleData.tsx
index 4ceb9ef..d18907a 100644
--- a/src/Components/SampleData/SampleData.tsx
+++ b/src/Components/SampleData/SampleData.tsx
@@ -2,12 +2,12 @@ export const SampleProducts = [
{
id: 1,
name: "Zidane's Water",
- last_modified: "2/24/2023 10:05AM",
+ date_added: "2/24/2023 10:05AM",
},
{
id: 2,
name: "Dan's Beefed Corn",
- last_modified: "2/25/2023 4:05PM",
+ date_added: "2/25/2023 4:05PM",
},
];
diff --git a/src/Components/Sidebar/Sidebar.tsx b/src/Components/Sidebar/Sidebar.tsx
index 7dd700c..f95da1f 100644
--- a/src/Components/Sidebar/Sidebar.tsx
+++ b/src/Components/Sidebar/Sidebar.tsx
@@ -45,13 +45,15 @@ export default function Sidebar() {
>
-
navigate("/Inventory")}
name="Inventory"
>
+
navigate("/Logs")} name="Logs">
+
+
diff --git a/src/Features/Redux/Slices/OldSession/OldSessionSlice.tsx b/src/Features/Redux/Slices/OldSession/OldSessionSlice.tsx
new file mode 100644
index 0000000..04e37e3
--- /dev/null
+++ b/src/Features/Redux/Slices/OldSession/OldSessionSlice.tsx
@@ -0,0 +1,17 @@
+import { createSlice } from "@reduxjs/toolkit";
+
+export const OldSessionSlice = createSlice({
+ name: "old_session_checked",
+ initialState: {
+ value: false,
+ },
+ reducers: {
+ set_checked: (state) => {
+ state.value = !state.value;
+ },
+ },
+});
+
+export const { set_checked } = OldSessionSlice.actions;
+
+export default OldSessionSlice.reducer;
diff --git a/src/Interfaces/Interfaces.tsx b/src/Interfaces/Interfaces.tsx
index e3bf52c..35ce41a 100644
--- a/src/Interfaces/Interfaces.tsx
+++ b/src/Interfaces/Interfaces.tsx
@@ -5,12 +5,20 @@ export interface ProductList {
export interface Product {
id: number;
name: string;
- last_modified: string;
+ date_added: string;
}
// Redux Interfaces
export interface LoginState {
- Login: { logged_in: boolean };
+ logged_in: {
+ value: boolean;
+ };
+}
+
+export interface OldSessionState {
+ old_session_checked: {
+ value: boolean;
+ };
}
export interface LoggedInUserState {
@@ -50,7 +58,6 @@ export interface ActivationParams {
export interface AddProductParams {
name: string;
- quantity: string;
}
export interface UpdateProductParams {
diff --git a/src/Plugins/Redux/Store/Store.tsx b/src/Plugins/Redux/Store/Store.tsx
index 169e668..a7e36b1 100644
--- a/src/Plugins/Redux/Store/Store.tsx
+++ b/src/Plugins/Redux/Store/Store.tsx
@@ -1,10 +1,12 @@
import { configureStore } from "@reduxjs/toolkit";
import LoginReducer from "../../../Features/Redux/Slices/Login/LoginSlice";
import LoggedInUserReducer from "../../../Features/Redux/Slices/LoggedInUserSlice/LoggedInUserSlice";
+import OldSessionReducer from "../../../Features/Redux/Slices/OldSession/OldSessionSlice";
export default configureStore({
reducer: {
logged_in: LoginReducer,
logged_in_user: LoggedInUserReducer,
+ old_session_checked: OldSessionReducer,
},
});
diff --git a/src/Routes/Activation/Activation.tsx b/src/Routes/Activation/Activation.tsx
new file mode 100644
index 0000000..ff5ddbb
--- /dev/null
+++ b/src/Routes/Activation/Activation.tsx
@@ -0,0 +1,58 @@
+import styles from "../../styles";
+import { useParams } from "react-router-dom";
+import { useEffect, useState } from "react";
+import { UserActivate } from "../../Components/Api/Api";
+import { ActivationParams } from "../../Interfaces/Interfaces";
+
+export default function Activation() {
+ let { uid, token } = useParams();
+ const [status, setStatus] = useState(0);
+ async function verify(activation: ActivationParams) {
+ let status = await UserActivate(activation);
+ if (status) {
+ setStatus(1);
+ } else {
+ setStatus(2);
+ }
+ }
+ useEffect(() => {
+ if (uid && token) {
+ verify({ uid, token });
+ }
+ }, [uid, token]);
+ if (status === 1) {
+ return (
+
+
User ID: {uid}
+
+ Activation Token: {token}
+
+
+ Activation Successful. Please login
+
+
+ );
+ }
+ if (status === 2) {
+ return (
+
+
User ID: {uid}
+
+ Activation Token: {token}
+
+
+ Invalid Activation Link
+
+
+ );
+ }
+ return (
+
+
User ID: {uid}
+
+ Activation Token: {token}
+
+
Activating...
+
+ );
+}
diff --git a/src/Routes/Dashboard/Dashboard.tsx b/src/Routes/Dashboard/Dashboard.tsx
index 751c3ba..8be0dce 100644
--- a/src/Routes/Dashboard/Dashboard.tsx
+++ b/src/Routes/Dashboard/Dashboard.tsx
@@ -8,13 +8,15 @@ 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";
export default function Dashboard() {
return (
-
+
+
-
+
2546 Unique Items
-
-
+
+
In inventory
-
+
-
+
Canned Pagmamahal
-
-
+
+
In Stock: 3
-
+
-
Recently Added
-
+
-
+
Zidane's Water
-
-
+
+
Added 02/17/2023
-
+
@@ -131,66 +133,58 @@ export default function Dashboard() {
-
- Recent
-
-
+
Recent
+
Transactions
-
+
-
+
Kopiko Blanca
-
-
- Added: 96
-
-
+
+
Added: 96
+
Removed: 105
-
-
+
+
02/17/2023
-
+
-
+
Zidane's Water
-
-
- Added: 49
-
-
+
+
Added: 49
+
Removed: 24
-
-
+
+
02/17/2023
-
+
-
+
Dan's Beefed Corn
-
-
- Added: 32
-
-
+
+
Added: 32
+
Removed: 64
-
-
+
+
02/17/2023
-
+
-
+
Canned Pagmamahal
-
+
-
Added: 0
-
+
Added: 0
+
Removed: 60
-
-
+
+
02/17/2023
-
+
diff --git a/src/Routes/Login/Login.tsx b/src/Routes/Login/Login.tsx
index f728fce..e2ace97 100644
--- a/src/Routes/Login/Login.tsx
+++ b/src/Routes/Login/Login.tsx
@@ -5,6 +5,9 @@ import { Button } from "@mui/material";
import { useDispatch } from "react-redux";
import { useNavigate } from "react-router-dom";
import { useState } from "react";
+import { Navigate } from "react-router-dom";
+import { LoginState } from "../../Interfaces/Interfaces";
+import { useSelector } from "react-redux";
import { UserInfo, UserLogin } from "../../Components/Api/Api";
import { toggle_login } from "../../Features/Redux/Slices/Login/LoginSlice";
@@ -18,8 +21,12 @@ export default function Login() {
password: "",
});
const [error, setError] = useState("");
+ const logged_in = useSelector((state: LoginState) => state.logged_in.value);
+ if (logged_in) {
+ return ;
+ }
return (
-
+
Username
diff --git a/src/Routes/Logs/Logs.tsx b/src/Routes/Logs/Logs.tsx
index ea53b52..5ef42a2 100644
--- a/src/Routes/Logs/Logs.tsx
+++ b/src/Routes/Logs/Logs.tsx
@@ -10,13 +10,15 @@ import {
TableRow,
} from "@mui/material";
import { SampleLogData } from "../../Components/SampleData/SampleData";
+import LoginChecker from "../../Components/LoginChecker/LoginChecker";
export default function Logs() {
return (
-
+
+
{
+ queryClient.invalidateQueries("products");
+ },
+ });
+ return (
+
+
+
+
+
+
+
+ Product Name
+
+
{
+ setProduct(e.target.value);
+ }}
+ maxLength={20}
+ />
+
+
+
+
+
+
+ );
+}
diff --git a/src/Routes/Product/Product.tsx b/src/Routes/Product/Product.tsx
new file mode 100644
index 0000000..5497a35
--- /dev/null
+++ b/src/Routes/Product/Product.tsx
@@ -0,0 +1,90 @@
+import * as React from "react";
+import styles from "../../styles";
+import { Button } 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";
+
+export default function Product() {
+ const navigate = useNavigate();
+ let { id } = useParams();
+ const {
+ data: product,
+ isLoading,
+ error,
+ } = useQuery({
+ queryKey: ["product", Number(id)],
+ queryFn: () => GetProduct(Number(id)),
+ });
+ const queryClient = useQueryClient();
+ const mutation = useMutation({
+ mutationFn: DeleteProduct,
+ onSuccess: () => {
+ queryClient.invalidateQueries("products");
+ },
+ });
+ if (isLoading) {
+ return (
+
+
+
+ Individual Product View for id {id}
+
+
+
+ Loading product...
+
+
+
+ );
+ } else if (error) {
+ return (
+
+
+
+ Individual Product View for id {id}
+
+
+
+ Error loading product
+
+
+
+ );
+ }
+ return (
+
+
+
+
+
+
+
+ Product Name: {product.name}
+
+
+ Date Added: {product.date_added}
+
+
+
+
+
+ );
+}
diff --git a/src/Routes/Products/Products.tsx b/src/Routes/Products/Products.tsx
index 03162d3..95e6a37 100644
--- a/src/Routes/Products/Products.tsx
+++ b/src/Routes/Products/Products.tsx
@@ -1,4 +1,4 @@
-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";
@@ -6,18 +6,66 @@ 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";
export default function Products() {
const navigate = useNavigate();
+ const {
+ data: products,
+ isLoading,
+ error,
+ } = useQuery("products", GetProducts, { retry: 0 });
+ if (isLoading) {
+ return (
+
+
+
+
+
+ Loading products...
+
+
+
+ );
+ } else if (error) {
+ return (
+
+
+
+
+ Error loading products
+
+
+
+ );
+ }
return (
-
+
-
- Products
-
+
Products
-
+
);
}
diff --git a/src/routes/Inventory/Inventory.tsx b/src/routes/Inventory/Inventory.tsx
index 5c2ae15..c9f5004 100644
--- a/src/routes/Inventory/Inventory.tsx
+++ b/src/routes/Inventory/Inventory.tsx
@@ -11,13 +11,15 @@ import {
} from "@mui/material";
import { SampleInventoryData } from "../../Components/SampleData/SampleData";
import StockRenderer from "../../Components/InventoryPage/StockRenderer/StockRenderer";
+import LoginChecker from "../../Components/LoginChecker/LoginChecker";
export default function Inventory() {
return (
-