From d9822bead010709d268f7d219113fbfbab06cefb Mon Sep 17 00:00:00 2001 From: sjaanus Date: Fri, 22 Jul 2022 12:27:19 +0000 Subject: [PATCH] Create a custom group popover for avatars (#1143) * Create a custom group tooltip for avatars * Remove data attribute * Fix naming convention * Fix naming convention * Run prettier manually * Prettier malfunction fix Co-authored-by: Jaanus Sellin --- frontend/.gitignore | 1 + .../GroupCardAvatars/GroupCardAvatars.tsx | 39 ++++++-- .../GroupPopover/GroupPopover.tsx | 88 +++++++++++++++++++ 3 files changed, 121 insertions(+), 7 deletions(-) create mode 100644 frontend/src/component/admin/groups/GroupsList/GroupCard/GroupCardAvatars/GroupPopover/GroupPopover.tsx diff --git a/frontend/.gitignore b/frontend/.gitignore index 7c68ab2ea8..7d5390b6df 100644 --- a/frontend/.gitignore +++ b/frontend/.gitignore @@ -50,5 +50,6 @@ build .DS_Store cypress/videos/* +cypress/downloads/* cypress/screenshots/* .env.local diff --git a/frontend/src/component/admin/groups/GroupsList/GroupCard/GroupCardAvatars/GroupCardAvatars.tsx b/frontend/src/component/admin/groups/GroupsList/GroupCard/GroupCardAvatars/GroupCardAvatars.tsx index 23dd3ebe8b..c5daf720a8 100644 --- a/frontend/src/component/admin/groups/GroupsList/GroupCard/GroupCardAvatars/GroupCardAvatars.tsx +++ b/frontend/src/component/admin/groups/GroupsList/GroupCard/GroupCardAvatars/GroupCardAvatars.tsx @@ -1,8 +1,9 @@ import { Avatar, Badge, styled } from '@mui/material'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { IGroupUser, Role } from 'interfaces/group'; -import { useMemo } from 'react'; +import React, { useMemo, useState } from 'react'; import StarIcon from '@mui/icons-material/Star'; +import { GroupPopover } from './GroupPopover/GroupPopover'; const StyledAvatars = styled('div')(({ theme }) => ({ display: 'inline-flex', @@ -42,6 +43,20 @@ export const GroupCardAvatars = ({ users }: IGroupCardAvatarsProps) => { () => users.sort((a, b) => (a.role < b.role ? 1 : -1)).slice(0, 9), [users] ); + + const [anchorEl, setAnchorEl] = useState(null); + const [popupUser, setPopupUser] = useState(); + + const onPopoverOpen = (event: React.MouseEvent) => { + setAnchorEl(event.currentTarget); + }; + + const onPopoverClose = () => { + setAnchorEl(null); + }; + + const avatarOpen = Boolean(anchorEl); + return ( {shownUsers.map(user => ( @@ -53,9 +68,11 @@ export const GroupCardAvatars = ({ users }: IGroupCardAvatarsProps) => { data-loading alt="Gravatar" src={user.imageUrl} - title={`${ - user.name || user.email || user.username - } (id: ${user.id})`} + onMouseEnter={event => { + onPopoverOpen(event); + setPopupUser(user); + }} + onMouseLeave={onPopoverClose} /> } elseShow={ @@ -71,9 +88,11 @@ export const GroupCardAvatars = ({ users }: IGroupCardAvatarsProps) => { data-loading alt="Gravatar" src={user.imageUrl} - title={`${ - user.name || user.email || user.username - } (id: ${user.id})`} + onMouseEnter={event => { + onPopoverOpen(event); + setPopupUser(user); + }} + onMouseLeave={onPopoverClose} /> } @@ -87,6 +106,12 @@ export const GroupCardAvatars = ({ users }: IGroupCardAvatarsProps) => { } /> + ); }; diff --git a/frontend/src/component/admin/groups/GroupsList/GroupCard/GroupCardAvatars/GroupPopover/GroupPopover.tsx b/frontend/src/component/admin/groups/GroupsList/GroupCard/GroupCardAvatars/GroupPopover/GroupPopover.tsx new file mode 100644 index 0000000000..dcd4f2d6b8 --- /dev/null +++ b/frontend/src/component/admin/groups/GroupsList/GroupCard/GroupCardAvatars/GroupPopover/GroupPopover.tsx @@ -0,0 +1,88 @@ +import { Popover, Badge, styled, Tooltip } from '@mui/material'; +import { IGroup, IGroupUser, Role } from 'interfaces/group'; +import { Link } from 'react-router-dom'; +import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; + +import { Badge as StyledBadge } from 'component/common/Badge/Badge'; + +import { RemoveGroup } from 'component/admin/groups/RemoveGroup/RemoveGroup'; +import { useState } from 'react'; +import StarIcon from '@mui/icons-material/Star'; +import { IUser } from '../../../../../../../interfaces/user'; + +const StyledPopover = styled(Popover)(({ theme }) => ({ + pointerEvents: 'none', + '.MuiPaper-root': { + padding: '12px', + }, +})); + +const StyledPopupStar = styled(StarIcon)(({ theme }) => ({ + color: theme.palette.warning.main, + fontSize: theme.fontSizes.smallBody, + marginLeft: theme.spacing(0.1), + marginTop: theme.spacing(2), +})); + +const StyledName = styled('div')(({ theme }) => ({ + color: theme.palette.text.secondary, + fontSize: theme.fontSizes.smallBody, + marginTop: theme.spacing(1), +})); + +interface IGroupPopoverProps { + user: IGroupUser | undefined; + + open: boolean; + anchorEl: HTMLElement | null; + + onPopoverClose(event: React.MouseEvent): void; +} + +export const GroupPopover = ({ + user, + open, + anchorEl, + onPopoverClose, +}: IGroupPopoverProps) => { + return ( + + {user?.role}} + elseShow={ + } + > + + {user?.role} + + + } + /> + + {user?.name} +
{user?.email}
+
+ ); +};