Skip to content

Commit e11e1c2

Browse files
#4085 : Notification items clickable
1 parent 2c34da7 commit e11e1c2

File tree

1 file changed

+63
-25
lines changed

1 file changed

+63
-25
lines changed

src/shared/components/Notifications/index.jsx

Lines changed: 63 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
33
import cn from 'classnames';
44
import _ from 'lodash';
55
import moment from 'moment';
6+
import { Link } from 'topcoder-react-utils';
67
import IconArrow from 'assets/images/notifications/arrow.svg';
78
import styles from './style.scss';
89
import TabsPanel from './TabsPanel';
@@ -18,39 +19,68 @@ const eventTypes = {
1819
},
1920
BROADCAST: 'admin.notification.broadcast',
2021
};
22+
23+
// Dynamic element, to select between Link and Div
24+
const ConditionalWrapper = ({
25+
condition, renderLink, renderDiv, children,
26+
}) => (
27+
condition ? renderLink(children) : renderDiv(children)
28+
);
29+
2130
const Item = ({
22-
item, auth, markNotificationAsRead, showPoint,
31+
item, auth, markNotificationAsRead, showPoint, isLink,
2332
}) => (
24-
<div className={styles['noti-item']}>
25-
<div className={styles.left}>
26-
<p className={styles.txt}>{item.contents}</p>
27-
<span className={styles['time-txt']}>{moment(item.date).fromNow()}</span>
28-
</div>
29-
<div className={styles.right}>
30-
{
31-
!item.isRead
32-
&& showPoint
33-
&& (
34-
<div
35-
role="button"
36-
className={cn([styles.point, item.isSeen && styles['point-grey'], !item.isSeen && styles['point-red']])}
37-
onClick={() => {
38-
markNotificationAsRead(item, auth.tokenV3);
39-
}}
40-
onKeyPress={() => {
41-
markNotificationAsRead(item, auth.tokenV3);
42-
}}
43-
tabIndex="0"
44-
/>
45-
)}
46-
</div>
47-
</div>
33+
<ConditionalWrapper
34+
condition={isLink}
35+
renderLink={children => (
36+
<Link
37+
to={`/challenges/${item.sourceId}`}
38+
className={styles['noti-item']}
39+
onClick={() => !item.isRead && markNotificationAsRead(item, auth.tokenV3)}
40+
>
41+
{children}
42+
</Link>
43+
)}
44+
renderDiv={children => (
45+
<div className={styles['noti-item']}>
46+
{children}
47+
</div>
48+
)}
49+
>
50+
<Fragment>
51+
<div className={styles.left}>
52+
<p className={styles.txt}>{item.contents}</p>
53+
<span className={styles['time-txt']}>{moment(item.date).fromNow()}</span>
54+
</div>
55+
<div className={styles.right}>
56+
{
57+
!item.isRead
58+
&& showPoint
59+
&& (
60+
<div
61+
role="button"
62+
className={cn([styles.point, item.isSeen && styles['point-grey'], !item.isSeen && styles['point-red']])}
63+
onClick={() => {
64+
if (!isLink) {
65+
markNotificationAsRead(item, auth.tokenV3);
66+
}
67+
}}
68+
onKeyPress={() => {
69+
markNotificationAsRead(item, auth.tokenV3);
70+
}}
71+
tabIndex="0"
72+
/>
73+
)}
74+
</div>
75+
</Fragment>
76+
</ConditionalWrapper>
4877
);
4978
Item.propTypes = {
5079
item: PropTypes.shape().isRequired,
5180
auth: PropTypes.shape().isRequired,
5281
markNotificationAsRead: PropTypes.func.isRequired,
5382
showPoint: PropTypes.bool.isRequired,
83+
isLink: PropTypes.bool.isRequired,
5484
};
5585

5686
const challenges = (listReceived) => {
@@ -102,6 +132,13 @@ export default class NotificationList extends React.Component {
102132
this.setState({ collapsedChallenges: collapsed });
103133
}
104134

135+
isLink = (item) => {
136+
const ret = (eventTypes.PROJECT.ACTIVE.includes(item.eventType)
137+
|| eventTypes.PROJECT.COMPLETED.includes(item.eventType))
138+
&& item.sourceId;
139+
return ret;
140+
}
141+
105142
render() {
106143
const {
107144
auth, notifications, loadNotifications, markNotificationAsRead,
@@ -180,6 +217,7 @@ export default class NotificationList extends React.Component {
180217
markNotificationAsRead={markNotificationAsRead}
181218
key={`noti-item-${item.id}`}
182219
showPoint={activeTab !== 'completed'}
220+
isLink={this.isLink(item)}
183221
/>
184222
))}
185223
</Fragment>

0 commit comments

Comments
 (0)