finishing slicing ui client benefit config

This commit is contained in:
korospace
2023-10-30 18:32:50 +07:00
parent e34ec97d27
commit de476ad3be
9 changed files with 497 additions and 29 deletions

View File

@@ -4,5 +4,5 @@ PORT=8000
REACT_APP_HOST_API_URL="http://lms.test"
VITE_API_URL="https://aso-api.linksehat.dev/api/internal"
# VITE_API_URL="http://localhost:8000/api/internal"
# VITE_API_URL="https://aso-api.linksehat.dev/api/internal"
VITE_API_URL="http://localhost:8000/api/internal"

View File

@@ -0,0 +1,58 @@
import Iconify from '@/components/Iconify';
import MenuPopover from './MenuPopover';
import { IconButton, MenuItem } from '@mui/material';
import { useEffect, useState } from 'react';
// ----------------------------------------------------------------------
type Props = {
actions: React.ReactNode;
};
export default function MoreMenu({ actions }: Props) {
const [open, setOpen] = useState<HTMLElement | null>(null);
// Close menu popover
useEffect(() => {
setOpen(null);
}, [actions])
const handleOpen = (event: React.MouseEvent<HTMLElement>) => {
setOpen(event.currentTarget);
};
const handleClose = () => {
setOpen(null);
};
return (
<>
<IconButton onClick={handleOpen}>
<Iconify icon={'eva:more-vertical-fill'} width={20} height={20} />
</IconButton>
<MenuPopover
open={Boolean(open)}
anchorEl={open}
onClose={handleClose}
anchorOrigin={{ vertical: 'top', horizontal: 'left' }}
transformOrigin={{ vertical: 'top', horizontal: 'right' }}
arrow="right-top"
sx={{
mt: -1,
width: 'auto',
minWidth: 160,
'& .MuiMenuItem-root': {
px: 1,
typography: 'body2',
borderRadius: 0.75,
'& svg': { mr: 2, width: 20, height: 20 },
},
}}
>
{actions}
</MenuPopover>
</>
);
}

View File

@@ -57,4 +57,4 @@ export default function TableMoreMenu({ actions, disableRipple }: Props) {
</MenuPopover>
    </>
  );
}
}

View File

