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/DashboardPage/Student/StudentDashboard.tsx b/src/Components/DashboardPage/Student/StudentDashboard.tsx index 702e93f..fcc8f40 100644 --- a/src/Components/DashboardPage/Student/StudentDashboard.tsx +++ b/src/Components/DashboardPage/Student/StudentDashboard.tsx @@ -1,27 +1,24 @@ + 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(); return (
-

- Student Actions -

+
@@ -30,30 +27,25 @@ export default function StudentDashboard() { ...styles.flex_column, ...{ alignSelf: "center", - justifyContent: "center", - flexWrap: "wrap", + backgroundColor: "#CCDDFF", + borderRadius: "20px", + paddingInline: "100px", + width: "100%", }, }} onClick={() => { navigate("/new/transaction"); }} > - +

- New Transaction + CLICK TO REQUEST BORROW ITEMS

diff --git a/src/Components/DashboardPage/Student/StudentTransactionListView.tsx b/src/Components/DashboardPage/Student/StudentTransactionListView.tsx index 7917ec8..8444a7c 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,14 +39,19 @@ export default function StudentTransactionListView() { ); } return ( -
-
+
+
{transactions.data ? ( @@ -65,12 +70,44 @@ export default function StudentTransactionListView() { }} transaction={transaction} /> + )) ) : ( <> )}
+ +
); diff --git a/src/Components/DashboardPage/Teacher/TeacherTransactionListView.tsx b/src/Components/DashboardPage/Teacher/TeacherTransactionListView.tsx index 69d6818..d3c8b33 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,36 @@ export default function TeacherTransactionListView() { }} transaction={transaction} /> + )) ) : ( @@ -76,6 +108,7 @@ export default function TeacherTransactionListView() { )}
+ SetEditTransactionOpen(false)} diff --git a/src/Components/DashboardPage/Technician/TechnicianEquipmentButtons.tsx b/src/Components/DashboardPage/Technician/TechnicianEquipmentButtons.tsx index 094289d..ed33c37 100644 --- a/src/Components/DashboardPage/Technician/TechnicianEquipmentButtons.tsx +++ b/src/Components/DashboardPage/Technician/TechnicianEquipmentButtons.tsx @@ -8,7 +8,6 @@ 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 ArticleIcon from '@mui/icons-material/Article'; import Popup from "reactjs-popup"; import AddItemModal from "../../AddItemModal/AddItemModal"; import AddSKUModal from "../../AddSKUModal/AddSKUModal"; @@ -161,7 +160,6 @@ export default function TechnicianEquipmentButtons() { View SKUs

-
- - +
); 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 b412176..9194677 100644 --- a/src/Components/DashboardPage/Technician/TechnicianWidgets.tsx +++ b/src/Components/DashboardPage/Technician/TechnicianWidgets.tsx @@ -47,226 +47,404 @@ export default function TechnicianWidgets() { >

- Pending Equipments -

- -

- {queries[1].data?.filter( - (equipment) => equipment.status == "Pending" - ).length || "Loading..."} + 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 || "Loading..."} + Borrowing Transaction

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

- Available Equipments -

+ {/* Pending Req */} +
+

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

-

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

-
-
-

- Broken Equipments -

+

+ Total Equipment +

+
+
+
+

+ Available +

+

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

-

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

-
-
-
-
-

- 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 || "Loading..."} -

-
-
-

