Skip to content
This repository was archived by the owner on Mar 13, 2025. It is now read-only.

Commit 3b82544

Browse files
#635 - Use claims for nickname and handle missing primary attributes gracefully
1 parent 99410ba commit 3b82544

File tree

7 files changed

+96
-23
lines changed

7 files changed

+96
-23
lines changed

client/src/components/AddToGroupModal/index.jsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import * as groupLib from "../../lib/groups";
1212

1313
import style from "./style.module.scss";
1414
import Axios from "axios";
15+
import { getNickname } from "../../lib/common";
1516

1617
export default function AddToGroupModal({ onCancel, updateUser, user }) {
1718
const apiClient = api();
@@ -42,7 +43,7 @@ export default function AddToGroupModal({ onCancel, updateUser, user }) {
4243
(async () => {
4344
const groups = await groupLib.getGroups(
4445
apiClient,
45-
auth0User.nickname,
46+
getNickname(auth0User),
4647
cancelTokenSource.token
4748
);
4849

client/src/components/Header/index.jsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React from "react";
22
import PT from "prop-types";
33

44
import { useSearch } from "../../lib/search";
5+
import { getNickname } from "../../lib/common";
56
import { ReactComponent as SearchTabIcon } from "../../assets/images/search-tab-icon.svg";
67
import { ReactComponent as GroupsTabIcon } from "../../assets/images/groups-tab-icon.svg";
78
import { ReactComponent as UploadsTabIcon } from "../../assets/images/uploads-tab-icon.svg";
@@ -102,7 +103,7 @@ export default function Header({
102103
className={style.accountMenu}
103104
onMouseDown={() => setShowAccountDropdown(!showAccountDropdown)}
104105
>
105-
{user.nickname}
106+
{getNickname(user)}
106107
{organization ? <>&nbsp;({organization.name})</> : ""}
107108
{showAccountDropdown ? (
108109
<div className={`${iconStyles.chevronUpG} ${style.arrow}`}></div>

client/src/components/ProfileCard/index.js

Lines changed: 70 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,53 @@ function ProfileCard({
2828
const apiClient = api();
2929

3030
if (formatData) {
31+
let title;
32+
let isAvailable;
33+
let company;
34+
let location;
35+
let isMissingAPrimaryAttribute = false;
36+
let missingPrimaryAttributes = [];
37+
38+
try {
39+
title = cardHelper.getUserPrimaryAttributeDetails(
40+
profile,
41+
config.PRIMARY_ATTRIBUTES.title
42+
);
43+
} catch (error) {
44+
missingPrimaryAttributes.push("Title");
45+
isMissingAPrimaryAttribute = true;
46+
}
47+
48+
try {
49+
isAvailable = cardHelper.getUserPrimaryAttributeDetails(
50+
profile,
51+
config.PRIMARY_ATTRIBUTES.availability
52+
);
53+
} catch (error) {
54+
missingPrimaryAttributes.push("Availability");
55+
isMissingAPrimaryAttribute = true;
56+
}
57+
58+
try {
59+
company = cardHelper.getUserPrimaryAttributeDetails(
60+
profile,
61+
config.PRIMARY_ATTRIBUTES.company
62+
);
63+
} catch (error) {
64+
missingPrimaryAttributes.push("Company");
65+
isMissingAPrimaryAttribute = true;
66+
}
67+
68+
try {
69+
location = cardHelper.getUserPrimaryAttributeDetails(
70+
profile,
71+
config.PRIMARY_ATTRIBUTES.location
72+
);
73+
} catch (error) {
74+
missingPrimaryAttributes.push("Location");
75+
isMissingAPrimaryAttribute = true;
76+
}
77+
3178
// The profile data structure received from api is converted to a format
3279
// that is easy to use for rendering the UI as well as updating the fields
3380
tempUser = {
@@ -38,27 +85,17 @@ function ProfileCard({
3885
groups: cardHelper.getUserGroups(profile),
3986
skills: cardHelper.getUserSkills(profile),
4087
achievements: cardHelper.getUserAchievements(profile),
41-
title: cardHelper.getUserPrimaryAttributeDetails(
42-
profile,
43-
config.PRIMARY_ATTRIBUTES.title
44-
),
45-
isAvailable: cardHelper.getUserPrimaryAttributeDetails(
46-
profile,
47-
config.PRIMARY_ATTRIBUTES.availability
48-
),
49-
company: cardHelper.getUserPrimaryAttributeDetails(
50-
profile,
51-
config.PRIMARY_ATTRIBUTES.company
52-
),
53-
location: cardHelper.getUserPrimaryAttributeDetails(
54-
profile,
55-
config.PRIMARY_ATTRIBUTES.location
56-
),
88+
title,
89+
isAvailable,
90+
company,
91+
location,
5792
companyAttributes: cardHelper.getUserCompanyAttributeDetails(profile),
5893
avatarColor,
5994
// Indicates if the user has been deactivated. The user is still shown in this case, but with a
6095
// clear indicator about its deactivated status.
6196
isDeactivated: cardHelper.isUserDeactivated(profile),
97+
isMissingAPrimaryAttribute,
98+
missingPrimaryAttributes,
6299
};
63100
} else {
64101
// Data is already in the format seen above. No further processing needed
@@ -264,6 +301,23 @@ function ProfileCard({
264301
containerStyle += ` ${styles.stripped}`;
265302
}
266303

304+
if (user.isMissingAPrimaryAttribute) {
305+
return (
306+
<div className={containerStyle}>
307+
<div className={styles.profileCardHeaderContainer}></div>
308+
<div className={styles.profileCardMainContainer}></div>
309+
<div className={styles.profileCardFooterContainer}></div>
310+
<div className={styles.deactivatedCard}>
311+
<span>
312+
User with handle {user.handle} is missing values for the following
313+
primary attribute(s):
314+
<br /> {user.missingPrimaryAttributes.join(", ")}{" "}
315+
</span>
316+
</div>
317+
</div>
318+
);
319+
}
320+
267321
return (
268322
<div className={containerStyle}>
269323
{showManageGroupsModal ? (

client/src/config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,6 @@ export default {
3636
domain: process.env.REACT_APP_AUTH0_DOMAIN,
3737
clientId: process.env.REACT_APP_AUTH0_CLIENTID,
3838
audience: process.env.REACT_APP_AUTH0_AUDIENCE,
39+
handleClaims: process.env.REACT_APP_AUTH0_CLAIMS_HANDLE,
3940
},
4041
};

client/src/lib/common.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import config from "../config";
2+
3+
/**
4+
* Returns the nickname of the logged in user
5+
* @param {Object} auth0User The auth0 user object
6+
*/
7+
export function getNickname(auth0User) {
8+
return auth0User[config.AUTH0.handleClaims];
9+
}

client/src/pages/Search/Groups.jsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import api from "../../services/api";
1111
import * as groupLib from "../../lib/groups";
1212

1313
import style from "./style.module.scss";
14+
import { getNickname } from "../../lib/common";
1415

1516
const colorIterator = makeColorIterator(avatarColors);
1617

@@ -37,7 +38,7 @@ export default function SearchGroups() {
3738
(async () => {
3839
const groups = await groupLib.getGroups(
3940
apiClient,
40-
auth0User.nickname,
41+
getNickname(auth0User),
4142
cancelTokenSource.token
4243
);
4344

client/src/pages/Search/index.jsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,16 @@ import * as OrgService from "../../services/user-org";
1818
import api from "../../services/api";
1919

2020
import Cookies from "js-cookie";
21+
import { getNickname } from "../../lib/common";
2122

2223
export default function SearchPage() {
2324
const apiClient = api();
24-
const { isLoading, isAuthenticated, user: auth0User, loginWithRedirect } = useAuth0();
25+
const {
26+
isLoading,
27+
isAuthenticated,
28+
user: auth0User,
29+
loginWithRedirect,
30+
} = useAuth0();
2531
const [tab, setTab] = React.useState(TABS.SEARCH);
2632
const [keyword, setKeyword] = React.useState(null);
2733
const [selectedOrg, setSelectedOrg] = React.useState(null);
@@ -37,7 +43,7 @@ export default function SearchPage() {
3743
(async () => {
3844
const organizations = await OrgService.getOrg(
3945
apiClient,
40-
auth0User.nickname
46+
getNickname(auth0User)
4147
);
4248

4349
setLoadingOrgs(false);
@@ -64,8 +70,8 @@ export default function SearchPage() {
6470
}, [keyword]);
6571

6672
const onSelectOrg = (org) => {
67-
const cookie = Cookies.get('auth0.is.authenticated');
68-
if (cookie && cookie === 'true') {
73+
const cookie = Cookies.get("auth0.is.authenticated");
74+
if (cookie && cookie === "true") {
6975
OrgService.setSingleOrg(org);
7076
setSelectedOrg(org);
7177
setShouldSelectOrg(false);

0 commit comments

Comments
 (0)