diff --git a/src/features/user/profile/components/ContactOption.js b/src/features/user/profile/components/ContactOption.js
new file mode 100644
index 0000000..4630546
--- /dev/null
+++ b/src/features/user/profile/components/ContactOption.js
@@ -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 (
+
+
+
+
+
+ {onClick ? (
+
+ {linkLabel}
+
+ ) : (
+
+ {linkLabel}
+
+ )}
+
+ }
+ />
+
+ );
+};
+
+ContactOption.propTypes = {
+ icon: PropTypes.object.isRequired,
+ tooltip: PropTypes.string.isRequired,
+ label: PropTypes.string,
+ link: PropTypes.string.isRequired,
+ onClick: PropTypes.func
+};
+
+export default ContactOption;
diff --git a/src/features/user/profile/components/ContactOptions.js b/src/features/user/profile/components/ContactOptions.js
new file mode 100644
index 0000000..4125638
--- /dev/null
+++ b/src/features/user/profile/components/ContactOptions.js
@@ -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) => (
+
+ ))}
+ >
+ );
+};
+
+ContactOptions.propTypes = {
+ contactOptions: PropTypes.array,
+ userName: PropTypes.object.isRequired
+};
+
+export default ContactOptions;
diff --git a/src/features/user/profile/components/UserProfileCardContent.js b/src/features/user/profile/components/UserProfileCardContent.js
index 7c32e60..c18c83a 100644
--- a/src/features/user/profile/components/UserProfileCardContent.js
+++ b/src/features/user/profile/components/UserProfileCardContent.js
@@ -11,10 +11,9 @@ import {
Tooltip
} from "@material-ui/core";
import UserProfilePicture from "./UserProfilePicture";
-import BusinessCenterIcon from "@material-ui/icons/BusinessCenter";
import { FileCopyOutlined } from "@material-ui/icons";
-import EmailIcon from "@material-ui/icons/Email";
-import { useToast } from "../../../../hooks";
+import ContactOptions from "./ContactOptions";
+import { useClipboard } from "../../../../hooks";
import { useTranslation } from "react-i18next";
import { makeStyles } from "@material-ui/core/styles";
import styles from "../styles";
@@ -22,65 +21,28 @@ import styles from "../styles";
const useStyles = makeStyles(styles);
const UserProfileCardContent = ({ userData }) => {
- const { email, profilePictureUrl } = userData;
+ const { profilePictureUrl } = userData;
const { t } = useTranslation();
- const { info } = useToast();
const classes = useStyles();
-
- const handleCopyToClipboard = url => () => {
- navigator.clipboard.writeText(url);
- info(t("Generic.CopiedToClipboard"));
- };
-
- const handleEmailSending = event => {
- window.location.href = `mailto:${email}`;
- event.preventDefault();
- };
+ const { copy } = useClipboard();
const userName = `${userData.firstName} ${userData.lastName}`;
return (
-
+
-
-
-
-
-
-
- {userName}
-
-
- }
- />
-
-
-
-
-
-
-
- {email}
-
-
- }
- />
-
+
{profilePictureUrl && (
-
+
diff --git a/src/features/user/profile/components/UserProfileComponent.js b/src/features/user/profile/components/UserProfileComponent.js
index 1caaf51..a16171c 100644
--- a/src/features/user/profile/components/UserProfileComponent.js
+++ b/src/features/user/profile/components/UserProfileComponent.js
@@ -11,9 +11,9 @@ const UserProfileComponent = ({ userData }) => {
const userLoginDate = useMemo(
() =>
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", {
diff --git a/src/features/user/profile/components/UserProfileContainer.js b/src/features/user/profile/components/UserProfileContainer.js
index 0fa469a..f9001d5 100644
--- a/src/features/user/profile/components/UserProfileContainer.js
+++ b/src/features/user/profile/components/UserProfileContainer.js
@@ -1,12 +1,10 @@
import React from "react";
-import { useTuitioDecodedToken } from "@flare/tuitio-client-react";
+import { useTuitioUserInfo } from "@flare/tuitio-client-react";
import UserProfileComponent from "./UserProfileComponent";
const UserProfileContainer = () => {
- const { decodedToken } = useTuitioDecodedToken();
- return (
- <>{decodedToken && }>
- );
+ const { userInfo } = useTuitioUserInfo();
+ return <>{userInfo && }>;
};
export default UserProfileContainer;
diff --git a/src/features/user/profile/components/UserProfilePicture.js b/src/features/user/profile/components/UserProfilePicture.js
index 6ca0002..1c0f45c 100644
--- a/src/features/user/profile/components/UserProfilePicture.js
+++ b/src/features/user/profile/components/UserProfilePicture.js
@@ -7,15 +7,14 @@ import DefaultUserProfilePicture from "../../../../assets/images/DefaultUserProf
const useStyles = makeStyles(style);
-const UserProfilePicture = ({ userData }) => {
+const UserProfilePicture = ({ pictureUrl }) => {
const classes = useStyles();
- const { profilePictureUrl } = userData;
- const url = profilePictureUrl ?? DefaultUserProfilePicture;
+ const url = pictureUrl ?? DefaultUserProfilePicture;
return ;
};
UserProfilePicture.propTypes = {
- userData: PropTypes.object.isRequired
+ pictureUrl: PropTypes.string
};
export default UserProfilePicture;
diff --git a/src/hooks/index.js b/src/hooks/index.js
index a6f8e8a..973e94d 100644
--- a/src/hooks/index.js
+++ b/src/hooks/index.js
@@ -1,4 +1,5 @@
import { useToast } from "./useToast";
import { useSensitiveInfo } from "../providers/SensitiveInfoProvider";
+import { useClipboard } from "./useClipboard";
-export { useToast, useSensitiveInfo };
+export { useToast, useSensitiveInfo, useClipboard };
diff --git a/src/hooks/useClipboard.js b/src/hooks/useClipboard.js
new file mode 100644
index 0000000..b2fd329
--- /dev/null
+++ b/src/hooks/useClipboard.js
@@ -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 };