Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions frontend/src/main-page/header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { Menu, Button } from "@chakra-ui/react";
import { FaCog } from "react-icons/fa";
import BellButton from "./Bell.tsx";
import { useLocation } from 'react-router-dom';
import UserButton from "./UserButton.tsx";

interface NavBarProps {
name: string;
Expand Down Expand Up @@ -72,13 +73,13 @@ const Header: React.FC = observer(() => {
</li>
))}
</ul>
<div className="header-right-controls flex items-center">
<div className="header-right-controls flex items-center gap-2">
<div className="bell-container">
<BellButton />
</div>
<Menu.Root>
<Menu.Trigger asChild>
<Button variant="ghost" p={1} ml={4}>
<Button variant="ghost" p={1}>
<FaCog size={24} />
</Button>
</Menu.Trigger>
Expand All @@ -95,6 +96,7 @@ const Header: React.FC = observer(() => {
</Menu.Content>
</Menu.Positioner>
</Menu.Root>
<UserButton />
</div>
</div>
</header>
Expand Down
16 changes: 16 additions & 0 deletions frontend/src/main-page/header/UserButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { faUser } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";

const UserButton = () => {
return (
<div>
<a href="/main/users">
<button className="text-[#000000] focus:outline-none">
<FontAwesomeIcon icon={faUser} />
</button>
</a>
</div>
);
};

export default UserButton;
22 changes: 22 additions & 0 deletions frontend/src/main-page/users/ApprovedUserCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import UserPositionCard from "./UserPositionCard";

interface ApprovedUserCardProps {
name: string;
email: string;
position: string;
}

const ApprovedUserCard = ({ name, email, position }: ApprovedUserCardProps) => {
return (
<div className="bg-white text-lg border rounded-md m-8 p-6 flex justify-around items-center">
<p className="font-semibold w-[140px] text-left">{name}</p>
<p className="w-[140px] text-left">xxxxxxx</p>
<p className="w-[140px] text-left">{email}</p>
<div className="w-[140px]">
<UserPositionCard position={position} />
</div>
</div>
);
};

export default ApprovedUserCard;
41 changes: 41 additions & 0 deletions frontend/src/main-page/users/PendingUserCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import UserPositionCard from "./UserPositionCard";
import { faCheck, faX } from "@fortawesome/free-solid-svg-icons";

interface PendingUserCardProps {
name: string;
email: string;
position: string;
dateRequested: Date;
}

const PendingUserCard = ({
name,
email,
position,
dateRequested,
}: PendingUserCardProps) => {
return (
<div className="bg-white text-lg border rounded-md m-8 p-6 flex justify-around items-center">
<p className="font-semibold w-[140px] text-left">{name}</p>
<p className="w-[140px] text-left">xxxxxxx</p>
<p className="w-[140px] text-left">{email}</p>
<div className="w-[140px]">
<UserPositionCard position={position} />
</div>
<p className="w-[140px] text-left">
{dateRequested.toLocaleDateString("en-GB")}
</p>
<div className="flex w-[140px] gap-3">
<button className="bg-[#c6fbd3] w-8 h-8 focus:outline-none rounded">
<FontAwesomeIcon icon={faCheck} style={{ color: "black" }} />
</button>
<button className="bg-[#fe9d92] w-8 h-8 focus:outline-none rounded">
<FontAwesomeIcon icon={faX} style={{ color: "black" }} />
</button>
</div>
</div>
);
};

export default PendingUserCard;
29 changes: 29 additions & 0 deletions frontend/src/main-page/users/UserPositionCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { useMemo } from "react";

interface UserPositionCardProps {
position: string;
}

const UserPositionCard = ({ position }: UserPositionCardProps) => {
const cardStyles = useMemo(() => {
switch (position.toLowerCase()) {
case "admin":
return "bg-[#BCFFD8] border-[#119548] text-[#119548]";
case "employee":
return "bg-[#FFF8CA] border-[#F8CC16] text-[#8a710c]";
case "deactive":
return "bg-[#FFB0B0] border-[#DF0404] text-[#DF0404]";
case "inactive":
default:
return "bg-[#D3D3D3] border-[#666666] text-[#666666]";
}
}, [position]);

return (
<div className={`py-1 px-6 rounded-sm border ${cardStyles}`}>
<p className="text-base">{position}</p>
</div>
);
};

export default UserPositionCard;
82 changes: 80 additions & 2 deletions frontend/src/main-page/users/Users.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,86 @@
import { useState } from "react";
import ApprovedUserCard from "./ApprovedUserCard";
import PendingUserCard from "./PendingUserCard";

// Represents a specific tab to show on the user page
enum UsersTab {
PendingUsers,
CurrentUsers,
}

function Users() {
const [usersTabStatus, setUsersTabStatus] = useState<UsersTab>(
UsersTab.CurrentUsers
);

return (
<div>

<div className="p-8">
<div className="text-left mb-5">
<h1 className="font-medium text-4xl">
{usersTabStatus === UsersTab.CurrentUsers
? "All Users"
: "Pending Users"}
</h1>
<p className="text-[#FF8476]"># new users</p>
</div>
<div className="min-h-screen bg-[#F5F4F4] border rounded-md relative">
<div className="absolute right-7 top-0 -translate-y-full flex">
<button
className={`w-52 h-16 border rounded-b-none focus:outline-none ${
usersTabStatus === UsersTab.PendingUsers
? "bg-[#F5F4F4] border-x-[#000000] border-t-[#000000]"
: "bg-[#F4F4F4] border-x-[#BFBBBB] border-t-[#BFBBBB] border-b-[#000000]"
}`}
onClick={() => setUsersTabStatus(UsersTab.PendingUsers)}
>
Pending Users
</button>
<button
className={`w-52 h-16 border rounded-b-none ml-2 focus:outline-none ${
usersTabStatus === UsersTab.CurrentUsers
? "bg-[#F5F4F4] border-x-[#000000] border-t-[#000000]"
: "bg-[#F4F4F4] border-x-[#BFBBBB] border-t-[#BFBBBB] border-b-[#000000]"
}`}
onClick={() => setUsersTabStatus(UsersTab.CurrentUsers)}
>
Current Users
</button>
</div>
<div>
{usersTabStatus === UsersTab.CurrentUsers ? (
<>
<div className="flex px-9 pb-3 m-7 border-b border-b-[#BFBBBB] font-semibold justify-around">
<p className="w-[140px] text-left">User Name</p>
<p className="w-[140px] text-left">User ID</p>
<p className="w-[140px] text-left">Email</p>
<p className="w-[140px] text-left">Position</p>
</div>
<ApprovedUserCard
name="Aaron Ashby"
email="a.ashby@mit.edu"
position="Employee"
/>
</>
) : (
<>
<div className="flex px-9 pb-3 m-7 border-b border-b-[#BFBBBB] font-semibold justify-around">
<p className="w-[140px] text-left">User Name</p>
<p className="w-[140px] text-left">User ID</p>
<p className="w-[140px] text-left">Email</p>
<p className="w-[140px] text-left">Position</p>
<p className="w-[140px] text-left">Date Requested</p>
<div className="w-[140px]"></div>
</div>
<PendingUserCard
name="Aaron Ashby"
email="a.ashby@uconn.edu"
position="Inactive"
dateRequested={new Date("02/14/2006")}
/>
</>
)}
</div>
</div>
</div>
);
}
Expand Down