175 lines
5.7 KiB
TypeScript
175 lines
5.7 KiB
TypeScript
import React, {useState} from 'react';
|
|
|
|
import {FormattedMessage, useIntl} from 'react-intl';
|
|
|
|
import Client4 from 'mattermost-redux/client/client4';
|
|
|
|
import {UserBadge} from '../../types/badges';
|
|
import BadgeImage from '../badge_image/badge_image';
|
|
import {markdown} from 'utils/markdown';
|
|
import Client from '../../client/api';
|
|
import ConfirmDialog from '../confirm_dialog/confirm_dialog';
|
|
|
|
import './user_badge_row.scss';
|
|
|
|
type Props = {
|
|
badge: UserBadge;
|
|
isCurrentUser: boolean;
|
|
currentUserID: string;
|
|
onClick: (badge: UserBadge) => void;
|
|
onRevoke?: (badge: UserBadge) => void;
|
|
}
|
|
|
|
const UserBadgeRow: React.FC<Props> = ({badge, onClick, isCurrentUser, currentUserID, onRevoke}: Props) => {
|
|
const intl = useIntl();
|
|
const time = new Date(badge.time);
|
|
const [confirmingRevoke, setConfirmingRevoke] = useState(false);
|
|
|
|
const canRevoke = badge.granted_by === currentUserID;
|
|
|
|
const handleRevoke = async () => {
|
|
try {
|
|
const client = new Client();
|
|
await client.revokeOwnership({
|
|
badge_id: String(badge.id),
|
|
user_id: badge.user,
|
|
time: String(badge.time),
|
|
});
|
|
onRevoke?.(badge);
|
|
} catch {
|
|
// ignore
|
|
} finally {
|
|
setConfirmingRevoke(false);
|
|
}
|
|
};
|
|
|
|
let reason = null;
|
|
if (badge.reason) {
|
|
reason = (
|
|
<div className='user-badge-reason'>
|
|
<FormattedMessage
|
|
id='badges.label.reason'
|
|
defaultMessage='Причина: {reason}'
|
|
values={{reason: badge.reason}}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|
|
let setStatus = null;
|
|
if (isCurrentUser && badge.image_type === 'emoji') {
|
|
setStatus = (
|
|
<div className='user-badge-set-status'>
|
|
<a
|
|
onClick={(e) => {
|
|
e.stopPropagation();
|
|
const c = new Client4();
|
|
c.updateCustomStatus({emoji: badge.image, text: badge.name});
|
|
}}
|
|
>
|
|
<FormattedMessage
|
|
id='badges.set_status'
|
|
defaultMessage='Установить как статус'
|
|
/>
|
|
</a>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
let revokeAction = null;
|
|
if (canRevoke && onRevoke) {
|
|
revokeAction = (
|
|
<div className='user-badge-revoke'>
|
|
<a
|
|
onClick={(e) => {
|
|
e.stopPropagation();
|
|
setConfirmingRevoke(true);
|
|
}}
|
|
>
|
|
<FormattedMessage
|
|
id='badges.revoke.btn'
|
|
defaultMessage='Снять достижение'
|
|
/>
|
|
</a>
|
|
</div>
|
|
);
|
|
if (confirmingRevoke) {
|
|
revokeAction = (
|
|
<>
|
|
{revokeAction}
|
|
<ConfirmDialog
|
|
onConfirm={handleRevoke}
|
|
onCancel={() => setConfirmingRevoke(false)}
|
|
>
|
|
<FormattedMessage
|
|
id='badges.revoke.confirm'
|
|
defaultMessage='Снять достижение?'
|
|
/>
|
|
</ConfirmDialog>
|
|
</>
|
|
);
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div
|
|
className='UserBadgesRow'
|
|
onClick={() => onClick(badge)}
|
|
>
|
|
<span className='user-badge-icon'>
|
|
<BadgeImage
|
|
badge={badge}
|
|
size={36}
|
|
/>
|
|
</span>
|
|
<div className='user-badge-text'>
|
|
<div className='user-badge-name'>
|
|
<span className='user-badge-label'>
|
|
<FormattedMessage
|
|
id='badges.label.name'
|
|
defaultMessage='Название:'
|
|
/>
|
|
</span>
|
|
{' '}
|
|
{badge.name}
|
|
</div>
|
|
<div className='user-badge-description'>
|
|
<span className='user-badge-label'>
|
|
<FormattedMessage
|
|
id='badges.label.description'
|
|
defaultMessage='Описание:'
|
|
/>
|
|
</span>
|
|
{' '}
|
|
{badge.description ? markdown(badge.description) : '—'}
|
|
</div>
|
|
<div className='user-badge-meta'>
|
|
<FormattedMessage
|
|
id='badges.label.type'
|
|
defaultMessage='Тип: {typeName}'
|
|
values={{typeName: badge.type_name}}
|
|
/>
|
|
</div>
|
|
<div className='user-badge-meta'>
|
|
<FormattedMessage
|
|
id='badges.label.granted_by'
|
|
defaultMessage='Выдал: {username}'
|
|
values={{username: badge.granted_by_name}}
|
|
/>
|
|
</div>
|
|
<div className='user-badge-meta'>
|
|
<FormattedMessage
|
|
id='badges.label.granted_at'
|
|
defaultMessage='Выдан: {date}'
|
|
values={{date: intl.formatDate(time, {day: '2-digit', month: '2-digit', year: 'numeric'})}}
|
|
/>
|
|
</div>
|
|
{reason}
|
|
{setStatus}
|
|
{revokeAction}
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default UserBadgeRow;
|