Skip to content
This repository was archived by the owner on Mar 13, 2025. It is now read-only.
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 9d3767d

Browse files
committedJul 25, 2020
Merge branch 'develop' into issue_315
2 parents 1d9b6bd + 0318b7f commit 9d3767d

File tree

24 files changed

+254
-151
lines changed

24 files changed

+254
-151
lines changed
 

‎client/package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 16 additions & 74 deletions
Loading

‎client/src/components/AddToGroupModal/Group/style.module.scss

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
height: 45px;
1111
padding: 0 30px;
1212
position: relative;
13+
justify-content: space-between;
1314

1415
&:last-child {
1516
border-bottom: 1px solid $lightGray2;
@@ -22,8 +23,3 @@
2223
max-width: 400px;
2324
white-space: nowrap;
2425
}
25-
26-
.switch {
27-
position: absolute;
28-
right: 30px;
29-
}

‎client/src/components/AddToGroupModal/index.jsx

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from "react";
1+
import React, { useEffect } from "react";
22
import PT from "prop-types";
33

44
import Button from "../Button";
@@ -10,6 +10,7 @@ import { useAuth0 } from "../../react-auth0-spa";
1010
import * as groupLib from "../../lib/groups";
1111

1212
import style from "./style.module.scss";
13+
import Axios from "axios";
1314

