diff --git a/index.html b/index.html index 6010514..cd834f8 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,7 @@ - CITC Equipment Tracker + CSM Equipment Tracker
diff --git a/package-lock.json b/package-lock.json index 5d37b69..97891f5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,12 +23,15 @@ "react-redux": "^8.1.3", "react-router-dom": "^6.18.0", "react-toastify": "^9.1.3", + "react-virtuoso": "^4.6.2", + "react-window": "^1.8.10", "reactjs-popup": "^2.0.6", "styled-components": "^6.1.1" }, "devDependencies": { "@types/react": "^18.2.15", "@types/react-dom": "^18.2.7", + "@types/react-window": "^1.8.8", "@typescript-eslint/eslint-plugin": "^6.0.0", "@typescript-eslint/parser": "^6.0.0", "@vitejs/plugin-react": "^4.0.3", @@ -1761,6 +1764,15 @@ "@types/react": "*" } }, + "node_modules/@types/react-window": { + "version": "1.8.8", + "resolved": "https://registry.npmjs.org/@types/react-window/-/react-window-1.8.8.tgz", + "integrity": "sha512-8Ls660bHR1AUA2kuRvVG9D/4XpRC6wjAaPT9dil7Ckc76eP9TKWZwwmgfq8Q1LANX3QNDnoU4Zp48A3w+zK69Q==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/scheduler": { "version": "0.16.5", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.5.tgz", @@ -3372,6 +3384,11 @@ "resolved": "https://registry.npmjs.org/media-engine/-/media-engine-1.0.3.tgz", "integrity": "sha512-aa5tG6sDoK+k70B9iEX1NeyfT8ObCKhNDs6lJVpwF6r8vhUfuKMslIcirq6HIUYuuUYLefcEQOn9bSBOvawtwg==" }, + "node_modules/memoize-one": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", + "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==" + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -3895,6 +3912,34 @@ "react-dom": ">=16.6.0" } }, + "node_modules/react-virtuoso": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/react-virtuoso/-/react-virtuoso-4.6.2.tgz", + "integrity": "sha512-vvlqvzPif+MvBrJ09+hJJrVY0xJK9yran+A+/1iwY78k0YCVKsyoNPqoLxOxzYPggspNBNXqUXEcvckN29OxyQ==", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": ">=16 || >=17 || >= 18", + "react-dom": ">=16 || >=17 || >= 18" + } + }, + "node_modules/react-window": { + "version": "1.8.10", + "resolved": "https://registry.npmjs.org/react-window/-/react-window-1.8.10.tgz", + "integrity": "sha512-Y0Cx+dnU6NLa5/EvoHukUD0BklJ8qITCtVEPY1C/nL8wwoZ0b5aEw8Ff1dOVHw7fCzMt55XfJDd8S8W8LCaUCg==", + "dependencies": { + "@babel/runtime": "^7.0.0", + "memoize-one": ">=3.1.1 <6" + }, + "engines": { + "node": ">8.0.0" + }, + "peerDependencies": { + "react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/reactjs-popup": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/reactjs-popup/-/reactjs-popup-2.0.6.tgz", diff --git a/package.json b/package.json index 389aa1a..a1000f4 100644 --- a/package.json +++ b/package.json @@ -25,12 +25,15 @@ "react-redux": "^8.1.3", "react-router-dom": "^6.18.0", "react-toastify": "^9.1.3", + "react-virtuoso": "^4.6.2", + "react-window": "^1.8.10", "reactjs-popup": "^2.0.6", "styled-components": "^6.1.1" }, "devDependencies": { "@types/react": "^18.2.15", "@types/react-dom": "^18.2.7", + "@types/react-window": "^1.8.8", "@typescript-eslint/eslint-plugin": "^6.0.0", "@typescript-eslint/parser": "^6.0.0", "@vitejs/plugin-react": "^4.0.3", diff --git a/src/App.tsx b/src/App.tsx index d294418..ddc36da 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -22,6 +22,7 @@ import AddTransactionPage from "./Pages/AddTransactionPage/AddTransactionPage"; import TransactionPage from "./Pages/TransactionPage/TransactionPage"; import EquipmentInstanceTallyPage from "./Pages/EquipmentTallyPage/EquipmentTallyPage"; import TransactionReportPage from "./Pages/TransactionReportPage/TransactionReportPage"; +import ManageEquipmentPage from "./Pages/ManageEquipmentPage/ManageEquipmentPage"; const queryClient = new QueryClient(); const router = createHashRouter([ @@ -67,6 +68,17 @@ const router = createHashRouter([ ), errorElement: , }, + { + path: "/view/ManageEquipment", + element: ( + <> + + + + + ), + errorElement: , + }, { path: "/view/equipment_instances/filter/:filter_by", element: ( diff --git a/src/Components/API/API.tsx b/src/Components/API/API.tsx index 10984e0..4c43e72 100644 --- a/src/Components/API/API.tsx +++ b/src/Components/API/API.tsx @@ -27,7 +27,7 @@ const debug = false; let backendURL; if (debug) { - backendURL = "http://localhost:8000/"; + backendURL = "http://localhost:8092/"; } else { backendURL = "https://csm-backend.keannu1.duckdns.org/"; } diff --git a/src/Components/DashboardPage/Student/StudentDashboard.tsx b/src/Components/DashboardPage/Student/StudentDashboard.tsx index 24fbc03..fcc8f40 100644 --- a/src/Components/DashboardPage/Student/StudentDashboard.tsx +++ b/src/Components/DashboardPage/Student/StudentDashboard.tsx @@ -1,7 +1,6 @@ + import styles from "../../../styles"; import { Button } from "@mui/material"; -import AddBoxIcon from "@mui/icons-material/AddBox"; -import { colors } from "../../../styles"; import { useNavigate } from "react-router-dom"; export default function StudentDashboard() { const navigate = useNavigate(); @@ -17,7 +16,7 @@ export default function StudentDashboard() { justifyContent: "center", flexWrap: "wrap", marginTop: "40px", - + width: "100%" }, @@ -28,11 +27,10 @@ export default function StudentDashboard() { ...styles.flex_column, ...{ alignSelf: "center", - justifyContent: "center", - flexWrap: "wrap", backgroundColor: "#CCDDFF", - paddingInline: "90px", - borderRadius: "20px" + borderRadius: "20px", + paddingInline: "100px", + width: "100%", }, }} onClick={() => { @@ -43,9 +41,8 @@ export default function StudentDashboard() {

CLICK TO REQUEST BORROW ITEMS diff --git a/src/Components/DashboardPage/Student/StudentTransactionListView.tsx b/src/Components/DashboardPage/Student/StudentTransactionListView.tsx index ef08e2c..07c1fd7 100644 --- a/src/Components/DashboardPage/Student/StudentTransactionListView.tsx +++ b/src/Components/DashboardPage/Student/StudentTransactionListView.tsx @@ -1,6 +1,6 @@ import { useQuery } from "@tanstack/react-query"; import { TransactionsByStudentAPI } from "../../API/API"; -import styles from "../../../styles"; +import styles, { colors } from "../../../styles"; import CircularProgress from "@mui/material/CircularProgress/CircularProgress"; import React, { useState } from "react"; import TransactionEntry from "../../TransactionEntry/TransactionEntry"; @@ -39,10 +39,11 @@ export default function StudentTransactionListView() { ); } return ( -

+
@@ -69,12 +70,43 @@ export default function StudentTransactionListView() { }} transaction={transaction} /> + )) ) : ( <> )}
+ +
); diff --git a/src/Components/DashboardPage/Teacher/TeacherTransactionListView.tsx b/src/Components/DashboardPage/Teacher/TeacherTransactionListView.tsx index 69d6818..b7f5b08 100644 --- a/src/Components/DashboardPage/Teacher/TeacherTransactionListView.tsx +++ b/src/Components/DashboardPage/Teacher/TeacherTransactionListView.tsx @@ -1,14 +1,16 @@ import { useQuery } from "@tanstack/react-query"; import { TransactionsByTeacherAPI } from "../../API/API"; -import styles from "../../../styles"; +import styles, { colors } from "../../../styles"; import CircularProgress from "@mui/material/CircularProgress/CircularProgress"; import React, { useState } from "react"; import TransactionEntry from "../../TransactionEntry/TransactionEntry"; import TransactionFilterMenu from "../../TransactionFilterMenu/TransactionFilterMenu"; import Popup from "reactjs-popup"; import EditTransactionModal from "../../EditTransactionModal/EditTransactionModal"; +import { useNavigate } from "react-router-dom"; export default function TeacherTransactionListView() { + const navigate = useNavigate(); const [EditTransactionOpen, SetEditTransactionOpen] = useState(false); const [SelectedTransaction, SetSelectedTransaction] = useState(0); const transactions = useQuery({ @@ -48,7 +50,7 @@ export default function TeacherTransactionListView() {
{transactions.data ? ( @@ -69,6 +71,35 @@ export default function TeacherTransactionListView() { }} transaction={transaction} /> + )) ) : ( @@ -76,6 +107,7 @@ export default function TeacherTransactionListView() { )}
+ SetEditTransactionOpen(false)} diff --git a/src/Components/DashboardPage/Technician/TechnicianEquipmentButtons.tsx b/src/Components/DashboardPage/Technician/TechnicianEquipmentButtons.tsx index c944e3a..3e5ed98 100644 --- a/src/Components/DashboardPage/Technician/TechnicianEquipmentButtons.tsx +++ b/src/Components/DashboardPage/Technician/TechnicianEquipmentButtons.tsx @@ -68,7 +68,7 @@ export default function TechnicianEquipmentButtons() { View All

- {/* */} - {/* */} + - {/* */} + - {/* SetAddSKUModalOpen(false)} modal @@ -285,8 +285,8 @@ export default function TechnicianEquipmentButtons() { }} > - */} - {/* + SetAddItemModalOpen(false)} modal @@ -304,7 +304,7 @@ export default function TechnicianEquipmentButtons() { }} > - */} + ); } diff --git a/src/Components/DashboardPage/Technician/TechnicianNavigation.tsx b/src/Components/DashboardPage/Technician/TechnicianNavigation.tsx new file mode 100644 index 0000000..ce853d5 --- /dev/null +++ b/src/Components/DashboardPage/Technician/TechnicianNavigation.tsx @@ -0,0 +1,125 @@ +import styles from "../../../styles"; +import { useNavigate } from "react-router-dom"; +import AssessmentIcon from "@mui/icons-material/Assessment"; + +import equipment from "../../../assets/Equipment.svg"; +import transaction from "../../../assets/Transaction.svg"; + +export default function TechnicianNavigation() { + const navigate = useNavigate(); + return ( + <> +
+
+

+ Feature +

+ + + + +
+
+ + ); +} diff --git a/src/Components/DashboardPage/Technician/TechnicianWidgets.tsx b/src/Components/DashboardPage/Technician/TechnicianWidgets.tsx index 188ea7d..9194677 100644 --- a/src/Components/DashboardPage/Technician/TechnicianWidgets.tsx +++ b/src/Components/DashboardPage/Technician/TechnicianWidgets.tsx @@ -6,7 +6,6 @@ import { UserAPI, TransactionsAPI, } from "../../API/API"; -import CircularProgress from "@mui/material/CircularProgress"; import moment from "moment"; export default function TechnicianWidgets() { @@ -34,22 +33,6 @@ export default function TechnicianWidgets() { }, ], }); - const isLoading = queries.some((result) => result.isLoading); - if (isLoading) { - return ( - <> - -

- Loading -

- - ); - } return (

- Pending Equipments -

- -

- {queries[1].data?.filter( - (equipment) => equipment.status == "Pending" - ).length || 0} + Summary

+ {/* Blue Capsule */}
-

- Equipments in Inventory -

+ {/* Transactions all */} +
+

+ Total Transactions Today +

+ +

+ {queries[3].data?.filter((transaction) => + moment(transaction.timestamp, "MM-DD-YYYY hh:mm A").isBetween( + todayStartOfDay, + todayEndOfDay + ) + ).length || "0"} +

+

+ Total Transactions this Month +

+ +

+ {queries[3].data?.filter((transaction) => + moment(transaction.timestamp, "MM-DD-YYYY hh:mm A").isBetween( + thisMonthStart, + thisMonthEnd + ) + ).length || "Loading..."} +

+
+
+
+

+ {queries[3].data?.filter( + (transaction) => + transaction.transaction_status == "Approved" + ).length || 0} +

+

+ Pending Request +

+
+
+

+ {queries[3].data?.filter( + (transaction) => + transaction.transaction_status == "Borrowed" + ).length || 0} +

+

+ On Borrow +

+
+
+

+ {queries[3].data?.filter( + (transaction) => + transaction.transaction_status == "Finalized" + ).length || 0} +

+

+ Success +

+
+
+

- {queries[1].data?.length || 0} + Borrowing Transaction

-
-
+ + {/* Yellow Capsule */}
-

- Available Equipments -

+ {/* Pending Req */} +
+

+ {queries[1].data?.length || "Loading..."} +

-

- {queries[1].data?.filter( - (equipment) => equipment.status == "Available" - ).length || 0} -

-
-
-

- Broken Equipments -

+

+ Total Equipment +

+
+
+
+

+ Available +

+

+ {queries[1].data?.filter( + (equipment) => equipment.status == "Available" + ).length || "Loading..."} +

-

- {queries[1].data?.filter( - (equipment) => equipment.status == "Broken" - ).length || 0} -

-
-
-
-
-

- Total Transactions Today -

+

+ Pending +

+

+ {queries[1].data?.filter( + (equipment) => equipment.status == "Pending" + ).length || 0} +

-

- {queries[3].data?.filter((transaction) => - moment(transaction.timestamp, "MM-DD-YYYY hh:mm A").isBetween( - todayStartOfDay, - todayEndOfDay - ) - ).length || 0} -

-
-
-

- Total Transactions this Month -

+

+ Broken +

+

+ {queries[1].data?.filter( + (equipment) => equipment.status == "Broken" + ).length || 0} +

+
+
+

- {queries[3].data?.filter((transaction) => - moment(transaction.timestamp, "MM-DD-YYYY hh:mm A").isBetween( - thisMonthStart, - thisMonthEnd - ) - ).length || 0} + Equipment Tracking

diff --git a/src/Components/Header/Header.tsx b/src/Components/Header/Header.tsx index 37984a6..219a8d1 100644 --- a/src/Components/Header/Header.tsx +++ b/src/Components/Header/Header.tsx @@ -1,5 +1,5 @@ import { useState } from "react"; -import styles, { colors } from "../../styles"; +import styles from "../../styles"; import MenuIcon from "@mui/icons-material/Menu"; import SidebarModal from "../Drawer/Drawer"; import { Drawer } from "@mui/material"; @@ -10,26 +10,32 @@ export interface props { export default function Header(props: props) { const [SidebarOpen, SetSidebarOpen] = useState(false); return ( + +
-

- {props.label} -

+ +
+

{props.label}

+
+ +
+
+ + +
+
SetSidebarOpen(false)}> diff --git a/src/Components/LoginModal/LoginModal.tsx b/src/Components/LoginModal/LoginModal.tsx index fb6a5c0..d92cd0d 100644 --- a/src/Components/LoginModal/LoginModal.tsx +++ b/src/Components/LoginModal/LoginModal.tsx @@ -6,14 +6,14 @@ import InputAdornment from "@mui/material/InputAdornment"; import IconButton from "@mui/material/IconButton"; import Visibility from "@mui/icons-material/Visibility"; import VisibilityOff from "@mui/icons-material/VisibilityOff"; -import LoginIcon from "@mui/icons-material/Login"; import Checkbox from "@mui/material/Checkbox"; -import Button from "../Button/Button"; import { useNavigate } from "react-router-dom"; import { LoginAPI } from "../API/API"; import { useDispatch } from "react-redux"; import { auth_toggle } from "../Plugins/Redux/Slices/AuthSlice/AuthSlice"; import { toast } from "react-toastify"; +import Logo_dako from "../../assets/Logo_dako.png" + export default function LoginModal() { const navigate = useNavigate(); const [showPassword, setShowPassword] = useState(false); @@ -28,25 +28,41 @@ export default function LoginModal() { <>
- -

Welcome back!

+ +

+ Welcome back! +

+

+ Sign In to Continue +

-
+
+

{error}

+
+ +
-

{error}

- +
+ ); } diff --git a/src/Components/RegisterModal/RegisterModal.tsx b/src/Components/RegisterModal/RegisterModal.tsx index ca49625..4bf18d8 100644 --- a/src/Components/RegisterModal/RegisterModal.tsx +++ b/src/Components/RegisterModal/RegisterModal.tsx @@ -1,13 +1,11 @@ import { useState } from "react"; -import styles from "../../styles"; -import { colors } from "../../styles"; +import styles, { colors } from "../../styles"; import TextField from "@mui/material/TextField"; import InputAdornment from "@mui/material/InputAdornment"; import IconButton from "@mui/material/IconButton"; import Visibility from "@mui/icons-material/Visibility"; import VisibilityOff from "@mui/icons-material/VisibilityOff"; -import { AppRegistration } from "@mui/icons-material"; -import Button from "../Button/Button"; +import Logo_dako from "../../assets/Logo_dako.png"; import { useNavigate } from "react-router-dom"; import { RegisterAPI } from "../API/API"; import { toast } from "react-toastify"; @@ -34,216 +32,263 @@ export default function RegisterModal() { const [error, setError] = useState(""); return ( <> -
- +
-

Get Started

-
+ > + -
- ) => { - setUser({ ...user, first_name: e.target.value }); - setError(""); - }} - value={user.first_name} - placeholder={"Enter your first name"} - /> - ) => - setUser({ ...user, last_name: e.target.value }) - } - value={user.last_name} - placeholder={"Enter your last name"} - /> - ) => - setUser({ ...user, email: e.target.value }) - } - value={user.email} - placeholder={"Enter your email"} - /> - - - Course - - ) => { - setUser({ ...user, course: e.target.value }); - setError(""); +

-

+

+ Enter required fields +

+
+ +
+

+ {error} +

+
+ +
+ ) => { + setUser({ ...user, first_name: e.target.value }); + setError(""); + }} + value={user.first_name} + placeholder={"Enter your first name"} + /> + ) => + setUser({ ...user, last_name: e.target.value }) + } + value={user.last_name} + placeholder={"Enter your last name"} + /> + ) => + setUser({ ...user, email: e.target.value }) + } + value={user.email} + placeholder={"Enter your email"} + /> + + + + Course + + ) => { + setUser({ ...user, course: e.target.value }); + setError(""); }} > - } - label="BS Chemistry" - style={styles.text_dark} - /> - } - label="BS Food Technology" - style={styles.text_dark} - /> - } - label="BS Applied Physics" - style={styles.text_dark} - /> - } - label="BS Environmental Science" - style={styles.text_dark} - /> -
-
-
- ) => { - setUser({ ...user, username: e.target.value }); - setError(""); - }} - value={user.username} - placeholder={"Enter username"} - /> - - setShowPassword(!showPassword)} - edge="end" - > - {showPassword ? : } - - - ), - }} - label="Password" - placeholder={"Enter password"} - onChange={(e: React.ChangeEvent) => - setUser({ ...user, password: e.target.value }) - } - value={user.password} - /> - - setShowPassword(!showPassword)} - edge="end" - > - {showPassword ? : } - - - ), - }} - label="Confirm Password" - placeholder={"Re-enter password"} - onChange={(e: React.ChangeEvent) => { - setUser({ ...user, confirm_password: e.target.value }); - setError(""); - }} - value={user.confirm_password} - /> -
-

