Skip to content

Commit 1292b4a

Browse files
authored
Merge pull request #203 from Code-4-Community/aaron/create-user-page-for-admin
172 Dev Aaron - Create User Page for Admin
2 parents c8803a2 + d24dcab commit 1292b4a

File tree

6 files changed

+192
-4
lines changed

6 files changed

+192
-4
lines changed

frontend/src/main-page/header/Header.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { Menu, Button } from "@chakra-ui/react";
1414
import { FaCog } from "react-icons/fa";
1515
import BellButton from "./Bell.tsx";
1616
import { useLocation } from 'react-router-dom';
17+
import UserButton from "./UserButton.tsx";
1718

1819
interface NavBarProps {
1920
name: string;
@@ -72,13 +73,13 @@ const Header: React.FC = observer(() => {
7273
</li>
7374
))}
7475
</ul>
75-
<div className="header-right-controls flex items-center">
76+
<div className="header-right-controls flex items-center gap-2">
7677
<div className="bell-container">
7778
<BellButton />
7879
</div>
7980
<Menu.Root>
8081
<Menu.Trigger asChild>
81-
<Button variant="ghost" p={1} ml={4}>
82+
<Button variant="ghost" p={1}>
8283
<FaCog size={24} />
8384
</Button>
8485
</Menu.Trigger>
@@ -95,6 +96,7 @@ const Header: React.FC = observer(() => {
9596
</Menu.Content>
9697
</Menu.Positioner>
9798
</Menu.Root>
99+
<UserButton />
98100
</div>
99101
</div>
100102
</header>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { faUser } from "@fortawesome/free-solid-svg-icons";
2+
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
3+
4+
const UserButton = () => {
5+
return (
6+
<div>
7+
<a href="/main/users">
8+
<button className="text-[#000000] focus:outline-none">
9+
<FontAwesomeIcon icon={faUser} />
10+
</button>
11+
</a>
12+
</div>
13+
);
14+
};
15+
16+
export default UserButton;
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import UserPositionCard from "./UserPositionCard";
2+
3+
interface ApprovedUserCardProps {
4+
name: string;
5+
email: string;
6+
position: string;
7+
}
8+
9+
const ApprovedUserCard = ({ name, email, position }: ApprovedUserCardProps) => {
10+
return (
11+
<div className="bg-white text-lg border rounded-md m-8 p-6 flex justify-around items-center">
12+
<p className="font-semibold w-[140px] text-left">{name}</p>
13+
<p className="w-[140px] text-left">xxxxxxx</p>
14+
<p className="w-[140px] text-left">{email}</p>
15+
<div className="w-[140px]">
16+
<UserPositionCard position={position} />
17+
</div>
18+
</div>
19+
);
20+
};
21+
22+
export default ApprovedUserCard;
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
2+
import UserPositionCard from "./UserPositionCard";
3+
import { faCheck, faX } from "@fortawesome/free-solid-svg-icons";
4+
5+
interface PendingUserCardProps {
6+
name: string;
7+
email: string;
8+
position: string;
9+
dateRequested: Date;
10+
}
11+
12+
const PendingUserCard = ({
13+
name,
14+
email,
15+
position,
16+
dateRequested,
17+
}: PendingUserCardProps) => {
18+
return (
19+
<div className="bg-white text-lg border rounded-md m-8 p-6 flex justify-around items-center">
20+
<p className="font-semibold w-[140px] text-left">{name}</p>
21+
<p className="w-[140px] text-left">xxxxxxx</p>
22+
<p className="w-[140px] text-left">{email}</p>
23+
<div className="w-[140px]">
24+
<UserPositionCard position={position} />
25+
</div>
26+
<p className="w-[140px] text-left">
27+
{dateRequested.toLocaleDateString("en-GB")}
28+
</p>
29+
<div className="flex w-[140px] gap-3">
30+
<button className="bg-[#c6fbd3] w-8 h-8 focus:outline-none rounded">
31+
<FontAwesomeIcon icon={faCheck} style={{ color: "black" }} />
32+
</button>
33+
<button className="bg-[#fe9d92] w-8 h-8 focus:outline-none rounded">
34+
<FontAwesomeIcon icon={faX} style={{ color: "black" }} />
35+
</button>
36+
</div>
37+
</div>
38+
);
39+
};
40+
41+
export default PendingUserCard;
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { useMemo } from "react";
2+
3+
interface UserPositionCardProps {
4+
position: string;
5+
}
6+
7+
const UserPositionCard = ({ position }: UserPositionCardProps) => {
8+
const cardStyles = useMemo(() => {
9+
switch (position.toLowerCase()) {
10+
case "admin":
11+
return "bg-[#BCFFD8] border-[#119548] text-[#119548]";
12+
case "employee":
13+
return "bg-[#FFF8CA] border-[#F8CC16] text-[#8a710c]";
14+
case "deactive":
15+
return "bg-[#FFB0B0] border-[#DF0404] text-[#DF0404]";
16+
case "inactive":
17+
default:
18+
return "bg-[#D3D3D3] border-[#666666] text-[#666666]";
19+
}
20+
}, [position]);
21+
22+
return (
23+
<div className={`py-1 px-6 rounded-sm border ${cardStyles}`}>
24+
<p className="text-base">{position}</p>
25+
</div>
26+
);
27+
};
28+
29+
export default UserPositionCard;

frontend/src/main-page/users/Users.tsx

Lines changed: 80 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,86 @@
1+
import { useState } from "react";
2+
import ApprovedUserCard from "./ApprovedUserCard";
3+
import PendingUserCard from "./PendingUserCard";
4+
5+
// Represents a specific tab to show on the user page
6+
enum UsersTab {
7+
PendingUsers,
8+
CurrentUsers,
9+
}
10+
111
function Users() {
12+
const [usersTabStatus, setUsersTabStatus] = useState<UsersTab>(
13+
UsersTab.CurrentUsers
14+
);
215

316
return (
4-
<div>
5-
17+
<div className="p-8">
18+
<div className="text-left mb-5">
19+
<h1 className="font-medium text-4xl">
20+
{usersTabStatus === UsersTab.CurrentUsers
21+
? "All Users"
22+
: "Pending Users"}
23+
</h1>
24+
<p className="text-[#FF8476]"># new users</p>
25+
</div>
26+
<div className="min-h-screen bg-[#F5F4F4] border rounded-md relative">
27+
<div className="absolute right-7 top-0 -translate-y-full flex">
28+
<button
29+
className={`w-52 h-16 border rounded-b-none focus:outline-none ${
30+
usersTabStatus === UsersTab.PendingUsers
31+
? "bg-[#F5F4F4] border-x-[#000000] border-t-[#000000]"
32+
: "bg-[#F4F4F4] border-x-[#BFBBBB] border-t-[#BFBBBB] border-b-[#000000]"
33+
}`}
34+
onClick={() => setUsersTabStatus(UsersTab.PendingUsers)}
35+
>
36+
Pending Users
37+
</button>
38+
<button
39+
className={`w-52 h-16 border rounded-b-none ml-2 focus:outline-none ${
40+
usersTabStatus === UsersTab.CurrentUsers
41+
? "bg-[#F5F4F4] border-x-[#000000] border-t-[#000000]"
42+
: "bg-[#F4F4F4] border-x-[#BFBBBB] border-t-[#BFBBBB] border-b-[#000000]"
43+
}`}
44+
onClick={() => setUsersTabStatus(UsersTab.CurrentUsers)}
45+
>
46+
Current Users
47+
</button>
48+
</div>
49+
<div>
50+
{usersTabStatus === UsersTab.CurrentUsers ? (
51+
<>
52+
<div className="flex px-9 pb-3 m-7 border-b border-b-[#BFBBBB] font-semibold justify-around">
53+
<p className="w-[140px] text-left">User Name</p>
54+
<p className="w-[140px] text-left">User ID</p>
55+
<p className="w-[140px] text-left">Email</p>
56+
<p className="w-[140px] text-left">Position</p>
57+
</div>
58+
<ApprovedUserCard
59+
name="Aaron Ashby"
60+
email="a.ashby@mit.edu"
61+
position="Employee"
62+
/>
63+
</>
64+
) : (
65+
<>
66+
<div className="flex px-9 pb-3 m-7 border-b border-b-[#BFBBBB] font-semibold justify-around">
67+
<p className="w-[140px] text-left">User Name</p>
68+
<p className="w-[140px] text-left">User ID</p>
69+
<p className="w-[140px] text-left">Email</p>
70+
<p className="w-[140px] text-left">Position</p>
71+
<p className="w-[140px] text-left">Date Requested</p>
72+
<div className="w-[140px]"></div>
73+
</div>
74+
<PendingUserCard
75+
name="Aaron Ashby"
76+
email="a.ashby@uconn.edu"
77+
position="Inactive"
78+
dateRequested={new Date("02/14/2006")}
79+
/>
80+
</>
81+
)}
82+
</div>
83+
</div>
684
</div>
785
);
886
}

0 commit comments

Comments
 (0)