- 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 || "Loading..."} + 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 17695fb..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.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 ca8e9d5..8458658 100644 --- a/src/Components/TransactionEntry/TransactionEntry.tsx +++ b/src/Components/TransactionEntry/TransactionEntry.tsx @@ -1,175 +1,116 @@ 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) { + + return ( ); } 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..7605d40 100644 --- a/src/Components/TransactionPDF/TransactionPDF.tsx +++ b/src/Components/TransactionPDF/TransactionPDF.tsx @@ -1,161 +1,348 @@ -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})`} + University of Science and Technology of Southern Philippines{" "} + {"\n"} + Lapasan, Cagayan de Oro City {"\n"} + College of Science and Mathematics + - {`(${props.transaction?.borrower.course})`} - - - 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/TransactionReportPDF/TransactionReportPDF.tsx b/src/Components/TransactionReportPDF/TransactionReportPDF.tsx index 2c6889c..e98df3a 100644 --- a/src/Components/TransactionReportPDF/TransactionReportPDF.tsx +++ b/src/Components/TransactionReportPDF/TransactionReportPDF.tsx @@ -1,4 +1,4 @@ -import { Document, Page, Text, View } from "@react-pdf/renderer"; +import { Document, Page, Text, View, Image } from "@react-pdf/renderer"; import { TransactionListType } from "../Types/Types"; import { colors } from "../../styles"; import count_transaction_equipments from "../../CountTransactionEquipments/CountTransactionEquipments"; @@ -6,6 +6,7 @@ import { filter_today, filter_thismonth, } from "../FilterTransaction/FilterTransaction"; +import ustplogo from "../../assets/ustp-logo.png"; type props = { transactions: TransactionListType | []; @@ -18,143 +19,245 @@ export default function TransactionReportPDF(props: props) { return ( - - Daily Transaction Report - + {/* Header */} - + + - Total Equipments Processed:{" "} - {count_transaction_equipments(transactions_today)} - - - Total Transactions: {transactions_today.length} - - - Rejected Transactions:{" "} - { - transactions_today.filter( - (transaction) => transaction.transaction_status == "Rejected" - ).length - } - - - Finalized Transactions:{" "} - { - transactions_today.filter( - (transaction) => transaction.transaction_status == "Finalized" - ).length - } - + + + Republic of the Philippines{"\n"} + + {" "} + UNIVERSITY OF SCIENCE and TECHNOLOGY OF SCIENCE AND TECHNOLOGY{" "} + + {"\n"} + College of Science and Mathematics + + + + {" "} + Department of Chemistry (Laboratory) + + + + - Monthly Transaction Report + + LABORATORY REPORTS + + - - Total Equipments Processed:{" "} - {count_transaction_equipments(transactions_thismonth)} - - + Transaction + + + - Total Transactions: {transactions_thismonth.length} - - Daily Transaction Report + + {" "} + • Total Equipments Processed:{" "} + {count_transaction_equipments(transactions_today)} + + + + {" "} + • Total Transactions: {transactions_today.length} + + + + {" "} + • Rejected Transactions:{" "} + { + transactions_today.filter( + (transaction) => transaction.transaction_status == "Rejected" + ).length + } + + + + {" "} + • Finalized Transactions:{" "} + { + transactions_today.filter( + (transaction) => transaction.transaction_status == "Finalized" + ).length + } + + + - Rejected Transactions:{" "} - { - transactions_thismonth.filter( - (transaction) => transaction.transaction_status == "Rejected" - ).length - } - - - Finalized Transactions:{" "} - { - transactions_thismonth.filter( - (transaction) => transaction.transaction_status == "Finalized" - ).length - } - + Monthly Transaction Report + + {" "} + • Total Equipments Processed:{" "} + {count_transaction_equipments(transactions_thismonth)} + + + + {" "} + • Total Transactions: {transactions_thismonth.length} + + + + {" "} + • Rejected Transactions:{" "} + { + transactions_thismonth.filter( + (transaction) => transaction.transaction_status == "Rejected" + ).length + } + + + + {" "} + • Finalized Transactions:{" "} + { + transactions_thismonth.filter( + (transaction) => transaction.transaction_status == "Finalized" + ).length + } + + diff --git a/src/Components/Types/Types.tsx b/src/Components/Types/Types.tsx index 7e362b5..1ad8d3b 100644 --- a/src/Components/Types/Types.tsx +++ b/src/Components/Types/Types.tsx @@ -110,6 +110,8 @@ export type UserType = { }; export type TransactionType = { + section: string; + additional_members: string; id: number; borrower: { id: number; @@ -143,6 +145,7 @@ export type TransactionCreateType = { consumables: string; transaction_status: string; additional_members: string; + section: string; }; export type TransactionUpdateType = { diff --git a/src/Pages/AddTransactionPage/AddTransactionPage.tsx b/src/Pages/AddTransactionPage/AddTransactionPage.tsx index 098b3eb..8c0d7f9 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, @@ -21,6 +20,9 @@ import { MenuItem, OutlinedInput, Autocomplete, + Alert, + Stack, + Button, } from "@mui/material"; import React from "react"; import Header from "../../Components/Header/Header"; @@ -38,7 +40,89 @@ export default function AddTransactionPage() { consumables: "", additional_members: "", borrower: 0, + section: "", }); + + // Function to calculate total equipment count + const calculateTotalEquipmentCount = () => { + const selectedItems = + equipments.data?.filter((equipment) => + transaction.equipments.includes(equipment.id) + ) || []; + + // Calculate total count + const totalCount = selectedItems.reduce((count) => count + 1, 0); + + return totalCount; + }; + + const handleShowSelectedItems = () => { + const selectedItems = + equipments.data?.filter((equipment) => + transaction.equipments.includes(equipment.id) + ) || []; + + // Explicitly define the type for equipmentCounts + const equipmentCounts: Record = {}; + const totalEquipmentCount = calculateTotalEquipmentCount(); + + // Calculate counts based on equipment name + selectedItems.forEach((item) => { + equipmentCounts[item.equipment_name] = + (equipmentCounts[item.equipment_name] || 0) + 1; + }); + + // Show alert + const formattedCounts = Object.entries(equipmentCounts).map( + ([name, count]) => `${count} pcs. of ${name}` + ); + + const confirmationMessage = `So, you're trying to borrow ${totalEquipmentCount} equipment(s):\n${formattedCounts.join( + "\n" + )}\nIs it correct?\n\nPlease click OK to continue request\nCancel if you still want to edit`; + + if (window.confirm(confirmationMessage)) { + // OK Button Logic + console.log(JSON.stringify(transaction)); + TransactionCreateAPI(transaction) + .then(async (data) => { + if (data[0]) { + setError("Created successfully"); + toast( + `New transaction created successfully, ${ + typeof data[1] == "object" ? "ID:" + data[1].id : "" + }`, + { + position: "top-right", + autoClose: 2000, + hideProgressBar: false, + closeOnClick: true, + pauseOnHover: true, + draggable: true, + progress: undefined, + theme: "light", + } + ); + queryClient.invalidateQueries({ + queryKey: ["equipment_instances"], + }); + queryClient.invalidateQueries({ + queryKey: ["transactions"], + }); + navigate("/dashboard"); + } else { + setError(JSON.stringify(data[1])); + } + }) + .catch((error) => { + setError(JSON.stringify(error)); + }); + } else { + // Cancel Button Logic + console.log("Cancel button clicked"); + } + }; + /* const [selecteditems, SetSelectedItems] = useState([]); const [selectedteacher, SetSelectedTeacher] = useState(0); @@ -110,6 +194,7 @@ export default function AddTransactionPage() { alignItems: "center", justifyContent: "center", overflowY: "scroll", + marginTop: 64, }, }} > @@ -122,46 +207,89 @@ export default function AddTransactionPage() { marginRight: "1rem", }} /> -