{error}

-
-
+ +
+ +
+ +
+
); } diff --git a/src/Components/StatusTextColor/StatusTextColor.tsx b/src/Components/StatusTextColor/StatusTextColor.tsx index 4354cff..6541377 100644 --- a/src/Components/StatusTextColor/StatusTextColor.tsx +++ b/src/Components/StatusTextColor/StatusTextColor.tsx @@ -1,6 +1,6 @@ import { colors } from "../../styles"; -export default function StatusTextColor(status: string) { +export function StatusTextColor(status: string) { if ( status === "Pending Approval" || status === "Returned: Pending Checking" @@ -11,8 +11,25 @@ export default function StatusTextColor(status: string) { status === "Finalized" || status === "Borrowed" ) { - return colors.dark_green; + return colors.darkgreen; } else { return colors.red; } } + +export function StatusBGColor(status: string) { + if ( + status === "Pending Approval" || + status === "Returned: Pending Checking" + ) { + return colors.lightorange; + } else if ( + status === "Approved" || + status === "Finalized" || + status === "Borrowed" + ) { + return colors.lightgreen; + } else { + return colors.lightred; + } +} diff --git a/src/Components/TransactionEntry/TransactionEntry.tsx b/src/Components/TransactionEntry/TransactionEntry.tsx index 2a47bff..8458658 100644 --- a/src/Components/TransactionEntry/TransactionEntry.tsx +++ b/src/Components/TransactionEntry/TransactionEntry.tsx @@ -1,13 +1,13 @@ import styles from "../../styles"; import { colors } from "../../styles"; import { TransactionType } from "../Types/Types"; -import StatusTextColor from "../StatusTextColor/StatusTextColor"; +import { StatusTextColor } from "../StatusTextColor/StatusTextColor"; import CircleSharpIcon from '@mui/icons-material/CircleSharp'; export interface props { transaction: TransactionType; onClick?: React.MouseEventHandler; - + } export default function TransactionEntry(props: props) { @@ -18,11 +18,12 @@ export default function TransactionEntry(props: props) { style={{ alignSelf: "center", justifySelf: "center", - width: "584px", backgroundColor: colors.header_color, - borderRadius: 16, - margin: "10px", + borderRadius: "7px 7px 0px 0px", + marginTop: "10px", paddingTop: "15px", + width: "100%", + maxWidth: "550px" }} onClick={props.onClick} @@ -105,28 +106,7 @@ export default function TransactionEntry(props: props) { {/* //GIWALA */} - -
-

- TAP TO VIEW -

-
diff --git a/src/Components/TransactionFilterMenu/TransactionFilterMenu.tsx b/src/Components/TransactionFilterMenu/TransactionFilterMenu.tsx index 467b007..a3c9f24 100644 --- a/src/Components/TransactionFilterMenu/TransactionFilterMenu.tsx +++ b/src/Components/TransactionFilterMenu/TransactionFilterMenu.tsx @@ -41,10 +41,11 @@ export default function TransactionFilterMenu(props: props) { alignSelf: "center", justifyContent: "center", flexWrap: "wrap", + width: "100%" }, }} > - + Filter Transactions diff --git a/src/Components/TransactionPDF/TransactionPDF.tsx b/src/Components/TransactionPDF/TransactionPDF.tsx index 80c3e40..767b66a 100644 --- a/src/Components/TransactionPDF/TransactionPDF.tsx +++ b/src/Components/TransactionPDF/TransactionPDF.tsx @@ -1,161 +1,355 @@ -import { Document, Page, Text, View } from "@react-pdf/renderer"; +import { Document, Page, Text, View, Image } from "@react-pdf/renderer"; import { TransactionType } from "../Types/Types"; import { colors } from "../../styles"; -import StatusTextColor from "../StatusTextColor/StatusTextColor"; +import { + StatusTextColor, + StatusBGColor, +} from "../StatusTextColor/StatusTextColor"; +import ustplogo from "../../assets/ustp-logo.png"; type props = { - transaction: TransactionType | null; + transaction: TransactionType; }; + export default function TransactionPDF(props: props) { return ( - + + {/* Whole Page */} - - + - Transaction ID: {props.transaction?.id} - - - {props.transaction?.timestamp} - - - - - + /> + + - Borrower: {props.transaction?.borrower.name}{" "} - {`(ID:${props.transaction?.borrower.id})`} + Department of Chemistry (Laboratory) - {`(${props.transaction?.borrower.course})`} + University of Science and Technology of Southern Philippines{" "} + {"\n"} + Lapasan Cagayan de Oro City {"\n"} - Teacher: {props.transaction?.teacher.name}{" "} - {`(ID:${props.transaction?.teacher.id})`} - - - Subject: {props.transaction?.subject} - - - Remarks: {props.transaction?.remarks} - - - Consumables: {props.transaction?.consumables} + BORROWER'S SLIP - - - Equipments: - + + + {/* Status */} + + + Status: {`${props.transaction.transaction_status}`} + + + + {/* Transaction ID */} + + + Transaction ID: #{props.transaction.id} + + + + + + Borrower Details + + + {/* Top Details */} + + {/* Borrower Details */} + - {props.transaction?.equipments.map((equipment) => ( + + Name:{" "} + + {props.transaction.borrower.name} + {" "} + + + Course:{" "} - {` - ${equipment.name} (ID:${equipment.id})`} - - ))} + style={{ textDecoration: "underline" }} + >{`${props.transaction.borrower.course}`}{" "} + {"\n"} + {/* Section: {props.transaction.section} */} + + + + + Timestamp:{" "} + + {props.transaction.timestamp} + + {"\n"} + Lab instructor:{" "} + + {props.transaction.teacher.name} + {" "} + + + Subject:{" "} + + {props.transaction.subject} + + + - + + {/* Equipment Section */} + - {`${props.transaction?.transaction_status}`} + Selected Equipment + {props.transaction.equipments.map((equipment) => ( + + {` - ${equipment.name} (ID:${equipment.id})`} + + ))} + {/* total Equipment */} + + + Total Equipment: {props.transaction.equipments.length} + + + {/* Consumables Area */} + + + Consumables + + + {props.transaction?.consumables} + + + + {/* Members here */} + + + Members + + + {props.transaction?.additional_members} + + {/* Remarks */} + + + + + Remarks + + + + + {props.transaction.remarks} + + diff --git a/src/Components/Types/Types.tsx b/src/Components/Types/Types.tsx index 7e362b5..ec01f8b 100644 --- a/src/Components/Types/Types.tsx +++ b/src/Components/Types/Types.tsx @@ -110,6 +110,7 @@ export type UserType = { }; export type TransactionType = { + additional_members: string; id: number; borrower: { id: number; diff --git a/src/CountTransactionEquipments/test b/src/CountTransactionEquipments/test deleted file mode 100644 index e69de29..0000000 diff --git a/src/Pages/AddTransactionPage/AddTransactionPage.tsx b/src/Pages/AddTransactionPage/AddTransactionPage.tsx index 4b698f9..cea0fe1 100644 --- a/src/Pages/AddTransactionPage/AddTransactionPage.tsx +++ b/src/Pages/AddTransactionPage/AddTransactionPage.tsx @@ -3,7 +3,6 @@ import styles from "../../styles"; import { colors } from "../../styles"; import TextField from "@mui/material/TextField"; import AddToQueueIcon from "@mui/icons-material/AddToQueue"; -import Button from "../../Components/Button/Button"; import { toast } from "react-toastify"; import { AvailableEquipmentInstancesAPI, @@ -20,6 +19,10 @@ import { CircularProgress, MenuItem, OutlinedInput, + Autocomplete, + Alert, + Stack + } from "@mui/material"; import React from "react"; import Header from "../../Components/Header/Header"; @@ -32,10 +35,10 @@ export default function AddTransactionPage() { equipments: [] as number[], teacher: 0, subject: "", - remarks: " ", + remarks: "", transaction_status: "Pending Approval", - consumables: " ", - additional_members: " ", + consumables: "", + additional_members: "", borrower: 0, }); /* @@ -109,6 +112,7 @@ export default function AddTransactionPage() { alignItems: "center", justifyContent: "center", overflowY: "scroll", + marginTop: 64 }, }} > @@ -124,31 +128,58 @@ export default function AddTransactionPage() {

Borrowing Form

-
+
- Items Requested - + equipments: newValue.map((item) => item.id), + }); + }} + renderInput={(params) => ( + + )} + /> - Assigned Teacher + + Assigned Teacher + - Subject + + Subject + ) => { @@ -180,21 +216,16 @@ export default function AddTransactionPage() { placeholder={"The subject requiring the equipments"} /> + - Remarks - ) => { - SetTransaction({ ...transaction, remarks: e.target.value }); - setError(""); + - - - Consumables + > + Consumables + - Additional Members + + Additional Members + + + + Remarks (optional) + + ) => { + SetTransaction({ ...transaction, remarks: e.target.value }); + setError(""); + }} + value={transaction.remarks} + placeholder={"Add a brief description of the request or N/A."} + /> +
-

