import { t } from '@lingui/macro'; import { Button, Input, Table, Tag, DatePicker, Form, Modal, Select, Space, Spin, message } from 'antd'; import React, { useContext, useEffect, useRef, useState } from 'react'; import type { GetRef } from 'antd'; import { Layout } from 'antd'; import { EditOutlined, DownloadOutlined, CheckCircleOutlined, ArrowLeftOutlined, ArrowRightOutlined, FullscreenOutlined, FullscreenExitOutlined, } from '@ant-design/icons'; import FileViewer from '@cyntler/react-doc-viewer'; import styled from 'styled-components'; const { Sider, Content } = Layout; import { baseURL } from "request/api"; import moment from 'moment'; const siderStyle: React.CSSProperties = { backgroundColor: '#fafafa', padding: 10, width: 200, }; const StyledTable = styled(Table)` & .sbt-table-cell { padding: 4px!important; } `; type InputRef = GetRef; type FormInstance = GetRef>; const EditableContext = React.createContext | null>(null); interface Item { key: string; accuracy: number; submitted: string; revised: string; action: string; } interface EditableRowProps { index: number; } const EditableRow: React.FC = ({ index, ...props }) => { const [form] = Form.useForm(); return (
); }; interface EditableCellProps { title: React.ReactNode; editable: boolean; children: React.ReactNode; dataIndex: keyof Item; record: Item; handleSave: (record: Item) => void; } const EditableCell: React.FC = ({ title, editable, children, dataIndex, record, handleSave, ...restProps }) => { const [editing, setEditing] = useState(false); const inputRef = useRef(null); const form = useContext(EditableContext)!; useEffect(() => { if (editing) { inputRef.current!.focus(); } }, [editing]); const toggleEdit = () => { setEditing(!editing); form.setFieldsValue({ [dataIndex]: record[dataIndex] }); }; const save = async () => { try { const values = await form.validateFields(); toggleEdit(); handleSave({ ...record, ...values }); } catch (errInfo) { console.log('Save failed:', errInfo); } }; let childNode = children; if (editable) { childNode = editing ? ( ) : (
{children}
); } return {childNode}; }; type EditableTableProps = Parameters[0]; type ColumnTypes = Exclude; const StyledEditOutlined = styled(EditOutlined)` & { color: #6666ff; margin-left: 8px; } &:hover { color: #0000ff; } `; const defaultColumns = [ { title: 'Key', dataIndex: 'key', key: 'key', width: 200, }, { title: 'Accuracy', dataIndex: 'acc', key: 'acc', render: (text, record) => { return
100%
; }, width: 150, }, { title: 'Predicted', dataIndex: 'predicted', key: 'predicted', }, { title: 'Submitted', dataIndex: 'submitted', key: 'submitted', }, { title: 'Revised', dataIndex: 'revised', key: 'revised', editable: true, }, ]; const FileCard = ({ file, isSelected, onClick }) => { const fileName = file["File Name"]; return (
{file["Doc Type"].toUpperCase()} {fileName ? fileName.substring(0, 25).replace("temp_", "") : fileName}
); }; const fetchAllRequests = async (filterDateRange, filterSubsidiaries, filterReviewState, filterIncludeTests, page = 1, page_size = 20) => { const startDate = (filterDateRange && filterDateRange[0]) ? filterDateRange[0].format('YYYY-MM-DD') : ''; const endDate = (filterDateRange && filterDateRange[1]) ? filterDateRange[1].format('YYYY-MM-DD') : ''; let filterStr = ""; filterStr += `page=${page}&page_size=${page_size}&`; if (filterSubsidiaries) { filterStr += `subsidiary=${filterSubsidiaries}&`; } if (filterReviewState) { filterStr += `is_reviewed=${filterReviewState}&`; } if (filterIncludeTests) { filterStr += `includes_tests=${filterIncludeTests}&`; } if (startDate && endDate) { filterStr += `start_date=${startDate}&end_date=${endDate}&`; } const token = localStorage.getItem('sbt-token') || ''; const data = await fetch(`${baseURL}/ctel/request_list/?${filterStr}`, { method: 'GET', headers: { "Authorization": `${JSON.parse(token)}` } }) .then(async (res) => { const data = await res.json(); return data; }); return data; }; const fetchRequest = async (id) => { const token = localStorage.getItem('sbt-token') || ''; const response = await fetch(`${baseURL}/ctel/request/${id}/`, { method: 'GET', headers: { "Authorization": `${JSON.parse(token)}` } }); return await (await response.json()).subscription_requests[0]; }; const ReviewPage = () => { const [loading, setLoading] = useState(false); const [fullscreen, setFullscreen] = useState(false); const [isModalOpen, setIsModalOpen] = useState(false); const [selectedFileId, setSelectedFileId] = useState(0); const selectFileByIndex = (index) => { setSelectedFileId(index); }; // Default date range: 1 month ago to today const [filterDateRange, setFilterDateRange] = useState([ moment().subtract(1, 'month'), moment(), ]); const [filterSubsidiaries, setFilterSubsidiaries] = useState('ALL'); const [filterReviewState, setFilterReviewState] = useState('all'); const [filterIncludeTests, setFilterIncludesTests] = useState('true'); const [requests, setRequests] = useState([]); const [currentRequest, setCurrentRequest] = useState(null); const [currentRequestIndex, setCurrentRequestIndex] = useState(1); const [hasNextRequest, setHasNextRequest] = useState(true); const [totalPages, setTotalPages] = useState(0); // purchase_date: "2024-01-20", // retailername: "Test Retailer", // sold_to_party: "Test Party", const dataSource = []; const predicted = (currentRequest && currentRequest["Reviewed Result"]) ? currentRequest["Reviewed Result"] : {}; const submitted = (currentRequest && currentRequest["Feedback Result"]) ? currentRequest["Feedback Result"] : {}; const revised = (currentRequest && currentRequest["Reviewed Result"]) ? currentRequest["Reviewed Result"] : {}; const keys = Object.keys(predicted); for (let i = 0; i < keys.length; i++) { let instance = {}; instance["key"] = keys[i]; instance["predicted"] = predicted[keys[i]]; instance["submitted"] = submitted[keys[i]]; instance["revised"] = revised[keys[i]]; dataSource.push(instance); } const [pageIndexToGoto, setPageIndexToGoto] = useState(1); const loadCurrentRequest = (requestID) => { setLoading(true); fetchAllRequests(filterDateRange, filterSubsidiaries, filterReviewState, filterIncludeTests, requestID, 2).then((data) => { setRequests(data?.subscription_requests); setHasNextRequest(data?.subscription_requests.length > 1); setTotalPages(data?.page?.total_pages); const requestData = fetchRequest(data?.subscription_requests[0].RequestID); requestData.then(async (data) => { if (data) setCurrentRequest(data); }).finally(() => { setLoading(false); }); }).finally(() => { setLoading(false); }); }; const gotoNextRequest = () => { const nextRequestIndex = currentRequestIndex + 1; setCurrentRequestIndex(nextRequestIndex); loadCurrentRequest(nextRequestIndex); }; const gotoPreviousRequest = () => { if (currentRequestIndex === 1) { return; } const previousRequestIndex = currentRequestIndex - 1; setCurrentRequestIndex(previousRequestIndex); loadCurrentRequest(previousRequestIndex); }; const reloadFilters = () => { setCurrentRequestIndex(1); fetchAllRequests(filterDateRange, filterSubsidiaries, filterReviewState, filterIncludeTests, currentRequestIndex, 2).then((data) => { setTotalPages(data?.page?.total_pages); setRequests(data?.subscription_requests); setHasNextRequest(data?.subscription_requests.length > 1); const firstRequest = fetchRequest(data?.subscription_requests[0].RequestID); firstRequest.then(async (data) => { console.log(firstRequest) if (data) setCurrentRequest(data); }); }); }; useEffect(() => { setCurrentRequestIndex(1); fetchAllRequests(filterDateRange, filterSubsidiaries, filterReviewState, filterIncludeTests, currentRequestIndex, 2).then((data) => { setTotalPages(data?.page?.total_pages); setRequests(data?.subscription_requests); setHasNextRequest(data?.subscription_requests.length > 1); const firstRequest = fetchRequest(data?.subscription_requests[0].RequestID); firstRequest.then(async (data) => { console.log(firstRequest) if (data) setCurrentRequest(data); }); }); }, []); const fileURL = (currentRequest && currentRequest["Files"][selectedFileId]) ? baseURL + currentRequest["Files"][selectedFileId]["File URL"].replace("http://be-ctel-sbt:9000/api", "") : "dummy.pdf"; const components = { body: { row: EditableRow, cell: EditableCell, }, }; // "Key", "Accuracy", "Submitted", "Revised" interface DataType { key: string; accuracy: number; submitted: string; revised: string; }; const handleSave = (row: DataType) => { const newData = [...dataSource]; console.log(row); // const index = newData.findIndex((item) => row.key === item.key); // const item = newData[index]; // newData.splice(index, 1, { // ...item, // ...row, // }); // setDataSource(newData); }; const columns = defaultColumns.map((col) => { if (!col.editable) { return col; } return { ...col, onCell: (record: DataType) => ({ record, editable: col.editable, dataIndex: col.dataIndex, title: col.title, handleSave, }), }; }); return (
   Request ID: {currentRequest?.RequestID}

Files ({currentRequest?.Files?.length})

{currentRequest?.Files.map((file, index) => ( { setSelectedFileId(index); } } /> ))}
{ if (pageIndexToGoto > totalPages) { message.error("RequestID is out of range."); return; } if (pageIndexToGoto < 1) { message.error("RequestID is out of range."); return; } setCurrentRequestIndex(pageIndexToGoto); loadCurrentRequest(pageIndexToGoto); }}> Go to } value={pageIndexToGoto} onChange={e => { setPageIndexToGoto(parseInt(e.target.value)); }} />

{totalPages ? ("Request: " + currentRequestIndex + "/" + totalPages) : "No Request. Adjust your search criteria to see more results."}

{/* } color="warning" style={{ padding: "4px 16px", marginLeft: 8 }}> Not Reviewed */} } color="success" style={{ padding: "4px 16px", marginLeft: 8 }}> Reviewed
{ setIsModalOpen(false); reloadFilters(); } } onCancel={ () => { setIsModalOpen(false); } } >
{ setFilterDateRange(value); }} style={{ width: 200 }} />