sbt-idp/cope2n-fe/src/pages/reports/report_detail/index.tsx
2024-02-01 12:54:12 +07:00

343 lines
9.3 KiB
TypeScript

import { DownloadOutlined } from '@ant-design/icons';
import { t } from '@lingui/macro';
import {
Button,
Space,
Table,
TableColumnsType,
Tooltip,
Typography,
} 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 { downloadReport } from 'request/report';
import styled from 'styled-components';
export interface ReportFormValues {
dateRange: [Dayjs, Dayjs];
includeTest: string;
}
const ReportContainer = styled.div`
margin-bottom: 16px;
`;
const HeaderContainer = styled(Space)`
display: flex;
flex-direction: row;\
gap: 16px;
margin-bottom: 16px;
`;
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']) < 25;
return (
<span style={{ color: isAbnormal ? 'red' : '' }}>
{record['IMEI1 Accuracy'] &&
Number(record['IMEI1 Accuracy']).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']) < 25;
return (
<span style={{ color: isAbnormal ? 'red' : '' }}>
{record['Invoice_Purchase Date Accuracy'] &&
Number(record['Invoice_Purchase Date Accuracy']).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']) < 25;
return (
<span style={{ color: isAbnormal ? 'red' : '' }}>
{record['Invoice_Retailer Accuracy'] &&
Number(record['Invoice_Retailer Accuracy']).toFixed(2)}
</span>
);
},
},
{
title: 'Retailer_Revised Accuracy',
dataIndex: 'Retailer_Revised Accuracy',
key: 'Retailer_Revised Accuracy',
render: (_, record) => {
const isAbnormal = Number(record['Retailer_Revised Accuracy']) < 25;
return (
<span style={{ color: isAbnormal ? 'red' : '' }}>
{record['Retailer_Revised Accuracy'] &&
Number(record['Retailer_Revised Accuracy']).toFixed(2)}
</span>
);
},
},
{
title: 'OCR Image Accuracy',
dataIndex: 'OCR Image Accuracy',
key: 'OCR Image Accuracy',
render: (_, record) => {
const isAbnormal = Number(record['OCR Image Accuracy']) < 25;
return (
<span style={{ color: isAbnormal ? 'red' : '' }}>
{record['OCR Image Accuracy'] &&
Number(record['OCR Image Accuracy']).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;
const handleDownloadReport = async () => {
const reportFile = await downloadReport(id);
const anchorElement = document.createElement('a');
anchorElement.href = URL.createObjectURL(reportFile);
anchorElement.download = `${id}.xlsx`; // Set the desired new filename
document.body.appendChild(anchorElement);
anchorElement.click();
// Clean up
document.body.removeChild(anchorElement);
URL.revokeObjectURL(anchorElement.href);
};
return (
<>
<SbtPageHeader
title={
<Tooltip
title={id}
style={{ cursor: 'pointer' }}
>{t`Report ${id.slice(0, 16)}...`}</Tooltip>
}
extra={
<Button
size='large'
type='primary'
icon={<DownloadOutlined />}
onClick={handleDownloadReport}
>
{t`Download Report`}
</Button>
}
/>
<HeaderContainer>
<Typography.Title level={5}>
Subsidiary:{' '}
<span style={{ fontWeight: '400' }}>
{report_data?.metadata?.subsidiary}
</span>
</Typography.Title>
<Typography.Title level={5}>
Start date:{' '}
<span style={{ fontWeight: '400' }}>
{report_data?.metadata?.start_at}
</span>
</Typography.Title>
<Typography.Title level={5}>
End date:{' '}
<span style={{ fontWeight: '400' }}>
{report_data?.metadata?.end_at}
</span>
</Typography.Title>
</HeaderContainer>
<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,
}}
scroll={{ x: 2000 }}
/>
</ReportContainer>
</>
);
};
export default ReportDetail;