From 15a550ae360e9430ebac5646fdd3e97b525961bb Mon Sep 17 00:00:00 2001 From: Viet Anh Nguyen Date: Wed, 21 Feb 2024 18:11:02 +0700 Subject: [PATCH] Integrate APIs --- cope2n-fe/src/pages/reviews/index.tsx | 301 +++++++++++++++++++------- cope2n-fe/src/request/api.ts | 2 +- 2 files changed, 229 insertions(+), 74 deletions(-) diff --git a/cope2n-fe/src/pages/reviews/index.tsx b/cope2n-fe/src/pages/reviews/index.tsx index ab34816..491d5a3 100644 --- a/cope2n-fe/src/pages/reviews/index.tsx +++ b/cope2n-fe/src/pages/reviews/index.tsx @@ -1,6 +1,6 @@ import { t } from '@lingui/macro'; import { Button, Input, Table, Tag, DatePicker, Form, Modal, Select, Space, Checkbox } from 'antd'; -import { useState } from 'react'; +import { useState, useEffect } from 'react'; import { Layout } from 'antd'; import { EditOutlined, DownloadOutlined, CheckCircleOutlined, @@ -13,6 +13,8 @@ import { 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', @@ -38,22 +40,6 @@ const StyledEditOutlined = styled(EditOutlined)` } `; - -const fileList = [ - { - name: "invoice.pdf", - url: "/dummpy.pdf", - type: "invoice", - isBadQuality: false, - }, - { - name: "invoice.pdf", - url: "/dummpy.pdf", - type: "imei", - isBadQuality: true, - } -] - const dataSource = [ { key: 'retailer_name', @@ -102,6 +88,7 @@ const columns = [ title: 'Key', dataIndex: 'key', key: 'key', + width: 200, }, { title: 'Accuracy', @@ -110,6 +97,7 @@ const columns = [ render: (text, record) => { return
100%
; }, + width: 150, }, { title: 'Predicted', @@ -142,6 +130,8 @@ const columns = [ const FileCard = ({ file, isSelected, onClick }) => { + const fileName = file["File Name"]; + return (
{ fontWeight: 'bold', padding: '4px 8px', cursor: 'default', - }}>{file.type.toUpperCase()} + }}>{file["Doc Type"].toUpperCase()} {file.name} + maxWidth: '50px', + overflow: 'hidden', + textOverflow: 'ellipsis', + }}> + {fileName? fileName.substring(0, 10) : 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 [fullscreen, setFullscreen] = useState(false); const [isModalOpen, setIsModalOpen] = useState(false); @@ -198,9 +235,86 @@ const ReviewPage = () => { const selectFileByIndex = (index) => { setSelectedFileId(index); }; - const [filterDateRange, setFilterDateRange] = useState(null); - const [filterSubsidiaries, setFilterSubsidiaries] = useState(''); - const [filterReviewState, setFilterReviewState] = useState(''); + + // 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); + + const gotoNextRequest = () => { + const nextRequestIndex = currentRequestIndex + 1; + setCurrentRequestIndex(nextRequestIndex); + fetchAllRequests(filterDateRange, filterSubsidiaries, filterReviewState, filterIncludeTests, nextRequestIndex, 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) => { + console.log(data) + if (data) setCurrentRequest(data); + }); + }); + }; + + const gotoPreviousRequest = () => { + if (currentRequestIndex === 1) { + return; + } + const previousRequestIndex = currentRequestIndex - 1; + setCurrentRequestIndex(previousRequestIndex); + fetchAllRequests(filterDateRange, filterSubsidiaries, filterReviewState, filterIncludeTests, previousRequestIndex, 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) => { + console.log(data) + if (data) setCurrentRequest(data); + }); + }); + }; + + + 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 ? baseURL + currentRequest["Files"][selectedFileId]["File URL"].replace("http://be-ctel-sbt:9000/api", "") : "dummy.pdf"; return (
{ width: '100%', height: '100%', maxWidth: '100%', - minHeight: '60%', - maxHeight: '60%', + minHeight: '70%', + maxHeight: '70%', display: 'flex', padding: '8px', }}> @@ -249,10 +363,10 @@ const ReviewPage = () => { style={{ color: "#333", padding: 10, - fontWeight: 'bold' + fontWeight: 'bold' }} - >Files ({fileList.length}) - {fileList.map((file, index) => ( + >Files ({currentRequest?.Files?.length}) + {currentRequest?.Files.map((file, index) => ( { setSelectedFileId(index); @@ -267,7 +381,7 @@ const ReviewPage = () => { }}> { }} />
- + - + - @@ -306,12 +435,12 @@ const ReviewPage = () => {
-

Request Review

- - - - - +

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

+ + "} /> + + +
{/* } color="warning" style={{ padding: "4px 16px", marginLeft: 8 }}> @@ -330,6 +459,7 @@ const ReviewPage = () => { onOk={ () => { setIsModalOpen(false); + reloadFilters(); } } onCancel={ @@ -359,40 +489,42 @@ const ReviewPage = () => { { - console.log(value); setFilterDateRange(value); }} style={{ width: 200 }} /> -
- + - + value={filterSubsidiaries} + defaultValue={filterSubsidiaries} + onChange={setFilterSubsidiaries} + /> + +
{ message: 'Please select review status', }, ]} + > +
-
-
diff --git a/cope2n-fe/src/request/api.ts b/cope2n-fe/src/request/api.ts index a0945df..6a54c3e 100644 --- a/cope2n-fe/src/request/api.ts +++ b/cope2n-fe/src/request/api.ts @@ -11,7 +11,7 @@ const environment = process.env.NODE_ENV; const AXIOS_TIMEOUT_MS = 30 * 60 * 1000; // This config sastified long-live upload file request const EXPIRED_PASSWORD_SIGNAL = 'expired_password'; -export const baseURL = environment === 'development' ? 'http://42.96.42.13:9000/api' : '/api'; +export const baseURL = environment === 'development' ? 'http://42.96.42.13:9881/api' : '/api'; export const API = axios.create({ timeout: AXIOS_TIMEOUT_MS,