476 lines
12 KiB
TypeScript
476 lines
12 KiB
TypeScript
import type { TableColumnsType } from 'antd';
|
|
import { Table } from 'antd';
|
|
import React from 'react';
|
|
|
|
interface DataType {
|
|
key: React.Key;
|
|
subSidiaries: string;
|
|
extractionDate: string | Date;
|
|
snOrImeiNumber: number;
|
|
invoiceNumber: number;
|
|
totalImages: number;
|
|
successfulNumber: number;
|
|
successfulPercentage: number;
|
|
badNumber: number;
|
|
badPercentage: number;
|
|
snImeiAAR: number; // AAR: Average Accuracy Rate
|
|
purchaseDateAAR: number;
|
|
retailerNameAAR: number;
|
|
snImeiAPT: number; // APT: Average Processing Time
|
|
invoiceAPT: number;
|
|
snImeiTC: number; // TC: transaction count
|
|
invoiceTC: number;
|
|
}
|
|
|
|
const columns: TableColumnsType<DataType> = [
|
|
{
|
|
title: 'Subs',
|
|
dataIndex: 'subSidiaries',
|
|
key: 'subSidiaries',
|
|
width: '100px',
|
|
},
|
|
{
|
|
title: 'OCR extraction date',
|
|
dataIndex: 'extractionDate',
|
|
key: 'extractionDate',
|
|
width: '130px',
|
|
},
|
|
{
|
|
title: 'OCR Images',
|
|
children: [
|
|
{
|
|
title: 'SN/IMEI',
|
|
dataIndex: 'snOrImeiNumber',
|
|
key: 'snOrImeiNumber',
|
|
width: '50px',
|
|
},
|
|
{
|
|
title: 'Invoice',
|
|
dataIndex: 'invoiceNumber',
|
|
key: 'invoiceNumber',
|
|
width: '50px',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
title: 'Total Images',
|
|
dataIndex: 'totalImages',
|
|
key: 'totalImages',
|
|
width: '130px',
|
|
},
|
|
{
|
|
title: 'Image Quality',
|
|
children: [
|
|
{
|
|
title: 'Successful',
|
|
dataIndex: 'successfulNumber',
|
|
key: 'successfulNumber',
|
|
width: '50px',
|
|
},
|
|
{
|
|
title: '% Successful',
|
|
dataIndex: 'successfulPercentage',
|
|
key: 'successfulPercentage',
|
|
width: '120px',
|
|
render: (_, record) => {
|
|
return <span>{(record.successfulPercentage * 100).toFixed(2)}</span>;
|
|
},
|
|
},
|
|
{
|
|
title: 'Bad',
|
|
dataIndex: 'badNumber',
|
|
key: 'badNumber',
|
|
width: '30px',
|
|
},
|
|
{
|
|
title: '% Bad',
|
|
dataIndex: 'badPercentage',
|
|
key: 'badPercentage',
|
|
width: '60px',
|
|
render: (_, record) => {
|
|
const isAbnormal = record.badPercentage * 100 > 10;
|
|
return (
|
|
<span style={{ color: isAbnormal ? 'red' : '' }}>
|
|
{(record.badPercentage * 100).toFixed(2)}
|
|
</span>
|
|
);
|
|
},
|
|
},
|
|
],
|
|
},
|
|
|
|
{
|
|
title: 'Average accuracy rate (%) \n(※ character-based)',
|
|
children: [
|
|
{
|
|
title: 'IMEI / Serial no.',
|
|
dataIndex: 'snImeiAAR',
|
|
key: 'snImeiAAR',
|
|
width: '130px',
|
|
render: (_, record) => {
|
|
const isAbnormal = record.snImeiAAR * 100 < 98;
|
|
return (
|
|
<span style={{ color: isAbnormal ? 'red' : '' }}>
|
|
{(record.snImeiAAR * 100).toFixed(2)}
|
|
</span>
|
|
);
|
|
},
|
|
},
|
|
{
|
|
title: 'Purchase date',
|
|
dataIndex: 'purchaseDateAAR',
|
|
key: 'purchaseDateAAR',
|
|
width: '130px',
|
|
render: (_, record) => {
|
|
const isAbnormal = record.purchaseDateAAR * 100 < 98;
|
|
return (
|
|
<span style={{ color: isAbnormal ? 'red' : '' }}>
|
|
{(record.purchaseDateAAR * 100).toFixed(2)}
|
|
</span>
|
|
);
|
|
},
|
|
},
|
|
{
|
|
title: 'Retailer name',
|
|
dataIndex: 'retailerNameAAR',
|
|
key: 'retailerNameAAR',
|
|
width: '130px',
|
|
render: (_, record) => {
|
|
const isAbnormal = record.retailerNameAAR * 100 < 98;
|
|
return (
|
|
<span style={{ color: isAbnormal ? 'red' : '' }}>
|
|
{(record.retailerNameAAR * 100).toFixed(2)}
|
|
</span>
|
|
);
|
|
},
|
|
},
|
|
],
|
|
},
|
|
{
|
|
title: 'Average Processing Time',
|
|
children: [
|
|
{
|
|
title: 'SN/IMEI',
|
|
dataIndex: 'snImeiAPT',
|
|
key: 'snImeiAPT',
|
|
render: (_, record) => {
|
|
const isAbnormal = record.snImeiAPT > 2;
|
|
return (
|
|
<span style={{ color: isAbnormal ? 'red' : '' }}>
|
|
{record.snImeiAPT.toFixed(2)}
|
|
</span>
|
|
);
|
|
},
|
|
},
|
|
{
|
|
title: 'Invoice',
|
|
dataIndex: 'invoiceAPT',
|
|
key: 'invoiceAPT',
|
|
render: (_, record) => {
|
|
const isAbnormal = record.invoiceAPT > 2;
|
|
return (
|
|
<span style={{ color: isAbnormal ? 'red' : '' }}>
|
|
{record.invoiceAPT.toFixed(2)}
|
|
</span>
|
|
);
|
|
},
|
|
},
|
|
],
|
|
},
|
|
{
|
|
title: 'Usage (Transaction Count)',
|
|
children: [
|
|
{
|
|
title: 'SN/IMEI',
|
|
dataIndex: 'snImeiTC',
|
|
key: 'snImeiTC',
|
|
},
|
|
{
|
|
title: 'Invoice',
|
|
dataIndex: 'invoiceTC',
|
|
key: 'invoiceTC',
|
|
},
|
|
],
|
|
},
|
|
];
|
|
|
|
interface ReportOverViewTableProps {
|
|
pagination: {
|
|
page: number;
|
|
page_size: number;
|
|
};
|
|
setPagination: React.Dispatch<
|
|
React.SetStateAction<{
|
|
page: number;
|
|
page_size: number;
|
|
}>
|
|
>;
|
|
isLoading: boolean;
|
|
data: any;
|
|
}
|
|
|
|
const ReportOverViewTable: React.FC<ReportOverViewTableProps> = ({
|
|
pagination,
|
|
setPagination,
|
|
isLoading,
|
|
data,
|
|
}) => {
|
|
// const [pagination, setPagination] = useState({
|
|
// page: 1,
|
|
// page_size: 10,
|
|
// });
|
|
// const { isLoading, data } = useOverViewReport({
|
|
// page: pagination.page,
|
|
// });
|
|
|
|
console.log('check >>>', pagination, isLoading, data);
|
|
|
|
const overviewDataResponse = data as any;
|
|
const dataSubsRows = overviewDataResponse?.overview_data
|
|
.map((item, index) => {
|
|
if (item.subs.includes('+')) {
|
|
return {
|
|
key: index,
|
|
subSidiaries: '',
|
|
extractionDate: item.extraction_date,
|
|
snOrImeiNumber: '',
|
|
invoiceNumber: '',
|
|
totalImages: item.total_images,
|
|
successfulNumber: item.images_quality.successful,
|
|
successfulPercentage: item.images_quality.successful_percent,
|
|
badNumber: item.images_quality.bad,
|
|
badPercentage: item.images_quality.bad_percent,
|
|
snImeiAAR: item.average_accuracy_rate.imei,
|
|
purchaseDateAAR: item.average_accuracy_rate.purchase_date,
|
|
retailerNameAAR: item.average_accuracy_rate.retailer_name,
|
|
snImeiAPT: item.average_processing_time.imei,
|
|
invoiceAPT: item.average_processing_time.invoice,
|
|
snImeiTC: item.usage.imei,
|
|
invoiceTC: item.usage.invoice,
|
|
};
|
|
} else {
|
|
return null;
|
|
}
|
|
})
|
|
.filter((item) => item);
|
|
|
|
const expandedRowRender = () => {
|
|
const subData = overviewDataResponse?.overview_data
|
|
.map((item, index) => {
|
|
if (!item.subs.includes('+')) {
|
|
return {
|
|
key: index,
|
|
subSidiaries: item.subs,
|
|
extractionDate: item.extraction_date,
|
|
snOrImeiNumber: item.num_imei,
|
|
invoiceNumber: item.num_invoice,
|
|
totalImages: item.total_images,
|
|
successfulNumber: item.images_quality.successful,
|
|
successfulPercentage: item.images_quality.successful_percent,
|
|
badNumber: item.images_quality.bad,
|
|
badPercentage: item.images_quality.bad_percent,
|
|
snImeiAAR: item.average_accuracy_rate.imei,
|
|
purchaseDateAAR: item.average_accuracy_rate.purchase_date,
|
|
retailerNameAAR: item.average_accuracy_rate.retailer_name,
|
|
snImeiAPT: item.average_processing_time.imei,
|
|
invoiceAPT: item.average_processing_time.invoice,
|
|
snImeiTC: item.usage.imei,
|
|
invoiceTC: item.usage.invoice,
|
|
};
|
|
} else {
|
|
return null;
|
|
}
|
|
})
|
|
.filter((item) => item);
|
|
|
|
const subColumns: TableColumnsType<DataType> = [
|
|
{
|
|
title: 'Subs',
|
|
dataIndex: 'subSidiaries',
|
|
key: 'subSidiaries',
|
|
width: '100px',
|
|
},
|
|
{
|
|
title: 'OCR extraction date',
|
|
dataIndex: 'extractionDate',
|
|
key: 'extractionDate',
|
|
width: '130px',
|
|
render: (_, record) => {
|
|
return <span>{record?.extractionDate.toString().split('T')[0]}</span>;
|
|
},
|
|
},
|
|
{
|
|
title: 'SN/IMEI',
|
|
dataIndex: 'snOrImeiNumber',
|
|
key: 'snOrImeiNumber',
|
|
width: '50px',
|
|
},
|
|
{
|
|
title: 'Invoice',
|
|
dataIndex: 'invoiceNumber',
|
|
key: 'invoiceNumber',
|
|
width: '50px',
|
|
},
|
|
{
|
|
title: 'Total Images',
|
|
dataIndex: 'totalImages',
|
|
key: 'totalImages',
|
|
width: '130px',
|
|
},
|
|
{
|
|
title: 'Successful',
|
|
dataIndex: 'successfulNumber',
|
|
key: 'successfulNumber',
|
|
width: '50px',
|
|
},
|
|
{
|
|
title: '% Successful',
|
|
dataIndex: 'successfulPercentage',
|
|
key: 'successfulPercentage',
|
|
width: '120px',
|
|
render: (_, record) => {
|
|
return <span>{(record.successfulPercentage * 100).toFixed(2)}</span>;
|
|
},
|
|
},
|
|
{
|
|
title: 'Bad',
|
|
dataIndex: 'badNumber',
|
|
key: 'badNumber',
|
|
width: '30px',
|
|
},
|
|
{
|
|
title: '% Bad',
|
|
dataIndex: 'badPercentage',
|
|
key: 'badPercentage',
|
|
width: '60px',
|
|
render: (_, record) => {
|
|
const isAbnormal = record.badPercentage * 100 > 10;
|
|
return (
|
|
<span style={{ color: isAbnormal ? 'red' : '' }}>
|
|
{(record.badPercentage * 100).toFixed(2)}
|
|
</span>
|
|
);
|
|
},
|
|
},
|
|
|
|
{
|
|
title: 'IMEI / Serial no.',
|
|
dataIndex: 'snImeiAAR',
|
|
key: 'snImeiAAR',
|
|
width: '130px',
|
|
render: (_, record) => {
|
|
const isAbnormal = record.snImeiAAR * 100 < 98;
|
|
return (
|
|
<span style={{ color: isAbnormal ? 'red' : '' }}>
|
|
{(record.snImeiAAR * 100).toFixed(2)}
|
|
</span>
|
|
);
|
|
},
|
|
},
|
|
{
|
|
title: 'Purchase date',
|
|
dataIndex: 'purchaseDateAAR',
|
|
key: 'purchaseDateAAR',
|
|
width: '130px',
|
|
render: (_, record) => {
|
|
const isAbnormal = record.purchaseDateAAR * 100 < 98;
|
|
return (
|
|
<span style={{ color: isAbnormal ? 'red' : '' }}>
|
|
{(record.purchaseDateAAR * 100).toFixed(2)}
|
|
</span>
|
|
);
|
|
},
|
|
},
|
|
{
|
|
title: 'Retailer name',
|
|
dataIndex: 'retailerNameAAR',
|
|
key: 'retailerNameAAR',
|
|
width: '130px',
|
|
render: (_, record) => {
|
|
const isAbnormal = record.retailerNameAAR * 100 < 98;
|
|
return (
|
|
<span style={{ color: isAbnormal ? 'red' : '' }}>
|
|
{(record.retailerNameAAR * 100).toFixed(2)}
|
|
</span>
|
|
);
|
|
},
|
|
},
|
|
|
|
{
|
|
title: 'SN/IMEI',
|
|
dataIndex: 'snImeiAPT',
|
|
key: 'snImeiAPT',
|
|
render: (_, record) => {
|
|
const isAbnormal = record.snImeiAPT > 2;
|
|
return (
|
|
<span style={{ color: isAbnormal ? 'red' : '' }}>
|
|
{record.snImeiAPT.toFixed(2)}
|
|
</span>
|
|
);
|
|
},
|
|
},
|
|
{
|
|
title: 'Invoice',
|
|
dataIndex: 'invoiceAPT',
|
|
key: 'invoiceAPT',
|
|
render: (_, record) => {
|
|
const isAbnormal = record.invoiceAPT > 2;
|
|
return (
|
|
<span style={{ color: isAbnormal ? 'red' : '' }}>
|
|
{record.invoiceAPT.toFixed(2)}
|
|
</span>
|
|
);
|
|
},
|
|
},
|
|
{
|
|
title: 'SN/IMEI',
|
|
dataIndex: 'snImeiTC',
|
|
key: 'snImeiTC',
|
|
},
|
|
{
|
|
title: 'Invoice',
|
|
dataIndex: 'invoiceTC',
|
|
key: 'invoiceTC',
|
|
},
|
|
];
|
|
return (
|
|
<Table
|
|
columns={subColumns}
|
|
dataSource={subData}
|
|
pagination={false}
|
|
bordered
|
|
// showHeader={false}
|
|
/>
|
|
);
|
|
};
|
|
return (
|
|
<div>
|
|
<Table
|
|
loading={isLoading}
|
|
columns={columns}
|
|
dataSource={dataSubsRows}
|
|
bordered
|
|
size='small'
|
|
expandable={{ expandedRowRender, defaultExpandedRowKeys: [0, 1] }}
|
|
scroll={{ x: 2000 }}
|
|
pagination={{
|
|
current: pagination.page,
|
|
pageSize: 10,
|
|
total: dataSubsRows?.length,
|
|
// showTotal: (total, range) =>
|
|
// `${range[0]}-${range[1]} of ${total} items`,
|
|
onChange: (page, pageSize) => {
|
|
setPagination({
|
|
page,
|
|
page_size: pageSize || 10,
|
|
});
|
|
},
|
|
showSizeChanger: false,
|
|
}}
|
|
/>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default ReportOverViewTable;
|