mirror of
https://github.com/lemeow125/Borrowing-TrackerFrontend.git
synced 2024-11-17 06:19:27 +08:00
Added conditional rendering to dashboard page and restrict certain pages select user types
This commit is contained in:
parent
0e4c1b9f31
commit
3d20af24c9
9 changed files with 646 additions and 468 deletions
|
@ -16,6 +16,7 @@ import EquipmentListPage from "./Pages/EquipmentListPage/EquipmentListPage";
|
||||||
import EquipmentLogsPage from "./Pages/EquipmentLogsPage/EquipmentLogsPage";
|
import EquipmentLogsPage from "./Pages/EquipmentLogsPage/EquipmentLogsPage";
|
||||||
import EquipmentInstanceLogsPage from "./Pages/EquipmentInstanceLogsPage/EquipmentInstanceLogsPage";
|
import EquipmentInstanceLogsPage from "./Pages/EquipmentInstanceLogsPage/EquipmentInstanceLogsPage";
|
||||||
import EquipmentInstancesFilteredListPage from "./Pages/EquipmentInstancesListPage/EquipmentInstancesFilteredListPage";
|
import EquipmentInstancesFilteredListPage from "./Pages/EquipmentInstancesListPage/EquipmentInstancesFilteredListPage";
|
||||||
|
import RestrictedPage from "./Components/RestrictedPage/RestrictedPage";
|
||||||
|
|
||||||
const queryClient = new QueryClient();
|
const queryClient = new QueryClient();
|
||||||
const router = createHashRouter([
|
const router = createHashRouter([
|
||||||
|
@ -44,6 +45,7 @@ const router = createHashRouter([
|
||||||
element: (
|
element: (
|
||||||
<>
|
<>
|
||||||
<Revalidator />
|
<Revalidator />
|
||||||
|
<RestrictedPage allow_only="Technician" />
|
||||||
<EquipmentInstancesListPage />
|
<EquipmentInstancesListPage />
|
||||||
</>
|
</>
|
||||||
),
|
),
|
||||||
|
@ -54,6 +56,7 @@ const router = createHashRouter([
|
||||||
element: (
|
element: (
|
||||||
<>
|
<>
|
||||||
<Revalidator />
|
<Revalidator />
|
||||||
|
<RestrictedPage allow_only="Technician" />
|
||||||
<EquipmentInstancesFilteredListPage />
|
<EquipmentInstancesFilteredListPage />
|
||||||
</>
|
</>
|
||||||
),
|
),
|
||||||
|
@ -64,6 +67,7 @@ const router = createHashRouter([
|
||||||
element: (
|
element: (
|
||||||
<>
|
<>
|
||||||
<Revalidator />
|
<Revalidator />
|
||||||
|
<RestrictedPage allow_only="Technician" />
|
||||||
<EquipmentInstanceLogsPage />
|
<EquipmentInstanceLogsPage />
|
||||||
</>
|
</>
|
||||||
),
|
),
|
||||||
|
@ -74,6 +78,7 @@ const router = createHashRouter([
|
||||||
element: (
|
element: (
|
||||||
<>
|
<>
|
||||||
<Revalidator />
|
<Revalidator />
|
||||||
|
<RestrictedPage allow_only="Technician" />
|
||||||
<EquipmentListPage />
|
<EquipmentListPage />
|
||||||
</>
|
</>
|
||||||
),
|
),
|
||||||
|
@ -84,6 +89,7 @@ const router = createHashRouter([
|
||||||
element: (
|
element: (
|
||||||
<>
|
<>
|
||||||
<Revalidator />
|
<Revalidator />
|
||||||
|
<RestrictedPage allow_only="Technician" />
|
||||||
<EquipmentLogsPage />
|
<EquipmentLogsPage />
|
||||||
</>
|
</>
|
||||||
),
|
),
|
||||||
|
|
|
@ -15,6 +15,7 @@ import {
|
||||||
PatchEquipmentType,
|
PatchEquipmentType,
|
||||||
EquipmentLogListType,
|
EquipmentLogListType,
|
||||||
EquipmentInstanceLogListType,
|
EquipmentInstanceLogListType,
|
||||||
|
UserType,
|
||||||
} from "../Types/Types";
|
} from "../Types/Types";
|
||||||
|
|
||||||
const debug = true;
|
const debug = true;
|
||||||
|
@ -135,7 +136,7 @@ export async function UserAPI() {
|
||||||
return instance
|
return instance
|
||||||
.get("api/v1/accounts/users/me/", config)
|
.get("api/v1/accounts/users/me/", config)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
return response.data;
|
return response.data as UserType;
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
console.log("Error retrieving user data");
|
console.log("Error retrieving user data");
|
||||||
|
|
261
src/Components/DashboardPage/TechnicianButtons.tsx
Normal file
261
src/Components/DashboardPage/TechnicianButtons.tsx
Normal file
|
@ -0,0 +1,261 @@
|
||||||
|
import { useQueries } from "@tanstack/react-query";
|
||||||
|
import styles from "../../styles";
|
||||||
|
import { EquipmentsAPI, EquipmentInstancesAPI, UserAPI } from "../API/API";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import { Button } from "@mui/material";
|
||||||
|
import FormatListBulletedIcon from "@mui/icons-material/FormatListBulleted";
|
||||||
|
import AddToQueueIcon from "@mui/icons-material/AddToQueue";
|
||||||
|
import NoteAddIcon from "@mui/icons-material/NoteAdd";
|
||||||
|
import NoteIcon from "@mui/icons-material/Note";
|
||||||
|
import { colors } from "../../styles";
|
||||||
|
import ScienceIcon from "@mui/icons-material/Science";
|
||||||
|
import ColorizeIcon from "@mui/icons-material/Colorize";
|
||||||
|
import { Dispatch, SetStateAction } from "react";
|
||||||
|
|
||||||
|
type props = {
|
||||||
|
SetAddSKUModalOpen: Dispatch<SetStateAction<boolean>>;
|
||||||
|
SetAddItemModalOpen: Dispatch<SetStateAction<boolean>>;
|
||||||
|
};
|
||||||
|
export default function TechnicianButtons(props: props) {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const queries = useQueries({
|
||||||
|
queries: [
|
||||||
|
{
|
||||||
|
queryKey: ["equipments"],
|
||||||
|
queryFn: EquipmentsAPI,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
queryKey: ["equipment_instances"],
|
||||||
|
queryFn: EquipmentInstancesAPI,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
queryKey: ["user"],
|
||||||
|
queryFn: UserAPI,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
...styles.text_dark,
|
||||||
|
...styles.text_L,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Equipments
|
||||||
|
</p>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
...styles.flex_row,
|
||||||
|
...{
|
||||||
|
alignSelf: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
flexWrap: "wrap",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
style={{
|
||||||
|
...styles.flex_column,
|
||||||
|
...{
|
||||||
|
alignSelf: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
flexWrap: "wrap",
|
||||||
|
display:
|
||||||
|
queries[2].data && queries[2].data.is_technician
|
||||||
|
? "initial"
|
||||||
|
: "none",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
navigate("/view/equipment_instances");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<FormatListBulletedIcon
|
||||||
|
style={{
|
||||||
|
height: 64,
|
||||||
|
width: 64,
|
||||||
|
fill: colors.font_dark,
|
||||||
|
marginLeft: "1rem",
|
||||||
|
marginRight: "1rem",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
...styles.text_dark,
|
||||||
|
...styles.text_M,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
View All
|
||||||
|
</p>
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
style={{
|
||||||
|
...styles.flex_column,
|
||||||
|
...{
|
||||||
|
alignSelf: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
flexWrap: "wrap",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
props.SetAddItemModalOpen(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<AddToQueueIcon
|
||||||
|
style={{
|
||||||
|
height: 64,
|
||||||
|
width: 64,
|
||||||
|
fill: colors.font_dark,
|
||||||
|
marginLeft: "1rem",
|
||||||
|
marginRight: "1rem",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
...styles.text_dark,
|
||||||
|
...styles.text_M,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Add Item
|
||||||
|
</p>
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
style={{
|
||||||
|
...styles.flex_column,
|
||||||
|
...{
|
||||||
|
alignSelf: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
flexWrap: "wrap",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
props.SetAddSKUModalOpen(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<NoteAddIcon
|
||||||
|
style={{
|
||||||
|
height: 64,
|
||||||
|
width: 64,
|
||||||
|
fill: colors.font_dark,
|
||||||
|
marginLeft: "1rem",
|
||||||
|
marginRight: "1rem",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
...styles.text_dark,
|
||||||
|
...styles.text_M,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Add SKU
|
||||||
|
</p>
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
style={{
|
||||||
|
...styles.flex_column,
|
||||||
|
...{
|
||||||
|
alignSelf: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
flexWrap: "wrap",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
navigate("/view/equipments");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<NoteIcon
|
||||||
|
style={{
|
||||||
|
height: 64,
|
||||||
|
width: 64,
|
||||||
|
fill: colors.font_dark,
|
||||||
|
marginLeft: "1rem",
|
||||||
|
marginRight: "1rem",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
...styles.text_dark,
|
||||||
|
...styles.text_M,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
View SKUs
|
||||||
|
</p>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
...styles.flex_row,
|
||||||
|
...{
|
||||||
|
alignSelf: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
flexWrap: "wrap",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
style={{
|
||||||
|
...styles.flex_column,
|
||||||
|
...{
|
||||||
|
alignSelf: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
flexWrap: "wrap",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ScienceIcon
|
||||||
|
style={{
|
||||||
|
height: 64,
|
||||||
|
width: 64,
|
||||||
|
fill: colors.font_dark,
|
||||||
|
marginLeft: "1rem",
|
||||||
|
marginRight: "1rem",
|
||||||
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
navigate("/view/equipment_instances/filter/Glassware");
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
...styles.text_dark,
|
||||||
|
...styles.text_M,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Glassware
|
||||||
|
</p>
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
style={{
|
||||||
|
...styles.flex_column,
|
||||||
|
...{
|
||||||
|
alignSelf: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
flexWrap: "wrap",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ColorizeIcon
|
||||||
|
style={{
|
||||||
|
height: 64,
|
||||||
|
width: 64,
|
||||||
|
fill: colors.font_dark,
|
||||||
|
marginLeft: "1rem",
|
||||||
|
marginRight: "1rem",
|
||||||
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
navigate("/view/equipment_instances/filter/Miscellaneous");
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
...styles.text_dark,
|
||||||
|
...styles.text_M,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Miscellaneous
|
||||||
|
</p>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
94
src/Components/DashboardPage/TechnicianLogs.tsx
Normal file
94
src/Components/DashboardPage/TechnicianLogs.tsx
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
import { Button } from "@mui/material";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import ManageSearchIcon from "@mui/icons-material/ManageSearch";
|
||||||
|
import styles from "../../styles";
|
||||||
|
import { colors } from "../../styles";
|
||||||
|
|
||||||
|
export default function TechnicianLogs() {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
...styles.text_dark,
|
||||||
|
...styles.text_L,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Logs
|
||||||
|
</p>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
...styles.flex_row,
|
||||||
|
...{
|
||||||
|
alignSelf: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
flexWrap: "wrap",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
style={{
|
||||||
|
...styles.flex_column,
|
||||||
|
...{
|
||||||
|
alignSelf: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
flexWrap: "wrap",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
navigate("/view/equipments/logs");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ManageSearchIcon
|
||||||
|
style={{
|
||||||
|
height: 64,
|
||||||
|
width: 64,
|
||||||
|
fill: colors.font_dark,
|
||||||
|
marginLeft: "1rem",
|
||||||
|
marginRight: "1rem",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
...styles.text_dark,
|
||||||
|
...styles.text_M,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
SKU Logs
|
||||||
|
</p>
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
style={{
|
||||||
|
...styles.flex_column,
|
||||||
|
...{
|
||||||
|
alignSelf: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
flexWrap: "wrap",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
navigate("/view/equipment_instances/logs");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ManageSearchIcon
|
||||||
|
style={{
|
||||||
|
height: 64,
|
||||||
|
width: 64,
|
||||||
|
fill: colors.font_dark,
|
||||||
|
marginLeft: "1rem",
|
||||||
|
marginRight: "1rem",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
...styles.text_dark,
|
||||||
|
...styles.text_M,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Item Logs
|
||||||
|
</p>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
180
src/Components/DashboardPage/TechnicianWidgets.tsx
Normal file
180
src/Components/DashboardPage/TechnicianWidgets.tsx
Normal file
|
@ -0,0 +1,180 @@
|
||||||
|
import { useQueries } from "@tanstack/react-query";
|
||||||
|
import styles from "../../styles";
|
||||||
|
import { EquipmentsAPI, EquipmentInstancesAPI, UserAPI } from "../API/API";
|
||||||
|
|
||||||
|
export default function TechnicianWidgets() {
|
||||||
|
const queries = useQueries({
|
||||||
|
queries: [
|
||||||
|
{
|
||||||
|
queryKey: ["equipments"],
|
||||||
|
queryFn: EquipmentsAPI,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
queryKey: ["equipment_instances"],
|
||||||
|
queryFn: EquipmentInstancesAPI,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
queryKey: ["user"],
|
||||||
|
queryFn: UserAPI,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<div style={styles.flex_column}>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
...styles.flex_row,
|
||||||
|
...{
|
||||||
|
alignSelf: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
flexWrap: "wrap",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
paddingLeft: "16px",
|
||||||
|
paddingRight: "16px",
|
||||||
|
margin: "16px",
|
||||||
|
borderRadius: 16,
|
||||||
|
backgroundColor: "#a6a6a6",
|
||||||
|
alignSelf: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
width: "16rem",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
...styles.text_dark,
|
||||||
|
...styles.text_M,
|
||||||
|
...{ float: "left", position: "absolute" },
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
SKUs in Database
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
...styles.text_dark,
|
||||||
|
...styles.text_L,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{queries[0].data ? queries[0].data.length : 0}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
paddingLeft: "16px",
|
||||||
|
paddingRight: "16px",
|
||||||
|
margin: "16px",
|
||||||
|
borderRadius: 16,
|
||||||
|
backgroundColor: "#a6a6a6",
|
||||||
|
alignSelf: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
width: "16rem",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
...styles.text_dark,
|
||||||
|
...styles.text_M,
|
||||||
|
...{ float: "left", position: "absolute" },
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Items in Database
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
...styles.text_dark,
|
||||||
|
...styles.text_L,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{queries[1].data ? queries[1].data.length : 0}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
...styles.flex_row,
|
||||||
|
...{
|
||||||
|
alignSelf: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
flexWrap: "wrap",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
paddingLeft: "16px",
|
||||||
|
paddingRight: "16px",
|
||||||
|
margin: "16px",
|
||||||
|
borderRadius: 16,
|
||||||
|
backgroundColor: "#a6a6a6",
|
||||||
|
alignSelf: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
width: "16rem",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
...styles.text_dark,
|
||||||
|
...styles.text_M,
|
||||||
|
...{ float: "left", position: "absolute" },
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Functional Items
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
...styles.text_dark,
|
||||||
|
...styles.text_L,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{queries[1].data
|
||||||
|
? queries[1].data.filter(
|
||||||
|
(equipment) => equipment.status == "WORKING"
|
||||||
|
).length
|
||||||
|
: 0}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
paddingLeft: "16px",
|
||||||
|
paddingRight: "16px",
|
||||||
|
margin: "16px",
|
||||||
|
borderRadius: 16,
|
||||||
|
backgroundColor: "#a6a6a6",
|
||||||
|
alignSelf: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
width: "16rem",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
...styles.text_dark,
|
||||||
|
...styles.text_M,
|
||||||
|
...{ float: "left", position: "absolute" },
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Broken Items
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
...styles.text_dark,
|
||||||
|
...styles.text_L,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{queries[1].data
|
||||||
|
? queries[1].data.filter(
|
||||||
|
(equipment) => equipment.status == "BROKEN"
|
||||||
|
).length
|
||||||
|
: 0}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
21
src/Components/RestrictedComponent/RestrictedComponent.tsx
Normal file
21
src/Components/RestrictedComponent/RestrictedComponent.tsx
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import React from "react";
|
||||||
|
import { UserAPI } from "../API/API";
|
||||||
|
import { useQuery } from "@tanstack/react-query";
|
||||||
|
|
||||||
|
type props = {
|
||||||
|
allow_only: string;
|
||||||
|
children: React.ReactNode;
|
||||||
|
};
|
||||||
|
export default function RestrictedComponent(props: props) {
|
||||||
|
const user = useQuery({ queryKey: ["user"], queryFn: UserAPI });
|
||||||
|
if (props.allow_only === "Teacher") {
|
||||||
|
if (user.data && user.data.is_teacher) {
|
||||||
|
return <>{props.children}</>;
|
||||||
|
}
|
||||||
|
} else if (props.allow_only === "Technician") {
|
||||||
|
if (user.data && user.data.is_technician) {
|
||||||
|
return <>{props.children}</>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return <></>;
|
||||||
|
}
|
46
src/Components/RestrictedPage/RestrictedPage.tsx
Normal file
46
src/Components/RestrictedPage/RestrictedPage.tsx
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
import { useEffect } from "react";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import { UserAPI } from "../API/API";
|
||||||
|
import { toast } from "react-toastify";
|
||||||
|
import { useQuery } from "@tanstack/react-query";
|
||||||
|
|
||||||
|
type props = {
|
||||||
|
allow_only: string;
|
||||||
|
};
|
||||||
|
export default function RestrictedPage(props: props) {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const user = useQuery({ queryKey: ["user"], queryFn: UserAPI });
|
||||||
|
useEffect(() => {
|
||||||
|
if (props.allow_only == "Teacher") {
|
||||||
|
if (user.data && !user.data.is_teacher) {
|
||||||
|
navigate("/");
|
||||||
|
toast("You are not a teacher!", {
|
||||||
|
position: "bottom-center",
|
||||||
|
autoClose: 2000,
|
||||||
|
hideProgressBar: false,
|
||||||
|
closeOnClick: true,
|
||||||
|
pauseOnHover: true,
|
||||||
|
draggable: true,
|
||||||
|
progress: undefined,
|
||||||
|
theme: "light",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else if (props.allow_only == "Technician") {
|
||||||
|
if (user.data && !user.data.is_technician) {
|
||||||
|
navigate("/");
|
||||||
|
toast("You are not a technician!", {
|
||||||
|
position: "bottom-center",
|
||||||
|
autoClose: 2000,
|
||||||
|
hideProgressBar: false,
|
||||||
|
closeOnClick: true,
|
||||||
|
pauseOnHover: true,
|
||||||
|
draggable: true,
|
||||||
|
progress: undefined,
|
||||||
|
theme: "light",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [navigate, props.allow_only, user.data]);
|
||||||
|
|
||||||
|
return <></>;
|
||||||
|
}
|
|
@ -96,3 +96,13 @@ export type EquipmentInstanceLogType = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export type EquipmentInstanceLogListType = Array<EquipmentInstanceLogType>;
|
export type EquipmentInstanceLogListType = Array<EquipmentInstanceLogType>;
|
||||||
|
|
||||||
|
export type UserType = {
|
||||||
|
username: string;
|
||||||
|
email: string;
|
||||||
|
avatar: string;
|
||||||
|
first_name: string;
|
||||||
|
last_name: string;
|
||||||
|
is_teacher: boolean;
|
||||||
|
is_technician: boolean;
|
||||||
|
};
|
||||||
|
|
|
@ -1,24 +1,21 @@
|
||||||
import Header from "../../Components/Header/Header";
|
import Header from "../../Components/Header/Header";
|
||||||
import styles from "../../styles";
|
import styles from "../../styles";
|
||||||
import { useQueries } from "@tanstack/react-query";
|
import { useQueries } from "@tanstack/react-query";
|
||||||
import { EquipmentsAPI, EquipmentInstancesAPI } from "../../Components/API/API";
|
import {
|
||||||
import { Button, CircularProgress } from "@mui/material";
|
EquipmentsAPI,
|
||||||
import FormatListBulletedIcon from "@mui/icons-material/FormatListBulleted";
|
EquipmentInstancesAPI,
|
||||||
import AddToQueueIcon from "@mui/icons-material/AddToQueue";
|
UserAPI,
|
||||||
import NoteAddIcon from "@mui/icons-material/NoteAdd";
|
} from "../../Components/API/API";
|
||||||
import NoteIcon from "@mui/icons-material/Note";
|
|
||||||
import ManageSearchIcon from "@mui/icons-material/ManageSearch";
|
|
||||||
import { colors } from "../../styles";
|
|
||||||
import { useNavigate } from "react-router-dom";
|
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import AddSKUModal from "../../Components/AddSKUModal/AddSKUModal";
|
import AddSKUModal from "../../Components/AddSKUModal/AddSKUModal";
|
||||||
import Popup from "reactjs-popup";
|
import Popup from "reactjs-popup";
|
||||||
import AddItemModal from "../../Components/AddItemModal/AddItemModal";
|
import AddItemModal from "../../Components/AddItemModal/AddItemModal";
|
||||||
import ScienceIcon from "@mui/icons-material/Science";
|
import RestrictedComponent from "../../Components/RestrictedComponent/RestrictedComponent";
|
||||||
import ColorizeIcon from "@mui/icons-material/Colorize";
|
import TechnicianWidgets from "../../Components/DashboardPage/TechnicianWidgets";
|
||||||
|
import TechnicianButtons from "../../Components/DashboardPage/TechnicianButtons";
|
||||||
|
import TechnicianLogs from "../../Components/DashboardPage/TechnicianLogs";
|
||||||
|
import CircularProgress from "@mui/material/CircularProgress/CircularProgress";
|
||||||
export default function Dashboard() {
|
export default function Dashboard() {
|
||||||
const navigate = useNavigate();
|
|
||||||
|
|
||||||
const queries = useQueries({
|
const queries = useQueries({
|
||||||
queries: [
|
queries: [
|
||||||
{
|
{
|
||||||
|
@ -29,6 +26,10 @@ export default function Dashboard() {
|
||||||
queryKey: ["equipment_instances"],
|
queryKey: ["equipment_instances"],
|
||||||
queryFn: EquipmentInstancesAPI,
|
queryFn: EquipmentInstancesAPI,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
queryKey: ["user"],
|
||||||
|
queryFn: UserAPI,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
const isLoading = queries.some((result) => result.isLoading);
|
const isLoading = queries.some((result) => result.isLoading);
|
||||||
|
@ -66,460 +67,18 @@ export default function Dashboard() {
|
||||||
return (
|
return (
|
||||||
<div style={styles.background}>
|
<div style={styles.background}>
|
||||||
<Header label={"Dashboard"} />
|
<Header label={"Dashboard"} />
|
||||||
<div style={styles.flex_column}>
|
<RestrictedComponent allow_only={"Technician"}>
|
||||||
<div
|
<TechnicianWidgets />
|
||||||
style={{
|
</RestrictedComponent>
|
||||||
...styles.flex_row,
|
<RestrictedComponent allow_only={"Technician"}>
|
||||||
...{
|
<TechnicianButtons
|
||||||
alignSelf: "center",
|
SetAddItemModalOpen={SetAddItemModalOpen}
|
||||||
justifyContent: "center",
|
SetAddSKUModalOpen={SetAddSKUModalOpen}
|
||||||
flexWrap: "wrap",
|
/>
|
||||||
},
|
</RestrictedComponent>
|
||||||
}}
|
<RestrictedComponent allow_only={"Technician"}>
|
||||||
>
|
<TechnicianLogs />
|
||||||
<div
|
</RestrictedComponent>
|
||||||
style={{
|
|
||||||
paddingLeft: "16px",
|
|
||||||
paddingRight: "16px",
|
|
||||||
margin: "16px",
|
|
||||||
borderRadius: 16,
|
|
||||||
backgroundColor: "#a6a6a6",
|
|
||||||
alignSelf: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
width: "16rem",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<p
|
|
||||||
style={{
|
|
||||||
...styles.text_dark,
|
|
||||||
...styles.text_M,
|
|
||||||
...{ float: "left", position: "absolute" },
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
SKUs in Database
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p
|
|
||||||
style={{
|
|
||||||
...styles.text_dark,
|
|
||||||
...styles.text_L,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{queries[0].data ? queries[0].data.length : 0}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
paddingLeft: "16px",
|
|
||||||
paddingRight: "16px",
|
|
||||||
margin: "16px",
|
|
||||||
borderRadius: 16,
|
|
||||||
backgroundColor: "#a6a6a6",
|
|
||||||
alignSelf: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
width: "16rem",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<p
|
|
||||||
style={{
|
|
||||||
...styles.text_dark,
|
|
||||||
...styles.text_M,
|
|
||||||
...{ float: "left", position: "absolute" },
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Items in Database
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p
|
|
||||||
style={{
|
|
||||||
...styles.text_dark,
|
|
||||||
...styles.text_L,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{queries[1].data ? queries[1].data.length : 0}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
...styles.flex_row,
|
|
||||||
...{
|
|
||||||
alignSelf: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
flexWrap: "wrap",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
paddingLeft: "16px",
|
|
||||||
paddingRight: "16px",
|
|
||||||
margin: "16px",
|
|
||||||
borderRadius: 16,
|
|
||||||
backgroundColor: "#a6a6a6",
|
|
||||||
alignSelf: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
width: "16rem",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<p
|
|
||||||
style={{
|
|
||||||
...styles.text_dark,
|
|
||||||
...styles.text_M,
|
|
||||||
...{ float: "left", position: "absolute" },
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Functional Items
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p
|
|
||||||
style={{
|
|
||||||
...styles.text_dark,
|
|
||||||
...styles.text_L,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{queries[1].data
|
|
||||||
? queries[1].data.filter(
|
|
||||||
(equipment) => equipment.status == "WORKING"
|
|
||||||
).length
|
|
||||||
: 0}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
paddingLeft: "16px",
|
|
||||||
paddingRight: "16px",
|
|
||||||
margin: "16px",
|
|
||||||
borderRadius: 16,
|
|
||||||
backgroundColor: "#a6a6a6",
|
|
||||||
alignSelf: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
width: "16rem",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<p
|
|
||||||
style={{
|
|
||||||
...styles.text_dark,
|
|
||||||
...styles.text_M,
|
|
||||||
...{ float: "left", position: "absolute" },
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Broken Items
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p
|
|
||||||
style={{
|
|
||||||
...styles.text_dark,
|
|
||||||
...styles.text_L,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{queries[1].data
|
|
||||||
? queries[1].data.filter(
|
|
||||||
(equipment) => equipment.status == "BROKEN"
|
|
||||||
).length
|
|
||||||
: 0}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<p
|
|
||||||
style={{
|
|
||||||
...styles.text_dark,
|
|
||||||
...styles.text_L,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Equipments
|
|
||||||
</p>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
...styles.flex_row,
|
|
||||||
...{
|
|
||||||
alignSelf: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
flexWrap: "wrap",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
style={{
|
|
||||||
...styles.flex_column,
|
|
||||||
...{
|
|
||||||
alignSelf: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
flexWrap: "wrap",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
onClick={() => {
|
|
||||||
navigate("/view/equipment_instances");
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<FormatListBulletedIcon
|
|
||||||
style={{
|
|
||||||
height: 64,
|
|
||||||
width: 64,
|
|
||||||
fill: colors.font_dark,
|
|
||||||
marginLeft: "1rem",
|
|
||||||
marginRight: "1rem",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<p
|
|
||||||
style={{
|
|
||||||
...styles.text_dark,
|
|
||||||
...styles.text_M,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
View All
|
|
||||||
</p>
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
style={{
|
|
||||||
...styles.flex_column,
|
|
||||||
...{
|
|
||||||
alignSelf: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
flexWrap: "wrap",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
onClick={() => {
|
|
||||||
SetAddItemModalOpen(true);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<AddToQueueIcon
|
|
||||||
style={{
|
|
||||||
height: 64,
|
|
||||||
width: 64,
|
|
||||||
fill: colors.font_dark,
|
|
||||||
marginLeft: "1rem",
|
|
||||||
marginRight: "1rem",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<p
|
|
||||||
style={{
|
|
||||||
...styles.text_dark,
|
|
||||||
...styles.text_M,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Add Item
|
|
||||||
</p>
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
style={{
|
|
||||||
...styles.flex_column,
|
|
||||||
...{
|
|
||||||
alignSelf: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
flexWrap: "wrap",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
onClick={() => {
|
|
||||||
SetAddSKUModalOpen(true);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<NoteAddIcon
|
|
||||||
style={{
|
|
||||||
height: 64,
|
|
||||||
width: 64,
|
|
||||||
fill: colors.font_dark,
|
|
||||||
marginLeft: "1rem",
|
|
||||||
marginRight: "1rem",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<p
|
|
||||||
style={{
|
|
||||||
...styles.text_dark,
|
|
||||||
...styles.text_M,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Add SKU
|
|
||||||
</p>
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
style={{
|
|
||||||
...styles.flex_column,
|
|
||||||
...{
|
|
||||||
alignSelf: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
flexWrap: "wrap",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
onClick={() => {
|
|
||||||
navigate("/view/equipments");
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<NoteIcon
|
|
||||||
style={{
|
|
||||||
height: 64,
|
|
||||||
width: 64,
|
|
||||||
fill: colors.font_dark,
|
|
||||||
marginLeft: "1rem",
|
|
||||||
marginRight: "1rem",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<p
|
|
||||||
style={{
|
|
||||||
...styles.text_dark,
|
|
||||||
...styles.text_M,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
View SKUs
|
|
||||||
</p>
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
...styles.flex_row,
|
|
||||||
...{
|
|
||||||
alignSelf: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
flexWrap: "wrap",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
style={{
|
|
||||||
...styles.flex_column,
|
|
||||||
...{
|
|
||||||
alignSelf: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
flexWrap: "wrap",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<ScienceIcon
|
|
||||||
style={{
|
|
||||||
height: 64,
|
|
||||||
width: 64,
|
|
||||||
fill: colors.font_dark,
|
|
||||||
marginLeft: "1rem",
|
|
||||||
marginRight: "1rem",
|
|
||||||
}}
|
|
||||||
onClick={() => {
|
|
||||||
navigate("/view/equipment_instances/filter/Glassware");
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<p
|
|
||||||
style={{
|
|
||||||
...styles.text_dark,
|
|
||||||
...styles.text_M,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Glassware
|
|
||||||
</p>
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
style={{
|
|
||||||
...styles.flex_column,
|
|
||||||
...{
|
|
||||||
alignSelf: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
flexWrap: "wrap",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<ColorizeIcon
|
|
||||||
style={{
|
|
||||||
height: 64,
|
|
||||||
width: 64,
|
|
||||||
fill: colors.font_dark,
|
|
||||||
marginLeft: "1rem",
|
|
||||||
marginRight: "1rem",
|
|
||||||
}}
|
|
||||||
onClick={() => {
|
|
||||||
navigate("/view/equipment_instances/filter/Miscellaneous");
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<p
|
|
||||||
style={{
|
|
||||||
...styles.text_dark,
|
|
||||||
...styles.text_M,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Miscellaneous
|
|
||||||
</p>
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
<p
|
|
||||||
style={{
|
|
||||||
...styles.text_dark,
|
|
||||||
...styles.text_L,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Logs
|
|
||||||
</p>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
...styles.flex_row,
|
|
||||||
...{
|
|
||||||
alignSelf: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
flexWrap: "wrap",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
style={{
|
|
||||||
...styles.flex_column,
|
|
||||||
...{
|
|
||||||
alignSelf: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
flexWrap: "wrap",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
onClick={() => {
|
|
||||||
navigate("/view/equipments/logs");
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<ManageSearchIcon
|
|
||||||
style={{
|
|
||||||
height: 64,
|
|
||||||
width: 64,
|
|
||||||
fill: colors.font_dark,
|
|
||||||
marginLeft: "1rem",
|
|
||||||
marginRight: "1rem",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<p
|
|
||||||
style={{
|
|
||||||
...styles.text_dark,
|
|
||||||
...styles.text_M,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
SKU Logs
|
|
||||||
</p>
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
style={{
|
|
||||||
...styles.flex_column,
|
|
||||||
...{
|
|
||||||
alignSelf: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
flexWrap: "wrap",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
onClick={() => {
|
|
||||||
navigate("/view/equipment_instances/logs");
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<ManageSearchIcon
|
|
||||||
style={{
|
|
||||||
height: 64,
|
|
||||||
width: 64,
|
|
||||||
fill: colors.font_dark,
|
|
||||||
marginLeft: "1rem",
|
|
||||||
marginRight: "1rem",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<p
|
|
||||||
style={{
|
|
||||||
...styles.text_dark,
|
|
||||||
...styles.text_M,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Item Logs
|
|
||||||
</p>
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
<Popup
|
<Popup
|
||||||
open={addSKUmodalOpen}
|
open={addSKUmodalOpen}
|
||||||
onClose={() => SetAddSKUModalOpen(false)}
|
onClose={() => SetAddSKUModalOpen(false)}
|
||||||
|
|
Loading…
Reference in a new issue