@@ -46,7 +46,7 @@ export const getClaimList = async ( member_id: string ): Promise<ResponseListing
* Add Lab Result Detail
*/
export const AddLabResultDetail = async ( claim_code: string,data: DetailLabResultListType ): Promise<boolean> => {
data.date = data.date != '' ? fDate(data.date) : '';
data.date = data.date != '' && data.date != null ? fDate(data.date) : '';
const formData = makeFormData({...data});

View File

@@ -21,6 +21,7 @@ import FormControlLabel from '@mui/material/FormControlLabel';
import Checkbox from '@mui/material/Checkbox';
import { enqueueSnackbar } from 'notistack';
import BenefitConfigurationList from './components/BenefitConfigurationList';
// ----------------------------------------------------------------------
@@ -43,13 +44,13 @@ export default function Detail() {
.then((response) => {
setCustomerData(response.data.data.customer_data);
setDocumentData(response.data.data.documents);
setRequestDocumentData(response.data.data.request_documents);
setRequestDocumentData(response.data.data.request_documents);
})
.catch((error) => {
console.error(error);
});
}, []);
}, []);
function toTitleCase(str) {
return str.replace(/\w\S*/g, function(txt) {
@@ -114,7 +115,7 @@ export default function Detail() {
enqueueSnackbar('Something Went Wrong', { variant: 'error' });
})
}
return (
<Page title='Detail'>
<Container maxWidth={themeStretch ? false : 'xl'}>
@@ -163,7 +164,7 @@ export default function Detail() {
</Grid>
) : ''}
{documentData ? (
<Grid item xs={12} spacing={2}>
<Grid item xs={12}>
<Card sx={{padding: 2}}>
<Stack direction="row" alignItems="center" sx={{marginBottom: 4}}>
<Typography variant='subtitle1' sx={{color: '#19BBBB'}} gutterBottom>Additional Documents</Typography>
@@ -175,9 +176,9 @@ export default function Detail() {
{documentData?.map((documentType, index) => (
<Stack direction="column" spacing={2} key={index}>
<Typography variant="Subtitle2" gutterBottom>
{documentType.type === 'claim-diagnosis' ?
{documentType.type === 'claim-diagnosis' ?
'Diagnosis'
: documentType.type === 'claim-kondisi' ?
: documentType.type === 'claim-kondisi' ?
'Condition'
: documentType.type === 'claim-result' ?
'Supporting Result'
@@ -204,13 +205,13 @@ export default function Detail() {
<Stack direction="column" spacing={2} sx={{marginBottom: 2}}>
{requestDocumentData?.map((documentType, index) => (
<Stack direction="column" spacing={2} key={index}>
<Stack direction="row" spacing={1} sx={{color: '#637381'}}>
<InsertDriveFileIcon />
<Typography variant="body2" gutterBottom>
{documentType.type === 'claim-diagnosis' ?
{documentType.type === 'claim-diagnosis' ?
'Diagnosis'
: documentType.type === 'claim-kondisi' ?
: documentType.type === 'claim-kondisi' ?
'Condition'
: documentType.type === 'claim-result' ?
'Supporting Result'
@@ -272,8 +273,8 @@ export default function Detail() {
</Card>
</Grid>
): ''}
<Grid item xs={12} spacing={2}>
<Card sx={{padding: 2}}>
<Grid item xs={12}>
<Card sx={{padding: 3}}>
<Stack direction="row" alignItems="center" sx={{marginBottom: 4}}>
<Typography variant='subtitle1' sx={{color: '#19BBBB'}} gutterBottom>History of Hospital Care</Typography>
<Button variant="outlined" startIcon={<AddIcon/>} sx={{marginLeft: 'auto'}}>
@@ -284,8 +285,8 @@ export default function Detail() {
</Stack>
</Card>
</Grid>
<Grid item xs={12} spacing={2}>
<Card sx={{padding: 2}}>
<Grid item xs={12}>
<Card sx={{padding: 3}}>
<Stack direction="row" alignItems="center" sx={{marginBottom: 4}}>
<Typography variant='subtitle1' sx={{color: '#19BBBB'}} gutterBottom>Diagnostic History</Typography>
</Stack>
@@ -293,8 +294,8 @@ export default function Detail() {
</Stack>
</Card>
</Grid>
<Grid item xs={12} spacing={2}>
<Card sx={{padding: 2}}>
<Grid item xs={12}>
<Card sx={{padding: 3}}>
<Stack direction="row" alignItems="center" sx={{marginBottom: 4}}>
<Typography variant='subtitle1' sx={{color: '#19BBBB'}} gutterBottom>Diagnosis Summary</Typography>
<Button variant="outlined" startIcon={<AddIcon/>} sx={{marginLeft: 'auto'}}>
@@ -305,8 +306,8 @@ export default function Detail() {
</Stack>
</Card>
</Grid>
<Grid item xs={12} spacing={2}>
<Card sx={{padding: 2}}>
<Grid item xs={12}>
<Card sx={{padding: 3}}>
<Stack direction="row" alignItems="center" sx={{marginBottom: 4}}>
<Typography variant='subtitle1' sx={{color: '#19BBBB'}} gutterBottom>Service</Typography>
<Button variant="outlined" startIcon={<AddIcon/>} sx={{marginLeft: 'auto'}}>
@@ -317,13 +318,31 @@ export default function Detail() {
</Stack>
</Card>
</Grid>
<Grid item xs={12} spacing={2}>
<Card sx={{padding: 2}}>
<Stack direction="row" alignItems="center" sx={{marginBottom: 4}}>
<Typography variant='subtitle1' sx={{color: '#19BBBB'}} gutterBottom>Client Benefit Configuration</Typography>
</Stack>
<Stack direction="column" spacing={2} sx={{marginBottom: 2}}>
</Stack>
<Grid item xs={12}>
<Card sx={{padding: 3}}>
<Grid container spacing={4}>
{/* title */}
<Grid item xs={12}>
<Typography variant='subtitle1' sx={{color: '#19BBBB'}}>Client Benefit Configuration</Typography>
</Grid>
{/* no benefit selected */}
{
false
?
(
<Grid item xs={12}>
<Typography variant='body2' sx={{color: '#919EAB', paddingBottom: '14px', textAlign: 'center'}}>Tidak ada benefit yang dipilih</Typography>
</Grid>
)
:
(
<Grid item xs={12}>
<BenefitConfigurationList />
</Grid>
)
}
</Grid>
</Card>
</Grid>
<Grid item xs={12} md={12}>
@@ -338,4 +357,4 @@ export default function Detail() {
</Container>
</Page>
);
}
}

View File

@@ -0,0 +1,23 @@
import { BenefitConfigurationListType } from "./Types";
/**
* Get Benefit Configuration List
*/
export const getBenefitConfigurationList = async ( ): Promise<BenefitConfigurationListType[]> => {
return [
{
benefit_name: 'Konsultasi Dokter Umum',
amount_incurred: 75000,
amount_approved: 75000,
amount_not_approved: 0,
excess_paid: 0
},
{
benefit_name: 'Biaya Perawatan Setelah Rawat Inap',
amount_incurred: 925000,
amount_approved: 50000,
amount_not_approved: 425000,
excess_paid: 0
},
];
};

View File

@@ -0,0 +1,10 @@
/**
* Benefit Configuration List Type
*/
export type BenefitConfigurationListType = {
benefit_name: string,
amount_incurred: number,
amount_approved: number,
amount_not_approved: number,
excess_paid: number
}

View File

@@ -0,0 +1,194 @@
import { useEffect, useState } from 'react';
import { Box, Grid } from '@mui/material';
import Button from '@mui/material/Button';
import { styled } from '@mui/material/styles';
import Dialog from '@mui/material/Dialog';
import DialogTitle from '@mui/material/DialogTitle';
import DialogContent from '@mui/material/DialogContent';
import DialogActions from '@mui/material/DialogActions';
import IconButton from '@mui/material/IconButton';
import CloseIcon from '@mui/icons-material/Close';
import Typography from '@mui/material/Typography';
import { useForm } from 'react-hook-form';
import { FormProvider, RHFTextField } from '@/components/hook-form';
/**
* Custom Style
* =====================================================
*/
const BootstrapDialog = styled(Dialog)(({ theme }) => ({
}));
/**
* Utils, Types, Functions
* ============================================
*/
import { BenefitConfigurationListType } from '../Model/Types';
import palette from '@/theme/palette';
/**
* Props
* =====================================================
*/
type Props = {
data?: BenefitConfigurationListType,
isOpen: boolean,
handleCancleProp: () => void,
};
export default function BenefitConfigurationDialog({ ...props }: Props) {
// setup form
// ====================================
const defaultValues: BenefitConfigurationListType = {
benefit_name: '',
amount_incurred: 0,
amount_approved: 0,
amount_not_approved: 0,
excess_paid: 0,
};
const methods = useForm<any>({
defaultValues
});
const { handleSubmit, reset, setValue, formState: { isDirty, isSubmitting } } = methods;
// Submit Form
// =====================================
const submitHandler = async (data: BenefitConfigurationListType) => {
return true;
}
// Set Value Form
// =====================================
useEffect(() => {
setValue('amount_incurred', props.data?.amount_incurred)
setValue('amount_approved', props.data?.amount_approved)
setValue('amount_not_approved', props.data?.amount_not_approved)
setValue('excess_paid', props.data?.excess_paid)
}, [props.data])
return (
<FormProvider methods={methods} onSubmit={handleSubmit(submitHandler)}>
<BootstrapDialog
onClose={props.handleCancleProp}
aria-labelledby="customized-dialog-title"
open={props.isOpen}
maxWidth={'md'}
>
<DialogTitle sx={{ m: 0, p: 2, background: palette.light.primary.main, color: palette.light.grey[0], display: 'flex', alignItems: 'center', justifyContent: 'space-between' }} id="customized-dialog-title">
<Typography variant="body2" sx={{ fontWeight: 'bold' }}>
Client Benefit Configuration
</Typography>
<IconButton
aria-label="close"
onClick={props.handleCancleProp}
sx={{color: (theme) => theme.palette.grey[0]}}
>
<CloseIcon />
</IconButton>
</DialogTitle>
<DialogContent sx={{ p: '0px' }}>
<Box sx={{ py: '24px', px: '32px'}}>
<Box sx={{ p: '24px', border: '1px solid rgba(0,0,0,0.125)', borderRadius: '12px'}}>
<Grid container spacing={3}>
{/* Benefit Name */}
<Grid item xs={12}>
<Typography variant="body2" sx={{ fontWeight: 'bold'}}>
{props.data?.benefit_name}
</Typography>
</Grid>
<Grid item xs={12}>
<Grid container spacing={3}>
<Grid item xs={3}>
<Grid container spacing={2}>
<Grid item xs={12}>
<Typography variant="body2" component="div">
Amount Incurred*
</Typography>
</Grid>
<Grid item xs={12} sx={{display: 'flex', gap: 1}}>
<RHFTextField
id="amount_incurred"
name='amount_incurred'
placeholder='Amount Incurred'
/>
</Grid>
</Grid>
</Grid>
<Grid item xs={3}>
<Grid container spacing={2}>
<Grid item xs={12}>
<Typography variant="body2" component="div">
Amount Approved*
</Typography>
</Grid>
<Grid item xs={12} sx={{display: 'flex', gap: 1}}>
<RHFTextField
id="amount_approved"
name='amount_approved'
placeholder='Amount Approved'
/>
</Grid>
</Grid>
</Grid>
<Grid item xs={3}>
<Grid container spacing={2}>
<Grid item xs={12}>
<Typography variant="body2" component="div">
Amount Not Approved*
</Typography>
</Grid>
<Grid item xs={12} sx={{display: 'flex', gap: 1}}>
<RHFTextField
id="amount_not_approved"
name='amount_not_approved'
placeholder='Amount Not Approved'
/>
</Grid>
</Grid>
</Grid>
<Grid item xs={3}>
<Grid container spacing={2}>
<Grid item xs={12}>
<Typography variant="body2" component="div">
Excess Paid*
</Typography>
</Grid>
<Grid item xs={12} sx={{display: 'flex', gap: 1}}>
<RHFTextField
id="excess_paid"
name='excess_paid'
placeholder='Excess Paid'
/>
</Grid>
</Grid>
</Grid>
</Grid>
</Grid>
</Grid>
</Box>
</Box>
</DialogContent>
<DialogActions>
<Button variant='outlined' onClick={props.handleCancleProp} aria-label="close">
Cancle
</Button>
<Button variant='contained' onClick={props.handleCancleProp}>
Save
</Button>
</DialogActions>
</BootstrapDialog>
</FormProvider>
);
}

View File

@@ -0,0 +1,164 @@
/**
* Core
* ============================================
*/
import { useEffect, useState } from 'react';
import { Box, Typography, Grid, MenuItem } from '@mui/material';
/**
* Components
* ============================================
*/
// - Global -
import MoreMenu from '@/components/MoreMenu';
/**
* Icon
* ============================================
*/
import { EditOutlined } from '@mui/icons-material';
/**
* Utils, Types, Functions
* ============================================
*/
import { BenefitConfigurationListType } from '../Model/Types';
import { getBenefitConfigurationList } from '../Model/Functions';
import palette from '@/theme/palette';
import BenefitConfigurationDialog from './BenefitConfigurationDialog';
export default function BenefitConfigurationList() {
// State
// --------------------
const [BenefitConfigurationList, setBenefitConfigurationList] = useState<BenefitConfigurationListType[]>();
const [BenefitConfigurationData, setBenefitConfigurationData] = useState<BenefitConfigurationListType>();
const [isDialogOpen, setIsDialogOpen] = useState<boolean>(false);
// Use Effect
// --------------------
useEffect(() => {
loadDataTableData();
}, [])
// Load Data
// -------------------
const loadDataTableData = async () => {
const response = await getBenefitConfigurationList();
setBenefitConfigurationList(response);
}
return (
<Box>
{/* row list */}
{
BenefitConfigurationList?.map((row, index) => {
return (
<Box key={index} sx={{ border: '1px solid rgba(0,0,0,0.125)', px: '24px', py: '20px', marginBottom: '24px', borderRadius: '12px'}}>
<Grid container spacing={2}>
<Grid item xs={12}>
<Grid container spacing={2}>
<Grid item xs={6}>
<Typography variant="body2" sx={{ fontWeight: 'bold'}}>
{row.benefit_name}
</Typography>
</Grid>
<Grid item xs={6} sx={{ display: 'flex', placeContent: 'end' }}>
<MoreMenu actions={
<>
<MenuItem onClick={() => {
setIsDialogOpen(true)
setBenefitConfigurationData(row)
}}
>
<EditOutlined />
Edit
</MenuItem>
</>
} />
</Grid>
</Grid>
</Grid>
<Grid item xs={12}>
<Box sx={{ py: '8px', px: '12px', background: palette.light.grey[50012], borderRadius: '6px'}}>
<Grid container spacing={1}>
{/* Amount Incurred */}
<Grid item xs={3}>
<Grid container sx={{ borderRight: `0.5px solid ${palette.light.grey[400]}` }}>
<Grid item xs={12}>
<Typography variant="caption">
Amount Incurred
</Typography>
</Grid>
<Grid item xs={12}>
<Typography variant="caption" sx={{ fontWeight: 'bold' }}>
{row.amount_incurred}
</Typography>
</Grid>
</Grid>
</Grid>
{/* Amount Approved */}
<Grid item xs={3}>
<Grid container sx={{ borderRight: `0.5px solid ${palette.light.grey[400]}` }}>
<Grid item xs={12}>
<Typography variant="caption">
Amount Approved
</Typography>
</Grid>
<Grid item xs={12}>
<Typography variant="caption" sx={{ fontWeight: 'bold' }}>
{row.amount_approved}
</Typography>
</Grid>
</Grid>
</Grid>
{/* Amount Not Approved */}
<Grid item xs={3}>
<Grid container sx={{ borderRight: `0.5px solid ${palette.light.grey[400]}` }}>
<Grid item xs={12}>
<Typography variant="caption">
Amount Not Approved
</Typography>
</Grid>
<Grid item xs={12}>
<Typography variant="caption" sx={{ fontWeight: 'bold' }}>
{row.amount_not_approved}
</Typography>
</Grid>
</Grid>
</Grid>
{/* Excess Paid* */}
<Grid item xs={3}>
<Grid container>
<Grid item xs={12}>
<Typography variant="caption">
Excess Paid*
</Typography>
</Grid>
<Grid item xs={12}>
<Typography variant="caption" sx={{ fontWeight: 'bold' }}>
{row.excess_paid}
</Typography>
</Grid>
</Grid>
</Grid>
</Grid>
</Box>
</Grid>
</Grid>
</Box>
)
})
}
{/* Dialog */}
<BenefitConfigurationDialog data={BenefitConfigurationData} isOpen={isDialogOpen} handleCancleProp={() => setIsDialogOpen(false)} />
</Box>
);
}