contact info refactoring

master
Tudor Stanciu 2023-04-01 20:17:23 +03:00
parent 3d3f8fe811
commit c5e7319324
3 changed files with 68 additions and 53 deletions

View File

@ -5,15 +5,32 @@ import {
ListItemText,
ListItemIcon,
Link,
Tooltip
Tooltip,
IconButton
} from "@material-ui/core";
const ContactIcon = ({ onIconClick, iconTooltip, ...props }) => {
if (!onIconClick) return <props.icon />;
return (
<Tooltip title={iconTooltip}>
<IconButton size="small" onClick={onIconClick}>
<props.icon />
</IconButton>
</Tooltip>
);
};
ContactIcon.propTypes = {
onIconClick: PropTypes.func,
iconTooltip: PropTypes.string
};
const ContactOption = ({ tooltip, label, link, onClick, ...props }) => {
const linkLabel = label ?? link;
return (
<ListItem dense>
<ListItemIcon>
<props.icon />
<ContactIcon {...props} />
</ListItemIcon>
<ListItemText
primary={
@ -35,11 +52,11 @@ const ContactOption = ({ tooltip, label, link, onClick, ...props }) => {
};
ContactOption.propTypes = {
icon: PropTypes.object.isRequired,
tooltip: PropTypes.string.isRequired,
label: PropTypes.string,
link: PropTypes.string.isRequired,
onClick: PropTypes.func
onClick: PropTypes.func,
onIconClick: PropTypes.func
};
export default ContactOption;

View File

@ -12,6 +12,7 @@ import GitHubIcon from "@material-ui/icons/GitHub";
import RedditIcon from "@material-ui/icons/Reddit";
import BookIcon from "@material-ui/icons/Book";
import MenuBookIcon from "@material-ui/icons/MenuBook";
import FileCopyOutlinedIcon from "@material-ui/icons/FileCopyOutlined";
import { useClipboard } from "../../../../hooks";
const icons = {
@ -24,6 +25,7 @@ const icons = {
REDDIT: RedditIcon,
BLOG: BookIcon,
CURRICULUM_VITAE: MenuBookIcon,
PROFILE_PICTURE: FileCopyOutlinedIcon,
DEFAULT: LanguageIcon
};
@ -68,6 +70,7 @@ const getLabel = (contactOption, userName) => {
switch (contactOption.contactTypeCode) {
case "EMAIL":
case "PHONE":
case "PROFILE_PICTURE":
return contactOption.contactValue;
case "PORTFOLIO":
return userName;
@ -81,7 +84,7 @@ const handleEmailSending = email => event => {
event.preventDefault();
};
const ContactOptions = ({ contactOptions, userName, profilePictureItem }) => {
const ContactOptions = ({ contactOptions, userName }) => {
const { t } = useTranslation();
const { copy } = useClipboard();
@ -99,6 +102,21 @@ const ContactOptions = ({ contactOptions, userName, profilePictureItem }) => {
[copy]
);
const getIconClickEvent = useCallback(
contactOption => {
switch (contactOption.contactTypeCode) {
case "PROFILE_PICTURE":
return {
onIconClick: copy(contactOption.contactValue),
iconTooltip: t("Generic.Copy")
};
default:
return { onIconClick: undefined, iconTooltip: undefined };
}
},
[copy, t]
);
const enrichedContactOptions = useMemo(
() =>
contactOptions.map(co => {
@ -106,6 +124,7 @@ const ContactOptions = ({ contactOptions, userName, profilePictureItem }) => {
const tooltip = getTooltip(co);
const label = getLabel(co, userName);
const onClick = getOnClickEvent(co);
const { onIconClick, iconTooltip } = getIconClickEvent(co);
const orderNo = getOrderNumber(co);
const option = {
icon,
@ -113,11 +132,13 @@ const ContactOptions = ({ contactOptions, userName, profilePictureItem }) => {
label,
link: co.contactValue,
onClick,
onIconClick,
iconTooltip,
orderNo
};
return option;
}),
[contactOptions, getOnClickEvent, t, userName]
[contactOptions, getOnClickEvent, getIconClickEvent, t, userName]
);
const sorted = useMemo(
@ -135,17 +156,17 @@ const ContactOptions = ({ contactOptions, userName, profilePictureItem }) => {
label={z.label}
link={z.link}
onClick={z.onClick}
onIconClick={z.onIconClick}
iconTooltip={z.iconTooltip}
/>
))}
{profilePictureItem && <>{profilePictureItem}</>}
</List>
);
};
ContactOptions.propTypes = {
contactOptions: PropTypes.array,
userName: PropTypes.string.isRequired,
profilePictureItem: PropTypes.node
userName: PropTypes.string.isRequired
};
export default ContactOptions;

View File

@ -1,19 +1,8 @@
import React from "react";
import React, { useMemo } from "react";
import PropTypes from "prop-types";
import {
Grid,
ListItem,
ListItemText,
ListItemIcon,
Link,
IconButton,
Tooltip
} from "@material-ui/core";
import { Grid } from "@material-ui/core";
import UserProfilePicture from "./UserProfilePicture";
import { FileCopyOutlined } from "@material-ui/icons";
import ContactOptions from "./ContactOptions";
import { useClipboard } from "../../../../hooks";
import { useTranslation } from "react-i18next";
import { makeStyles } from "@material-ui/core/styles";
import styles from "../styles";
@ -21,11 +10,26 @@ const useStyles = makeStyles(styles);
const UserProfileCardContent = ({ userData }) => {
const { profilePictureUrl } = userData;
const { t } = useTranslation();
const classes = useStyles();
const { copy } = useClipboard();
const userName = `${userData.firstName} ${userData.lastName}`;
const userName = useMemo(
() => `${userData.firstName} ${userData.lastName}`,
[userData.firstName, userData.lastName]
);
const _contactOptions = useMemo(
() =>
profilePictureUrl
? [
...userData.contactOptions,
{
id: userData.contactOptions.length + 1,
contactTypeCode: "PROFILE_PICTURE",
contactValue: profilePictureUrl
}
]
: userData.contactOptions,
[profilePictureUrl, userData.contactOptions]
);
return (
<div className={classes.panel}>
@ -33,35 +37,8 @@ const UserProfileCardContent = ({ userData }) => {
<Grid container spacing={2}>
<Grid item xs={12} sm={6}>
<ContactOptions
contactOptions={userData.contactOptions}
contactOptions={_contactOptions}
userName={userName}
profilePictureItem={
<>
{profilePictureUrl && (
<ListItem dense>
<ListItemIcon>
<Tooltip title={t("Generic.Copy")}>
<IconButton
size="small"
onClick={copy(profilePictureUrl)}
>
<FileCopyOutlined />
</IconButton>
</Tooltip>
</ListItemIcon>
<ListItemText
primary={
<Tooltip title={t("Generic.OpenInNewTab")}>
<Link href={profilePictureUrl} target="_blank">
{profilePictureUrl}
</Link>
</Tooltip>
}
/>
</ListItem>
)}
</>
}
/>
</Grid>
</Grid>