{error}

+ +
-
+ +

{error}

+ + +
); } diff --git a/src/Pages/DashboardPage/DashboardPage.tsx b/src/Pages/DashboardPage/DashboardPage.tsx index 4f493d9..bc923ef 100644 --- a/src/Pages/DashboardPage/DashboardPage.tsx +++ b/src/Pages/DashboardPage/DashboardPage.tsx @@ -2,40 +2,40 @@ import Header from "../../Components/Header/Header"; import styles from "../../styles"; import RestrictedComponent from "../../Components/RestrictedComponent/RestrictedComponent"; import TechnicianWidgets from "../../Components/DashboardPage/Technician/TechnicianWidgets"; -import TechnicianEquipmentButtons from "../../Components/DashboardPage/Technician/TechnicianEquipmentButtons"; -import TechnicianLogButtons from "../../Components/DashboardPage/Technician/TechnicianLogButtons"; import StudentTransactionListView from "../../Components/DashboardPage/Student/StudentTransactionListView"; import StudentDashboard from "../../Components/DashboardPage/Student/StudentDashboard"; +import TechnicianNavigation from "../../Components/DashboardPage/Technician/TechnicianNavigation"; import TeacherTransactionListView from "../../Components/DashboardPage/Teacher/TeacherTransactionListView"; export default function Dashboard() { return (
- - - - - - -
- - - -
-
- - - +
+ + + + + +
+ + + +
+
+ + + +
); } diff --git a/src/Pages/EquipmentInstancesListPage/EquipmentInstancesListPage.tsx b/src/Pages/EquipmentInstancesListPage/EquipmentInstancesListPage.tsx index f875f95..e72d3c5 100644 --- a/src/Pages/EquipmentInstancesListPage/EquipmentInstancesListPage.tsx +++ b/src/Pages/EquipmentInstancesListPage/EquipmentInstancesListPage.tsx @@ -16,22 +16,14 @@ import { useState } from "react"; import Popup from "reactjs-popup"; import Autocomplete from "@mui/material/Autocomplete"; import SearchIcon from "@mui/icons-material/Search"; -import AddItemModal from "../../Components/AddItemModal/AddItemModal"; -import AddToQueueIcon from "@mui/icons-material/AddToQueue"; -import ScienceIcon from "@mui/icons-material/Science"; -import ColorizeIcon from "@mui/icons-material/Colorize"; -import { Button } from "@mui/material"; -import { useNavigate } from "react-router-dom"; export default function EquipmentInstancesListPage() { const [editmodalOpen, SetEditModalOpen] = useState(false); const [selectedItem, SetSelectedItem] = useState(0); - const [additemmodalOpen, SetAddItemModalOpen] = useState(false); - const navigate = useNavigate(); const equipment_instances = useQuery({ queryKey: ["equipment_instances"], @@ -81,195 +73,81 @@ export default function EquipmentInstancesListPage() { width: "100%", minHeight: "100%", minWidth: "100%", - flexWrap: "wrap", }} > - {/* ADDED/INSERTED BUTTON,POPUP, TWO CATEGORY BUTTONS*/} - - - SetAddItemModalOpen(false)} - modal - position={"top center"} - contentStyle={{ - width: "32rem", - borderRadius: 16, - borderColor: "grey", - borderStyle: "solid", - borderWidth: 1, - padding: 16, - alignContent: "center", - justifyContent: "center", - textAlign: "center", - }} - > - - - - - - -
-
- - - theme.palette.getContrastText( - theme.palette.background.paper - ), - }, - }} - value={filter} - onChange={(_event, newValue) => { - setFilter(newValue); - }} - freeSolo - id="custom-input-demo" - options={["Available", "Broken", "Glassware", "Miscellaneous"]} - renderInput={(params) => ( -
- -
- )} - /> -

