replaced useTuitioDecodedToken with useTuitioUserInfo

master
Tudor Stanciu 2023-03-31 01:54:45 +03:00
parent c4275df4bc
commit 9c80ed0bfb
8 changed files with 231 additions and 60 deletions

View File

@ -0,0 +1,45 @@
import React from "react";
import PropTypes from "prop-types";
import {
ListItem,
ListItemText,
ListItemIcon,
Link,
Tooltip
} from "@material-ui/core";
const ContactOption = ({ tooltip, label, link, onClick, ...props }) => {
const linkLabel = label ?? link;
return (
<ListItem dense>
<ListItemIcon>
<props.icon />
</ListItemIcon>
<ListItemText
primary={
<Tooltip title={tooltip}>
{onClick ? (
<Link href="#" onClick={onClick}>
{linkLabel}
</Link>
) : (
<Link href={link} target="_blank">
{linkLabel}
</Link>
)}
</Tooltip>
}
/>
</ListItem>
);
};
ContactOption.propTypes = {
icon: PropTypes.object.isRequired,
tooltip: PropTypes.string.isRequired,
label: PropTypes.string,
link: PropTypes.string.isRequired,
onClick: PropTypes.func
};
export default ContactOption;

View File

@ -0,0 +1,148 @@
import React, { useCallback, useMemo } from "react";
import PropTypes from "prop-types";
import { useTranslation } from "react-i18next";
import ContactOption from "./ContactOption";
import BusinessCenterIcon from "@material-ui/icons/BusinessCenter";
import EmailIcon from "@material-ui/icons/Email";
import PhoneAndroidIcon from "@material-ui/icons/PhoneAndroid";
import LanguageIcon from "@material-ui/icons/Language";
import LinkedInIcon from "@material-ui/icons/LinkedIn";
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 { useClipboard } from "../../../../hooks";
const icons = {
EMAIL: EmailIcon,
PHONE: PhoneAndroidIcon,
PORTFOLIO: BusinessCenterIcon,
LINKEDIN: LinkedInIcon,
GITHUB: GitHubIcon,
GITEA: GitHubIcon,
REDDIT: RedditIcon,
BLOG: BookIcon,
CURRICULUM_VITAE: MenuBookIcon,
DEFAULT: LanguageIcon
};
const tooltips = {
EMAIL: "Generic.SendEmail",
PHONE: "Generic.Copy",
PORTFOLIO: "User.Profile.OpenPortfolio",
DEFAULT: "Generic.OpenInNewTab"
};
const orderNumbers = {
PORTFOLIO: 1,
EMAIL: 2,
PHONE: 3,
CURRICULUM_VITAE: 4,
LINKEDIN: 5,
GITEA: 6,
GITHUB: 7,
BLOG: 8,
WEBSITE: 9,
REDDIT: 10,
DEFAULT: 100
};
const getIcon = contactOption => {
const icon = icons[contactOption.contactTypeCode] || icons.DEFAULT;
return icon;
};
const getTooltip = contactOption => {
const tooltip = tooltips[contactOption.contactTypeCode] || tooltips.DEFAULT;
return tooltip;
};
const getOrderNumber = contactOption => {
const orderNo =
orderNumbers[contactOption.contactTypeCode] || orderNumbers.DEFAULT;
return orderNo;
};
const getLabel = (contactOption, userName) => {
switch (contactOption.contactTypeCode) {
case "EMAIL":
case "PHONE":
return contactOption.contactValue;
case "PORTFOLIO":
return userName;
default:
return contactOption.contactTypeName;
}
};
const handleEmailSending = email => event => {
window.location.href = `mailto:${email}`;
event.preventDefault();
};
const ContactOptions = ({ contactOptions, userName }) => {
const { t } = useTranslation();
const { copy } = useClipboard();
const getOnClickEvent = useCallback(
contactOption => {
switch (contactOption.contactTypeCode) {
case "EMAIL":
return handleEmailSending(contactOption.contactValue);
case "PHONE":
return copy(contactOption.contactValue);
default:
return undefined;
}
},
[copy]
);
const enrichedContactOptions = useMemo(
() =>
contactOptions.map(co => {
const icon = getIcon(co);
const tooltip = getTooltip(co);
const label = getLabel(co, userName);
const onClick = getOnClickEvent(co);
const orderNo = getOrderNumber(co);
const option = {
icon,
tooltip: t(tooltip),
label,
link: co.contactValue,
onClick,
orderNo
};
return option;
}),
[contactOptions, getOnClickEvent, t, userName]
);
const sorted = useMemo(
() => enrichedContactOptions.sort((a, b) => a.orderNo - b.orderNo),
[enrichedContactOptions]
);
return (
<>
{sorted.map((z, index) => (
<ContactOption
key={`contact_${index}`}
icon={z.icon}
tooltip={z.tooltip}
label={z.label}
link={z.link}
onClick={z.onClick}
/>
))}
</>
);
};
ContactOptions.propTypes = {
contactOptions: PropTypes.array,
userName: PropTypes.object.isRequired
};
export default ContactOptions;

View File

