[WIP] Add Approve Button
This commit is contained in:
@@ -0,0 +1,97 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\Internal\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Helpers\Helper;
|
||||||
|
use App\Models\ClaimRequest;
|
||||||
|
use Illuminate\Contracts\Support\Renderable;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Routing\Controller;
|
||||||
|
|
||||||
|
class ClaimRequestController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
* @return Renderable
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$claimRequests = ClaimRequest::query()
|
||||||
|
->with(['member'])
|
||||||
|
->paginate();
|
||||||
|
|
||||||
|
return $claimRequests;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for creating a new resource.
|
||||||
|
* @return Renderable
|
||||||
|
*/
|
||||||
|
public function create()
|
||||||
|
{
|
||||||
|
return view('internal::create');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
* @param Request $request
|
||||||
|
* @return Renderable
|
||||||
|
*/
|
||||||
|
public function store(Request $request)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the specified resource.
|
||||||
|
* @param int $id
|
||||||
|
* @return Renderable
|
||||||
|
*/
|
||||||
|
public function show($id)
|
||||||
|
{
|
||||||
|
return view('internal::show');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for editing the specified resource.
|
||||||
|
* @param int $id
|
||||||
|
* @return Renderable
|
||||||
|
*/
|
||||||
|
public function edit($id)
|
||||||
|
{
|
||||||
|
return view('internal::edit');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
* @param Request $request
|
||||||
|
* @param int $id
|
||||||
|
* @return Renderable
|
||||||
|
*/
|
||||||
|
public function update(Request $request, $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the specified resource from storage.
|
||||||
|
* @param int $id
|
||||||
|
* @return Renderable
|
||||||
|
*/
|
||||||
|
public function destroy($id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
public function approve($id)
|
||||||
|
{
|
||||||
|
$claimRequest = ClaimRequest::findOrFail($id);
|
||||||
|
|
||||||
|
$claimRequest->status = 'approved';
|
||||||
|
$claimRequest->save();
|
||||||
|
|
||||||
|
// Generate LOG
|
||||||
|
|
||||||
|
return $claimRequest;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ use Modules\Internal\Http\Controllers\Api\AuthController;
|
|||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Modules\Internal\Http\Controllers\Api\BenefitController;
|
use Modules\Internal\Http\Controllers\Api\BenefitController;
|
||||||
use Modules\Internal\Http\Controllers\Api\ClaimController;
|
use Modules\Internal\Http\Controllers\Api\ClaimController;
|
||||||
|
use Modules\Internal\Http\Controllers\Api\ClaimRequestController;
|
||||||
use Modules\Internal\Http\Controllers\Api\CorporateBenefitController;
|
use Modules\Internal\Http\Controllers\Api\CorporateBenefitController;
|
||||||
use Modules\Internal\Http\Controllers\Api\CorporateController;
|
use Modules\Internal\Http\Controllers\Api\CorporateController;
|
||||||
use Modules\Internal\Http\Controllers\Api\CorporateFormulariumController;
|
use Modules\Internal\Http\Controllers\Api\CorporateFormulariumController;
|
||||||
@@ -120,6 +121,9 @@ Route::prefix('internal')->group(function () {
|
|||||||
Route::get('search-specialities', [SpecialityController::class, 'searchSpeciality']);
|
Route::get('search-specialities', [SpecialityController::class, 'searchSpeciality']);
|
||||||
Route::resource('organizations', OrganizationController::class);
|
Route::resource('organizations', OrganizationController::class);
|
||||||
Route::resource('doctors', DoctorController::class);
|
Route::resource('doctors', DoctorController::class);
|
||||||
|
|
||||||
|
Route::get('claim-requests', [ClaimRequestController::class, 'index'])->name('claim-requests.index');
|
||||||
|
Route::post('claim-requests/{id}/approve', [ClaimRequestController::class, 'approve'])->name('claim-requests.approve');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Route::resource('organizations', OrganizationController::class);
|
// Route::resource('organizations', OrganizationController::class);
|
||||||
|
|||||||
@@ -58,6 +58,13 @@ const navConfig = [
|
|||||||
{ title: 'Hospitals', path: '/hospitals' },
|
{ title: 'Hospitals', path: '/hospitals' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: 'LOG REQUEST',
|
||||||
|
path: '/claim-requests',
|
||||||
|
// children: [
|
||||||
|
// { title: 'Request', path: '/case-request' },
|
||||||
|
// ],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: 'CASE MANAGEMENT',
|
title: 'CASE MANAGEMENT',
|
||||||
path: '/claims',
|
path: '/claims',
|
||||||
|
|||||||
64
frontend/dashboard/src/pages/ClaimRequests/CreateUpdate.tsx
Executable file
64
frontend/dashboard/src/pages/ClaimRequests/CreateUpdate.tsx
Executable file
@@ -0,0 +1,64 @@
|
|||||||
|
import * as Yup from 'yup';
|
||||||
|
import { yupResolver } from '@hookform/resolvers/yup';
|
||||||
|
import { Autocomplete, Button, Card, Collapse, Container, Divider, Grid, Stack, Table, TableBody, TableCell, TableRow, TextField, Typography } from '@mui/material';
|
||||||
|
import { Controller, useForm } from 'react-hook-form';
|
||||||
|
import { useParams, useNavigate } from 'react-router-dom';
|
||||||
|
import HeaderBreadcrumbs from '../../components/HeaderBreadcrumbs';
|
||||||
|
import { FormProvider, RHFCheckbox, RHFSelect, RHFTextField } from '../../components/hook-form';
|
||||||
|
import Page from '../../components/Page';
|
||||||
|
import useSettings from '../../hooks/useSettings';
|
||||||
|
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||||
|
import MemberSelectDialog from '../../components/dialogs/MemberSelectDialog';
|
||||||
|
import { styled } from '@mui/system';
|
||||||
|
import axios from '../../utils/axios';
|
||||||
|
import { enqueueSnackbar } from 'notistack';
|
||||||
|
import { LoadingButton } from '@mui/lab';
|
||||||
|
import { fCurrency } from '../../utils/formatNumber';
|
||||||
|
import Iconify from '../../components/Iconify';
|
||||||
|
import Form from './Form';
|
||||||
|
|
||||||
|
export default function ClaimsCreateUpdate() {
|
||||||
|
|
||||||
|
const { themeStretch } = useSettings();
|
||||||
|
const { id } = useParams();
|
||||||
|
|
||||||
|
const isEdit = id ? true : false;
|
||||||
|
|
||||||
|
const [currentClaim, setCurrentClaim] = useState();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isEdit) {
|
||||||
|
axios.get('/claims/' + id).then((res) => {
|
||||||
|
// console.log('Yeet', res.data);
|
||||||
|
setCurrentClaim(res.data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [id]);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Page title={isEdit ? `Edit Claim : ${currentClaim?.id}` : "Create New Claim"}>
|
||||||
|
<Container maxWidth={themeStretch ? false : 'xl'}>
|
||||||
|
<Stack direction="row" alignItems="center">
|
||||||
|
<HeaderBreadcrumbs
|
||||||
|
heading={
|
||||||
|
!isEdit
|
||||||
|
? 'Create New Claim'
|
||||||
|
: `Edit Claim : ${currentClaim?.code}`
|
||||||
|
}
|
||||||
|
links={[
|
||||||
|
{ name: 'Dashboard', href: '/dashboard' },
|
||||||
|
{
|
||||||
|
name: 'Claim',
|
||||||
|
href: '/claims',
|
||||||
|
},
|
||||||
|
{ name: !isEdit ? 'Create' : currentClaim?.id ?? '' },
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
|
||||||
|
<Form isEdit={isEdit} currentClaim={currentClaim} />
|
||||||
|
</Container>
|
||||||
|
</Page>
|
||||||
|
);
|
||||||
|
}
|
||||||
596
frontend/dashboard/src/pages/ClaimRequests/Form.tsx
Normal file
596
frontend/dashboard/src/pages/ClaimRequests/Form.tsx
Normal file
@@ -0,0 +1,596 @@
|
|||||||
|
import * as Yup from 'yup';
|
||||||
|
import { useSnackbar } from 'notistack';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import { yupResolver } from '@hookform/resolvers/yup';
|
||||||
|
import { Controller, useForm } from 'react-hook-form';
|
||||||
|
import React, { useEffect, useMemo, useState } from 'react';
|
||||||
|
import axios from '../../utils/axios';
|
||||||
|
import { FormProvider, RHFTextField } from '../../components/hook-form';
|
||||||
|
import {
|
||||||
|
Autocomplete,
|
||||||
|
Button,
|
||||||
|
Grid,
|
||||||
|
Stack,
|
||||||
|
Table,
|
||||||
|
TableBody,
|
||||||
|
TableCell,
|
||||||
|
TableRow,
|
||||||
|
TextField,
|
||||||
|
Typography,
|
||||||
|
useTheme,
|
||||||
|
List,
|
||||||
|
ListItem,
|
||||||
|
IconButton,
|
||||||
|
ListItemAvatar,
|
||||||
|
Avatar,
|
||||||
|
ListItemText,
|
||||||
|
} from '@mui/material';
|
||||||
|
import Iconify from '../../components/Iconify';
|
||||||
|
import { LoadingButton } from '@mui/lab';
|
||||||
|
import { fCurrency } from '../../utils/formatNumber';
|
||||||
|
import MemberSelectDialog from '../../components/dialogs/MemberSelectDialog';
|
||||||
|
import { Add, DeleteOutline } from '@mui/icons-material';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
isEdit: boolean;
|
||||||
|
currentClaim?: any;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function ClaimForm({ isEdit, currentClaim }: Props) {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const { enqueueSnackbar } = useSnackbar();
|
||||||
|
|
||||||
|
const NewCorporateSchema = Yup.object().shape({
|
||||||
|
name: Yup.string().required('Name is required'),
|
||||||
|
code: Yup.string().required('Corporate Code is required'),
|
||||||
|
active: Yup.boolean().required('Corporate Status is required'),
|
||||||
|
// file: Yup.boolean().required('Corporate Status is required'),
|
||||||
|
});
|
||||||
|
|
||||||
|
const defaultValues = useMemo(
|
||||||
|
() => ({
|
||||||
|
member: currentClaim?.member || {},
|
||||||
|
member_id: currentClaim?.member_id || null,
|
||||||
|
diagnosis_id: currentClaim?.diagnosis_id || null,
|
||||||
|
total_claim: currentClaim?.total_claim || 0,
|
||||||
|
}),
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
[currentClaim]
|
||||||
|
);
|
||||||
|
|
||||||
|
const methods = useForm<any>({
|
||||||
|
resolver: yupResolver(NewCorporateSchema),
|
||||||
|
defaultValues,
|
||||||
|
});
|
||||||
|
const {
|
||||||
|
reset,
|
||||||
|
watch,
|
||||||
|
control,
|
||||||
|
setValue,
|
||||||
|
getValues,
|
||||||
|
setError,
|
||||||
|
handleSubmit,
|
||||||
|
formState: { isSubmitting },
|
||||||
|
} = methods;
|
||||||
|
|
||||||
|
const values = watch();
|
||||||
|
|
||||||
|
const [isCheckingLimit, setIsCheckingLimit] = useState(false);
|
||||||
|
const [isEligible, setIsEligible] = useState(false);
|
||||||
|
const [memberBenefits, setMemberBenefits] = useState([]);
|
||||||
|
const [diagnosisOption, setDiagnosisOption] = useState([]);
|
||||||
|
const [isMemberDialogOpen, setIsMemberDialogOpen] = useState(false);
|
||||||
|
const [member, setMember] = useState({})
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
console.log('defaultValues', defaultValues);
|
||||||
|
if (isEdit && currentClaim) {
|
||||||
|
reset(defaultValues);
|
||||||
|
setMember(defaultValues.member)
|
||||||
|
}
|
||||||
|
if (!isEdit) {
|
||||||
|
reset(defaultValues);
|
||||||
|
setMember(defaultValues.member)
|
||||||
|
}
|
||||||
|
}, [isEdit, currentClaim]);
|
||||||
|
|
||||||
|
const fileSelected = (event, type) => {
|
||||||
|
const files = event.target.files;
|
||||||
|
const currentFiles = getValues(`uploaded_files.${type}`) ?? [];
|
||||||
|
|
||||||
|
setValue(`uploaded_files.${type}`, [...currentFiles, ...files]);
|
||||||
|
|
||||||
|
console.log('currentFiles', getValues('uploaded_files'));
|
||||||
|
};
|
||||||
|
|
||||||
|
const memberSelected = (member) => {
|
||||||
|
setMember(member)
|
||||||
|
};
|
||||||
|
|
||||||
|
const checkLimit = async () => {
|
||||||
|
console.log('CHECKING LIMIT');
|
||||||
|
};
|
||||||
|
|
||||||
|
const onSubmit = async (data: any) => {
|
||||||
|
try {
|
||||||
|
if (!isEdit) {
|
||||||
|
const response = await axios.post('/claims', data);
|
||||||
|
} else {
|
||||||
|
const response = await axios.put('/claims/' + currentClaim?.id ?? '', data);
|
||||||
|
}
|
||||||
|
reset();
|
||||||
|
enqueueSnackbar(
|
||||||
|
!isEdit ? 'Organizations Created Successfully!' : 'Organizations Udpated Successfully!',
|
||||||
|
{ variant: 'success' }
|
||||||
|
);
|
||||||
|
navigate('/claims');
|
||||||
|
} catch (error: any) {
|
||||||
|
if (error && error.response.status === 422) {
|
||||||
|
for (const [key, value] of Object.entries(error.response.data.errors)) {
|
||||||
|
setError(key, { message: value[0] });
|
||||||
|
enqueueSnackbar(value[0] ?? 'Failed Processing Request', { variant: 'error' });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
enqueueSnackbar(error.message ?? 'Failed Processing Request', { variant: 'error' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const ascent = document?.querySelector('ascent');
|
||||||
|
if (ascent != null) {
|
||||||
|
ascent.innerHTML = '';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function generate(files, element: React.ReactElement) {
|
||||||
|
return files.map((value) =>
|
||||||
|
React.cloneElement(element, {
|
||||||
|
key: value,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const headStyle = {};
|
||||||
|
return (
|
||||||
|
<FormProvider methods={methods} onSubmit={handleSubmit(onSubmit)}>
|
||||||
|
<Stack spacing={3}>
|
||||||
|
<Typography variant="h6">Member</Typography>
|
||||||
|
|
||||||
|
<Stack spacing={2} direction="row">
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<RHFTextField
|
||||||
|
name="member_id"
|
||||||
|
label="Member"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
value={member?.name || ''}
|
||||||
|
InputProps={{
|
||||||
|
readOnly: true,
|
||||||
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
if (!isEdit) setIsMemberDialogOpen(true);
|
||||||
|
if (isEdit) enqueueSnackbar('Cannot Change Member', { variant: 'error' });
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
{/* <Grid item xs={2}>
|
||||||
|
<Button variant="outlined" fullWidth sx={{ p: 1.8 }} onClick={() => {
|
||||||
|
setIsMemberDialogOpen(true)
|
||||||
|
}}>
|
||||||
|
{member ? 'Change' : 'Search'}
|
||||||
|
</Button>
|
||||||
|
</Grid> */}
|
||||||
|
</Stack>
|
||||||
|
|
||||||
|
{member?.id && (
|
||||||
|
<Stack>
|
||||||
|
<Grid container spacing={2}>
|
||||||
|
<Grid item xs={12} md={6}>
|
||||||
|
<Table border="light-700">
|
||||||
|
<TableBody>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell style={headStyle} align="left">
|
||||||
|
Name
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="left">{member?.full_name}</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell style={headStyle} align="left">
|
||||||
|
DOB
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="left">
|
||||||
|
{member?.birth_date} ({member?.age + ' years'})
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell style={headStyle} align="left">
|
||||||
|
Marital Status
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="left">{member?.marital_status}</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell style={headStyle} align="left">
|
||||||
|
Record Type
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="left">{member?.record_type}</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell style={headStyle} align="left">
|
||||||
|
Principal ID
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="left">
|
||||||
|
{member?.principal_id} (
|
||||||
|
{member?.relation_with_principal})
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12} md={6}>
|
||||||
|
<Table border="light-700">
|
||||||
|
<TableBody>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell style={headStyle} align="left">
|
||||||
|
Plan
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="left">{member?.current_plan?.code}</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell style={headStyle} align="left">
|
||||||
|
Active
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="left">
|
||||||
|
{member?.current_plan?.start} -{' '}
|
||||||
|
{member?.current_plan?.end} (Active)
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell style={headStyle} align="left">
|
||||||
|
Corporate Limit
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="left">
|
||||||
|
{fCurrency(0)} / {fCurrency(member?.current_plan?.limit_rules)}
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell style={headStyle} align="left">
|
||||||
|
Plan Usage
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="left">
|
||||||
|
{fCurrency(0)} / {fCurrency(member?.current_plan?.limit_rules)}
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Stack>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Controller
|
||||||
|
name="benefit"
|
||||||
|
control={control}
|
||||||
|
render={({ field: { onChange, value } }) => (
|
||||||
|
<Autocomplete
|
||||||
|
options={memberBenefits}
|
||||||
|
getOptionLabel={(option) =>
|
||||||
|
option ? `#${option.id} (${option.code}) ${option.description}` : ''
|
||||||
|
}
|
||||||
|
value={value || ''}
|
||||||
|
onChange={(event: any, newValue: any) => {
|
||||||
|
setValue('benefit_id', newValue?.id);
|
||||||
|
onChange(newValue);
|
||||||
|
}}
|
||||||
|
renderInput={(params) => (
|
||||||
|
<TextField
|
||||||
|
name="benefit"
|
||||||
|
{...params}
|
||||||
|
label="Benefit"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
// onKeyPress={(event) => {
|
||||||
|
// if (event.key === 'Enter')
|
||||||
|
// searchDiagnosis(event.target.value)
|
||||||
|
// }}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Controller
|
||||||
|
name="diagnosis"
|
||||||
|
control={control}
|
||||||
|
render={({ field: { onChange, value } }) => (
|
||||||
|
<Autocomplete
|
||||||
|
options={diagnosisOption}
|
||||||
|
getOptionLabel={(option) => (option ? `(${option.code}) ${option.name}` : '')}
|
||||||
|
value={value || ''}
|
||||||
|
onChange={(event: any, newValue: any) => {
|
||||||
|
setValue('diagnosis_id', newValue?.id);
|
||||||
|
// setValue('diagnosis', newValue)
|
||||||
|
onChange(newValue);
|
||||||
|
}}
|
||||||
|
renderInput={(params) => (
|
||||||
|
<TextField
|
||||||
|
name="diagnosis"
|
||||||
|
{...params}
|
||||||
|
label="Diagnosis"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
onKeyPress={(event) => {
|
||||||
|
if (event.key === 'Enter') searchDiagnosis(event.target.value);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{isCheckingLimit && (
|
||||||
|
<Stack
|
||||||
|
sx={{
|
||||||
|
backgroundColor: 'gray',
|
||||||
|
paddingY: 1,
|
||||||
|
paddingX: 1.5,
|
||||||
|
mb: 2,
|
||||||
|
borderRadius: '3-xl',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{/* Checking */}
|
||||||
|
<Typography sx={{ typography: 'caption', display: 'flex', alignItems: 'center' }}>
|
||||||
|
<Iconify
|
||||||
|
icon="bxs:info-circle"
|
||||||
|
width={12}
|
||||||
|
height={13}
|
||||||
|
sx={{ color: '#424242', marginRight: '6px' }}
|
||||||
|
/>
|
||||||
|
<Typography variant="caption" component="span">
|
||||||
|
Please Wait, Checking Eligibilty
|
||||||
|
</Typography>
|
||||||
|
</Typography>
|
||||||
|
</Stack>
|
||||||
|
)}
|
||||||
|
{false && isCheckingLimit == false && isEligible == null && (
|
||||||
|
<Stack
|
||||||
|
sx={{
|
||||||
|
backgroundColor: 'gray',
|
||||||
|
paddingY: 1,
|
||||||
|
paddingX: 1.5,
|
||||||
|
mb: 2,
|
||||||
|
borderRadius: '3-xl',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{/* No Data Selected */}
|
||||||
|
<Typography sx={{ typography: 'caption', display: 'flex', alignItems: 'center' }}>
|
||||||
|
<Iconify
|
||||||
|
icon="bxs:info-circle"
|
||||||
|
width={12}
|
||||||
|
height={13}
|
||||||
|
sx={{ color: '#424242', marginRight: '6px' }}
|
||||||
|
/>
|
||||||
|
<Typography variant="caption" component="span">
|
||||||
|
Please Select Diagnosis !
|
||||||
|
</Typography>
|
||||||
|
</Typography>
|
||||||
|
</Stack>
|
||||||
|
)}
|
||||||
|
{!isCheckingLimit && isEligible !== null && isEligible && (
|
||||||
|
<Stack
|
||||||
|
sx={{
|
||||||
|
backgroundColor: '#B2E8E8',
|
||||||
|
paddingY: 1,
|
||||||
|
paddingX: 1.5,
|
||||||
|
mb: 2,
|
||||||
|
borderRadius: '3-xl',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{/* Eligible */}
|
||||||
|
<Typography sx={{ typography: 'caption', display: 'flex', alignItems: 'center' }}>
|
||||||
|
<Iconify
|
||||||
|
icon="bxs:lock-alt"
|
||||||
|
width={12}
|
||||||
|
height={13}
|
||||||
|
sx={{ color: '#424242', marginRight: '6px' }}
|
||||||
|
/>
|
||||||
|
<Typography variant="caption" component="span">
|
||||||
|
Diagnosis is Eligible
|
||||||
|
</Typography>
|
||||||
|
</Typography>
|
||||||
|
<Typography sx={{ typography: 'caption', color: '#637381' }}>
|
||||||
|
125.000.000 / 125.000.000
|
||||||
|
</Typography>
|
||||||
|
</Stack>
|
||||||
|
)}
|
||||||
|
{!isCheckingLimit && isEligible !== null && !isEligible && (
|
||||||
|
<Stack
|
||||||
|
sx={{
|
||||||
|
backgroundColor: '#B2E8E8',
|
||||||
|
paddingY: 1,
|
||||||
|
paddingX: 1.5,
|
||||||
|
mb: 2,
|
||||||
|
borderRadius: '3-xl',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{/* Not Eligible */}
|
||||||
|
{/* <Typography sx={{ typography: 'caption', display: 'flex', alignItems: 'center' }}>
|
||||||
|
<Iconify
|
||||||
|
icon="bxs:lock-alt"
|
||||||
|
width={12}
|
||||||
|
height={13}
|
||||||
|
sx={{ color: '#424242', marginRight: '6px' }}
|
||||||
|
/>
|
||||||
|
<Typography variant="caption" component="span">
|
||||||
|
Not Eligible
|
||||||
|
</Typography>
|
||||||
|
</Typography>
|
||||||
|
<Typography sx={{ typography: 'caption', color: '#637381' }}>
|
||||||
|
125.000.000 / 125.000.000
|
||||||
|
</Typography> */}
|
||||||
|
</Stack>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<RHFTextField type="number" name="total_claim" label="Total Claim" />
|
||||||
|
|
||||||
|
{isEdit && (
|
||||||
|
<React.Fragment>
|
||||||
|
<Typography variant="h6">Documents</Typography>
|
||||||
|
|
||||||
|
<List>
|
||||||
|
{(getValues('uploaded_files.invoice') && getValues('uploaded_files.invoice').length
|
||||||
|
? getValues('uploaded_files.invoice')
|
||||||
|
: []
|
||||||
|
).map((file, index) => (
|
||||||
|
<ListItem
|
||||||
|
secondaryAction={
|
||||||
|
<IconButton edge="end" aria-label="delete">
|
||||||
|
<DeleteOutline />
|
||||||
|
</IconButton>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<ListItemAvatar>
|
||||||
|
<Avatar>
|
||||||
|
{/* <FileIcon /> */}
|
||||||
|
I
|
||||||
|
</Avatar>
|
||||||
|
</ListItemAvatar>
|
||||||
|
<ListItemText primary={file.name} secondary={file.type} />
|
||||||
|
</ListItem>
|
||||||
|
))}
|
||||||
|
</List>
|
||||||
|
<Button
|
||||||
|
variant="outlined"
|
||||||
|
startIcon={<Add />}
|
||||||
|
component="label"
|
||||||
|
sx={{ paddingY: 2, width: '100%', ':hover': { border: 'none' } }}
|
||||||
|
>
|
||||||
|
Invoice
|
||||||
|
<input
|
||||||
|
name="invoice"
|
||||||
|
hidden
|
||||||
|
accept="image/*,application/pdf"
|
||||||
|
multiple
|
||||||
|
type="file"
|
||||||
|
onChange={(event) => {
|
||||||
|
fileSelected(event, 'invoice');
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Button>
|
||||||
|
<List>
|
||||||
|
{(getValues('uploaded_files.prescription') && getValues('uploaded_files.prescription').length
|
||||||
|
? getValues('uploaded_files.prescription')
|
||||||
|
: []
|
||||||
|
).map((file, index) => (
|
||||||
|
<ListItem
|
||||||
|
secondaryAction={
|
||||||
|
<IconButton edge="end" aria-label="delete">
|
||||||
|
<DeleteOutline />
|
||||||
|
</IconButton>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<ListItemAvatar>
|
||||||
|
<Avatar>
|
||||||
|
{/* <FileIcon /> */}
|
||||||
|
P
|
||||||
|
</Avatar>
|
||||||
|
</ListItemAvatar>
|
||||||
|
<ListItemText primary={file.name} secondary={file.type} />
|
||||||
|
</ListItem>
|
||||||
|
))}
|
||||||
|
</List>
|
||||||
|
<Button
|
||||||
|
variant="outlined"
|
||||||
|
startIcon={<Add />}
|
||||||
|
component="label"
|
||||||
|
sx={{ paddingY: 2, width: '100%', ':hover': { border: 'none' } }}
|
||||||
|
>
|
||||||
|
Prescription
|
||||||
|
<input
|
||||||
|
name="prescription"
|
||||||
|
hidden
|
||||||
|
accept="image/*,application/pdf"
|
||||||
|
multiple
|
||||||
|
type="file"
|
||||||
|
onChange={(event) => {
|
||||||
|
fileSelected(event, 'prescription');
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<List>
|
||||||
|
{(getValues('uploaded_files.diagnosis') && getValues('uploaded_files.diagnosis').length
|
||||||
|
? getValues('uploaded_files.diagnosis')
|
||||||
|
: []
|
||||||
|
).map((file, index) => (
|
||||||
|
<ListItem
|
||||||
|
secondaryAction={
|
||||||
|
<IconButton edge="end" aria-label="delete">
|
||||||
|
<DeleteOutline />
|
||||||
|
</IconButton>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<ListItemAvatar>
|
||||||
|
<Avatar>
|
||||||
|
{/* <FileIcon /> */}
|
||||||
|
DR
|
||||||
|
</Avatar>
|
||||||
|
</ListItemAvatar>
|
||||||
|
<ListItemText primary={file.name} secondary={file.type} />
|
||||||
|
</ListItem>
|
||||||
|
))}
|
||||||
|
</List>
|
||||||
|
<Button
|
||||||
|
variant="outlined"
|
||||||
|
startIcon={<Add />}
|
||||||
|
component="label"
|
||||||
|
sx={{ paddingY: 2, width: '100%', ':hover': { border: 'none' } }}
|
||||||
|
>
|
||||||
|
Doctor Result
|
||||||
|
<input
|
||||||
|
name="invoice"
|
||||||
|
hidden
|
||||||
|
accept="image/*,application/pdf"
|
||||||
|
multiple
|
||||||
|
type="file"
|
||||||
|
onChange={(event) => {
|
||||||
|
fileSelected(event, 'diagnosis');
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Button>
|
||||||
|
</React.Fragment>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{isEligible === true ? (
|
||||||
|
<LoadingButton
|
||||||
|
onClick={handleSubmit(onSubmit)}
|
||||||
|
variant="contained"
|
||||||
|
color="success"
|
||||||
|
style={{ color: '#ffffff' }}
|
||||||
|
size="large"
|
||||||
|
fullWidth={true}
|
||||||
|
loading={isCheckingLimit}
|
||||||
|
>
|
||||||
|
Create Claim
|
||||||
|
</LoadingButton>
|
||||||
|
) : (
|
||||||
|
<LoadingButton
|
||||||
|
onClick={checkLimit}
|
||||||
|
variant="outlined"
|
||||||
|
size="large"
|
||||||
|
fullWidth={true}
|
||||||
|
loading={isCheckingLimit}
|
||||||
|
>
|
||||||
|
Check Limit
|
||||||
|
</LoadingButton>
|
||||||
|
)}
|
||||||
|
</Stack>
|
||||||
|
|
||||||
|
<MemberSelectDialog
|
||||||
|
openDialog={isMemberDialogOpen}
|
||||||
|
setOpenDialog={setIsMemberDialogOpen}
|
||||||
|
onSelect={memberSelected}
|
||||||
|
></MemberSelectDialog>
|
||||||
|
</FormProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
30
frontend/dashboard/src/pages/ClaimRequests/Index.tsx
Executable file
30
frontend/dashboard/src/pages/ClaimRequests/Index.tsx
Executable file
@@ -0,0 +1,30 @@
|
|||||||
|
import { Card, Stack } from "@mui/material";
|
||||||
|
import HeaderBreadcrumbs from "../../components/HeaderBreadcrumbs";
|
||||||
|
import Page from "../../components/Page";
|
||||||
|
import List from "./List";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export default function Claims() {
|
||||||
|
|
||||||
|
const pageTitle = 'Claim Request';
|
||||||
|
return (
|
||||||
|
<Page title={ pageTitle } sx={{ mx: 2}}>
|
||||||
|
|
||||||
|
<HeaderBreadcrumbs
|
||||||
|
heading={ pageTitle }
|
||||||
|
links={[
|
||||||
|
{ name: 'Dashboard', href: '/dashboard' },
|
||||||
|
{
|
||||||
|
name: 'Claim Request',
|
||||||
|
href: '/claim-requests',
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* <Stack> */}
|
||||||
|
<List />
|
||||||
|
{/* </Stack> */}
|
||||||
|
</Page>
|
||||||
|
);
|
||||||
|
}
|
||||||
272
frontend/dashboard/src/pages/ClaimRequests/List.tsx
Executable file
272
frontend/dashboard/src/pages/ClaimRequests/List.tsx
Executable file
@@ -0,0 +1,272 @@
|
|||||||
|
// @mui
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Button,
|
||||||
|
Card,
|
||||||
|
Collapse,
|
||||||
|
IconButton,
|
||||||
|
MenuItem,
|
||||||
|
Table,
|
||||||
|
TableBody,
|
||||||
|
TableCell,
|
||||||
|
TableRow,
|
||||||
|
TextField,
|
||||||
|
Typography,
|
||||||
|
Stack,
|
||||||
|
Menu,
|
||||||
|
ButtonGroup,
|
||||||
|
Link,
|
||||||
|
Chip,
|
||||||
|
} 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, useEffect, useRef, useState } from 'react';
|
||||||
|
import { Navigate, useNavigate, useSearchParams } from 'react-router-dom';
|
||||||
|
// components
|
||||||
|
import axios from '../../utils/axios';
|
||||||
|
import { LaravelPaginatedData, LaravelPaginatedDataDefault } from '../../@types/paginated-data';
|
||||||
|
import DataTable from '../../components/LaravelTable';
|
||||||
|
import { fCurrency } from '../../utils/formatNumber';
|
||||||
|
import EditRoundedIcon from '@mui/icons-material/EditRounded';
|
||||||
|
import { LoadingButton } from '@mui/lab';
|
||||||
|
import { enqueueSnackbar } from 'notistack';
|
||||||
|
// import LoadingButton from '@/theme/overrides/LoadingButton';
|
||||||
|
|
||||||
|
export default function List() {
|
||||||
|
const [searchParams, setSearchParams] = useSearchParams();
|
||||||
|
const [importResult, setImportResult] = useState(null);
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
function SearchInput(props: any) {
|
||||||
|
// SEARCH
|
||||||
|
const searchInput = useRef<HTMLInputElement>(null);
|
||||||
|
const [searchText, setSearchText] = useState('');
|
||||||
|
|
||||||
|
const handleSearchChange = (event: any) => {
|
||||||
|
const newSearchText = event.target.value ?? '';
|
||||||
|
setSearchText(newSearchText);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSearchSubmit = (event: any) => {
|
||||||
|
event.preventDefault();
|
||||||
|
props.onSearch({ search: searchText }); // Trigger to Parent
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// Trigger First Search
|
||||||
|
setSearchText(searchParams.get('search') ?? '');
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form onSubmit={handleSearchSubmit} style={{ width: '100%' }}>
|
||||||
|
<TextField
|
||||||
|
id="search-input"
|
||||||
|
ref={searchInput}
|
||||||
|
label="Search"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
onChange={handleSearchChange}
|
||||||
|
value={searchText}
|
||||||
|
/>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 handleClose = () => {
|
||||||
|
setAnchorEl(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Stack direction={'row'} spacing={2} sx={{ p: 2 }}>
|
||||||
|
<SearchInput onSearch={applyFilter} />
|
||||||
|
{/* <Button
|
||||||
|
variant="outlined"
|
||||||
|
startIcon={<AddIcon />}
|
||||||
|
sx={{ p: 1.8 }}
|
||||||
|
onClick={() => {
|
||||||
|
navigate('/claims/create');
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Create
|
||||||
|
</Button> */}
|
||||||
|
</Stack>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dummy Default Data
|
||||||
|
const [dataTableIsLoading, setDataTableLoading] = useState(true);
|
||||||
|
const [dataTableData, setDataTableData] = useState<LaravelPaginatedData>(
|
||||||
|
LaravelPaginatedDataDefault
|
||||||
|
);
|
||||||
|
|
||||||
|
const loadDataTableData = async (appliedFilter: any | null = null) => {
|
||||||
|
setDataTableLoading(true);
|
||||||
|
const filter = appliedFilter ? appliedFilter : Object.fromEntries([...searchParams.entries()]);
|
||||||
|
const response = await axios.get('/claim-requests', { params: filter });
|
||||||
|
// console.log(response.data);
|
||||||
|
setDataTableLoading(false);
|
||||||
|
|
||||||
|
setDataTableData(response.data);
|
||||||
|
};
|
||||||
|
|
||||||
|
const applyFilter = async (searchFilter: { search: string }) => {
|
||||||
|
await loadDataTableData(searchFilter);
|
||||||
|
setSearchParams(searchFilter);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlePageChange = (event: ChangeEvent, value: number): void => {
|
||||||
|
const filter = Object.fromEntries([...searchParams.entries(), ['page', value]]);
|
||||||
|
loadDataTableData(filter);
|
||||||
|
setSearchParams(filter);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleApprove = (claimRequest) => {
|
||||||
|
axios.post(`claim-requests/${claimRequest.id}/approve`)
|
||||||
|
.then((response) => {
|
||||||
|
enqueueSnackbar('Success Approve', {variant: 'success'})
|
||||||
|
loadDataTableData()
|
||||||
|
})
|
||||||
|
.catch(({response}) => {
|
||||||
|
enqueueSnackbar(response.data.message ?? 'Something went wrong!', {variant : "error"})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
loadDataTableData();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const headStyle = {
|
||||||
|
fontWeight: 'bold',
|
||||||
|
};
|
||||||
|
|
||||||
|
// Called on every row to map the data to the columns
|
||||||
|
function createData(data: any): any {
|
||||||
|
return {
|
||||||
|
...data,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
/* ------------------ TABLE ROW ------------------ */
|
||||||
|
}
|
||||||
|
function Row(props: { row: ReturnType<typeof createData> }) {
|
||||||
|
const { row } = props;
|
||||||
|
const [open, setOpen] = React.useState(false);
|
||||||
|
const [loadingApprove, setLoadingApprove] = React.useState(false);
|
||||||
|
|
||||||
|
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.code}</TableCell>
|
||||||
|
<TableCell align="left">{row.member?.full_name}</TableCell>
|
||||||
|
<TableCell align="left">{row.submission_date}</TableCell>
|
||||||
|
<TableCell align="right"><Chip label={row.status}/></TableCell>
|
||||||
|
<TableCell align="right">{ row.status == 'requested' && (<LoadingButton loading={loadingApprove} variant="outlined" onClick={() => {handleApprove(row)}}>Approve</LoadingButton> )}</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">
|
||||||
|
Description : {row.description}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
</Collapse>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
/* ------------------ END TABLE ROW ------------------ */
|
||||||
|
}
|
||||||
|
|
||||||
|
function TableContent() {
|
||||||
|
return (
|
||||||
|
<Table aria-label="collapsible table">
|
||||||
|
{/* ------------------ TABLE HEADER ------------------ */}
|
||||||
|
<TableBody>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell style={headStyle} align="left" />
|
||||||
|
<TableCell style={headStyle} align="left">
|
||||||
|
Code
|
||||||
|
</TableCell>
|
||||||
|
<TableCell style={headStyle} align="left">
|
||||||
|
Member Name
|
||||||
|
</TableCell>
|
||||||
|
<TableCell style={headStyle} align="left">
|
||||||
|
Submission Date
|
||||||
|
</TableCell>
|
||||||
|
<TableCell style={headStyle} align="left">
|
||||||
|
Status
|
||||||
|
</TableCell>
|
||||||
|
<TableCell style={headStyle} align="right">
|
||||||
|
Action
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableBody>
|
||||||
|
{/* ------------------ END TABLE HEADER ------------------ */}
|
||||||
|
|
||||||
|
{/* ------------------ TABLE ROW ------------------ */}
|
||||||
|
{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>
|
||||||
|
)}
|
||||||
|
{/* ------------------ END TABLE ROW ------------------ */}
|
||||||
|
</Table>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card>
|
||||||
|
<ImportForm />
|
||||||
|
|
||||||
|
<DataTable
|
||||||
|
isLoading={dataTableIsLoading}
|
||||||
|
lastRequest={0}
|
||||||
|
data={dataTableData}
|
||||||
|
handlePageChange={handlePageChange}
|
||||||
|
TableContent={<TableContent />}
|
||||||
|
/>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -221,6 +221,10 @@ export default function Router() {
|
|||||||
path: 'claims',
|
path: 'claims',
|
||||||
element: <Claims />,
|
element: <Claims />,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'claim-requests',
|
||||||
|
element: <ClaimRequests />,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'claims/create',
|
path: 'claims/create',
|
||||||
element: <ClaimsCreate />,
|
element: <ClaimsCreate />,
|
||||||
@@ -339,3 +343,5 @@ const Profile = Loadable(lazy(() => import('../pages/Profile/Index')));
|
|||||||
|
|
||||||
const Claims = Loadable(lazy(() => import('../pages/Claims/Index')));
|
const Claims = Loadable(lazy(() => import('../pages/Claims/Index')));
|
||||||
const ClaimsCreate = Loadable(lazy(() => import('../pages/Claims/CreateUpdate')));
|
const ClaimsCreate = Loadable(lazy(() => import('../pages/Claims/CreateUpdate')));
|
||||||
|
|
||||||
|
const ClaimRequests = Loadable(lazy(() => import('../pages/ClaimRequests/Index')));
|
||||||
Reference in New Issue
Block a user