answer/ui/src/pages/Admin/Flags/index.tsx

160 lines
4.8 KiB
TypeScript
Raw Normal View History

2022-09-27 17:59:05 +08:00
import React, { FC } from 'react';
2022-10-09 18:20:19 +08:00
import { Button, Form, Table, Stack } from 'react-bootstrap';
2022-09-27 17:59:05 +08:00
import { useSearchParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import {
FormatTime,
BaseUserCard,
Empty,
Pagination,
2022-10-09 18:20:19 +08:00
QueryGroup,
} from '@/components';
import { useReportModal } from '@/hooks';
import * as Type from '@/common/interface';
2022-10-29 20:43:52 +08:00
import { useFlagSearch } from '@/services';
import { escapeRemove } from '@/utils';
import { pathFactory } from '@/router/pathFactory';
2022-09-27 17:59:05 +08:00
const flagFilterKeys: Type.FlagStatus[] = ['pending', 'completed'];
const flagTypeKeys: Type.FlagType[] = ['all', 'question', 'answer', 'comment'];
const Flags: FC = () => {
const { t } = useTranslation('translation', { keyPrefix: 'admin.flags' });
const [urlSearchParams, setUrlSearchParams] = useSearchParams();
const curFilter = urlSearchParams.get('status') || flagFilterKeys[0];
const curType = urlSearchParams.get('type') || flagTypeKeys[0];
const PAGE_SIZE = 20;
2022-09-27 17:59:05 +08:00
const curPage = Number(urlSearchParams.get('page')) || 1;
2022-09-28 10:06:18 +08:00
const {
data: listData,
isLoading,
mutate: refreshList,
} = useFlagSearch({
page_size: PAGE_SIZE,
2022-09-27 17:59:05 +08:00
page: curPage,
status: curFilter as Type.FlagStatus,
object_type: curType as Type.FlagType,
});
2022-09-28 10:06:18 +08:00
const reportModal = useReportModal(refreshList);
2022-09-27 17:59:05 +08:00
const count = listData?.count || 0;
2022-10-09 18:20:19 +08:00
2022-09-27 17:59:05 +08:00
const onTypeChange = (evt) => {
urlSearchParams.set('type', evt.target.value);
setUrlSearchParams(urlSearchParams);
};
const handleReview = ({ id, object_type }) => {
reportModal.onShow({
id,
type: object_type,
isBackend: true,
action: 'review',
});
};
return (
<>
<h3 className="mb-4">{t('title')}</h3>
<div className="d-flex justify-content-between align-items-center mb-3">
2022-10-09 18:20:19 +08:00
<QueryGroup
data={flagFilterKeys}
currentSort={curFilter}
sortKey="status"
i18nKeyPrefix="admin.flags"
2022-10-09 18:20:19 +08:00
/>
2022-09-27 17:59:05 +08:00
<Form.Select
value={curType}
onChange={onTypeChange}
size="sm"
style={{ width: '12.25rem' }}>
{flagTypeKeys.map((li) => {
return (
<option value={li} key={li}>
{li}
</option>
);
})}
</Form.Select>
</div>
<Table>
<thead>
<tr>
<th>{t('flagged')}</th>
<th style={{ width: '20%' }}>{t('created')}</th>
2022-09-29 10:44:27 +08:00
{curFilter !== 'completed' ? (
<th style={{ width: '20%' }}>{t('action')}</th>
) : null}
2022-09-27 17:59:05 +08:00
</tr>
</thead>
<tbody className="align-middle">
{listData?.list?.map((li) => {
return (
<tr key={li.id}>
<td>
<Stack>
<small className="text-secondary">
Flagged {li.object_type}
</small>
<BaseUserCard data={li.reported_user} className="mt-2" />
<a
href={pathFactory.questionLanding(
li.question_id,
li.title,
)}
2022-09-27 17:59:05 +08:00
target="_blank"
className="text-wrap text-break mt-2"
rel="noreferrer">
{li.title}
</a>
<small className="text-break text-wrap word">
{escapeRemove(li.excerpt)}
2022-09-27 17:59:05 +08:00
</small>
</Stack>
</td>
<td>
<Stack>
<FormatTime
time={li.created_at}
className="fs-14 text-secondary"
/>
<BaseUserCard data={li.report_user} className="mt-2 mb-2" />
2022-10-14 17:12:34 +08:00
{li.flagged_reason ? (
<small>{li.flagged_content}</small>
2022-09-27 17:59:05 +08:00
) : (
<small>
{li.reason?.name}
<br />
<span className="text-secondary">{li.content}</span>
</small>
)}
</Stack>
</td>
2022-09-29 10:44:27 +08:00
{curFilter !== 'completed' ? (
<td>
<Button variant="link" onClick={() => handleReview(li)}>
{t('review')}
</Button>
</td>
) : null}
2022-09-27 17:59:05 +08:00
</tr>
);
})}
</tbody>
</Table>
{Number(count) <= 0 && !isLoading && <Empty />}
<div className="mt-4 mb-2 d-flex justify-content-center">
<Pagination
currentPage={curPage}
totalSize={count}
pageSize={PAGE_SIZE}
2022-09-27 17:59:05 +08:00
/>
</div>
</>
);
};
export default Flags;