Reflow UI

This commit is contained in:
Viet Anh Nguyen 2024-02-20 15:01:06 +07:00
parent 18d9be2987
commit 5fed071439
2 changed files with 322 additions and 70 deletions

View File

@ -35,7 +35,7 @@ function LeftMenu() {
const generalSubItems = [ const generalSubItems = [
getItem(t`Dashboard`, '/dashboard', <AppstoreOutlined />), getItem(t`Dashboard`, '/dashboard', <AppstoreOutlined />),
getItem(t`Reports`, '/reports', <BarChartOutlined />), getItem(t`Reports`, '/reports', <BarChartOutlined />),
// getItem(t`Review`, '/reviews', <FileSearchOutlined />), getItem(t`Review`, '/reviews', <FileSearchOutlined />),
getItem(t`Inference`, '/inference', <RotateRightOutlined />), getItem(t`Inference`, '/inference', <RotateRightOutlined />),
// getItem(t`Users`, '/users', <UsergroupAddOutlined />), // getItem(t`Users`, '/users', <UsergroupAddOutlined />),
]; ];

View File

@ -1,9 +1,17 @@
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { Button, message, Upload, Input, Table } from 'antd'; import { Button, Input, Table, Tag, DatePicker, Form, Modal, Select, Space, Checkbox } from 'antd';
import { SbtPageHeader } from 'components/page-header';
import { useState } from 'react'; import { useState } from 'react';
import { Layout } from 'antd'; import { Layout } from 'antd';
import {
EditOutlined, DownloadOutlined, CheckCircleOutlined,
ClockCircleOutlined,
ArrowLeftOutlined,
ArrowRightOutlined,
FullscreenOutlined,
FullscreenExitOutlined,
} from '@ant-design/icons';
import FileViewer from '@cyntler/react-doc-viewer'; import FileViewer from '@cyntler/react-doc-viewer';
import styled from 'styled-components';
const { Sider, Content } = Layout; const { Sider, Content } = Layout;
const siderStyle: React.CSSProperties = { const siderStyle: React.CSSProperties = {
@ -13,6 +21,24 @@ const siderStyle: React.CSSProperties = {
}; };
const StyledTable = styled(Table)`
& .sbt-table-cell {
padding: 4px!important;
}
`;
const StyledEditOutlined = styled(EditOutlined)`
& {
color: #6666ff;
margin-left: 8px;
}
&:hover {
color: #0000ff;
}
`;
const fileList = [ const fileList = [
{ {
name: "invoice.pdf", name: "invoice.pdf",
@ -30,7 +56,7 @@ const fileList = [
const dataSource = [ const dataSource = [
{ {
key: '1', key: 'retailer_name',
value: 'Mike', value: 'Mike',
}, },
{ {
@ -41,6 +67,34 @@ const dataSource = [
key: '3', key: '3',
value: 'Mike', value: 'Mike',
}, },
{
key: '3',
value: 'Mike',
},
{
key: '3',
value: 'Mike',
},
{
key: '3',
value: 'Mike',
},
{
key: '3',
value: 'Mike',
},
{
key: '3',
value: 'Mike',
},
{
key: '3',
value: 'Mike',
},
{
key: '3',
value: 'Mike',
},
]; ];
const columns = [ const columns = [
@ -49,6 +103,14 @@ const columns = [
dataIndex: 'key', dataIndex: 'key',
key: 'key', key: 'key',
}, },
{
title: 'Accuracy',
dataIndex: 'acc',
key: 'acc',
render: (text, record) => {
return <div>100%</div>;
},
},
{ {
title: 'Predicted', title: 'Predicted',
dataIndex: 'value', dataIndex: 'value',
@ -63,6 +125,18 @@ const columns = [
title: 'Revised', title: 'Revised',
dataIndex: 'value', dataIndex: 'value',
key: 'value', key: 'value',
render: (text, record) => {
return (
<div style={{
display: 'flex',
lineHeight: '2',
}}>
{text}
<StyledEditOutlined />
</div>
)
},
}, },
]; ];
@ -75,7 +149,9 @@ const FileCard = ({ file, isSelected, onClick }) => {
backgroundColor: isSelected ? '#d4ecff' : '#fff', backgroundColor: isSelected ? '#d4ecff' : '#fff',
padding: '4px 8px', padding: '4px 8px',
marginRight: '4px', marginRight: '4px',
marginTop: '4px', marginTop: '2px',
position: 'relative',
height: '100px',
}} onClick={onClick}> }} onClick={onClick}>
<div> <div>
<span style={{ <span style={{
@ -83,36 +159,74 @@ const FileCard = ({ file, isSelected, onClick }) => {
color: '#333', color: '#333',
fontWeight: 'bold', fontWeight: 'bold',
padding: '4px 8px', padding: '4px 8px',
cursor: 'default',
}}>{file.type.toUpperCase()}</span> }}>{file.type.toUpperCase()}</span>
<span style={{ <span style={{
fontSize: '12px', fontSize: '12px',
color: '#aaa', color: '#aaa',
fontWeight: 'bold', fontWeight: 'bold',
padding: '4px 8px', padding: '4px 8px',
cursor: 'default',
}}>{file.name}</span> }}>{file.name}</span>
</div> </div>
<div style={{
padding: '4px',
position: 'absolute',
bottom: 2,
right: 2,
}}>
<Button style={{
margin: '4px 2px',
}}>
Review
</Button>
<Button style={{
margin: '4px 2px',
}}>
<DownloadOutlined />
</Button>
</div>
</div> </div>
); );
}; };
const InferencePage = () => { const ReviewPage = () => {
const [fullscreen, setFullscreen] = useState(false);
const [isModalOpen, setIsModalOpen] = useState(false);
const [selectedFileId, setSelectedFileId] = useState(0); const [selectedFileId, setSelectedFileId] = useState(0);
const selectFileByIndex = (index) => { const selectFileByIndex = (index) => {
setSelectedFileId(index); setSelectedFileId(index);
}; };
const [filterDateRange, setFilterDateRange] = useState(null);
const [filterSubsidiaries, setFilterSubsidiaries] = useState('');
const [filterReviewState, setFilterReviewState] = useState('');
return ( return (
<> <div style={fullscreen ? {
{/* <SbtPageHeader position: 'absolute',
title={t`Result Review`} top: 0,
/> */} left: 0,
<Layout style={{
overflow: 'hidden',
width: '100%', width: '100%',
height: '100%',
backgroundColor: '#fff',
zIndex: 1000,
} : {
height: '100%',
}}>
<Button onClick={() => {
setFullscreen(!fullscreen);
}}>
{fullscreen ? <FullscreenExitOutlined /> : <FullscreenOutlined />}
{fullscreen ? 'Exit Fullscreen' : 'Enter Fullscreen'}
</Button>
<Layout style={{
overflow: 'auto',
width: '100%',
height: '100%',
maxWidth: '100%', maxWidth: '100%',
minHeight: 'calc(100vh - 100px)', minHeight: '60%',
maxHeight: 'calc(100vh - 100px)', maxHeight: '60%',
display: 'flex', display: 'flex',
padding: '8px', padding: '8px',
}}> }}>
@ -122,13 +236,34 @@ const InferencePage = () => {
backgroundColor: '#efefef', backgroundColor: '#efefef',
height: '100%', height: '100%',
display: 'flex', display: 'flex',
flexDirection: 'column', flexDirection: 'row',
flexGrow: 1,
}}> }}>
<div
style={{
width: "200px",
display: "flex",
flexDirection: "column",
flexGrow: 0,
}}>
<h2
style={{
color: "#333",
padding: 10,
fontWeight: 'bold'
}}
>Files ({fileList.length})</h2>
{fileList.map((file, index) => (
<FileCard key={index} file={file} isSelected={index === selectedFileId} onClick={
() => {
setSelectedFileId(index);
}
} />
))}
</div>
<div style={{ <div style={{
border: "1px solid #ccc", border: "1px solid #ccc",
flexGrow: 1, flexGrow: 1,
height: '500px', height: '100%',
}}> }}>
<FileViewer documents={ <FileViewer documents={
[ [
@ -144,38 +279,155 @@ const InferencePage = () => {
pdfVerticalScrollByDefault: true, // false as default pdfVerticalScrollByDefault: true, // false as default
}} /> }} />
</div> </div>
<div
style={{
width: "100%",
display: "flex",
flexDirection: "row",
height: "100px",
flexGrow: 0,
}}>
{fileList.map((file, index) => (
<FileCard key={index} file={file} isSelected={index === selectedFileId} onClick={
() => {
setSelectedFileId(index);
}
} />
))}
</div>
</Content> </Content>
<Sider width="400px" style={siderStyle}> <Sider width="300px" style={siderStyle}>
<h2 style={{ margin: "0 0 10px 0" }}>Overview</h2> <Space.Compact style={{ width: '100%', marginBottom: 16 }}>
<Input defaultValue="All" readOnly />
<Button type="primary" size="large"
onClick={() => {
setIsModalOpen(true);
}}
>
Filters
</Button>
</Space.Compact>
<div style={{ display: "flex", justifyContent: "space-between", marginBottom: 8 }}>
<div>
<Button type="default">
<ArrowLeftOutlined />
Previous
</Button>
<Button type="default">
Next
<ArrowRightOutlined />
</Button>
<Button type="default">
Go to
</Button>
</div>
</div>
<h2 style={{ margin: "20px 0 10px 0" }}>Request Review</h2>
<Input size='small' addonBefore="Request ID" style={{ marginBottom: "4px" }} readOnly /> <Input size='small' addonBefore="Request ID" style={{ marginBottom: "4px" }} readOnly />
<Input size='small' addonBefore="Redemption" style={{ marginBottom: "4px" }} readOnly /> <Input size='small' addonBefore="Redemption" style={{ marginBottom: "4px" }} readOnly />
<Input size='small' addonBefore="Uploaded date" style={{ marginBottom: "4px" }} readOnly /> <Input size='small' addonBefore="Uploaded date" style={{ marginBottom: "4px" }} readOnly />
<Input size='small' addonBefore="Request time" style={{ marginBottom: "4px" }} readOnly /> <Input size='small' addonBefore="Request time" style={{ marginBottom: "4px" }} readOnly />
<Input size='small' addonBefore="Processing time" style={{ marginBottom: "4px" }} readOnly /> <Input size='small' addonBefore="Processing time" style={{ marginBottom: "4px" }} readOnly />
<div style={{ marginBottom: "8px", marginTop: "8px", display: "flex" }}> <div style={{ marginBottom: "8px", marginTop: "8px", display: "flex" }}>
<Button type="primary" size='middle'>Confirm result</Button> <Button type="primary">Mark Not-reviewed</Button>
{/* <Tag icon={<ClockCircleOutlined />} color="warning" style={{ padding: "4px 16px", marginLeft: 8 }}>
Not Reviewed
</Tag> */}
<Tag icon={<CheckCircleOutlined />} color="success" style={{ padding: "4px 16px", marginLeft: 8 }}>
Reviewed
</Tag>
</div> </div>
<Table dataSource={dataSource} columns={columns} />
</Sider> </Sider>
</Layout> </Layout>
</> <Modal
title={t`Report Filters`}
open={isModalOpen}
width={700}
onOk={
() => {
setIsModalOpen(false);
}
}
onCancel={
() => {
setIsModalOpen(false);
}
}
>
<Form
style={{
marginTop: 30,
}}
>
<Form.Item
name='dateRange'
label={t`Date (GMT+8)`}
rules={[
{
required: true,
message: 'Please select a date range',
},
]}
style={{
marginBottom: 10,
}}
>
<DatePicker.RangePicker
value={filterDateRange}
onChange={(value) => {
console.log(value);
setFilterDateRange(value);
}}
style={{ width: 200 }}
/>
</Form.Item>
<div style={{ marginTop: 10, display: 'flex' }}>
<Form.Item
name='subsidiary'
label={t`Subsidiary`}
rules={[
{
required: true,
message: 'Please select a subsidiary',
},
]}
style={{
marginBottom: 10,
}}
>
<Select
placeholder='Select a subsidiary'
style={{ width: 200 }}
options={[
{ value: 'ALL', label: 'ALL' },
{ value: 'SEAU', label: 'SEAU' },
{ value: 'SESP', label: 'SESP' },
{ value: 'SME', label: 'SME' },
{ value: 'SEPCO', label: 'SEPCO' },
{ value: 'TSE', label: 'TSE' },
{ value: 'SEIN', label: 'SEIN' },
]}
/>
</Form.Item>
<Form.Item
name='reviewed'
label={t`Reviewed`}
rules={[
{
required: true,
message: 'Please select review status',
},
]}
style={{ marginLeft: 16 }}
>
<Select
style={{ width: 200 }}
options={[
{ value: 'ALL', label: 'ALL' },
{ value: 'YES', label: 'YES' },
{ value: 'NO', label: 'NO' },
]}
defaultValue={'ALL'}
/>
</Form.Item>
</div>
</Form>
</Modal>
<div
style={{
height: '40%',
overflowY: 'auto',
}}
>
<StyledTable dataSource={dataSource} columns={columns}
/>
</div>
</div>
); );
}; };
export default InferencePage; export default ReviewPage;