@ -11,10 +11,9 @@ import {
Tooltip Tooltip
} from "@material-ui/core"; } from "@material-ui/core";
import UserProfilePicture from "./UserProfilePicture"; import UserProfilePicture from "./UserProfilePicture";
import BusinessCenterIcon from "@material-ui/icons/BusinessCenter";
import { FileCopyOutlined } from "@material-ui/icons"; import { FileCopyOutlined } from "@material-ui/icons";
import EmailIcon from "@material-ui/icons/Email"; import ContactOptions from "./ContactOptions";
import { useToast } from "../../../../hooks"; import { useClipboard } from "../../../../hooks";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { makeStyles } from "@material-ui/core/styles"; import { makeStyles } from "@material-ui/core/styles";
import styles from "../styles"; import styles from "../styles";
@ -22,65 +21,28 @@ import styles from "../styles";
const useStyles = makeStyles(styles); const useStyles = makeStyles(styles);
const UserProfileCardContent = ({ userData }) => { const UserProfileCardContent = ({ userData }) => {
const { email, profilePictureUrl } = userData; const { profilePictureUrl } = userData;
const { t } = useTranslation(); const { t } = useTranslation();
const { info } = useToast();
const classes = useStyles(); const classes = useStyles();
const { copy } = useClipboard();
const handleCopyToClipboard = url => () => {
navigator.clipboard.writeText(url);
info(t("Generic.CopiedToClipboard"));
};
const handleEmailSending = event => {
window.location.href = `mailto:${email}`;
event.preventDefault();
};
const userName = `${userData.firstName} ${userData.lastName}`; const userName = `${userData.firstName} ${userData.lastName}`;
return ( return (
<div className={classes.panel}> <div className={classes.panel}>
<UserProfilePicture userData={userData} /> <UserProfilePicture pictureUrl={userData.profilePictureUrl} />
<Grid container spacing={2}> <Grid container spacing={2}>
<Grid item xs={12} sm={6}> <Grid item xs={12} sm={6}>
<List> <List>
<ListItem dense> <ContactOptions
<ListItemIcon> contactOptions={userData.contactOptions}
<BusinessCenterIcon /> userName={userName}
</ListItemIcon> />
<ListItemText
primary={
<Tooltip title={t("User.Profile.OpenPortfolio")}>
<Link href="https://lab.code-rove.com/tsp/" target="_blank">
{userName}
</Link>
</Tooltip>
}
/>
</ListItem>
<ListItem dense>
<ListItemIcon>
<EmailIcon />
</ListItemIcon>
<ListItemText
primary={
<Tooltip title={t("Generic.SendEmail")}>
<Link href="#" onClick={handleEmailSending}>
{email}
</Link>
</Tooltip>
}
/>
</ListItem>
{profilePictureUrl && ( {profilePictureUrl && (
<ListItem dense> <ListItem dense>
<ListItemIcon> <ListItemIcon>
<Tooltip title={t("Generic.Copy")}> <Tooltip title={t("Generic.Copy")}>
<IconButton <IconButton size="small" onClick={copy(profilePictureUrl)}>
size="small"
onClick={handleCopyToClipboard(profilePictureUrl)}
>
<FileCopyOutlined /> <FileCopyOutlined />
</IconButton> </IconButton>
</Tooltip> </Tooltip>

View File

@ -11,9 +11,9 @@ const UserProfileComponent = ({ userData }) => {
const userLoginDate = useMemo( const userLoginDate = useMemo(
() => () =>
t("DATE_FORMAT", { t("DATE_FORMAT", {
date: { value: userData.createdAt, format: "DD-MM-YYYY HH:mm:ss" } date: { value: userData.lastLoginDate, format: "DD-MM-YYYY HH:mm:ss" }
}), }),
[t, userData.createdAt] [t, userData.lastLoginDate]
); );
const userDescription = t("User.Profile.Description", { const userDescription = t("User.Profile.Description", {

View File

@ -1,12 +1,10 @@
import React from "react"; import React from "react";
import { useTuitioDecodedToken } from "@flare/tuitio-client-react"; import { useTuitioUserInfo } from "@flare/tuitio-client-react";
import UserProfileComponent from "./UserProfileComponent"; import UserProfileComponent from "./UserProfileComponent";
const UserProfileContainer = () => { const UserProfileContainer = () => {
const { decodedToken } = useTuitioDecodedToken(); const { userInfo } = useTuitioUserInfo();
return ( return <>{userInfo && <UserProfileComponent userData={userInfo} />}</>;
<>{decodedToken && <UserProfileComponent userData={decodedToken} />}</>
);
}; };
export default UserProfileContainer; export default UserProfileContainer;

View File

@ -7,15 +7,14 @@ import DefaultUserProfilePicture from "../../../../assets/images/DefaultUserProf
const useStyles = makeStyles(style); const useStyles = makeStyles(style);
const UserProfilePicture = ({ userData }) => { const UserProfilePicture = ({ pictureUrl }) => {
const classes = useStyles(); const classes = useStyles();
const { profilePictureUrl } = userData; const url = pictureUrl ?? DefaultUserProfilePicture;
const url = profilePictureUrl ?? DefaultUserProfilePicture;
return <Avatar src={url} alt="..." className={classes.profilePicture} />; return <Avatar src={url} alt="..." className={classes.profilePicture} />;
}; };
UserProfilePicture.propTypes = { UserProfilePicture.propTypes = {
userData: PropTypes.object.isRequired pictureUrl: PropTypes.string
}; };
export default UserProfilePicture; export default UserProfilePicture;

View File

@ -1,4 +1,5 @@
import { useToast } from "./useToast"; import { useToast } from "./useToast";
import { useSensitiveInfo } from "../providers/SensitiveInfoProvider"; import { useSensitiveInfo } from "../providers/SensitiveInfoProvider";
import { useClipboard } from "./useClipboard";
export { useToast, useSensitiveInfo }; export { useToast, useSensitiveInfo, useClipboard };

18
src/hooks/useClipboard.js Normal file
View File

@ -0,0 +1,18 @@
import { useCallback } from "react";
import { useTranslation } from "react-i18next";
import { useToast } from "./useToast";
const useClipboard = () => {
const { t } = useTranslation();
const { info } = useToast();
const copy = useCallback(
url => () => {
navigator.clipboard.writeText(url);
info(t("Generic.CopiedToClipboard"));
},
[info, t]
);
return { copy };
};
export { useClipboard };