Skip to content

Commit

Permalink
Merge pull request #313 from djnunez-aot/user-table-front-end
Browse files Browse the repository at this point in the history
User Management Table Front end
  • Loading branch information
jadmsaadaot authored Feb 27, 2025
2 parents 653a43b + 2a3f605 commit d1ee62e
Show file tree
Hide file tree
Showing 8 changed files with 341 additions and 2 deletions.
20 changes: 18 additions & 2 deletions submit-web/src/components/Shared/Table/common.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,22 @@ export const SubmitTableCell = styled(TableCell)(() => ({
},
}));

export const PlainTableCell = styled(TableCell)(() => ({
borderTop: `1px solid ${BCDesignTokens.themeGray40}`,
borderBottom: `1px solid ${BCDesignTokens.themeGray40}`,
padding: `${BCDesignTokens.layoutPaddingSmall} !important`,
"&:first-of-type": {
borderLeft: `1px solid ${BCDesignTokens.themeGray40}`,
borderTopLeftRadius: 5,
borderBottomLeftRadius: 5,
},
"&:last-of-type": {
borderRight: `1px solid ${BCDesignTokens.themeGray40}`,
borderTopRightRadius: 5,
borderBottomRightRadius: 5,
},
}));

export const SubmitTableHead = styled(TableHead)(() => ({}));