- Results Found:{" "} - { - equipment_instances?.data?.filter((equipment) => - filter !== null - ? // If filter is not null, we filter if it matches any criteria - equipment.equipment_name - .toLowerCase() - .includes(filter.toLowerCase()) || - equipment.category - .toLowerCase() - .includes(filter.toLowerCase()) || - equipment.last_updated - .toLowerCase() - .includes(filter?.toLowerCase()) || - equipment.status.toLowerCase() == filter.toLowerCase() - : // If filter keyword is null then we just pass through everything as if we did not filter at all - true - ).length - } -

-
+
+ +
+ +
- > - - - - - SetAddSKUModalOpen(false)} - modal - position={"top center"} - contentStyle={{ - width: "32rem", - borderRadius: 16, - borderColor: "grey", - borderStyle: "solid", - borderWidth: 1, - padding: 16, - alignContent: "center", - justifyContent: "center", - textAlign: "center", - }} - > - - + + -
-
+ + + theme.palette.getContrastText(theme.palette.background.paper), + }, + }} + value={filter} + onChange={(_event, newValue) => { + setFilter(newValue); + }} + freeSolo + id="custom-input-demo" + options={["Glassware", "Miscellaneous"]} + renderInput={(params) => ( +
+ +
+ )} + /> +

- - - theme.palette.getContrastText( - theme.palette.background.paper - ), - }, - }} - value={filter} - onChange={(_event, newValue) => { - setFilter(newValue); - }} - freeSolo - id="custom-input-demo" - options={["Glassware", "Miscellaneous"]} - renderInput={(params) => ( -

- -
- )} - /> -