1415
export default function AddToGroupModal({ onCancel, updateUser, user }) {
1516
const apiClient = api();
@@ -21,34 +22,50 @@ export default function AddToGroupModal({ onCancel, updateUser, user }) {
2122
const [updatingGroups, setUpdatingGroups] = React.useState(false);
2223
const [userGroups, setUserGroups] = React.useState(user.groups);
2324
const [creatingGroup, setCreatingGroup] = React.useState(false);
25+
const cancelTokenSource = Axios.CancelToken.source();
26+
27+
/**
28+
* Component unmount trigger
29+
*/
30+
useEffect(() => {
31+
return () => {
32+
cancelTokenSource.cancel();
33+
};
34+
});
2435

2536
React.useEffect(() => {
2637
if (isLoading || !isAuthenticated) {
2738
return;
2839
}
2940

3041
(async () => {
31-
const groups = await groupLib.getGroups(apiClient, auth0User.nickname);
32-
33-
groups.myGroups.forEach((g, i, a) => {
34-
userGroups.forEach((ug, iug, aug) => {
35-
if (g.id === ug.id && !ug.isDeleted) {
36-
a[i] = { ...g, isSelected: true };
37-
}
42+
const groups = await groupLib.getGroups(
43+
apiClient,
44+
auth0User.nickname,
45+
cancelTokenSource.token
46+
);
47+
48+
if (groups) {
49+
groups.myGroups.forEach((g, i, a) => {
50+
userGroups.forEach((ug, iug, aug) => {
51+
if (g.id === ug.id && !ug.isDeleted) {
52+
a[i] = { ...g, isSelected: true };
53+
}
54+
});
3855
});
39-
});
4056

41-
groups.otherGroups.forEach((g, i, a) => {
42-
userGroups.forEach((ug, iug, aug) => {
43-
if (g.id === ug.id && !ug.isDeleted) {
44-
a[i] = { ...g, isSelected: true };
45-
}
57+
groups.otherGroups.forEach((g, i, a) => {
58+
userGroups.forEach((ug, iug, aug) => {
59+
if (g.id === ug.id && !ug.isDeleted) {
60+
a[i] = { ...g, isSelected: true };
61+
}
62+
});
4663
});
47-
});
4864

49-
setMyGroups(groups.myGroups);
50-
setOtherGroups(groups.otherGroups);
51-
setIsLoadingGroups(false);
65+
setMyGroups(groups.myGroups);
66+
setOtherGroups(groups.otherGroups);
67+
setIsLoadingGroups(false);
68+
}
5269
})();
5370
// eslint-disable-next-line react-hooks/exhaustive-deps
5471
}, [isLoading, isAuthenticated, auth0User]);
@@ -111,7 +128,7 @@ export default function AddToGroupModal({ onCancel, updateUser, user }) {
111128

112129
const newGroup = await groupLib.createGroup(apiClient, groupName);
113130

114-
if (newGroup.id) {
131+
if (newGroup && newGroup.id) {
115132
const newOtherGroups = JSON.parse(JSON.stringify(otherGroups));
116133

117134
newOtherGroups.push(newGroup);
@@ -121,6 +138,8 @@ export default function AddToGroupModal({ onCancel, updateUser, user }) {
121138
alert(`Group with name ${groupName} created successfully`);
122139

123140
setFilter("");
141+
} else if (newGroup.message) {
142+
alert(newGroup.message);
124143
} else {
125144
alert("Group creation failed");
126145
}
@@ -129,7 +148,11 @@ export default function AddToGroupModal({ onCancel, updateUser, user }) {
129148
};
130149

131150
return (
132-
<Modal onCancel={onCancel}>
151+
<Modal
152+
onCancel={onCancel}
153+
className={style.container}
154+
overlayClassName={style.overlay}
155+
>
133156
<h1 className={style.title}>Add to Group</h1>
134157
<div className={style.searchRow}>
135158
<ZoomIcon className={style.zoomIcon} />

‎client/src/components/AddToGroupModal/style.module.scss

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
@import "../../styles/mixins";
22

3+
.container {
4+
z-index: 1100;
5+
}
6+
7+
.overlay {
8+
z-index: 1010;
9+
}
10+
311
.buttons {
412
display: flex;
513
justify-content: flex-end;

‎client/src/components/FiltersSideMenu/filters.js

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,28 @@ export default function SearchTabFilters({ locations, achievements }) {
2626
const [locationsData, setLocationsData] = useState(locations);
2727
const [achievementsData, setAchievementsData] = useState(achievements);
2828

29+
/**
30+
* Component unmount trigger
31+
*/
32+
useEffect(() => {
33+
return () => {
34+
handleReset();
35+
};
36+
// eslint-disable-next-line react-hooks/exhaustive-deps
37+
}, []);
38+
39+
const handleReset = () => {
40+
search.selectLocations([]);
41+
search.selectSkills([]);
42+
search.selectAchievements([]);
43+
search.selectAvailability({
44+
isAvailableSelected: false,
45+
isUnavailableSelected: false,
46+
});
47+
search.selectCompanyAttributes({});
48+
search.changePageNumber(1);
49+
};
50+
2951
useEffect(() => {
3052
setLocationsData(locations);
3153
setAchievementsData(achievements);
@@ -202,7 +224,10 @@ export default function SearchTabFilters({ locations, achievements }) {
202224

203225
return (
204226
<div className={styles.searchTabFilters}>
205-
<Summary filtersApplied={numberOfFiltersApplied} />
227+
<Summary
228+
filtersApplied={numberOfFiltersApplied}
229+
handleReset={handleReset}
230+
/>
206231
{search.isFilterActive(FILTERS.LOCATIONS) && (
207232
<div className={utilityStyles.mt32}>
208233
<Collapsible title="Location" collapsed={false}>
@@ -302,21 +327,7 @@ SearchTabFilters.propTypes = {
302327
achievements: PT.array,
303328
};
304329

305-
function Summary({ filtersApplied }) {
306-
const search = useSearch();
307-
308-
const handleReset = () => {
309-
search.selectLocations([]);
310-
search.selectSkills([]);
311-
search.selectAchievements([]);
312-
search.selectAvailability({
313-
isAvailableSelected: false,
314-
isUnavailableSelected: false,
315-
});
316-
search.selectCompanyAttributes({});
317-
search.changePageNumber(1);
318-
};
319-
330+
function Summary({ filtersApplied, handleReset }) {
320331
return (
321332
<div className={styles.searchTabFiltersSummary}>
322333
<div className={styles.searchTabFiltersSummaryTextContainer}>

‎client/src/components/GroupsSideMenu/filters.module.css

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151

5252
.groupTabFiltersContentSearchCreate {
5353
align-self: flex-end;
54-
margin-left: auto;
54+
margin-left: 15px;
5555
}
5656

5757
.groupTabGroupsContainer {
@@ -83,13 +83,13 @@
8383

8484
.sectionItem {
8585
cursor: pointer;
86-
height: 24px;
8786
width: 322px;
8887
border-radius: 10px;
8988
border: 1px solid gray1_025;
9089

9190
display: flex;
9291
flex-direction: row;
92+
align-items: center;
9393
padding-left: 17px;
9494
padding-top: 13px;
9595
padding-bottom: 13px;
@@ -101,12 +101,13 @@
101101
}
102102

103103
.sectionItemTitle {
104-
align-self: flex-start;
105104
color: gray2;
105+
word-break: break-word;
106+
padding-right: 12px;
106107
}
107108

108109
.sectionItemBadge {
109-
align-self: flex-start;
110+
align-self: center;
110111
margin-left: auto;
111112
color: gray1;
112113

‎client/src/components/Header/index.jsx

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

4-
import { ReactComponent as DownArrow } from "../../assets/images/down-arrow.svg";
54
import { ReactComponent as SearchTabIcon } from "../../assets/images/search-tab-icon.svg";
65
import { ReactComponent as GroupsTabIcon } from "../../assets/images/groups-tab-icon.svg";
76
import { ReactComponent as UploadsTabIcon } from "../../assets/images/uploads-tab-icon.svg";
@@ -29,6 +28,13 @@ export default function Header({
2928
const [searchText, setSearchText] = React.useState("");
3029
const [showAccountDropdown, setShowAccountDropdown] = React.useState(false);
3130

31+
const profileDropdownEl = React.useRef(null);
32+
React.useEffect(() => {
33+
if (showAccountDropdown) {
34+
profileDropdownEl.current.focus();
35+
}
36+
}, [showAccountDropdown]);
37+
3238
const handleSearch = (value) => {
3339
value = value || searchText;
3440

@@ -101,7 +107,12 @@ export default function Header({
101107
<div className={`${iconStyles.chevronDownG} ${style.arrow}`}></div>
102108
)}
103109
{showAccountDropdown && (
104-
<ul className={style.dropdown}>
110+
<ul
111+
tabIndex="0"
112+
className={style.dropdown}
113+
ref={profileDropdownEl}
114+
onBlur={() => setShowAccountDropdown(false)}
115+
>
105116
<li
106117
className={style.dropdownItem}
107118
onClick={() => logoutWithRedirect()}

‎client/src/components/Header/style.module.scss

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
.logo {
44
display: flex;
55
align-items: center;
6+
7+
img {
8+
width: 80px;
9+
height: auto;
10+
}
611
}
712

813
.accountMenu {
@@ -32,6 +37,10 @@
3237
border-bottom-left-radius: 4px;
3338
border-bottom-right-radius: 4px;
3439
overflow: hidden;
40+
41+
&:focus {
42+
outline: none;
43+
}
3544
}
3645

3746
.dropdownItem {
@@ -76,6 +85,7 @@
7685

7786
.downArrow {
7887
margin-left: 15px;
88+
overflow: hidden;
7989
}
8090

8191
.menu {
@@ -124,6 +134,12 @@
124134
&::placeholder {
125135
opacity: 0.5;
126136
}
137+
138+
&::-ms-clear {
139+
display: none;
140+
height: 0;
141+
width: 0;
142+
}
127143
}
128144

129145
.title {

‎client/src/components/Input/style.module.scss

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,12 @@
1717
border: 0;
1818
color: $black;
1919
font: 400 12pt/1.25 Inter;
20-
height: 38px;
20+
height: 36px;
2121
outline: none;
22+
23+
&::-ms-clear {
24+
display: none;
25+
}
2226
}
2327

2428
.label {

‎client/src/components/Modal/index.jsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import PT from "prop-types";
44

55
import style from "./style.module.scss";
66

7-
export default function Modal({ children, className }) {
7+
export default function Modal({ children, className, overlayClassName = "" }) {
88
const [portal, setPortal] = React.useState();
99

1010
React.useEffect(() => {
@@ -21,6 +21,9 @@ export default function Modal({ children, className }) {
2121
let containerStyle = style.container;
2222
if (className) containerStyle += ` ${className}`;
2323

24+
let overlayStyle = style.overlay;
25+
if (overlayClassName) overlayStyle += ` ${overlayClassName}`;
26+
2427
return portal
2528
? ReactDom.createPortal(
2629
<>
@@ -32,7 +35,7 @@ export default function Modal({ children, className }) {
3235
</div>
3336
<button
3437
aria-label="Cancel"
35-
className={style.overlay}
38+
className={overlayStyle}
3639
ref={(node) => {
3740
if (node) {
3841
node.focus();

‎client/src/components/Pill/style.module.scss

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@
1515
}
1616
}
1717

18+
@-moz-document url-prefix() {
19+
.close {
20+
margin-bottom: 2px;
21+
}
22+
}
23+
1824
.container {
1925
align-items: center;
2026
background: $white;

‎client/src/components/ProfileCard/profileCard.module.css

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@
7474
}
7575

7676
.profileCardMainContainer {
77-
height: 100px;
7877
width: 100%;
7978
margin-bottom: 44px;
8079
}
@@ -95,6 +94,8 @@
9594
font-family: Helvetica;
9695
font-size: 20px;
9796
color: gray2;
97+
word-break: break-all;
98+
padding-bottom: 10px;
9899
}
99100

100101
.mainNameBagde {

‎client/src/components/SuggestionBox/index.jsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import config from "../../config";
44
import api from "../../services/api";
55
import style from "./style.module.scss";
66

7+
const NO_RESULTS_FOUND = "no results found";
8+
79
/**
810
* Decides what is displayed after the user selects a suggestion
911
* @param {Object} suggestion The selected suggestion
@@ -88,7 +90,8 @@ export default function SuggestionBox({
8890

8991
const onSuggestionsFetchRequested = async ({ value }) => {
9092
if (purpose === "skills") {
91-
const data = await getSkillsSuggestions(apiClient, value);
93+
let data = await getSkillsSuggestions(apiClient, value);
94+
if (data.length < 1) data = [{ name: NO_RESULTS_FOUND }];
9295
setSuggestions(data);
9396
} else {
9497
const data = await getCompanyAttributesSuggestions(
@@ -104,7 +107,7 @@ export default function SuggestionBox({
104107

105108
const onSuggestionSelected = (event, { suggestion }) => {
106109
if (purpose === "skills") {
107-
onSelect(suggestion);
110+
if (suggestion.name !== NO_RESULTS_FOUND) onSelect(suggestion);
108111
} else {
109112
onSelect(companyAttrId, suggestion);
110113
}

‎client/src/components/Upload/Initial/index.jsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,15 @@ export default function Initial({ onError, onUpload, templateId }) {
3232
const { data } = await apiClient.get(url);
3333
window.location = data.url;
3434
} catch (error) {
35-
if (onError) onError(error.toJSON());
35+
if (onError) onError(error);
3636
}
3737
};
3838

3939
const upload = (files) => {
4040
const allowedMineTypes = [
4141
"application/vnd.ms-excel",
4242
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
43+
"text/csv",
4344
];
4445
if (files && files[0] && allowedMineTypes.indexOf(files[0].type) !== -1)
4546
onUpload(files[0]);

‎client/src/components/collapsible/index.js

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,14 @@ export default function Collapsible({ title, children, collapsed = false }) {
2020
<div className={mainStyle}>
2121
<div className={styles.collapsibleHeader}>
2222
<div className={styles.collapsibleTitle}>{title}</div>
23-
<div className={styles.collapsibleChevronContainer}>
23+
<div
24+
className={styles.collapsibleChevronContainer}
25+
onClick={() => setIsCollapsed(!isCollapsed)}
26+
>
2427
{isCollapsed ? (
25-
<div
26-
className={iconStyles.chevronDownG}
27-
onClick={() => setIsCollapsed(!isCollapsed)}
28-
></div>
28+
<div className={iconStyles.chevronDownG}></div>
2929
) : (
30-
<div
31-
className={iconStyles.chevronUpG}
32-
onClick={() => setIsCollapsed(!isCollapsed)}
33-
></div>
30+
<div className={iconStyles.chevronUpG}></div>
3431
)}
3532
</div>
3633
</div>

‎client/src/components/tag/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,10 @@ export default function Tag({
6464
}, [text, selected]);
6565

6666
return (
67-
<button className={mainStyle} onClick={onClickAction}>
67+
<button className={mainStyle} title={text} onClick={onClickAction}>
6868
{text ? (
6969
<div className={styles.tagContent}>
70-
{text && <span title={text}>{text}</span>}
70+
{text && <span>{text}</span>}
7171
{icon && <TagButton icon={icon} />}
7272
</div>
7373
) : (

‎client/src/lib/groups.js

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,26 @@
11
import config from "../config";
22
import * as OrgService from "../services/user-org";
3+
import Axios from "axios";
34

45
/**
56
* Returns the groups for the logged in user
67
* @param {Object} apiClient The api client
78
* @param {Object} handle The logged in user's handle
89
*/
9-
export async function getGroups(apiClient, handle) {
10+
export async function getGroups(apiClient, handle, cancelToken) {
1011
let myGroups = [];
1112
let otherGroups = [];
1213
let response;
1314

1415
// First, we get the userId of the current user
1516
try {
16-
response = await apiClient.get(`${config.API_URL}/users?handle=${handle}`);
17+
response = await apiClient.get(`${config.API_URL}/users?handle=${handle}`, {
18+
cancelToken,
19+
});
1720
} catch (error) {
21+
if (Axios.isCancel(error)) {
22+
return undefined;
23+
}
1824
console.log(error);
1925
// TODO - handle error
2026
return { myGroups, otherGroups };
@@ -33,9 +39,13 @@ export async function getGroups(apiClient, handle) {
3339
// Now, get my groups first
3440
try {
3541
response = await apiClient.get(
36-
`${config.GROUPS_API_URL}?universalUID=${userId}&membershipType=user`
42+
`${config.GROUPS_API_URL}?universalUID=${userId}&membershipType=user`,
43+
{ cancelToken }
3744
);
3845
} catch (error) {
46+
if (Axios.isCancel(error)) {
47+
return undefined;
48+
}
3949
console.log(error);
4050
// TODO - handle error
4151
return { myGroups, otherGroups };
@@ -56,9 +66,13 @@ export async function getGroups(apiClient, handle) {
5666
// Fetch all groups in the org
5767
try {
5868
response = await apiClient.get(
59-
`${config.GROUPS_API_URL}?organizationId=${organizationId}`
69+
`${config.GROUPS_API_URL}?organizationId=${organizationId}`,
70+
{ cancelToken }
6071
);
6172
} catch (error) {
73+
if (Axios.isCancel(error)) {
74+
return undefined;
75+
}
6276
console.log(error);
6377
// TODO - handle error
6478
return { myGroups, otherGroups };
@@ -86,9 +100,13 @@ export async function getGroups(apiClient, handle) {
86100
// Now, get member counts
87101
try {
88102
response = await apiClient.get(
89-
`${config.GROUPS_API_URL}/memberGroups/groupMembersCount?universalUID=${userId}`
103+
`${config.GROUPS_API_URL}/memberGroups/groupMembersCount?universalUID=${userId}`,
104+
{ cancelToken }
90105
);
91106
} catch (error) {
107+
if (Axios.isCancel(error)) {
108+
return undefined;
109+
}
92110
console.log(error);
93111
// TODO - handle error
94112
return { myGroups, otherGroups };
@@ -105,9 +123,13 @@ export async function getGroups(apiClient, handle) {
105123
// Fetch all groups in the org
106124
try {
107125
response = await apiClient.get(
108-
`${config.GROUPS_API_URL}/memberGroups/groupMembersCount?organizationId=${organizationId}`
126+
`${config.GROUPS_API_URL}/memberGroups/groupMembersCount?organizationId=${organizationId}`,
127+
{ cancelToken }
109128
);
110129
} catch (error) {
130+
if (Axios.isCancel(error)) {
131+
return undefined;
132+
}
111133
console.log(error);
112134
// TODO - handle error
113135
return { myGroups, otherGroups };

‎client/src/pages/Search/Global.jsx

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,14 @@ function getOrderByText(orderBy) {
3636
}
3737
}
3838

39+
function usePrevious(value) {
40+
const ref = React.useRef();
41+
React.useEffect(() => {
42+
ref.current = value;
43+
});
44+
return ref.current;
45+
}
46+
3947
export default function SearchGlobal({ keyword }) {
4048
const { isLoading, isAuthenticated, user: auth0User } = useAuth0();
4149
const apiClient = api();
@@ -50,13 +58,18 @@ export default function SearchGlobal({ keyword }) {
5058
const [windowWidth, setWindowWidth] = React.useState(window.innerWidth);
5159
const [orderBy, setOrderBy] = React.useState(config.DEFAULT_SORT_ORDER);
5260
const [totalPages, setTotalPages] = React.useState(0);
61+
const dropdownRef = React.useRef(null);
62+
63+
const prevOrderBy = usePrevious(orderBy);
5364

5465
const usersPerPage = config.ITEMS_PER_PAGE;
5566

5667
React.useEffect(() => {
5768
window.addEventListener("resize", updateWindowDimensions);
69+
window.addEventListener("click", onWholeContentClick);
5870
return () => {
5971
window.removeEventListener("resize", updateWindowDimensions);
72+
window.removeEventListener("click", onWholeContentClick);
6073
};
6174
});
6275

@@ -181,6 +194,11 @@ export default function SearchGlobal({ keyword }) {
181194
}
182195
});
183196

197+
// reset first page when change orderBy
198+
if (prevOrderBy !== "undefined" && prevOrderBy !== orderBy) {
199+
searchContext.pagination.page = 1;
200+
}
201+
184202
if (searchContext.pagination.page !== page) {
185203
setPage(searchContext.pagination.page);
186204
}
@@ -222,6 +240,7 @@ export default function SearchGlobal({ keyword }) {
222240
});
223241

224242
setUsers(data);
243+
setSortByDropdownShown(false);
225244
setTotalResults(Number(headers["x-total"]));
226245
setTotalPages(Number(headers["x-total-pages"]));
227246
}
@@ -241,6 +260,25 @@ export default function SearchGlobal({ keyword }) {
241260
setWindowWidth(window.innerWidth);
242261
};
243262

263+
/**
264+
* Sets the new page number and gets the new set of users
265+
* @param {Number} newPageNumber The new page number
266+
*/
267+
const onChangePage = async (newPageNumber) => {
268+
if (window) {
269+
window.scrollTo({
270+
top: 0,
271+
});
272+
}
273+
searchContext.changePageNumber(newPageNumber);
274+
};
275+
276+
const onWholeContentClick = (evt) => {
277+
if (dropdownRef.current && !dropdownRef.current.contains(evt.target)) {
278+
setSortByDropdownShown(false);
279+
}
280+
};
281+
244282
return (
245283
<>
246284
<div className={style.sideMenu}>
@@ -258,6 +296,7 @@ export default function SearchGlobal({ keyword }) {
258296
</div>
259297
<div
260298
className={style.sort}
299+
ref={dropdownRef}
261300
onClick={() => setSortByDropdownShown(!sortByDropdownShown)}
262301
style={{
263302
marginRight:
@@ -274,7 +313,7 @@ export default function SearchGlobal({ keyword }) {
274313
{getOrderByText(orderBy)}
275314
</span>
276315
)}
277-
<DownArrowIcon />
316+
<DownArrowIcon className={style.downArrow} />
278317
{sortByDropdownShown && (
279318
<ul className={style.dropdown}>
280319
<li
@@ -320,7 +359,11 @@ export default function SearchGlobal({ keyword }) {
320359
})}
321360
</div>
322361
<div>
323-
<Pagination currentPage={page} numPages={totalPages} />
362+
<Pagination
363+
currentPage={page}
364+
numPages={totalPages}
365+
onChangePage={onChangePage}
366+
/>
324367
</div>
325368
</div>
326369
)}

‎client/src/pages/Search/Groups.jsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,11 @@ export default function SearchGroups() {
129129
* @param {Number} newPageNumber The new page number
130130
*/
131131
const onChangePage = async (newPageNumber) => {
132+
if (window) {
133+
window.scrollTo({
134+
top: 0,
135+
});
136+
}
132137
setPage(newPageNumber);
133138
await getMembersInGroup(selectedGroup.id, newPageNumber);
134139
};

‎client/src/pages/Search/style.module.scss

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@
5656
margin-bottom: 100px;
5757
}
5858

59+
.downArrow {
60+
overflow: hidden;
61+
}
62+
5963
.pills {
6064
margin: 15px -5px 0;
6165
}
@@ -108,6 +112,7 @@
108112

109113
&:hover {
110114
background-color: $blue;
115+
color: $white;
111116
}
112117
}
113118

‎client/src/services/api.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export default () => {
3535
});
3636
} else if (
3737
error.response &&
38-
error.response.status === 409 &&
38+
error.response.data &&
3939
error.response.data.message
4040
) {
4141
const modError = new Error(error.response.data.message);

‎package-lock.json

Lines changed: 6 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@
2222
"@hapi/joi": "^16.1.8",
2323
"aws-sdk": "^2.627.0",
2424
"axios": "^0.19.2",
25-
"clsx": "^1.1.1",
2625
"bluebird": "^3.5.1",
2726
"body-parser": "^1.19.0",
27+
"clsx": "^1.1.1",
2828
"config": "^3.2.4",
2929
"cors": "^2.8.5",
3030
"dynamoose": "^1.8.0",

0 commit comments

Comments
 (0)
This repository has been archived.