Skip to content

Commit 2218dba

Browse files
authored
Merge pull request #1441 from TomChapmanGov/my_workplans
Staff Avatar Hover Cards
2 parents f726888 + fc334b6 commit 2218dba

File tree

4 files changed

+185
-17
lines changed

4 files changed

+185
-17
lines changed

epictrack-web/src/components/myWorkplans/Card/CardFooter.tsx

Lines changed: 83 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,50 @@
1-
import { Avatar, AvatarGroup, Button, Grid } from "@mui/material";
1+
import {
2+
Avatar,
3+
AvatarGroup,
4+
Box,
5+
Button,
6+
Grid,
7+
ListItem,
8+
avatarGroupClasses,
9+
} from "@mui/material";
210
import { Palette } from "../../../styles/theme";
311
import { ETCaption1, ETCaption2, ETParagraph } from "../../shared";
412
import Icons from "../../icons";
513
import { IconProps } from "../../icons/type";
614
import { CardProps } from "./type";
715
import { useNavigate } from "react-router-dom";
16+
import React from "react";
17+
import UserMenu from "../../shared/userMenu/UserMenu";
18+
import RenderSurplus from "./RenderSurplus";
19+
import { Staff } from "../../../models/staff";
820

921
const EyeIcon: React.FC<IconProps> = Icons["EyeIcon"];
1022