- Results Found:{" "} - { - equipments?.data?.filter((equipment) => - filter !== null - ? // If filter is not null, we filter if it matches any criteria - equipment.name - .toLowerCase() - .includes(filter.toLowerCase()) || - equipment.category - .toLowerCase() - .includes(filter.toLowerCase()) || - equipment.last_updated - .toLowerCase() - .includes(filter?.toLowerCase()) || - equipment.category.toLowerCase() == filter.toLowerCase() - : // If filter keyword is null then we just pass through everything as if we did not filter at all - true - ).length - } -

-
+ Results Found:{" "} + { + equipment_instances?.data?.filter((equipment) => + filter !== null + ? // If filter is not null, we filter if it matches any criteria + equipment.equipment_name + .toLowerCase() + .includes(filter.toLowerCase()) || + equipment.category + .toLowerCase() + .includes(filter.toLowerCase()) || + equipment.last_updated + .toLowerCase() + .includes(filter?.toLowerCase()) || + equipment.status.toLowerCase() == filter.toLowerCase() + : // If filter keyword is null then we just pass through everything as if we did not filter at all + true + ).length + } +

+
@@ -51,19 +52,26 @@ export default function LandingPage() { >

- CSM Inventory + Welcome! +

+ +

+ CSM Borrowing and Inventory
Monitoring and Management System

diff --git a/src/Pages/ManageEquipmentPage/ManageEquipmentPage.tsx b/src/Pages/ManageEquipmentPage/ManageEquipmentPage.tsx new file mode 100644 index 0000000..5bcabe9 --- /dev/null +++ b/src/Pages/ManageEquipmentPage/ManageEquipmentPage.tsx @@ -0,0 +1,20 @@ +import Header from "../../Components/Header/Header"; +import styles from "../../styles"; +import RestrictedComponent from "../../Components/RestrictedComponent/RestrictedComponent"; +import TechnicianEquipmentButtons from "../../Components/DashboardPage/Technician/TechnicianEquipmentButtons"; +import TechnicianLogButtons from "../../Components/DashboardPage/Technician/TechnicianLogButtons"; + + +export default function ManageEquipmentPage() { +return ( +
+
+
+ + + + +
+
+); +} diff --git a/src/Pages/TransactionPage/TransactionPage.tsx b/src/Pages/TransactionPage/TransactionPage.tsx index f4d7d5a..ab6ceb2 100644 --- a/src/Pages/TransactionPage/TransactionPage.tsx +++ b/src/Pages/TransactionPage/TransactionPage.tsx @@ -53,6 +53,7 @@ export default function TransactionPage() { alignContent: "center", justifyContent: "center", alignItems: "center", + marginTop: 64 }} > - Equipments + Additional Members + + + Additional Members + + + Actions @@ -189,6 +202,9 @@ export default function TransactionsListPage() { transaction.borrower.name .toLowerCase() .includes(filter.toLowerCase()) || + transaction.additional_members + .toLowerCase() + .includes(filter.toLowerCase()) || transaction.teacher.name .toLowerCase() .includes(filter.toLowerCase()) || @@ -313,6 +329,28 @@ export default function TransactionsListPage() { > {transaction.consumables} + { + if ( + transaction.transaction_status != "Finalized" && + transaction.transaction_status != "Rejected" + ) { + SetSelectedTransaction(transaction.id); + SetEditTransactionOpen(true); + } + }} + > + {transaction.additional_members} +

Involved Items: {transaction.equipments.length} @@ -403,6 +441,46 @@ export default function TransactionsListPage() { + + + )) ) : ( diff --git a/src/assets/Equipment.svg b/src/assets/Equipment.svg new file mode 100644 index 0000000..5cc567e --- /dev/null +++ b/src/assets/Equipment.svg @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/Profile-Icon.png b/src/assets/Profile-Icon.png new file mode 100644 index 0000000..c1f29dd Binary files /dev/null and b/src/assets/Profile-Icon.png differ diff --git a/src/assets/Transaction.svg b/src/assets/Transaction.svg new file mode 100644 index 0000000..e81218f --- /dev/null +++ b/src/assets/Transaction.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/assets/ustp-logo.png b/src/assets/ustp-logo.png new file mode 100644 index 0000000..ff20f52 Binary files /dev/null and b/src/assets/ustp-logo.png differ diff --git a/src/index.css b/src/index.css index b2acf00..610c080 100644 --- a/src/index.css +++ b/src/index.css @@ -82,3 +82,40 @@ button:focus-visible { background-color: #f9f9f9; } } + +.custom-scrollbar { + overflow-y: scroll; + max-height: 800px; + scrollbar-width: thin; /* For Firefox */ + -webkit-overflow-scrolling: touch; /* For smooth scrolling on iOS */ + -ms-overflow-style: none; /* For IE */ + scrollbar-color: transparent transparent; /* For WebKit */ +} + +.custom-scrollbar::-webkit-scrollbar { + width: 6px; /* Adjust the width as needed */ +} + +.custom-scrollbar::-webkit-scrollbar-thumb { + background-color: #c4c4c4; /* Color of the thumb */ + border-radius: 3px; /* Rounded corners of the thumb */ +} + +.custom-scrollbar::-webkit-scrollbar-track { + background-color: #f0f0f0; /* Color of the track */ +} + +.capsule { + display: flex; + width: 374px; + padding: 10px; + justify-content: center; + align-items: center; + align-content: center; + gap: 30px; + flex-wrap: wrap; + + border-radius: 6px; + border: 1px dashed #000; + background: #DDEDFF; +} \ No newline at end of file diff --git a/src/styles.tsx b/src/styles.tsx index 315f0fa..436befc 100644 --- a/src/styles.tsx +++ b/src/styles.tsx @@ -1,5 +1,5 @@ export const colors = { - background: "#FFFFFF", + background: "#F2FAF4", header_color: "#b2dfab", font_dark: "#2e482e", font_light: "#0e410d", @@ -11,9 +11,20 @@ export const colors = { green: "#80b28a", gray: "#8F8F8F", dark_green: "#17561D", - dark_blue: "#19639D" + dark_blue: "#19639D", + + font_dark_red: "#570404", + + dandelion: "#FBB217", + + lightgreen: "#D9FFD8", + darkgreen: "#00360C", + lightorange: "#FEFFCD", + lightred: "#ECC4B8", + + form_dark: "#000000", + form_title: "#1E1A4D" - }; const styles: { [key: string]: React.CSSProperties } = { @@ -30,7 +41,16 @@ const styles: { [key: string]: React.CSSProperties } = { overflowY: "scroll", }, - + text_normal: { + color: colors.font_dark, + fontWeight: "500", + }, + + text_dark_red: { + color: colors.font_dark_red, + fontWeight: "bold", + }, + text_dark: { color: colors.font_dark, fontWeight: "bold",