export const SubmitTableContainer = styled(TableContainer)(() => ({
Expand All @@ -60,7 +76,7 @@ export const SubmitTablePrimaryRow = ({
const childrenWithProps = React.Children.map(children, (child) =>
React.isValidElement(child)
? React.cloneElement(child, { error } as any)
: child,
: child
);

return (
Expand Down Expand Up @@ -93,7 +109,7 @@ export const SubmitPrimaryRowTableCell = styled(TableCell)<{ error?: boolean }>(
borderTopRightRadius: 5,
borderBottomRightRadius: 5,
},
}),
})
);

export const SubmitSubTableCell = styled(TableCell)(() => ({
Expand Down
52 changes: 52 additions & 0 deletions submit-web/src/components/Shared/TableBox/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { Box, Divider, Paper, PaperProps, Typography } from "@mui/material";
import { BCDesignTokens } from "epic.theme";
import React from "react";

type TableBoxProps = {
mainLabel: React.ReactNode;
label?: string;
children: React.ReactNode;
actionBox?: React.ReactNode;
} & PaperProps;
export const TableBox = ({
children,
mainLabel = "",
actionBox,
...rest
}: TableBoxProps) => {
return (
<Paper
elevation={2}
{...rest}
sx={{
boxShadow: BCDesignTokens.surfaceShadowMedium,
maxWidth: "1448px",
border: `1px solid ${BCDesignTokens.themeGray40}`,
}}
>
<Box
sx={{
display: "flex",
alignItems: "center",
justifyContent: "space-between",
width: "auto",
padding: "12px 24px",
}}
>
<Typography variant="h2" sx={{ fontWeight: 400 }}>
{mainLabel || ""}
</Typography>
{actionBox}
</Box>
<Divider />
<Box
sx={{
padding: "24px 16px 16px 16px",
alignSelf: "stretch",
}}
>
{children}
</Box>
</Paper>
);
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { MainListItem } from "./MainListItem";
import ProjectsSubRoutes from "./ProjectsSubRoutes";
import { SubListItem } from "./SubListItem";

export default function EntityRoutes() {
return (
Expand All @@ -17,6 +18,13 @@ export default function EntityRoutes() {
path: "/proponent/profile",
}}
/>
<SubListItem
key={`sub-list-user-management`}
route={{
name: "User Management",
path: `/proponent/user-management`,
}}
/>
</>
);
}
50 changes: 50 additions & 0 deletions submit-web/src/components/UserManagement/UserTableHead.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { TableHead, TableRow } from "@mui/material";
import { BCDesignTokens } from "epic.theme";
import { SubmitTableHeadCell } from "@/components/Shared/Table/common";

export default function UserTableHead() {
return (
<TableHead
sx={{
border: 0,
".MuiTableCell-root": {
p: BCDesignTokens.layoutPaddingXsmall,
},
}}
>
<TableRow>
<SubmitTableHeadCell
sx={{
width: "35%",
}}
>
Email
</SubmitTableHeadCell>
<SubmitTableHeadCell
align="left"
sx={{
width: "25%",
}}
>
User Name
</SubmitTableHeadCell>
<SubmitTableHeadCell
align="left"
sx={{
width: "25%",
}}
>
Access
</SubmitTableHeadCell>
<SubmitTableHeadCell
align="left"
sx={{
width: "15%",
}}
>
Status
</SubmitTableHeadCell>
</TableRow>
</TableHead>
);
}
24 changes: 24 additions & 0 deletions submit-web/src/components/UserManagement/UserTableRow.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { PlainTableCell } from "@/components/Shared/Table/common";
import { User } from "@/models/User";
import { TableRow } from "@mui/material";
import { SubmitLink } from "../Shared/SubmitLink";
import UserStatusChip from "../UserStatusChip";

export default function UserTableRow({ user }: { user: User }) {
return (
<TableRow>
<PlainTableCell align="left" width={"35%"}>
<SubmitLink>{user.account_user.work_email_address}</SubmitLink>
</PlainTableCell>
<PlainTableCell align="left" width={"25%"}>
<SubmitLink>{user.account_user.full_name}</SubmitLink>
</PlainTableCell>
<PlainTableCell align="left" width={"25%"}>
{user.account_user.position}
</PlainTableCell>
<PlainTableCell align="left" width={"15%"}>
<UserStatusChip status={"INVITED"} />
</PlainTableCell>
</TableRow>
);
}
52 changes: 52 additions & 0 deletions submit-web/src/components/UserManagement/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { Box, Button, Table, TableBody, TableContainer } from "@mui/material";
import { BCDesignTokens } from "epic.theme";
import { Stack } from "@mui/material";
import { ContentBoxSkeleton } from "../Shared/ContentBox/ContentBoxSkeleton";
import UserTableHead from "./UserTableHead";
import UserTableRow from "./UserTableRow";
import { TableBox } from "../Shared/TableBox";
import { Add } from "@mui/icons-material";
import { User } from "@/models/User";

export const UserTable = ({ users }: { users: User[] }) => {
return (
<TableBox
mainLabel={"User Management"}
actionBox={
<Button variant="outlined" startIcon={<Add />}>
Add New User
</Button>
}
>
<Box
display={"flex"}
justifyContent={"space-between"}
sx={{
pt: BCDesignTokens.layoutPaddingMedium,
pb: BCDesignTokens.layoutPaddingXlarge,
}}
>
<TableContainer component={Box} sx={{ height: "100%" }}>
<Table>
<UserTableHead />
<TableBody>
{users.map((user) => (
<UserTableRow key={user.id} user={user} />
))}
</TableBody>
</Table>
</TableContainer>
</Box>
</TableBox>
);
};

export const DataSkeleton = () => {
return (
<Stack spacing={2} direction={"column"}>
<ContentBoxSkeleton />
<ContentBoxSkeleton />
<ContentBoxSkeleton />
</Stack>
);
};
50 changes: 50 additions & 0 deletions submit-web/src/components/UserStatusChip/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { Chip } from "@mui/material";
import { BCDesignTokens } from "epic.theme";

type StyleProps = {
sx: Record<string, string | number>;
label: string;
};

export type UserPackageStatus = "ACTIVE_USER" | "INVITED";

const statusStyles: Record<UserPackageStatus, StyleProps> = {
ACTIVE_USER: {
sx: {
borderRadius: 1,
border: `1px solid ${BCDesignTokens.supportBorderColorSuccess}`,
background: BCDesignTokens.supportSurfaceColorSuccess,
height: "24px",
},
label: "Active User",
},
INVITED: {
sx: {
borderRadius: 1,
border: `1px solid #9B6BDA`,
background: "#F6E4FF",
height: "24px",
},
label: "Invited",
},
};

type UserStatusChipProps = Readonly<{
status: UserPackageStatus;
}>;
export default function UserStatusChip({ status }: UserStatusChipProps) {
const style = statusStyles[status];

if (!style) {
return null;
}

return (
<Chip
sx={{
...style.sx,
}}
label={style.label}
/>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { PageGrid } from "@/components/Shared/PageGrid";
import { DataSkeleton, UserTable } from "@/components/UserManagement";
import { User } from "@/models/User";
import { Grid } from "@mui/material";
import { createFileRoute } from "@tanstack/react-router";
import { Else, If, Then } from "react-if";

export const Route = createFileRoute(
"/proponent/_proponentLayout/user-management/"
)({
component: UsersPage,
meta: () => [{ title: "User Management" }],
});

function UsersPage() {
const mockUsers: User[] = [
{
id: 1,
auth_guid: "123e4567-e89b-12d3-a456-426614174000",
type: "PROPONENT",
account_user: {
id: 101,
account_id: 1001,
first_name: "John",
last_name: "Doe",
full_name: "John Doe",
position: "Software Engineer",
work_email_address: "john.doe@example.com",
work_contact_number: "123-456-7890",
auth_guid: "123e4567-e89b-12d3-a456-426614174001",
account: {
id: 1001,
proponent_id: 1001,
},
},
staff_user: {
id: 201,
first_name: "John",
last_name: "Doe",
work_email_address: "john.doe@example.com",
user_id: 1,
},
},
{
id: 2,
auth_guid: "223e4567-e89b-12d3-a456-426614174000",
type: "STAFF",
account_user: {
id: 102,
account_id: 1002,
first_name: "Jane",
last_name: "Smith",
full_name: "Jane Smith",
position: "Project Manager",
work_email_address: "jane.smith@example.com",
work_contact_number: "987-654-3210",
auth_guid: "223e4567-e89b-12d3-a456-426614174001",
account: {
id: 1002,
proponent_id: 1001,
},
},
staff_user: {
id: 202,
first_name: "Jane",
last_name: "Smith",
work_email_address: "jane.smith@example.com",
user_id: 2,
},
},
];

return (
<PageGrid>
<Grid item xs={12}>
<If condition={false}>
<Then>
<DataSkeleton />
</Then>
<Else>
<UserTable users={mockUsers} />
</Else>
</If>
</Grid>
</PageGrid>
);
}

0 comments on commit d1ee62e

Please sign in to comment.