alarm service

This commit is contained in:
Muhammad Fajar
2022-11-29 15:22:46 +07:00
parent 1f5695cf6a
commit e83a6784f3
4 changed files with 181 additions and 365 deletions

View File

@@ -0,0 +1,24 @@
/* ---------------------------------- @mui ---------------------------------- */
import { TablePagination, TablePaginationProps } from '@mui/material';
import { Box } from '@mui/system';
export default function BaseTablePagination({
count,
onPageChange,
page,
rowsPerPage,
onRowsPerPageChange,
}: TablePaginationProps) {
return (
<Box sx={{ m: 2 }} display="flex" justifyContent="flex-end">
<TablePagination
component="div"
count={count}
page={page}
onPageChange={onPageChange}
rowsPerPage={rowsPerPage}
onRowsPerPageChange={onRowsPerPageChange}
/>
</Box>
);
}

View File

@@ -1,19 +1,105 @@
// mui
import { Container, Grid, Card } from '@mui/material';
// components
/* ---------------------------------- react --------------------------------- */
import { useState, SyntheticEvent } from 'react';
/* ---------------------------------- @mui ---------------------------------- */
import { Box, Tabs, Tab, Container, Grid, Card, Typography } from '@mui/material';
import { styled } from '@mui/material/styles';
/* ------------------------------- components ------------------------------- */
import Page from '../../components/Page';
// utils
/* ---------------------------------- hooks --------------------------------- */
import useSettings from '../../hooks/useSettings';
// sections
// import ListTable from '../../sections/claimreports/ListTable';
// import ClaimStatusCard from '../../sections/claimreports/ClaimStatusCard';
import List from './List';
/* ------------------------------ tabs setting ------------------------------ */
/* ---------------------------------- types --------------------------------- */
interface TabPanelProps {
children?: React.ReactNode;
index: number;
value: number;
}
interface StyledTabsProps {
children?: React.ReactNode;
value: number;
onChange: (event: React.SyntheticEvent, newValue: number) => void;
}
interface StyledTabProps {
label: string;
icon?: string | React.ReactElement;
}
/* -------------------------------- tab style ------------------------------- */
function TabPanel(props: TabPanelProps) {
const { children, value, index, ...other } = props;
return (
<div
role="tabpanel"
hidden={value !== index}
id={`simple-tabpanel-${index}`}
aria-labelledby={`simple-tab-${index}`}
{...other}
>
{value === index && (
<Box>
<Typography>{children}</Typography>
</Box>
)}
</div>
);
}
function a11yProps(index: number) {
return {
id: `simple-tab-${index}`,
'aria-controls': `simple-tabpanel-${index}`,
};
}
const StyledTabs = styled((props: StyledTabsProps) => <Tabs {...props} />)({
backgroundColor: '#F4F6F8',
padding: '0 24px',
'& .MuiTabs-indicator': {
display: 'flex',
justifyContent: 'space-between',
backgroundColor: 'transparent',
},
'& .MuiTabs-indicatorSpan': {
maxWidth: 40,
backgroundColor: '#635ee7',
},
});
const StyledTab = styled((props: StyledTabProps) => <Tab disableRipple {...props} />)(
({ theme }) => ({
textTransform: 'none',
fontWeight: 600,
color: theme.palette.grey[600],
marginRight: '5rem',
'&.Mui-selected': {
color: '#212B36',
borderBottom: '2px solid ' + theme.palette.primary.main,
},
'&:hover': {
color: '#212B36',
opacity: 1,
borderBottom: '2px solid ' + theme.palette.primary.main,
},
})
);
/* -------------------------------------------------------------------------- */
export default function Drugs() {
const { themeStretch } = useSettings();
// const { corporate_id } = useParams();
const [value, setValue] = useState(0);
const handleChange = (event: SyntheticEvent, newValue: number) => {
setValue(newValue);
};
return (
<Page title="Alarm Center">
@@ -21,7 +107,22 @@ export default function Drugs() {
<Grid container>
<Grid item xs={12} lg={12} md={12}>
<Card>
<List />
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
<StyledTabs value={value} onChange={handleChange} aria-label="basic tabs example">
<StyledTab label="All Data (20)" {...a11yProps(0)} />
<StyledTab label="Ongoing (5)" {...a11yProps(1)} />
<StyledTab label="Done (15)" {...a11yProps(2)} />
</StyledTabs>
</Box>
<TabPanel value={value} index={0}>
<List />
</TabPanel>
<TabPanel value={value} index={1}>
Item Two
</TabPanel>
<TabPanel value={value} index={2}>
Item Two
</TabPanel>
</Card>
</Grid>
</Grid>

View File

@@ -1,16 +1,6 @@
// @mui
import {
Box,
Button,
Card,
Collapse,
IconButton,
InputLabel,
MenuItem,
OutlinedInput,
Paper,
Select,
SelectChangeEvent,
Table,
TableBody,
TableCell,
@@ -18,39 +8,17 @@ import {
TableHead,
TableRow,
TextField,
Typography,
Badge,
Tab,
Tabs,
CardHeader,
Stack,
Menu,
ButtonGroup,
Pagination,
Grid,
} from '@mui/material';
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight';
import AddIcon from '@mui/icons-material/Add';
import UploadIcon from '@mui/icons-material/Upload';
import CancelIcon from '@mui/icons-material/Cancel';
// hooks
import React, { ChangeEvent, Component, useEffect, useRef, useState } from 'react';
import useSettings from '../../hooks/useSettings';
import { useNavigate, useParams, useSearchParams } from 'react-router-dom';
import React, { ChangeEvent, useEffect, useRef, useState } from 'react';
import { useSearchParams } from 'react-router-dom';
// components
import axios from '../../utils/axios';
import { LaravelPaginatedData } from '../../@types/paginated-data';
import { Icd } from '../../@types/diagnosis';
import BasePagination from '../../components/BasePagination';
import { Member } from '../../@types/member';
export default function List() {
const navigate = useNavigate();
const { themeStretch } = useSettings();
const { corporate_id } = useParams();
const [searchParams, setSearchParams] = useSearchParams();
const [importResult, setImportResult] = useState(null);
function SearchInput(props: any) {
// SEARCH
@@ -70,10 +38,10 @@ export default function List() {
useEffect(() => {
// Trigger First Search
setSearchText(searchParams.get('search') ?? '');
}, [searchParams]);
}, []);
return (
<form onSubmit={handleSearchSubmit} style={{ width: '100%' }}>
<form onSubmit={handleSearchSubmit} style={{ width: '100%', padding: '20px 24px' }}>
<TextField
id="search-input"
ref={searchInput}
@@ -87,331 +55,55 @@ export default function List() {
);
}
function ImportForm(props: any) {
// IMPORT
// Create Button Menu
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
const createMenu = Boolean(anchorEl);
const importForm = useRef<HTMLInputElement>(null);
const [currentImportFileName, setCurrentImportFileName] = useState(null);
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
const handleImportButton = () => {
if (importForm?.current) {
handleClose();
importForm.current ? importForm.current.click() : console.log('No File selected');
} else {
alert('No file selected');
}
};
const handleCancelImportButton = () => {
importForm.current.value = '';
importForm.current.dispatchEvent(new Event('change', { bubbles: true }));
};
const handleImportChange = (event: any) => {
if (event.target.files[0]) {
setCurrentImportFileName(event.target.files[0].name);
} else {
setCurrentImportFileName(null);
}
};
const handleUpload = () => {
if (importForm.current?.files.length) {
const formData = new FormData();
formData.append('file', importForm.current?.files[0]);
axios
.post(`master/formularium/import`, formData)
.then((response) => {
handleCancelImportButton();
loadDataTableData();
setImportResult(response.data);
// alert('Succesfully read '+ response.data.total_successed_row + ' with ' + response.data.total_failed_row + ' failed rows');
})
.catch((response) => {
alert(
'Looks like something went wrong. Please check your data and try again. ' +
response.message
);
});
} else {
alert('No File Selected');
}
};
return (
<div>
<input
type="file"
id="file"
ref={importForm}
style={{ display: 'none' }}
onChange={handleImportChange}
accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel, text/plain"
/>
{!currentImportFileName && (
<Stack direction={'row'} spacing={2} sx={{ p: 2 }}>
<SearchInput onSearch={applyFilter} />
</Stack>
)}
{currentImportFileName && (
<Stack direction={'row'} spacing={2} sx={{ p: 2 }}>
<ButtonGroup variant="outlined" aria-label="outlined button group" fullWidth>
<Button onClick={handleImportButton} fullWidth>
{currentImportFileName ?? 'No File Selected'}
</Button>
<Button
onClick={handleCancelImportButton}
size="small"
fullWidth={false}
sx={{ p: 1.8 }}
>
<CancelIcon color="error" />
</Button>
</ButtonGroup>
<Button
id="upload-button"
variant="outlined"
startIcon={<UploadIcon />}
sx={{ p: 1.8 }}
onClick={handleUpload}
>
Upload
</Button>
</Stack>
)}
{importResult && (
<Stack direction={'row'} sx={{ px: 2, pb: 2 }}>
<Box sx={{ color: 'text.secondary' }}>
Last Import Result Report :{' '}
<a href={importResult.result_file?.url ?? '#'}>
{importResult.result_file?.name ?? '-'}
</a>
</Box>
</Stack>
)}
</div>
);
}
// Called on every row to map the data to the columns
function createData(member: Member): Member {
return {
...member,
};
}
// Generate the every row of the table
function Row(props: { row: ReturnType<typeof createData> }) {
const { row } = props;
const [open, setOpen] = React.useState(true);
return (
<React.Fragment>
<TableRow sx={{ '& > *': { borderBottom: 'unset' } }}>
<TableCell>
<IconButton aria-label="expand row" size="small" onClick={() => setOpen(!open)}>
{open ? <KeyboardArrowDownIcon /> : <KeyboardArrowRightIcon />}
</IconButton>
</TableCell>
<TableCell align="left">{row.member_id}</TableCell>
<TableCell align="left">{row.payor_id}</TableCell>
<TableCell align="left">{row.name}</TableCell>
<TableCell align="left">{row.nik}</TableCell>
<TableCell align="left">{row.nric}</TableCell>
<TableCell align="right">
<Button variant="outlined" color="success" size="small">
Active
</Button>
</TableCell>
{/* <TableCell align="right"><Button variant="outlined" color="error" size="small">Disable</Button></TableCell> */}
</TableRow>
{/* COLLAPSIBLE ROW */}
<TableRow>
<TableCell style={{ paddingBottom: 0, paddingTop: 0 }} colSpan={99}>
<Collapse in={open} timeout="auto" unmountOnExit>
<Box sx={{ borderBottom: 1 }}>
<Typography variant="body2" gutterBottom component="div">
<Grid></Grid>
</Typography>
</Box>
</Collapse>
</TableCell>
</TableRow>
</React.Fragment>
);
}
// Dummy Default Data
const [dataTableIsLoading, setDataTableLoading] = useState(true);
const [dataTableLastRequest, setDataTableLastRequest] = useState(0);
const [dataTableResponseState, setDataTableResponseState] = useState('idle');
const [dataTableData, setDataTableData] = useState<LaravelPaginatedData>({
current_page: 1,
data: [],
path: '',
first_page_url: '',
last_page: 1,
last_page_url: '',
next_page_url: '',
prev_page_url: '',
per_page: 10,
from: 0,
to: 0,
total: 0,
});
const [dataTablePage, setDataTablePage] = useState(5);
const loadDataTableData = async (appliedFilter: any | null = null) => {
setDataTableLoading(true);
const filter = appliedFilter ? appliedFilter : Object.fromEntries([...searchParams.entries()]);
const response = await axios.get('/members', { params: filter });
setDataTableData(response.data.members);
setDataTableLoading(false);
};
const headStyle = {
fontWeight: 'bold',
};
const applyFilter = async (searchFilter: string) => {
await loadDataTableData({ search: searchFilter });
setSearchParams({ search: searchFilter });
};
const handlePageChange = (event: ChangeEvent, value: number) => {
const filter = Object.fromEntries([...searchParams.entries(), ['page', value]]);
loadDataTableData(filter);
setSearchParams(filter);
};
useEffect(() => {
loadDataTableData();
}, []);
return (
<Stack>
<Stack
direction="row"
spacing={5}
sx={{ backgroundColor: '#F4F6F8', paddingX: 3, paddingY: '13px' }}
>
<Button variant="subtitle2" sx={{ position: 'relative' }}>
All Data ( Count )
<Typography
sx={{
borderBottom: '2px solid #19BBBB',
borderRadius: '1px',
position: 'absolute',
bottom: '-13px',
left: 0,
width: '100%',
}}
component="span"
/>
</Button>
<Button variant="subtitle2" sx={{ position: 'relative' }}>
Ongoing ( Count )
{/* <Typography
sx={{
borderBottom: '2px solid #19BBBB',
borderRadius: '1px',
position: 'absolute',
bottom: '-13px',
left: 0,
width: '100%',
}}
component="span"
/> */}
</Button>
<Button variant="subtitle2" sx={{ position: 'relative' }}>
Done ( Count )
{/* <Typography
sx={{
borderBottom: '2px solid #19BBBB',
borderRadius: '1px',
position: 'absolute',
bottom: '-13px',
left: 0,
width: '100%',
}}
component="span"
/> */}
</Button>
</Stack>
{/* Search */}
<SearchInput />
<ImportForm />
{/* The Main Table */}
<TableContainer component={Paper}>
<Table aria-label="collapsible table">
<TableHead>
<TableRow>
<TableCell style={headStyle} align="left">
No
</TableCell>
<TableCell style={headStyle} align="left">
Name
</TableCell>
<TableCell style={headStyle} align="left">
Member ID
</TableCell>
<TableCell style={headStyle} align="left">
Service
</TableCell>
<TableCell style={headStyle} align="left">
Start Date
</TableCell>
<TableCell style={headStyle} align="left">
End Date
</TableCell>
<TableCell style={headStyle} align="right" width={100}>
Status
</TableCell>
</TableRow>
</TableHead>
<TableBody>
<TableRow>
<TableCell colSpan={8} align="center">
No Data
</TableCell>
</TableRow>
</TableBody>
</Table>
</TableContainer>
<Card>
{/* The Main Table */}
<TableContainer component={Paper}>
<Table aria-label="collapsible table">
<TableBody>
<TableRow>
<TableCell style={headStyle} align="left">
No
</TableCell>
<TableCell style={headStyle} align="left">
Name
</TableCell>
<TableCell style={headStyle} align="left">
Member ID
</TableCell>
<TableCell style={headStyle} align="left">
Service
</TableCell>
<TableCell style={headStyle} align="left">
Start Date
</TableCell>
<TableCell style={headStyle} align="left">
End Date
</TableCell>
<TableCell style={headStyle} align="right" width={100}>
Status
</TableCell>
</TableRow>
</TableBody>
{dataTableIsLoading ? (
<TableBody>
<TableRow>
<TableCell colSpan={8} align="center">
Loading
</TableCell>
</TableRow>
</TableBody>
) : dataTableData.data.length === 0 ? (
<TableBody>
<TableRow>
<TableCell colSpan={8} align="center">
No Data
</TableCell>
</TableRow>
</TableBody>
) : (
<TableBody>
{dataTableData.data.map((row) => (
<Row key={row.id} row={row} />
))}
</TableBody>
)}
</Table>
</TableContainer>
<BasePagination paginationData={dataTableData} onPageChange={handlePageChange} />
</Card>
{/* Pagination */}
{/* <BasePagination onPageChange={handlePageChange} /> */}
</Stack>
);
}

View File

@@ -1,6 +1,5 @@
// mui
import {
Button,
Box,
Tabs,
Tab,
@@ -18,7 +17,7 @@ import Page from '../../components/Page';
import Iconify from '../../components/Iconify';
// utils
import useSettings from '../../hooks/useSettings';
import { useRef, useState, SyntheticEvent } from 'react';
import { useState, SyntheticEvent } from 'react';
// sections
// import ListTable from '../../sections/claimreports/ListTable';
// import ClaimStatusCard from '../../sections/claimreports/ClaimStatusCard';