New Transaction

+

Borrowing Form

-
- - +
+ + + Items Requested + + a.id - b.id) || []} + getOptionLabel={(option) => + `${option.equipment_name} (ID:${option.id})` + } + value={ + equipments.data?.filter((equipment) => + transaction.equipments.includes(equipment.id) + ) || [] + } + onChange={(_event, newValue) => { + SetTransaction({ + ...transaction, + equipments: newValue.map((item) => item.id), + }); + }} + renderInput={(params) => ( + + )} + /> + + +
- Items Requested - - a.id - b.id) || []} - getOptionLabel={(option) => - `${option.equipment_name} (ID:${option.id})` - } - value={ - equipments.data?.filter((equipment) => - transaction.equipments.includes(equipment.id) - ) || [] - } - onChange={(_event, newValue) => { - SetTransaction({ - ...transaction, - equipments: newValue.map((item) => item.id), - }); - }} - renderInput={(params) => ( - - )} - /> - +

+ Total equipment to borrow: {calculateTotalEquipmentCount()} +

+
+
+ + + + + Section + + ) => { + SetTransaction({ ...transaction, section: e.target.value }); + setError(""); + }} + label={"Section"} + value={transaction.section} + placeholder={"Type Section Here"} + /> + + - - - Remarks - - ) => { - SetTransaction({ ...transaction, remarks: e.target.value }); - setError(""); - }} - value={transaction.remarks} - placeholder={"Optionally add a brief description of the request"} - /> - + @@ -268,59 +399,81 @@ export default function AddTransactionPage() { }} value={transaction.additional_members} placeholder={ - "Write down any additional members borrowing on behalf of this transaction" + "1. Full Name ex. (Daniel John Padilla)\n2. Kathryn Bernardo \n3. ..." } /> + + + Remarks (optional) + + ) => { + SetTransaction({ ...transaction, remarks: e.target.value }); + setError(""); + }} + value={transaction.remarks} + placeholder={"Add a brief description of the request or N/A."} + /> +
-

{error}

+
+ > + + + NOTE: please be reminded that borrowing of lab apparatus can only be + made once. Further requests of additional apparatus will not be + entertained. + + +
+ +

{error}

