291 lines
7.9 KiB
TypeScript
291 lines
7.9 KiB
TypeScript
![]() |
import { DownloadOutlined } from '@ant-design/icons';
|
||
|
import { t } from '@lingui/macro';
|
||
|
import { Button, Space, Table, TableColumnsType, Tooltip } from 'antd';
|
||
|
import { SbtPageHeader } from 'components/page-header';
|
||
|
import { Dayjs } from 'dayjs';
|
||
|
import { ReportDetailList, ReportItemDetail } from 'models';
|
||
|
import { useReportDetailList } from 'queries/report';
|
||
|
import { useState } from 'react';
|
||
|
import { useParams } from 'react-router-dom';
|
||
|
import styled from 'styled-components';
|
||
|
|
||
|
export interface ReportFormValues {
|
||
|
dateRange: [Dayjs, Dayjs];
|
||
|
includeTest: string;
|
||
|
}
|
||
|
|
||
|
const ReportContainer = styled.div`
|
||
|
margin-bottom: 16px;
|
||
|
`;
|
||
|
|
||
|
const CustomSpace = styled(Space)`
|
||
|
&.sbt-space {
|
||
|
/* Add your custom styles here */
|
||
|
}
|
||
|
`;
|
||
|
|
||
|
const ReportInformationContainer = styled.div`
|
||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
||
|
padding: 16px;
|
||
|
border-radius: 10px;
|
||
|
width: 100%;
|
||
|
height: 400px;
|
||
|
`;
|
||
|
|
||
|
const columns: TableColumnsType<ReportItemDetail> = [
|
||
|
{
|
||
|
title: 'Request ID',
|
||
|
dataIndex: 'Request ID',
|
||
|
key: 'Request ID',
|
||
|
width: 100,
|
||
|
render: (value, record, index) => {
|
||
|
const shortenedValue =
|
||
|
String(value).length > 20
|
||
|
? String(value).substring(0, 20) + '...'
|
||
|
: String(value);
|
||
|
return <Tooltip title={value}>{shortenedValue}</Tooltip>;
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
title: 'Redemption Number',
|
||
|
dataIndex: 'Redemption Number',
|
||
|
key: 'Redemption Number',
|
||
|
},
|
||
|
{
|
||
|
title: 'Image type',
|
||
|
dataIndex: 'Image type',
|
||
|
key: 'Image type',
|
||
|
},
|
||
|
{
|
||
|
title: 'IMEI_user submitted',
|
||
|
dataIndex: 'IMEI_user submitted',
|
||
|
key: 'IMEI_user submitted',
|
||
|
},
|
||
|
{
|
||
|
title: 'IMEI_OCR retrieved',
|
||
|
dataIndex: 'IMEI_OCR retrieved',
|
||
|
key: 'IMEI_OCR retrieved',
|
||
|
},
|
||
|
|
||
|
{
|
||
|
title: 'IMEI1 Accuracy',
|
||
|
dataIndex: 'IMEI1 Accuracy',
|
||
|
key: 'IMEI1 Accuracy',
|
||
|
render: (_, record) => {
|
||
|
const isAbnormal = Number(record['IMEI1 Accuracy']) * 100 < 25;
|
||
|
return (
|
||
|
<span style={{ color: isAbnormal ? 'red' : '' }}>
|
||
|
{record['IMEI1 Accuracy'] &&
|
||
|
(Number(record['IMEI1 Accuracy']) * 100).toFixed(2)}
|
||
|
</span>
|
||
|
);
|
||
|
},
|
||
|
},
|
||
|
|
||
|
{
|
||
|
title: 'Invoice_Purchase Date_Consumer',
|
||
|
dataIndex: 'Invoice_Purchase Date_Consumer',
|
||
|
key: 'Invoice_Purchase Date_Consumer',
|
||
|
},
|
||
|
{
|
||
|
title: 'Invoice_Purchase Date_OCR',
|
||
|
dataIndex: 'Invoice_Purchase Date_OCR',
|
||
|
key: 'Invoice_Purchase Date_OCR',
|
||
|
},
|
||
|
{
|
||
|
title: 'Invoice_Purchase Date Accuracy',
|
||
|
dataIndex: 'Invoice_Purchase Date Accuracy',
|
||
|
key: 'Invoice_Purchase Date Accuracy',
|
||
|
render: (_, record) => {
|
||
|
const isAbnormal =
|
||
|
Number(record['Invoice_Purchase Date Accuracy']) * 100 < 25;
|
||
|
return (
|
||
|
<span style={{ color: isAbnormal ? 'red' : '' }}>
|
||
|
{record['Invoice_Purchase Date Accuracy'] &&
|
||
|
(Number(record['Invoice_Purchase Date Accuracy']) * 100).toFixed(2)}
|
||
|
</span>
|
||
|
);
|
||
|
},
|
||
|
},
|
||
|
|
||
|
{
|
||
|
title: 'Invoice_Retailer_Consumer',
|
||
|
dataIndex: 'Invoice_Retailer_Consumer',
|
||
|
key: 'Invoice_Retailer_Consumer',
|
||
|
},
|
||
|
{
|
||
|
title: 'Invoice_Retailer_OCR',
|
||
|
dataIndex: 'Invoice_Retailer_OCR',
|
||
|
key: 'Invoice_Retailer_OCR',
|
||
|
},
|
||
|
{
|
||
|
title: 'Invoice_Retailer Accuracy',
|
||
|
dataIndex: 'Invoice_Retailer Accuracy',
|
||
|
key: 'Invoice_Retailer Accuracy',
|
||
|
render: (_, record) => {
|
||
|
const isAbnormal = Number(record['Invoice_Retailer Accuracy']) * 100 < 25;
|
||
|
return (
|
||
|
<span style={{ color: isAbnormal ? 'red' : '' }}>
|
||
|
{record['Invoice_Retailer Accuracy'] &&
|
||
|
(Number(record['Invoice_Retailer Accuracy']) * 100).toFixed(2)}
|
||
|
</span>
|
||
|
);
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
title: 'Retailer_Revised Accuracy',
|
||
|
dataIndex: 'Retailer_Revised Accuracy',
|
||
|
key: 'Retailer_Revised Accuracy',
|
||
|
render: (_, record) => {
|
||
|
const isAbnormal = Number(record['Retailer_Revised Accuracy']) * 100 < 25;
|
||
|
return (
|
||
|
<span style={{ color: isAbnormal ? 'red' : '' }}>
|
||
|
{record['Retailer_Revised Accuracy'] &&
|
||
|
(Number(record['Retailer_Revised Accuracy']) * 100).toFixed(2)}
|
||
|
</span>
|
||
|
);
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
title: 'OCR Image Accuracy',
|
||
|
dataIndex: 'OCR Image Accuracy',
|
||
|
key: 'OCR Image Accuracy',
|
||
|
render: (_, record) => {
|
||
|
const isAbnormal = Number(record['OCR Image Accuracy']) * 100 < 25;
|
||
|
return (
|
||
|
<span style={{ color: isAbnormal ? 'red' : '' }}>
|
||
|
{record['OCR Image Accuracy'] &&
|
||
|
(Number(record['OCR Image Accuracy']) * 100).toFixed(2)}
|
||
|
</span>
|
||
|
);
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
title: 'OCR Image Speed (seconds)',
|
||
|
dataIndex: 'OCR Image Speed (seconds)',
|
||
|
key: 'OCR Image Speed (seconds)',
|
||
|
render: (_, record) => {
|
||
|
const isAbnormal = Number(record['OCR Image Speed (seconds)']) > 2;
|
||
|
return (
|
||
|
<span style={{ color: isAbnormal ? 'red' : '' }}>
|
||
|
{record['OCR Image Speed (seconds)'] &&
|
||
|
Number(record['OCR Image Speed (seconds)']).toFixed(2)}
|
||
|
</span>
|
||
|
);
|
||
|
},
|
||
|
sorter: (a, b) =>
|
||
|
a['OCR Image Speed (seconds)'] - b['OCR Image Speed (seconds)'],
|
||
|
},
|
||
|
{
|
||
|
title: 'Reviewed',
|
||
|
dataIndex: 'Reviewed',
|
||
|
key: 'Reviewed',
|
||
|
},
|
||
|
{
|
||
|
title: 'Bad Image Reasons',
|
||
|
dataIndex: 'Bad Image Reasons',
|
||
|
key: 'Bad Image Reasons',
|
||
|
},
|
||
|
{
|
||
|
title: 'Countermeasures',
|
||
|
dataIndex: 'Countermeasures',
|
||
|
key: 'Countermeasures',
|
||
|
},
|
||
|
{
|
||
|
title: 'IMEI_Revised Accuracy',
|
||
|
dataIndex: 'IMEI_Revised Accuracy',
|
||
|
key: 'IMEI_Revised Accuracy',
|
||
|
render: (_, record) => {
|
||
|
const isAbnormal = Number(record['IMEI_Revised Accuracy']) * 100 < 25;
|
||
|
return (
|
||
|
<span style={{ color: isAbnormal ? 'red' : '' }}>
|
||
|
{record['IMEI_Revised Accuracy'] &&
|
||
|
(Number(record['IMEI_Revised Accuracy']) * 100).toFixed(2)}
|
||
|
</span>
|
||
|
);
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
title: 'Purchase Date_Revised Accuracy',
|
||
|
dataIndex: 'Purchase Date_Revised Accuracy',
|
||
|
key: 'Purchase Date_Revised Accuracy',
|
||
|
render: (_, record) => {
|
||
|
const isAbnormal =
|
||
|
Number(record['Purchase Date_Revised Accuracy']) * 100 < 25;
|
||
|
return (
|
||
|
<span style={{ color: isAbnormal ? 'red' : '' }}>
|
||
|
{record['Purchase Date_Revised Accuracy'] &&
|
||
|
(Number(record['Purchase Date_Revised Accuracy']) * 100).toFixed(2)}
|
||
|
</span>
|
||
|
);
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
title: 'Retailer_Revised Accuracy',
|
||
|
dataIndex: 'Retailer_Revised Accuracy',
|
||
|
key: 'Retailer_Revised Accuracy',
|
||
|
render: (_, record) => {
|
||
|
const isAbnormal = Number(record['Retailer_Revised Accuracy']) * 100 < 25;
|
||
|
return (
|
||
|
<span style={{ color: isAbnormal ? 'red' : '' }}>
|
||
|
{record['Retailer_Revised Accuracy'] &&
|
||
|
(Number(record['Retailer_Revised Accuracy']) * 100).toFixed(2)}
|
||
|
</span>
|
||
|
);
|
||
|
},
|
||
|
},
|
||
|
];
|
||
|
|
||
|
const ReportDetail = () => {
|
||
|
const [pagination, setPagination] = useState({
|
||
|
page: 1,
|
||
|
page_size: 10,
|
||
|
});
|
||
|
const { id } = useParams<{ id: string }>();
|
||
|
|
||
|
const { isLoading, data } = useReportDetailList({
|
||
|
report_id: id,
|
||
|
page: pagination.page,
|
||
|
});
|
||
|
const report_data = data as ReportDetailList;
|
||
|
|
||
|
return (
|
||
|
<>
|
||
|
<SbtPageHeader
|
||
|
title={t`Report`}
|
||
|
extra={
|
||
|
<Button size='large' type='primary' icon={<DownloadOutlined />}>
|
||
|
{t`Download Report`}
|
||
|
</Button>
|
||
|
}
|
||
|
/>
|
||
|
<ReportContainer>
|
||
|
<Table
|
||
|
loading={isLoading}
|
||
|
columns={columns}
|
||
|
dataSource={report_data?.report_detail}
|
||
|
bordered
|
||
|
size='small'
|
||
|
pagination={{
|
||
|
current: pagination.page,
|
||
|
pageSize: pagination.page_size,
|
||
|
total: report_data?.page.count,
|
||
|
showTotal: (total, range) =>
|
||
|
`${range[0]}-${range[1]} of ${total} items`,
|
||
|
onChange: (page, pageSize) => {
|
||
|
setPagination({
|
||
|
page,
|
||
|
page_size: pageSize || 10,
|
||
|
});
|
||
|
},
|
||
|
showSizeChanger: false,
|
||
|
position: ['bottomLeft'],
|
||
|
}}
|
||
|
/>
|
||
|
</ReportContainer>
|
||
|
</>
|
||
|
);
|
||
|
};
|
||
|
|
||
|
export default ReportDetail;
|