1123
const CardFooter = ({ workplan }: CardProps) => {
1224
const navigate = useNavigate();
25+
const [staffHover, setStaffHover] = React.useState<any>(null);
26+
const [userMenuAnchorEl, setUserMenuAnchorEl] =
27+
React.useState<null | HTMLElement>(null);
1328
const team_lead = workplan.staff_info.find((staff: any) => {
1429
if (staff.role.name === "Team Lead") {
1530
return staff.staff.full_name;
1631
}
1732
return false;
1833
});
1934

35+
const handleCloseUserMenu = (event: React.MouseEvent<HTMLElement>) => {
36+
setUserMenuAnchorEl(null);
37+
setStaffHover(null);
38+
};
39+
40+
const handleOpenUserMenu = (
41+
event: React.MouseEvent<HTMLElement>,
42+
staff: any
43+
) => {
44+
setStaffHover(staff);
45+
setUserMenuAnchorEl(event.currentTarget);
46+
};
47+
2048
return (
2149
<Grid
2250
container
@@ -27,7 +55,7 @@ const CardFooter = ({ workplan }: CardProps) => {
2755
borderTop: `1px solid var(--neutral-background-dark, #DBDCDC)`,
2856
padding: "16px 32px",
2957
alignItems: "center",
30-
height: "80px",
58+
// height: "80px",
3159
}}
3260
>
3361
<Grid item>
@@ -68,23 +96,61 @@ const CardFooter = ({ workplan }: CardProps) => {
6896
<ETCaption1 color={Palette.neutral.main}>STAFF</ETCaption1>
6997
</Grid>
7098
<Grid item>
71-
<AvatarGroup max={4}>
99+
<AvatarGroup
100+
spacing={1}
101+
max={4}
102+
renderSurplus={(surplus: number) => (
103+
<RenderSurplus
104+
renderSurplus={surplus}
105+
staff={workplan.staff_info as unknown as Staff[]}
106+
/>
107+
)}
108+
sx={{
109+
[`& .${avatarGroupClasses.avatar}`]: {
110+
width: "24px",
111+
height: "24px",
112+
},
113+
}}
114+
>
72115
{workplan.staff_info.map((staff: any) => {
73116
return (
74-
<Avatar
75-
key={staff.staff.id}
76-
sx={{
77-
bgcolor: Palette.neutral.bg.main,
78-
color: Palette.neutral.dark,
79-
lineHeight: "12px",
80-
width: "24px",
81-
height: "24px",
82-
}}
83-
>
84-
<ETCaption2
85-
bold
86-
>{`${staff.staff.first_name[0]}${staff.staff.last_name[0]}`}</ETCaption2>
87-
</Avatar>
117+
<>
118+
<Avatar
119+
key={staff.staff.id}
120+
sx={{
121+
bgcolor: Palette.neutral.bg.main,
122+
color: Palette.neutral.dark,
123+
lineHeight: "12px",
124+
width: "24px",
125+
height: "24px",
126+
}}
127+
onMouseEnter={(event) => {
128+
event.stopPropagation();
129+
event.preventDefault();
130+
handleOpenUserMenu(event, staff.staff);
131+
}}
132+
// onMouseLeave={handleCloseUserMenu}
133+
>
134+
<ETCaption2
135+
bold
136+
>{`${staff.staff.first_name[0]}${staff.staff.last_name[0]}`}</ETCaption2>
137+
</Avatar>
138+
<UserMenu
139+
onMouseLeave={handleCloseUserMenu}
140+
anchorEl={userMenuAnchorEl}
141+
email={staffHover?.email || ""}
142+
phone={staffHover?.phone || ""}
143+
position={staffHover?.position?.name || ""}
144+
firstName={staffHover?.first_name || ""}
145+
lastName={staffHover?.last_name || ""}
146+
onClose={handleCloseUserMenu}
147+
origin={{ vertical: "top", horizontal: "left" }}
148+
sx={{
149+
pointerEvents: "none",
150+
}}
151+
id={staff.staff.id}
152+
/>
153+
</>
88154
);
89155
})}
90156
</AvatarGroup>
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import {
2+
Avatar,
3+
Grid,
4+
Menu,
5+
MenuItem,
6+
PopoverOrigin,
7+
Typography,
8+
} from "@mui/material";
9+
import { Staff } from "../../../models/staff";
10+
import React from "react";
11+
import { ETCaption2 } from "../../shared";
12+
import { Palette } from "../../../styles/theme";
13+
14+
interface RenderSurplusProps {
15+
renderSurplus: number;
16+
staff: any[];
17+
}
18+
19+
const RenderSurplus = ({ renderSurplus, staff }: RenderSurplusProps) => {
20+
const [userListAnchor, setUserListAnchor] =
21+
React.useState<null | HTMLElement>(null);
22+
23+
const remainingStaff = staff.slice(renderSurplus - 1);
24+
25+
const handleOpenUserMenu = (event: React.MouseEvent<HTMLElement>) => {
26+
setUserListAnchor(event.currentTarget);
27+
};
28+
29+
const handleCloseUserMenu = () => {
30+
setUserListAnchor(null);
31+
};
32+
33+
return (
34+
<>
35+
<Avatar
36+
onMouseEnter={(event) => {
37+
event.stopPropagation();
38+
event.preventDefault();
39+
handleOpenUserMenu(event);
40+
}}
41+
>
42+
<Typography sx={{ textAlign: "center" }}>...</Typography>
43+
</Avatar>
44+
<Menu
45+
open={Boolean(userListAnchor)}
46+
onMouseLeave={handleCloseUserMenu}
47+
anchorEl={userListAnchor}
48+
anchorOrigin={{ vertical: "top", horizontal: "left" }}
49+
onClose={handleCloseUserMenu}
50+
sx={{
51+
mt: "2.5rem",
52+
}}
53+
PaperProps={{
54+
style: {
55+
pointerEvents: "none",
56+
width: 320,
57+
boxShadow: "0px 12px 24px 0px rgba(0, 0, 0, 0.10)",
58+
},
59+
}}
60+
MenuListProps={{
61+
style: {
62+
paddingTop: 0,
63+
paddingBottom: 0,
64+
pointerEvents: "auto",
65+
},
66+
}}
67+
>
68+
{remainingStaff.map((staffObject: any) => {
69+
return (
70+
<MenuItem>
71+
<Avatar
72+
sx={{
73+
bgcolor: Palette.neutral.bg.main,
74+
color: Palette.neutral.dark,
75+
width: "32px",
76+
height: "32px",
77+
padding: "4px 8px",
78+
marginRight: "8px",
79+
}}
80+
>
81+
<ETCaption2>{`${staffObject?.staff?.first_name[0]}${staffObject?.staff?.last_name[0]}`}</ETCaption2>
82+
</Avatar>
83+
<Grid container direction={"column"}>
84+
<Grid item>
85+
<ETCaption2 bold>{staffObject?.staff?.full_name}</ETCaption2>
86+
</Grid>
87+
<Grid item>
88+
<ETCaption2>{staffObject?.staff?.position?.name}</ETCaption2>
89+
</Grid>
90+
</Grid>
91+
</MenuItem>
92+
);
93+
})}
94+
</Menu>
95+
</>
96+
);
97+
};
98+
99+
export default RenderSurplus;

epictrack-web/src/components/shared/userMenu/UserMenu.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ const UserMenu = (props: UserMenuProps) => {
3838
phone,
3939
origin,
4040
id,
41+
onMouseLeave,
4142
} = props;
4243
const menuOrigin = React.useMemo(() => {
4344
if (origin === undefined)
@@ -60,6 +61,7 @@ const UserMenu = (props: UserMenuProps) => {
6061
transformOrigin={menuOrigin}
6162
open={Boolean(anchorEl)}
6263
onClose={onClose}
64+
onMouseLeave={onMouseLeave}
6365
PaperProps={{
6466
style: {
6567
pointerEvents: "none",

epictrack-web/src/components/shared/userMenu/type.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@ export interface UserMenuProps {
1212
origin?: PopoverOrigin;
1313
sx?: SxProps;
1414
id?: string;
15+
onMouseLeave?: (event: React.MouseEvent<HTMLElement>) => any;
1516
}

0 commit comments

Comments
 (0)