style: post summary card design updates
This commit is contained in:
@@ -47,7 +47,7 @@ export default function DiscussionSidebar({ displaySidebar, postActionBarRef })
|
||||
ref={sidebarRef}
|
||||
className={classNames('flex-column position-sticky', {
|
||||
'd-none': !displaySidebar,
|
||||
'd-flex overflow-auto': displaySidebar,
|
||||
'd-flex overflow-auto box-shadow-centered-1': displaySidebar,
|
||||
'w-100': !isOnDesktop,
|
||||
'sidebar-desktop-width': isOnDesktop && !isOnXLDesktop,
|
||||
'w-25 sidebar-XL-width': isOnXLDesktop,
|
||||
|
||||
@@ -15,8 +15,8 @@ import AuthorLabel from '../../common/AuthorLabel';
|
||||
import { DiscussionContext } from '../../common/context';
|
||||
import { discussionsPath, isPostPreviewAvailable } from '../../utils';
|
||||
import messages from './messages';
|
||||
import PostFooter from './PostFooter';
|
||||
import { PostAvatar } from './PostHeader';
|
||||
import PostSummaryFooter from './PostSummaryFooter';
|
||||
import { postShape } from './proptypes';
|
||||
|
||||
function PostLink({
|
||||
@@ -56,20 +56,17 @@ function PostLink({
|
||||
}
|
||||
to={linkUrl}
|
||||
onClick={() => isSelected(post.id)}
|
||||
style={{ lineHeight: '22px' }}
|
||||
aria-current={isSelected(post.id) ? 'page' : undefined}
|
||||
role="option"
|
||||
tabIndex={(isSelected(post.id) || idx === 0) ? 0 : -1}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
classNames('d-flex flex-row pt-2.5 pb-2 px-4 border-primary-500 position-relative',
|
||||
{ 'bg-light-300': read })
|
||||
classNames('d-flex flex-row pt-2 pb-2 px-4 border-primary-500 position-relative',
|
||||
{ 'bg-light-300': read },
|
||||
{ 'post-summary-card-selected': post.id === postId })
|
||||
}
|
||||
style={post.id === postId ? {
|
||||
borderRightWidth: '4px',
|
||||
borderRightStyle: 'solid',
|
||||
} : null}
|
||||
style={{ height: '87px' }}
|
||||
>
|
||||
<PostAvatar post={post} authorLabel={post.authorLabel} fromPostLink read={read} />
|
||||
<div className="d-flex flex-column flex-fill" style={{ minWidth: 0 }}>
|
||||
@@ -100,20 +97,20 @@ function PostLink({
|
||||
)}
|
||||
|
||||
{canSeeReportedBadge && (
|
||||
<Badge
|
||||
variant="danger"
|
||||
data-testid="reported-post"
|
||||
className={`font-weight-500 badge-padding ${showAnsweredBadge ? 'ml-2' : 'ml-auto'}`}
|
||||
>
|
||||
{intl.formatMessage(messages.contentReported)}
|
||||
<span className="sr-only">{' '}reported</span>
|
||||
</Badge>
|
||||
<Badge
|
||||
variant="danger"
|
||||
data-testid="reported-post"
|
||||
className={`font-weight-500 badge-padding ${showAnsweredBadge ? 'ml-2' : 'ml-auto'}`}
|
||||
>
|
||||
{intl.formatMessage(messages.contentReported)}
|
||||
<span className="sr-only">{' '}reported</span>
|
||||
</Badge>
|
||||
)}
|
||||
|
||||
{post.pinned && (
|
||||
<Icon
|
||||
src={PushPin}
|
||||
className={`icon-size ${canSeeReportedBadge || showAnsweredBadge ? 'ml-2' : 'ml-auto'}`}
|
||||
className={`post-summary-icons-dimensions text-gray-700 ${canSeeReportedBadge || showAnsweredBadge ? 'ml-2' : 'ml-auto'}`}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
@@ -123,7 +120,7 @@ function PostLink({
|
||||
authorLabel={post.authorLabel}
|
||||
labelColor={authorLabelColor && `text-${authorLabelColor}`}
|
||||
/>
|
||||
<PostFooter post={post} preview intl={intl} showNewCountLabel={read} />
|
||||
<PostSummaryFooter post={post} preview showNewCountLabel={read} />
|
||||
</div>
|
||||
</div>
|
||||
{!showDivider && post.pinned && <div className="pt-1 bg-light-500 border-top border-light-700" />}
|
||||
|
||||
147
src/discussions/posts/post/PostSummaryFooter.jsx
Normal file
147
src/discussions/posts/post/PostSummaryFooter.jsx
Normal file
@@ -0,0 +1,147 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { useSelector } from 'react-redux';
|
||||
import * as timeago from 'timeago.js';
|
||||
|
||||
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
|
||||
import {
|
||||
Badge, Icon, OverlayTrigger, Tooltip,
|
||||
} from '@edx/paragon';
|
||||
import {
|
||||
Locked,
|
||||
} from '@edx/paragon/icons';
|
||||
|
||||
import {
|
||||
People,
|
||||
QuestionAnswer,
|
||||
QuestionAnswerOutline,
|
||||
StarFilled,
|
||||
StarOutline, ThumbUpFilled, ThumbUpOutline,
|
||||
} from '../../../components/icons';
|
||||
import timeLocale from '../../common/time-locale';
|
||||
import { selectUserHasModerationPrivileges } from '../../data/selectors';
|
||||
import messages from './messages';
|
||||
import { postShape } from './proptypes';
|
||||
|
||||
function PostSummaryFooter({
|
||||
post,
|
||||
intl,
|
||||
preview,
|
||||
showNewCountLabel,
|
||||
}) {
|
||||
const userHasModerationPrivileges = useSelector(selectUserHasModerationPrivileges);
|
||||
timeago.register('time-locale', timeLocale);
|
||||
|
||||
return (
|
||||
<div className="d-flex align-items-center text-gray-700" style={{ lineHeight: '20px' }}>
|
||||
<div className="d-flex align-items-center mr-4.5">
|
||||
<OverlayTrigger
|
||||
overlay={(
|
||||
<Tooltip id={`liked-${post.id}-tooltip`}>
|
||||
{intl.formatMessage(post.voted ? messages.removeLike : messages.like)}
|
||||
</Tooltip>
|
||||
)}
|
||||
>
|
||||
<Icon src={post.voted ? ThumbUpFilled : ThumbUpOutline} className="post-summary-icons-dimensions mr-0.5">
|
||||
<span className="sr-only">{' '}{intl.formatMessage(post.voted ? messages.removeLike : messages.like)}</span>
|
||||
</Icon>
|
||||
</OverlayTrigger>
|
||||
<div className="font-family-inter font-style-normal">
|
||||
{(post.voteCount && post.voteCount > 0) ? post.voteCount : null}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<OverlayTrigger
|
||||
overlay={(
|
||||
<Tooltip id={`follow-${post.id}-tooltip`}>
|
||||
{intl.formatMessage(post.following ? messages.unFollow : messages.follow)}
|
||||
</Tooltip>
|
||||
)}
|
||||
>
|
||||
<Icon src={post.following ? StarFilled : StarOutline} className="post-summary-icons-dimensions mr-0.5">
|
||||
<span className="sr-only">{' '}{ intl.formatMessage(post.following ? messages.srOnlyFollowDescription : messages.srOnlyUnFollowDescription)}</span>
|
||||
</Icon>
|
||||
</OverlayTrigger>
|
||||
|
||||
{preview && post.commentCount > 1 && (
|
||||
<div className="d-flex align-items-center ml-4.5">
|
||||
<OverlayTrigger
|
||||
overlay={(
|
||||
<Tooltip id={`follow-${post.id}-tooltip`}>
|
||||
{intl.formatMessage(messages.viewActivity)}
|
||||
</Tooltip>
|
||||
)}
|
||||
>
|
||||
<Icon src={post.unreadCommentCount ? QuestionAnswer : QuestionAnswerOutline} className="post-summary-icons-dimensions mr-0.5">
|
||||
<span className="sr-only">{' '} {intl.formatMessage(messages.viewActivity)}</span>
|
||||
</Icon>
|
||||
</OverlayTrigger>
|
||||
{post.commentCount}
|
||||
</div>
|
||||
)}
|
||||
{showNewCountLabel && preview && post?.unreadCommentCount > 0 && post.commentCount > 1 && (
|
||||
<Badge variant="light" className="ml-2">
|
||||
{intl.formatMessage(messages.newLabel, { count: post.unreadCommentCount })}
|
||||
</Badge>
|
||||
)}
|
||||
<div className="d-flex flex-fill justify-content-end align-items-center">
|
||||
{post.groupId && userHasModerationPrivileges && (
|
||||
<>
|
||||
<OverlayTrigger
|
||||
overlay={(
|
||||
<Tooltip id={`visibility-${post.id}-tooltip`}>{post.groupName}</Tooltip>
|
||||
)}
|
||||
>
|
||||
<span data-testid="cohort-icon" className="post-summary-icons-dimensions">
|
||||
<People />
|
||||
</span>
|
||||
</OverlayTrigger>
|
||||
<span
|
||||
className="text-gray-700 mx-1.5 font-weight-500"
|
||||
style={{ fontSize: '16px' }}
|
||||
>
|
||||
·
|
||||
</span>
|
||||
</>
|
||||
)}
|
||||
<span title={post.createdAt} className="text-gray-700 post-summary-timestamp">
|
||||
{timeago.format(post.createdAt, 'time-locale')}
|
||||
</span>
|
||||
{!preview && post.closed
|
||||
&& (
|
||||
<OverlayTrigger
|
||||
overlay={(
|
||||
<Tooltip id={`closed-${post.id}-tooltip`}>
|
||||
{intl.formatMessage(messages.postClosed)}
|
||||
</Tooltip>
|
||||
)}
|
||||
>
|
||||
<Icon
|
||||
src={Locked}
|
||||
style={{
|
||||
width: '1rem',
|
||||
height: '1rem',
|
||||
}}
|
||||
className="ml-3 post-summary-icons-dimensions"
|
||||
/>
|
||||
</OverlayTrigger>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
PostSummaryFooter.propTypes = {
|
||||
intl: intlShape.isRequired,
|
||||
post: postShape.isRequired,
|
||||
preview: PropTypes.bool,
|
||||
showNewCountLabel: PropTypes.bool,
|
||||
};
|
||||
|
||||
PostSummaryFooter.defaultProps = {
|
||||
preview: false,
|
||||
showNewCountLabel: false,
|
||||
};
|
||||
|
||||
export default injectIntl(PostSummaryFooter);
|
||||
@@ -131,6 +131,16 @@ const messages = defineMessages({
|
||||
defaultMessage: 'No preview available',
|
||||
description: 'No preview available',
|
||||
},
|
||||
srOnlyFollowDescription: {
|
||||
id: 'discussions.post.follow.description',
|
||||
defaultMessage: 'you are following this post',
|
||||
description: 'tell screen readers if user is following a post',
|
||||
},
|
||||
srOnlyUnFollowDescription: {
|
||||
id: 'discussions.post.unfollow.description',
|
||||
defaultMessage: 'you are not following this post',
|
||||
description: 'tell screen readers if user is not following a post',
|
||||
},
|
||||
});
|
||||
|
||||
export default messages;
|
||||
|
||||
@@ -62,6 +62,21 @@ $fa-font-path: "~font-awesome/fonts";
|
||||
width: 20px !important;
|
||||
}
|
||||
|
||||
.post-summary-icons-dimensions {
|
||||
height: 16px !important;
|
||||
width: 16px !important;
|
||||
}
|
||||
|
||||
.post-summary-timestamp {
|
||||
font-size: 12px !important;
|
||||
line-height: 20px !important;
|
||||
}
|
||||
|
||||
.post-summary-card-selected {
|
||||
border-right-width: 4px;
|
||||
border-right-style: solid;
|
||||
}
|
||||
|
||||
.mr-0\.5 {
|
||||
margin-right: 2px;
|
||||
}
|
||||
@@ -133,7 +148,7 @@ header {
|
||||
}
|
||||
|
||||
.sidebar-desktop-width {
|
||||
min-width: 25rem;
|
||||
min-width: 29rem;
|
||||
}
|
||||
|
||||
.sidebar-XL-width {
|
||||
@@ -264,3 +279,7 @@ header {
|
||||
z-index: 0 !important;
|
||||
}
|
||||
|
||||
.badge {
|
||||
padding: 1px 5px !important;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user