Skip to content

Commit

Permalink
Merge pull request #534 from ITPNYU/main
Browse files Browse the repository at this point in the history
Prod release 12/16
  • Loading branch information
rlho authored Dec 16, 2024
2 parents ec4172e + 7e67616 commit 5890511
Show file tree
Hide file tree
Showing 13 changed files with 203 additions and 32 deletions.
16 changes: 16 additions & 0 deletions booking-app/app/equipment/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// app/liaison/page.tsx

"use client";

import Equipment from "@/components/src/client/routes/equipment/Equipment";
import { Suspense } from "react";

const EquipmentPage: React.FC = () => {
return (
<Suspense fallback={<div>Loading...</div>}>
<Equipment />
</Suspense>
);
};

export default EquipmentPage;
1 change: 1 addition & 0 deletions booking-app/clientInfo
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
o4Qd0YDOKtCR95EUyQ2Rbp5UbNUa:XkfbKenefg7ntnRR1D3r3nTo_lQa
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Typography } from "@mui/material";
import { EquipmentUsers } from "./EquipmentUsers";
import { Liaisons } from "./Liaisons";

export const Approvers = () => (
<div>
<Typography style={{ marginBottom: 24 }} variant="h6">
Liaison Users
</Typography>
<Liaisons />
<Typography style={{ marginTop: 48, marginBottom: 24 }} variant="h6">
Equipment Users
</Typography>
<EquipmentUsers />
</div>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { useContext, useMemo } from "react";

import { ApproverLevel, TableNames } from "../../../../policy";
import { formatDate } from "../../../utils/date";
import AddRow from "../../components/AddRow";
import ListTable from "../../components/ListTable";
import { DatabaseContext } from "../../components/Provider";

const AddEquipmentForm = ({ equipmentEmails, reloadEquipmentEmails }) => {
return (
<AddRow
addDuplicateErrorMessage="This user is already registered"
addFailedErrorMessage="Failed to add user as equipments"
columnNameUniqueValue="email"
inputPlaceholder="Add email"
tableName={TableNames.APPROVERS}
rows={equipmentEmails}
rowsRefresh={reloadEquipmentEmails}
title="Equipment Users"
extra={{
values: { level: ApproverLevel.EQUIPMENT },
}}
/>
);
};

export const EquipmentUsers = () => {
const { equipmentUsers, reloadApproverUsers } = useContext(DatabaseContext);
const equipmentEmails = useMemo<string[]>(
() => equipmentUsers.map((user) => user.email),
[equipmentUsers]
);

const rows = useMemo(() => {
const filtered = equipmentUsers.map((liaison) => {
const { level, ...other } = liaison;
return other;
});
const sorted = filtered.sort((a, b) =>
a.department.localeCompare(b.department)
);
return sorted as unknown as { [key: string]: string }[];
}, [equipmentUsers]);

return (
<ListTable
tableName={TableNames.APPROVERS}
columnNameToRemoveBy="email"
rows={rows}
rowsRefresh={reloadApproverUsers}
topRow={
<AddEquipmentForm
equipmentEmails={equipmentEmails}
reloadEquipmentEmails={reloadApproverUsers}
/>
}
columnFormatters={{ createdAt: formatDate }}
/>
);
};
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
import { Divider, ListItemButton, ListItemText, Stack } from "@mui/material";

import Grid from "@mui/material/Unstable_Grid2";
import { useState } from "react";
import { AdminUsers } from "./AdminUsers";
import { Approvers } from "./Approvers";
import { BannedUsers } from "./Ban";
import BookingTypes from "./BookingTypes";
import { Departments } from "./Departments";
import ExportDatabase from "./ExportDatabase";
import Grid from "@mui/material/Unstable_Grid2";
import { Liaisons } from "./Liaisons";
import { PAUsers } from "./PAUsers";
import PolicySettings from "./PolicySettings";
import SafetyTrainedUsers from "./SafetyTraining";
import SyncCalendars from "./SyncCalendars";
import { useState } from "react";

const tabs = [
{ label: "Safety Training", id: "safetyTraining" },
{ label: "PA Users", id: "pa" },
{ label: "Admin Users", id: "admin" },
{ label: "Liaisons", id: "liaisons" },
{ label: "Approvers", id: "approvers" },
{ label: "Departments", id: "departments" },
{ label: "Ban", id: "ban" },
{ label: "Booking Types", id: "bookingTypes" },
Expand Down Expand Up @@ -51,7 +51,7 @@ export default function Settings() {
{tab === "safetyTraining" && <SafetyTrainedUsers />}
{tab === "pa" && <PAUsers />}
{tab === "admin" && <AdminUsers />}
{tab === "liaisons" && <Liaisons />}
{tab === "approvers" && <Approvers />}
{tab === "ban" && <BannedUsers />}
{tab === "departments" && <Departments />}
{tab === "bookingTypes" && <BookingTypes />}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { BookingStatusLabel, PageContextLevel } from "@/components/src/types";
import {
cancel,
checkOut,
Expand All @@ -7,13 +6,14 @@ import {
decline,
noShow,
} from "@/components/src/server/db";
import { BookingStatusLabel, PageContextLevel } from "@/components/src/types";
import { useContext, useMemo, useState } from "react";

import { Timestamp } from "@firebase/firestore";
import { useRouter } from "next/navigation";
import { BookingContext } from "../../booking/bookingProvider";
import { DatabaseContext } from "../../components/Provider";
import { Timestamp } from "@firebase/firestore";
import useExistingBooking from "./useExistingBooking";
import { useRouter } from "next/navigation";

export enum Actions {
CANCEL = "Cancel",
Expand Down Expand Up @@ -185,6 +185,7 @@ export default function useBookingActions({
}, [status]);

const liaisonOptions = [Actions.FIRST_APPROVE, Actions.DECLINE];
const equipmentOptions = [Actions.MODIFICATION, Actions.DECLINE];

const adminOptions = useMemo(() => {
if (
Expand Down Expand Up @@ -216,6 +217,8 @@ export default function useBookingActions({
return paOptions;
case PageContextLevel.LIAISON:
return liaisonOptions;
case PageContextLevel.EQUIPMENT:
return equipmentOptions;
default:
return adminOptions;
}
Expand Down
12 changes: 6 additions & 6 deletions booking-app/components/src/client/routes/components/AddRow.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Box, IconButton, TextField } from "@mui/material";
import { IconButton, TextField } from "@mui/material";
import React, { useMemo, useState } from "react";

import { Timestamp } from "@firebase/firestore";
import { AddCircleOutline } from "@mui/icons-material";
import Grid from "@mui/material/Unstable_Grid2/Grid2";
import Loading from "./Loading";
import { TableNames } from "../../../policy";
import { Timestamp } from "@firebase/firestore";
import { clientSaveDataToFirestore } from "../../../../../lib/firebase/firebase";
import { TableNames } from "../../../policy";
import Loading from "./Loading";

interface Props {
addDuplicateErrorMessage?: string;
Expand All @@ -18,9 +18,9 @@ interface Props {
rowsRefresh: () => Promise<void>;
title: string;
extra?: {
components: React.ReactNode[];
components?: React.ReactNode[];
values: { [key: string]: any };
updates: ((x: string) => void)[];
updates?: ((x: string) => void)[];
};
}

Expand Down
54 changes: 38 additions & 16 deletions booking-app/components/src/client/routes/components/Provider.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { ApproverLevel, TableNames } from "@/components/src/policy";
import React, { createContext, useEffect, useMemo, useState } from "react";
import {
AdminUser,
Approver,
Expand All @@ -14,22 +16,23 @@ import {
Settings,
UserApiData,
} from "../../../types";
import { ApproverLevel, TableNames } from "@/components/src/policy";
import React, { createContext, useEffect, useMemo, useState } from "react";

import { useAuth } from "@/components/src/client/routes/components/AuthProvider";
import { fetchAllBookings, fetchAllFutureBooking } from "@/components/src/server/db";
import {
fetchAllBookings,
fetchAllFutureBooking,
} from "@/components/src/server/db";
import { clientFetchAllDataFromCollection } from "@/lib/firebase/firebase";
import { Timestamp } from "firebase-admin/firestore";


export interface DatabaseContextType {
adminUsers: AdminUser[];
bannedUsers: Ban[];
futureBookings: Booking[];
allBookings: Booking[];
bookingsLoading: boolean;
liaisonUsers: Approver[];
equipmentUsers: Approver[];
departmentNames: DepartmentType[];
operationHours: OperationHours[];
pagePermission: PagePermission;
Expand Down Expand Up @@ -61,6 +64,7 @@ export const DatabaseContext = createContext<DatabaseContextType>({
allBookings: [],
bookingsLoading: true,
liaisonUsers: [],
equipmentUsers: [],
departmentNames: [],
operationHours: [],
pagePermission: PagePermission.BOOKING,
Expand Down Expand Up @@ -96,6 +100,7 @@ export const DatabaseProvider = ({
const [allBookings, setAllBookings] = useState<Booking[]>([]);
const [adminUsers, setAdminUsers] = useState<AdminUser[]>([]);
const [liaisonUsers, setLiaisonUsers] = useState<Approver[]>([]);
const [equipmentUsers, setEquipmentUsers] = useState<Approver[]>([]);
const [departmentNames, setDepartmentName] = useState<DepartmentType[]>([]);
const [operationHours, setOperationHours] = useState<OperationHours[]>([]);
const [paUsers, setPaUsers] = useState<PaUser[]>([]);
Expand Down Expand Up @@ -137,24 +142,27 @@ export const DatabaseProvider = ({
const pagePermission = useMemo<PagePermission>(() => {
// Early return if no email
if (!userEmail) return PagePermission.BOOKING;

// Pre-compute email lists once
const adminEmails = adminUsers.map(admin => admin.email);
const liaisonEmails = liaisonUsers.map(liaison => liaison.email);
const paEmails = paUsers.map(pa => pa.email);

const adminEmails = adminUsers.map((admin) => admin.email);
const liaisonEmails = liaisonUsers.map((liaison) => liaison.email);
const paEmails = paUsers.map((pa) => pa.email);
const equipmentEmails = equipmentUsers.map((e) => e.email);

// Check permissions
if (adminEmails.includes(userEmail)) return PagePermission.ADMIN;
if (equipmentEmails.includes(userEmail)) return PagePermission.EQUIPMENT;
if (liaisonEmails.includes(userEmail)) return PagePermission.LIAISON;
if (paEmails.includes(userEmail)) return PagePermission.PA;

return PagePermission.BOOKING;
}, [
userEmail,
// Make sure we're using the actual arrays in dependencies
JSON.stringify(adminUsers),
JSON.stringify(liaisonUsers),
JSON.stringify(paUsers)
JSON.stringify(paUsers),
JSON.stringify(equipmentUsers),
]);

useEffect(() => {
Expand All @@ -176,9 +184,13 @@ export const DatabaseProvider = ({
fetchRoomSettings();
}, [user]);

useEffect(()=>{
if(pagePermission === PagePermission.ADMIN || pagePermission === PagePermission.LIAISON || pagePermission === PagePermission.PA)
fetchBookings();
useEffect(() => {
if (
pagePermission === PagePermission.ADMIN ||
pagePermission === PagePermission.LIAISON ||
pagePermission === PagePermission.PA
)
fetchBookings();
}, [pagePermission]);

const fetchActiveUserEmail = () => {
Expand All @@ -196,8 +208,11 @@ export const DatabaseProvider = ({
};

const fetchBookings = async () => {
try{
const bookingsResponse : Booking[] = await fetchAllBookings(LIMIT, lastItem);
try {
const bookingsResponse: Booking[] = await fetchAllBookings(
LIMIT,
lastItem
);
setLastItem(bookingsResponse[bookingsResponse.length - 1].requestedAt);
setAllBookings((oldBookings) => [...oldBookings, ...bookingsResponse]);
} catch (error) {
Expand Down Expand Up @@ -312,14 +327,20 @@ export const DatabaseProvider = ({
level: Number(item.level),
}));
const liaisons = all.filter((x) => x.level === ApproverLevel.FIRST);
const equipmentUsers = all.filter(
(x) => x.level === ApproverLevel.EQUIPMENT
);

const finalApprover = all.filter(
(x) => x.level === ApproverLevel.FINAL
)[0];
setLiaisonUsers(liaisons);
setEquipmentUsers(equipmentUsers);
setPolicySettings({ finalApproverEmail: finalApprover.email });
})
.catch((error) => console.error("Error fetching data:", error));
};

const fetchDepartmentNames = async () => {
clientFetchAllDataFromCollection(TableNames.DEPARTMENTS)
.then((fetchedData) => {
Expand Down Expand Up @@ -400,6 +421,7 @@ export const DatabaseProvider = ({
futureBookings,
allBookings,
liaisonUsers,
equipmentUsers,
departmentNames,
operationHours,
paUsers,
Expand Down
10 changes: 10 additions & 0 deletions booking-app/components/src/client/routes/components/navBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ export default function NavBar() {
case PagePermission.LIAISON:
router.push("/liaison");
break;
case PagePermission.EQUIPMENT:
router.push("/equipment");
break;
}
};

Expand All @@ -103,6 +106,8 @@ export default function NavBar() {
setSelectedView(PagePermission.ADMIN);
} else if (pathname.includes("/liaison")) {
setSelectedView(PagePermission.LIAISON);
} else if (pathname.includes("/equipment")) {
setSelectedView(PagePermission.EQUIPMENT);
}
}, [pathname]);

Expand Down Expand Up @@ -133,6 +138,8 @@ export default function NavBar() {
pagePermission === PagePermission.LIAISON ||
pagePermission === PagePermission.ADMIN;
const showAdmin = pagePermission === PagePermission.ADMIN;
const showEquipment =
pagePermission === PagePermission.ADMIN || PagePermission.EQUIPMENT;

return (
<Select size="small" value={selectedView} onChange={handleRoleChange}>
Expand All @@ -142,6 +149,9 @@ export default function NavBar() {
<MenuItem value={PagePermission.LIAISON}>Liaison</MenuItem>
)}
{showAdmin && <MenuItem value={PagePermission.ADMIN}>Admin</MenuItem>}
{showEquipment && (
<MenuItem value={PagePermission.EQUIPMENT}>Equipment</MenuItem>
)}
</Select>
);
}, [pagePermission, selectedView]);
Expand Down
Loading

0 comments on commit 5890511

Please sign in to comment.