|
| 1 | +import React, { useCallback } from 'react'; |
| 2 | +import { useDispatch } from 'react-redux'; |
| 3 | +import { useIntl } from '@edx/frontend-platform/i18n'; |
| 4 | +import PropTypes from 'prop-types'; |
| 5 | +import { Icon } from '@edx/paragon'; |
| 6 | +import { Link } from 'react-router-dom'; |
| 7 | +import * as timeago from 'timeago.js'; |
| 8 | +import { getIconByType } from './utils'; |
| 9 | +import { markNotificationsAsRead } from './data/thunks'; |
| 10 | +import messages from './messages'; |
| 11 | +import timeLocale from '../common/time-locale'; |
| 12 | + |
| 13 | +const NotificationRowItem = ({ |
| 14 | + id, type, contentUrl, content, courseName, createdAt, lastRead, |
| 15 | +}) => { |
| 16 | + timeago.register('time-locale', timeLocale); |
| 17 | + const intl = useIntl(); |
| 18 | + const dispatch = useDispatch(); |
| 19 | + |
| 20 | + const handleMarkAsRead = useCallback(() => { |
| 21 | + dispatch(markNotificationsAsRead(id)); |
| 22 | + }, [dispatch, id]); |
| 23 | + |
| 24 | + const { icon: iconComponent, class: iconClass } = getIconByType(type); |
| 25 | + |
| 26 | + return ( |
| 27 | + <Link |
| 28 | + target="_blank" |
| 29 | + className="d-flex mb-2 align-items-center text-decoration-none" |
| 30 | + to={contentUrl} |
| 31 | + onClick={handleMarkAsRead} |
| 32 | + > |
| 33 | + <Icon src={iconComponent} className={`${iconClass} mr-4 notification-icon`} /> |
| 34 | + <div className="d-flex w-100"> |
| 35 | + <div className="d-flex align-items-center w-100"> |
| 36 | + <div className="py-10px w-100 px-0 cursor-pointer"> |
| 37 | + <span |
| 38 | + className="line-height-24 text-gray-700 mb-2 notification-item-content overflow-hidden content" |
| 39 | + // eslint-disable-next-line react/no-danger |
| 40 | + dangerouslySetInnerHTML={{ __html: content }} |
| 41 | + /> |
| 42 | + <div className="py-0 d-flex"> |
| 43 | + <span className="font-size-12 text-gray-500 line-height-20"> |
| 44 | + <span>{courseName}</span> |
| 45 | + <span className="text-light-700 px-1.5">{intl.formatMessage(messages.fullStop)}</span> |
| 46 | + <span>{timeago.format(createdAt, 'time-locale')}</span> |
| 47 | + </span> |
| 48 | + </div> |
| 49 | + </div> |
| 50 | + {!lastRead && ( |
| 51 | + <div className="d-flex py-1.5 px-1.5 ml-2 cursor-pointer"> |
| 52 | + <span className="bg-brand-500 rounded unread" /> |
| 53 | + </div> |
| 54 | + )} |
| 55 | + </div> |
| 56 | + </div> |
| 57 | + </Link> |
| 58 | + ); |
| 59 | +}; |
| 60 | + |
| 61 | +NotificationRowItem.propTypes = { |
| 62 | + id: PropTypes.string.isRequired, |
| 63 | + type: PropTypes.string.isRequired, |
| 64 | + contentUrl: PropTypes.string.isRequired, |
| 65 | + content: PropTypes.node.isRequired, |
| 66 | + courseName: PropTypes.string.isRequired, |
| 67 | + createdAt: PropTypes.string.isRequired, |
| 68 | + lastRead: PropTypes.string.isRequired, |
| 69 | +}; |
| 70 | + |
| 71 | +export default React.memo(NotificationRowItem); |
0 commit comments