Admin Reports: restyle with Tailwind
This commit is contained in:
parent
c483a60ef1
commit
5ef9a93371
5 changed files with 68 additions and 198 deletions
|
@ -51,7 +51,7 @@ const families = {
|
|||
};
|
||||
|
||||
export type Sizes = keyof typeof sizes
|
||||
type Tags = 'abbr' | 'p' | 'span' | 'pre' | 'time' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'label'
|
||||
type Tags = 'abbr' | 'p' | 'span' | 'pre' | 'time' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'label' | 'blockquote'
|
||||
type Directions = 'ltr' | 'rtl'
|
||||
|
||||
interface IText extends Pick<React.HTMLAttributes<HTMLParagraphElement>, 'dangerouslySetInnerHTML' | 'tabIndex' | 'lang'> {
|
||||
|
|
|
@ -1,16 +1,14 @@
|
|||
import noop from 'lodash/noop';
|
||||
import React from 'react';
|
||||
import { useIntl, defineMessages } from 'react-intl';
|
||||
|
||||
import { openModal } from 'soapbox/actions/modals';
|
||||
import { deleteStatusModal } from 'soapbox/actions/moderation';
|
||||
import StatusContent from 'soapbox/components/status-content';
|
||||
import StatusMedia from 'soapbox/components/status-media';
|
||||
import { HStack, Stack } from 'soapbox/components/ui';
|
||||
import DropdownMenu from 'soapbox/containers/dropdown-menu-container';
|
||||
import Bundle from 'soapbox/features/ui/components/bundle';
|
||||
import { MediaGallery, Video, Audio } from 'soapbox/features/ui/util/async-components';
|
||||
import { useAppDispatch } from 'soapbox/hooks';
|
||||
|
||||
import type { AdminReport, Attachment, Status } from 'soapbox/types/entities';
|
||||
import type { AdminReport, Status } from 'soapbox/types/entities';
|
||||
|
||||
const messages = defineMessages({
|
||||
viewStatus: { id: 'admin.reports.actions.view_status', defaultMessage: 'View post' },
|
||||
|
@ -26,10 +24,6 @@ const ReportStatus: React.FC<IReportStatus> = ({ status }) => {
|
|||
const intl = useIntl();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const handleOpenMedia = (media: Attachment, index: number) => {
|
||||
dispatch(openModal('MEDIA', { media, status, index }));
|
||||
};
|
||||
|
||||
const handleDeleteStatus = () => {
|
||||
dispatch(deleteStatusModal(intl, status.id));
|
||||
};
|
||||
|
@ -49,84 +43,20 @@ const ReportStatus: React.FC<IReportStatus> = ({ status }) => {
|
|||
}];
|
||||
};
|
||||
|
||||
const getMedia = () => {
|
||||
const firstAttachment = status.media_attachments.get(0);
|
||||
|
||||
if (firstAttachment) {
|
||||
if (status.media_attachments.some(item => item.type === 'unknown')) {
|
||||
// Do nothing
|
||||
} else if (firstAttachment.type === 'video') {
|
||||
const video = firstAttachment;
|
||||
|
||||
return (
|
||||
<Bundle fetchComponent={Video} >
|
||||
{(Component: any) => (
|
||||
<Component
|
||||
preview={video.preview_url}
|
||||
blurhash={video.blurhash}
|
||||
src={video.url}
|
||||
alt={video.description}
|
||||
aspectRatio={video.meta.getIn(['original', 'aspect'])}
|
||||
width={239}
|
||||
height={110}
|
||||
inline
|
||||
sensitive={status.sensitive}
|
||||
onOpenVideo={noop}
|
||||
/>
|
||||
)}
|
||||
</Bundle>
|
||||
);
|
||||
} else if (firstAttachment.type === 'audio') {
|
||||
const audio = firstAttachment;
|
||||
|
||||
return (
|
||||
<Bundle fetchComponent={Audio}>
|
||||
{(Component: any) => (
|
||||
<Component
|
||||
src={audio.url}
|
||||
alt={audio.description}
|
||||
inline
|
||||
sensitive={status.sensitive}
|
||||
onOpenAudio={noop}
|
||||
/>
|
||||
)}
|
||||
</Bundle>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<Bundle fetchComponent={MediaGallery}>
|
||||
{(Component: any) => (
|
||||
<Component
|
||||
media={status.media_attachments}
|
||||
sensitive={status.sensitive}
|
||||
height={110}
|
||||
onOpenMedia={handleOpenMedia}
|
||||
/>
|
||||
)}
|
||||
</Bundle>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const media = getMedia();
|
||||
const menu = makeMenu();
|
||||
|
||||
return (
|
||||
<div className='admin-report__status'>
|
||||
<div className='admin-report__status-content'>
|
||||
<HStack space={2} alignItems='start'>
|
||||
<Stack space={2} grow>
|
||||
<StatusContent status={status} />
|
||||
{media}
|
||||
</div>
|
||||
<div className='admin-report__status-actions'>
|
||||
<DropdownMenu
|
||||
items={menu}
|
||||
src={require('@tabler/icons/dots-vertical.svg')}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<StatusMedia status={status} />
|
||||
</Stack>
|
||||
|
||||
<DropdownMenu
|
||||
items={menu}
|
||||
src={require('@tabler/icons/dots-vertical.svg')}
|
||||
/>
|
||||
</HStack>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import { deactivateUserModal, deleteUserModal } from 'soapbox/actions/moderation
|
|||
import snackbar from 'soapbox/actions/snackbar';
|
||||
import Avatar from 'soapbox/components/avatar';
|
||||
import HoverRefWrapper from 'soapbox/components/hover-ref-wrapper';
|
||||
import { Accordion, Button, HStack } from 'soapbox/components/ui';
|
||||
import { Accordion, Button, Stack, HStack, Text } from 'soapbox/components/ui';
|
||||
import DropdownMenu from 'soapbox/containers/dropdown-menu-container';
|
||||
import { useAppDispatch, useAppSelector } from 'soapbox/hooks';
|
||||
import { makeGetReport } from 'soapbox/selectors';
|
||||
|
@ -82,49 +82,68 @@ const Report: React.FC<IReport> = ({ id }) => {
|
|||
const reporterAcct = account.acct as string;
|
||||
|
||||
return (
|
||||
<div className='admin-report' key={report.id}>
|
||||
<div className='admin-report__avatar'>
|
||||
<HoverRefWrapper accountId={targetAccount.id as string} inline>
|
||||
<Link to={`/@${acct}`} title={acct}>
|
||||
<Avatar account={targetAccount} size={32} />
|
||||
</Link>
|
||||
</HoverRefWrapper>
|
||||
</div>
|
||||
<div className='admin-report__content'>
|
||||
<h4 className='admin-report__title'>
|
||||
<HStack space={3} className='p-3' key={report.id}>
|
||||
<HoverRefWrapper accountId={targetAccount.id} inline>
|
||||
<Link to={`/@${acct}`} title={acct}>
|
||||
<Avatar account={targetAccount} size={32} />
|
||||
</Link>
|
||||
</HoverRefWrapper>
|
||||
|
||||
<Stack space={3} grow>
|
||||
<Text tag='h4' weight='bold' truncate>
|
||||
<FormattedMessage
|
||||
id='admin.reports.report_title'
|
||||
defaultMessage='Report on {acct}'
|
||||
values={{ acct: (
|
||||
<HoverRefWrapper accountId={account.id as string} inline>
|
||||
<HoverRefWrapper accountId={account.id} inline>
|
||||
<Link to={`/@${acct}`} title={acct}>@{acct}</Link>
|
||||
</HoverRefWrapper>
|
||||
) }}
|
||||
/>
|
||||
</h4>
|
||||
<div className='admin-report__statuses'>
|
||||
{statusCount > 0 && (
|
||||
<Accordion
|
||||
headline={`Reported posts (${statusCount})`}
|
||||
expanded={accordionExpanded}
|
||||
onToggle={handleAccordionToggle}
|
||||
>
|
||||
{statuses.map(status => <ReportStatus report={report} status={status} key={status.id} />)}
|
||||
</Accordion>
|
||||
)}
|
||||
</div>
|
||||
<div className='admin-report__quote'>
|
||||
</Text>
|
||||
|
||||
{statusCount > 0 && (
|
||||
<Accordion
|
||||
headline={`Reported posts (${statusCount})`}
|
||||
expanded={accordionExpanded}
|
||||
onToggle={handleAccordionToggle}
|
||||
>
|
||||
<Stack space={4}>
|
||||
{statuses.map(status => (
|
||||
<ReportStatus
|
||||
key={status.id}
|
||||
report={report}
|
||||
status={status}
|
||||
/>
|
||||
))}
|
||||
</Stack>
|
||||
</Accordion>
|
||||
)}
|
||||
|
||||
<Stack>
|
||||
{(report.comment || '').length > 0 && (
|
||||
<blockquote className='md' dangerouslySetInnerHTML={{ __html: report.comment }} />
|
||||
<Text
|
||||
tag='blockquote'
|
||||
dangerouslySetInnerHTML={{ __html: report.comment }}
|
||||
/>
|
||||
)}
|
||||
<span className='byline'>
|
||||
—
|
||||
<HoverRefWrapper accountId={account.id as string} inline>
|
||||
<Link to={`/@${reporterAcct}`} title={reporterAcct}>@{reporterAcct}</Link>
|
||||
|
||||
<HStack space={1}>
|
||||
<Text theme='muted' tag='span'>—</Text>
|
||||
|
||||
<HoverRefWrapper accountId={account.id} inline>
|
||||
<Link
|
||||
to={`/@${reporterAcct}`}
|
||||
title={reporterAcct}
|
||||
className='text-primary-600 dark:text-accent-blue hover:underline'
|
||||
>
|
||||
@{reporterAcct}
|
||||
</Link>
|
||||
</HoverRefWrapper>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</HStack>
|
||||
</Stack>
|
||||
</Stack>
|
||||
|
||||
<HStack space={2} alignItems='start'>
|
||||
<Button onClick={handleCloseReport}>
|
||||
<FormattedMessage id='admin.reports.actions.close' defaultMessage='Close' />
|
||||
|
@ -132,7 +151,7 @@ const Report: React.FC<IReport> = ({ id }) => {
|
|||
|
||||
<DropdownMenu items={menu} src={require('@tabler/icons/dots-vertical.svg')} />
|
||||
</HStack>
|
||||
</div>
|
||||
</HStack>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ const Reports: React.FC = () => {
|
|||
showLoading={showLoading}
|
||||
scrollKey='admin-reports'
|
||||
emptyMessage={intl.formatMessage(messages.emptyMessage)}
|
||||
className='divide-y divide-solid divide-gray-200 dark:divide-gray-800'
|
||||
>
|
||||
{reports.map(report => report && <Report id={report} key={report} />)}
|
||||
</ScrollableList>
|
||||
|
|
|
@ -56,86 +56,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.admin-report {
|
||||
padding: 15px;
|
||||
display: flex;
|
||||
border-bottom: 1px solid var(--brand-color--faint);
|
||||
|
||||
&__content {
|
||||
padding: 0 16px;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-weight: bold;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
&__quote {
|
||||
font-size: 14px;
|
||||
|
||||
a {
|
||||
color: var(--brand-color--hicontrast);
|
||||
}
|
||||
|
||||
.byline {
|
||||
font-size: 12px;
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: fit-content;
|
||||
margin-left: auto;
|
||||
|
||||
.icon-button {
|
||||
padding-left: 10px;
|
||||
|
||||
> div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
> .svg-icon {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__status-content {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
&__status {
|
||||
display: flex;
|
||||
border-bottom: 1px solid var(--accent-color--med);
|
||||
padding: 10px 0;
|
||||
|
||||
&:last-child {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.status__content {
|
||||
flex: 1;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&-actions {
|
||||
padding: 3px 10px;
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.logentry {
|
||||
padding: 15px;
|
||||
|
||||
|
|
Loading…
Reference in a new issue