+
); } diff --git a/src/Pages/DashboardPage/DashboardPage.tsx b/src/Pages/DashboardPage/DashboardPage.tsx index 89ce800..bc923ef 100644 --- a/src/Pages/DashboardPage/DashboardPage.tsx +++ b/src/Pages/DashboardPage/DashboardPage.tsx @@ -2,39 +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/EquipmentInstanceLogsPage/EquipmentInstanceLogsPage.tsx b/src/Pages/EquipmentInstanceLogsPage/EquipmentInstanceLogsPage.tsx index 80dd527..e78a342 100644 --- a/src/Pages/EquipmentInstanceLogsPage/EquipmentInstanceLogsPage.tsx +++ b/src/Pages/EquipmentInstanceLogsPage/EquipmentInstanceLogsPage.tsx @@ -58,6 +58,7 @@ export default function EquipmentInstanceLogsPage() { minHeight: "100%", minWidth: "100%", flexWrap: "wrap", + marginTop: "2rem", }} >
diff --git a/src/Pages/EquipmentInstancesListPage/EquipmentInstancesFilteredListPage.tsx b/src/Pages/EquipmentInstancesListPage/EquipmentInstancesFilteredListPage.tsx index 303f2ee..56183cb 100644 --- a/src/Pages/EquipmentInstancesListPage/EquipmentInstancesFilteredListPage.tsx +++ b/src/Pages/EquipmentInstancesListPage/EquipmentInstancesFilteredListPage.tsx @@ -65,6 +65,7 @@ export default function EquipmentInstancesFilteredListPage() { minHeight: "100%", minWidth: "100%", flexWrap: "wrap", + marginTop: "7rem" }} > + + +
+ + + + + +
+ }}> + +
+ +
+ + + 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", + }} + > + + + @@ -58,6 +59,7 @@ export default function EquipmentLogsPage() { minHeight: "100%", minWidth: "100%", flexWrap: "wrap", + marginTop: "6rem" }} > -
+
-
- - - 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:{" "} - { - 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 - } -

-
+
+
+
+ + + 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:{" "} + { + 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 + } +

+
+
+ ID @@ -192,7 +206,7 @@ export default function EquipmentTallyPage() {

- Available: + Available: {"\n"} { equipment_instances.data?.filter( (equipment_instance) => @@ -203,7 +217,7 @@ export default function EquipmentTallyPage() { }

- Pending: + Pending: {"\n"} { equipment_instances.data?.filter( (equipment_instance) => @@ -214,7 +228,24 @@ export default function EquipmentTallyPage() { }

- Broken: + Borrowed: {"\n"} + { + equipment_instances.data?.filter( + (equipment_instance) => + equipment_instance.equipment_name == + equipment.name && + equipment_instance.status == "Borrowed" + ).length + } +

+

+ Broken: {"\n"} { equipment_instances.data?.filter( (equipment_instance) => @@ -224,6 +255,26 @@ export default function EquipmentTallyPage() { ).length }

+
+

+ Total: {"\n"} + { + equipment_instances.data?.filter( + (equipment_instance) => + equipment_instance.equipment_name === + equipment.name + ).length + } +

+
diff --git a/src/Pages/LandingPage/LandingPage.tsx b/src/Pages/LandingPage/LandingPage.tsx index c91d636..9058a1b 100644 --- a/src/Pages/LandingPage/LandingPage.tsx +++ b/src/Pages/LandingPage/LandingPage.tsx @@ -37,6 +37,7 @@ export default function LandingPage() { minHeight: "100%", minWidth: "100%", flexWrap: "wrap", + backgroundColor: "#F2FAF4" }} >
@@ -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..f74146d --- /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 }} > Consumables + + Additional Members + Equipments + + 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,47 @@ 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 2c3fac6..610c080 100644 --- a/src/index.css +++ b/src/index.css @@ -14,6 +14,21 @@ -webkit-text-size-adjust: 100%; } +/* width */ +::-webkit-scrollbar { + width: 5px; +} + +/* Track */ +::-webkit-scrollbar-track { + background: none; +} + +/* Handle */ +::-webkit-scrollbar-thumb { + background: #888; +} + a { font-weight: 500; color: #646cff; @@ -67,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 2e4c3ba..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", @@ -9,6 +9,23 @@ export const colors = { red: "#a44141", orange: "#c57331", green: "#80b28a", + gray: "#8F8F8F", + dark_green: "#17561D", + 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 } = { background: { @@ -16,19 +33,46 @@ const styles: { [key: string]: React.CSSProperties } = { position: "fixed", top: 0, left: 0, + height: "100%", width: "100%", minHeight: "100%", minWidth: "100%", 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", }, + text_super_dark: { + color: colors.font_dark, + fontWeight: 900, + }, text_light: { color: colors.font_light, fontWeight: "bold", + + }, + + text_dark_blue:{ + color:colors.dark_blue, + fontWeight:"bold" + }, + text_gray: { + color: colors.gray, + + }, text_red: { color: colors.red, @@ -42,9 +86,16 @@ const styles: { [key: string]: React.CSSProperties } = { color: colors.green, fontWeight: "bold", }, + text_dark_green: { + color: colors.dark_green, + fontWeight: "bold", + + }, + text_XL: { fontSize: "clamp(2rem, 3rem, 8rem)", }, + text_L: { fontSize: "clamp(1.5rem, 2rem, 6rem)", }, @@ -94,6 +145,21 @@ const styles: { [key: string]: React.CSSProperties } = { marginLeft: "1rem", marginRight: "1rem", }, + bform_label: { + display: "flex", + justifyContent: "left", + marginTop: "10px", + }, + + bform_label2: { + display: "flex", + justifyContent: "left", + marginTop: "10px", + marginBottom: "10px", + }, + + + }; export default styles;