Skip to content

Commit ecab660

Browse files
Merge pull request #6712 from topcoder-platform/develop
Release v1.19.3
2 parents d21ec47 + 182b8f7 commit ecab660

File tree

33 files changed

+698
-66
lines changed

33 files changed

+698
-66
lines changed

.circleci/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ workflows:
363363
filters:
364364
branches:
365365
only:
366-
- feature/dice-setup
366+
- feat/badges-box
367367
# This is beta env for production soft releases
368368
- "build-prod-beta":
369369
context : org-global

__tests__/shared/components/challenge-listing/Filters/__snapshots__/FiltersPanel.jsx.snap

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,10 @@ exports[`Matches shallow shapshot 2`] = `
6666
disabled={false}
6767
expanding={false}
6868
isAuth={false}
69+
isReviewer={false}
70+
loading={true}
6971
past={false}
72+
reviewCount={0}
7073
/>
7174
</div>
7275
</div>

__tests__/shared/components/challenge-listing/Sidebar/__snapshots__/index.jsx.snap

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ exports[`Matches shallow shapshot 1`] = `
1313
disabled={false}
1414
expanding={false}
1515
isAuth={false}
16+
loading={true}
1617
past={false}
18+
reviewCount={0}
1719
selectBucket={[MockFunction]}
1820
/>
1921
</div>
@@ -36,7 +38,9 @@ exports[`Matches shallow shapshot 2`] = `
3638
disabled={false}
3739
expanding={false}
3840
isAuth={false}
41+
loading={true}
3942
past={false}
43+
reviewCount={0}
4044
selectBucket={[MockFunction]}
4145
/>
4246
</div>

__tests__/shared/components/challenge-listing/__snapshots__/index.jsx.snap

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ exports[`Matches shallow shapshot 1 shapshot 1 1`] = `
2929
>
3030
<Connect(SidebarContainer)
3131
expanding={false}
32+
reviewCount={0}
3233
setFilterState={[MockFunction]}
3334
/>
3435
<Connect(Container)
@@ -99,6 +100,7 @@ exports[`Matches shallow shapshot 2 shapshot 2 1`] = `
99100
>
100101
<Connect(SidebarContainer)
101102
expanding={false}
103+
reviewCount={0}
102104
setFilterState={[MockFunction]}
103105
/>
104106
<Connect(Container)

automated-smoke-test/page-objects/pages/topcoder/challenge-listing/challenge-listing.helper.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -724,7 +724,7 @@ export class ChallengeListingPageHelper {
724724
static async verifyOpenForReviewChallengesOnly() {
725725
await this.waitForSubCommunity();
726726
const openForReviewLink = await ChallengeListingPageObject.filterChallengesBy(
727-
'Open for review'
727+
'Review Opportunities'
728728
);
729729
await openForReviewLink.click();
730730
await this.waitForLoadingNewChallengeList();
@@ -799,11 +799,11 @@ export class ChallengeListingPageHelper {
799799
expect(headers.length).toBe(0);
800800

801801
const openForReviewLink = await ChallengeListingPageObject.filterChallengesBy(
802-
'Open for review'
802+
'Review Opportunities'
803803
);
804804
await openForReviewLink.click();
805805

806-
await this.waitTillOnlyOneHeaderPresentWithText('Open for review');
806+
await this.waitTillOnlyOneHeaderPresentWithText('Review Opportunities');
807807
await CommonHelper.waitUntilVisibilityOf(
808808
() =>
809809
CommonHelper.findElementByText(

src/shared/actions/page/profile.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ async function getGamificationBadgesInit(handle) {
2121
* @param {String} handle Topcoder member handle.
2222
* @return {Action}
2323
*/
24-
async function getGamificationBadgesDone(handle) {
24+
async function getGamificationBadgesDone(handle, limit) {
2525
try {
2626
const memberInfo = await fetch(`${config.API.V5}/members/${handle}`)
2727
.then(response => response.json());
28-
const badges = await fetch(`${config.API.V5}/gamification/badges/assigned/${memberInfo.userId}?organization_id=${config.GAMIFICATION.ORG_ID}`)
28+
const badges = await fetch(`${config.API.V5}/gamification/badges/assigned/${memberInfo.userId}?organization_id=${config.GAMIFICATION.ORG_ID}&limit=${limit || 4}`)
2929
.then(response => response.json());
3030

3131
return {
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import React, { useState } from 'react';
2+
import PT from 'prop-types';
3+
import { Link } from 'react-router-dom';
4+
import { get } from 'lodash';
5+
import { Modal } from 'topcoder-react-ui-kit';
6+
import IconClose from 'assets/images/tc-edu/icon-close-big.svg';
7+
import FallBackAwardIcon from 'assets/images/default-award.svg';
8+
import md from 'utils/markdown';
9+
import { format } from 'date-fns';
10+
import AwardModal from '../ProfilePage/Awards/AwardModal';
11+
12+
import style from './styles.scss';
13+
14+
const ProfileBadges = ({ badges, handleParam }) => {
15+
const [showModal, setShowModal] = useState(false);
16+
const [modalData, setModalData] = useState({});
17+
18+
return (
19+
<div styleName="outer-container">
20+
<Link
21+
to={`/members/${handleParam}`}
22+
styleName="memberPageBackLink"
23+
>
24+
<svg
25+
xmlns="http://www.w3.org/2000/svg"
26+
width="14"
27+
height="12"
28+
fill="none"
29+
viewBox="0 0 14 12"
30+
>
31+
<path
32+
fill="#137D60"
33+
fillRule="evenodd"
34+
d="M6.766 11.366a.8.8 0 01-1.132 0l-4.8-4.8a.8.8 0 010-1.132l4.8-4.8a.8.8 0 111.132 1.132L3.33 5.2h9.27a.8.8 0 010 1.6H3.33l3.435 3.434a.8.8 0 010 1.132z"
35+
clipRule="evenodd"
36+
/>
37+
</svg>
38+
Return to Profile
39+
</Link>
40+
<div styleName="badgesWrap">
41+
<div styleName="seactionTitle">COMMUNITY AWARDS & HONORS</div>
42+
<div styleName="badgesGrid">
43+
{
44+
badges.rows.map((reward) => {
45+
const title = get(reward, 'org_badge.badge_name');
46+
const imageUrl = get(reward, 'org_badge.badge_image_url');
47+
let description = get(reward, 'org_badge.badge_description');
48+
if (description) {
49+
description = md(description);
50+
}
51+
let awardedAt = get(reward, 'awarded_at');
52+
if (awardedAt) {
53+
awardedAt = format(new Date(awardedAt), 'PPP');
54+
}
55+
56+
return (
57+
<div
58+
role="presentation"
59+
styleName="awardBadge"
60+
onClick={() => {
61+
setShowModal(true);
62+
setModalData({
63+
title,
64+
description,
65+
imageUrl,
66+
awardedAt,
67+
});
68+
}}
69+
>
70+
{
71+
imageUrl ? (
72+
<img src={imageUrl} alt="award-badge" styleName="image" />
73+
) : (
74+
<FallBackAwardIcon styleName="image" />
75+
)
76+
}
77+
<div styleName="title">
78+
<span>
79+
<div dangerouslySetInnerHTML={{ __html: title }} />
80+
</span>
81+
</div>
82+
</div>
83+
);
84+
})
85+
}
86+
</div>
87+
</div>
88+
{
89+
showModal && (
90+
<Modal onCancel={() => setShowModal(false)} theme={style}>
91+
<div styleName="award-modal">
92+
<div styleName="header">
93+
<h2 styleName="title">Community Awards & Honors</h2>
94+
<div styleName="icon" role="presentation" onClick={() => setShowModal(false)}>
95+
<IconClose />
96+
</div>
97+
</div>
98+
<hr />
99+
100+
<AwardModal
101+
modalData={modalData}
102+
/>
103+
</div>
104+
</Modal>
105+
)
106+
}
107+
</div>
108+
);
109+
};
110+
111+
ProfileBadges.defaultProps = {
112+
badges: {},
113+
};
114+
115+
ProfileBadges.propTypes = {
116+
badges: PT.shape(),
117+
handleParam: PT.string.isRequired,
118+
};
119+
120+
export default ProfileBadges;
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
/* stylelint-disable no-descending-specificity */
2+
@import "~styles/mixins";
3+
4+
.outer-container {
5+
width: 100%;
6+
max-width: $screen-max;
7+
margin: 0 auto;
8+
display: flex;
9+
flex-direction: column;
10+
11+
@include xs-to-md {
12+
margin: 0 32px;
13+
}
14+
15+
.memberPageBackLink {
16+
text-transform: uppercase;
17+
color: $listing-checkbox-green;
18+
font-weight: 700;
19+
font-family: Roboto, sans-serif;
20+
margin: 32px 0;
21+
display: flex;
22+
align-items: center;
23+
24+
svg {
25+
margin-right: 6px;
26+
}
27+
}
28+
29+
.badgesWrap {
30+
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.2);
31+
border-radius: 8px;
32+
display: flex;
33+
flex-direction: column;
34+
padding: 32px;
35+
margin-bottom: 32px;
36+
37+
.seactionTitle {
38+
@include barlow-medium;
39+
40+
font-weight: 600;
41+
color: #2a2a2a;
42+
font-size: 22px;
43+
line-height: 26px;
44+
text-transform: uppercase;
45+
padding-bottom: 24px;
46+
border-bottom: 2px solid #e9e9e9;
47+
}
48+
49+
.badgesGrid {
50+
display: grid;
51+
grid-template-columns: repeat(6, 1fr);
52+
53+
@include xs-to-sm {
54+
grid-template-columns: repeat(2, 1fr);
55+
}
56+
57+
@include md {
58+
grid-template-columns: repeat(4, 1fr);
59+
}
60+
61+
.awardBadge {
62+
display: flex;
63+
flex-direction: column;
64+
align-items: center;
65+
justify-content: center;
66+
cursor: pointer;
67+
padding-top: 32px;
68+
69+
.image {
70+
width: 100px;
71+
height: 100px;
72+
}
73+
74+
.title {
75+
@include roboto-bold;
76+
$color: $tco-black;
77+
78+
font-size: 12px;
79+
font-weight: 700;
80+
line-height: 16px;
81+
display: flex;
82+
flex-direction: column;
83+
justify-content: center;
84+
text-align: center;
85+
align-items: center;
86+
max-width: 130px;
87+
margin-top: 17px;
88+
text-transform: uppercase;
89+
90+
@include xs-to-sm {
91+
max-width: unset;
92+
}
93+
}
94+
}
95+
}
96+
}
97+
}
98+
99+
.award-modal {
100+
padding-bottom: 10px;
101+
border-radius: 8px;
102+
margin: 25px 32px 32px;
103+
104+
.header {
105+
display: flex;
106+
justify-content: space-between;
107+
margin-bottom: 25px;
108+
109+
.title {
110+
@include barlow-medium;
111+
112+
font-weight: 600;
113+
color: #2a2a2a;
114+
font-size: 22px;
115+
line-height: 26px;
116+
text-transform: uppercase;
117+
}
118+
119+
.icon {
120+
cursor: pointer;
121+
margin-top: 5px;
122+
}
123+
}
124+
}
125+
126+
hr {
127+
opacity: 0.5;
128+
}
129+
130+
.container {
131+
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.2);
132+
border-radius: 8px;
133+
min-width: 600px;
134+
135+
@include xs-to-sm {
136+
width: 90%;
137+
min-width: unset;
138+
}
139+
}
140+
141+
.overlay {
142+
background-color: #0c0c0c;
143+
opacity: 0.85;
144+
}

src/shared/components/ProfilePage/Awards/AwardBadge/index.jsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const AwardBadge = ({
1717
}
1818
<div styleName="title">
1919
<span>
20+
{/* eslint-disable-next-line react/no-danger */}
2021
<div dangerouslySetInnerHTML={{ __html: title }} />
2122
</span>
2223
</div>

src/shared/components/ProfilePage/Awards/AwardBadge/styles.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
border-radius: 8px;
77
display: flex;
88
cursor: pointer;
9+
min-width: 316px;
910

1011
.image {
1112
width: 48px;

0 commit comments

Comments
 (0)