Update Claim, Final LOG, Request LOG

This commit is contained in:
ivan-sim
2023-12-20 16:27:57 +07:00
parent 40371bd53a
commit 4defd4fa2f
28 changed files with 2779 additions and 216 deletions

View File

@@ -1,15 +0,0 @@
{
"greeting": "Hello",
"buttonText": "Click Me",
"infoLogin": "Enter the registered account",
"txtLogin1" : "Sign in to Hospital Portal",
"txtLogin2" : "Enter your details below",
"txtCardSearchMember1" : "Guarantee Submission",
"txtCardSearchMember2" : "Find Member",
"txtCardSearchMember3" : "Date Birth",
"txtCardSearchMember4" : "Member ID",
"txtCardSearchMember5" : "Member",
"txtDialogMember1" : "Benefit Summary",
"txtDialogMember2" : "Request LOG",
"txtDialogMember3" : "Member Detail"
}

View File

@@ -1,15 +0,0 @@
{
"greeting": "Halo",
"buttonText": "Klik Saya",
"infoLogin": "Masukan akun yang telah terdaftar",
"txtLogin1" : "Masuk ke Hospital Portal",
"txtLogin2" : "Masukkan detail Anda di bawah ini",
"txtCardSearchMember1" : "Pengajuan Jaminan",
"txtCardSearchMember2" : "Cari Anggota",
"txtCardSearchMember3" : "Tanggal Lahir",
"txtCardSearchMember4" : "Member ID",
"txtCardSearchMember5" : "Member",
"txtDialogMember1" : "Ringkasan Manfaat",
"txtDialogMember2" : "Request LOG",
"txtDialogMember3" : "Detail Member"
}

View File

@@ -6,10 +6,33 @@
"txtLogin2" : "Enter your details below",
"txtCardSearchMember1" : "Membership Query",
"txtCardSearchMember2" : "Search Member",
"txtCardSearchMember3" : "Date Birth",
"txtCardSearchMember3" : "Date of Birth",
"txtCardSearchMember4" : "Member ID",
"txtCardSearchMember5" : "Member",
"txtDialogMember1" : "Benefit",
"txtDialogMember1" : "Services",
"txtDialogMember2" : "Request LOG",
"txtDialogMember3" : "Detail"
"txtDialogMember3" : "Detail",
"txtDialogMember4" : "Please select services",
"txtDialogMember5" : "Submission Date",
"txtDateBirth" : "Date of Birth",
"txtGender" : "Gender",
"txtMaritalStatus" : "Marital Status",
"txtLanguage" : "Language",
"txtRelationship" : "Relationship",
"txtRequestDate" : "Request Date",
"txtMemberID" : "Member ID",
"txtClaimCode" : "Claim Code",
"txtRequestCode" : "Request Code",
"txtName" : "Name",
"txtStatus" : "Status",
"txtSearch" : "Search Name or Member ID...",
"txtAll" : "All",
"txtSubmissionDate" : "Submission Date",
"txtDataNotFound" : "Data Not Found",
"txtConditionDocument" : "Condition Document",
"txtDiagnosisDokument" : "Diagnosis Dokument",
"txtSupportingResultDocument" : "Supporting Result Document",
"txtAddResult" : "Add Result",
"txtServiceType" : "Service Type",
"txtAdditionalDocuments" : "Additional Documents"
}

View File

@@ -9,7 +9,30 @@
"txtCardSearchMember3" : "Tanggal Lahir",
"txtCardSearchMember4" : "Member ID",
"txtCardSearchMember5" : "Member",
"txtDialogMember1" : "Manfaat",
"txtDialogMember1" : "Layanan",
"txtDialogMember2" : "Request LOG",
"txtDialogMember3" : "Detail"
"txtDialogMember3" : "Detail",
"txtDialogMember4" : "Mohon pilih layanan",
"txtDialogMember5" : "Tanggal Pengajuan",
"txtDateBirth" : "Tanggal Lahir",
"txtGender" : "Jenis Kelamin",
"txtMaritalStatus" : "Status Perkawinan",
"txtLanguage" : "Bahasa",
"txtRelationship" : "Hubungan",
"txtRequestDate" : "Tanggal Permintaan",
"txtMemberID" : "ID Anggota",
"txtClaimCode" : "Kode Klaim",
"txtRequestCode" : "Kode Pengajuan",
"txtName" : "Nama",
"txtStatus" : "Status",
"txtSearch" : "Cari Nama atau ID Anggota...",
"txtAll" : "Semua",
"txtSubmissionDate" : "Tanggal Pengajuan",
"txtDataNotFound" : "Data Tidak Ditemukan",
"txtConditionDocument" : "Dokumen Kondisi",
"txtDiagnosisDokument" : "Dokumen Diagnosa",
"txtSupportingResultDocument" : "Dokumen Hasil Pendukung",
"txtAddResult" : "Tambah Hasil",
"txtServiceType" : "Tipe Layanan",
"txtAdditionalDocuments" : "Dokumen Tambahan"
}

View File

@@ -42,6 +42,8 @@ import { Download, Search as SearchIcon, Upload } from '@mui/icons-material';
import { DivisionDataProps, Order, PaginationTableProps, TableListProps } from '../@types/table';
import { InputAdornment } from '@mui/material';
import GetAppIcon from '@mui/icons-material/GetApp';
import { LanguageContext } from '@/contexts/LanguageContext';
/* --------------------------------- styled --------------------------------- */
const BorderLinearProgress = styled(LinearProgress)(({ theme }) => ({
height: 10,
@@ -83,6 +85,8 @@ export default function Table<T>({
]);
params.setAppliedParams(parameters);
};
const { localeData }: any = useContext(LanguageContext);
/* -------------------------------------------------------------------------- */
/* -------------------------- enchanced table head -------------------------- */
@@ -219,7 +223,7 @@ export default function Table<T>({
</InputAdornment>
),
}}
placeholder="Search Name or Member ID... "
placeholder={localeData.txtSearch}
/>
</form>
</Grid>
@@ -239,7 +243,7 @@ export default function Table<T>({
</InputAdornment>
),
}}
placeholder="Search Name or Member ID... "
placeholder={localeData.txtSearch}
/>
</form>
</Grid>
@@ -299,7 +303,7 @@ export default function Table<T>({
label="Status"
onChange={filterStatus.config.handleStatusChange}
>
<MenuItem value="all">All</MenuItem>
<MenuItem value="all">{localeData.txtAll}</MenuItem>
{filterStatus.config.filterData.map((row: StatusDataProps, index) => (
<MenuItem key={index} value={row.id}>
{row.name}
@@ -336,7 +340,7 @@ export default function Table<T>({
{/* End Table Header */}
{/* Table Body */}
<TableBody>
{loadings.isLoading && rows.length >= 1 ? (
{loadings.isLoading ? (
<TableRow>
<TableCell colSpan={headCells?.length} align="center">
Loading . . .
@@ -358,7 +362,7 @@ export default function Table<T>({
) : (
<TableRow>
<TableCell colSpan={6} align="center">
No Data Found
{localeData.txtDataNotFound}
</TableCell>
</TableRow>
)}

View File

@@ -12,7 +12,7 @@ const ICONS = {
ecommerce: getIcon('ic_ecommerce'),
analytics: getIcon('ic_analytics'),
dashboard: getIcon('ic_dashboard'),
hospital: getIcon('ic_banking'),
ic_booking: getIcon('ic_booking'),
};
const navConfig = [
@@ -21,6 +21,9 @@ const navConfig = [
{
items: [{ title: 'Dashboard', path: '/dashboard', icon: ICONS.dashboard }],
},
{
items: [{ title: 'Claim', path: '/claim', icon: ICONS.ic_booking }],
},
// Membership
// ----------------------------------------------------------------------

View File

@@ -25,7 +25,7 @@ export default function NavbarDocs() {
</div>
<Button variant="contained">Documentation</Button>
<Typography variant='body2'>Hak Cipta © 2023 - 2024 Link Sehat</Typography>
<Typography variant='body2'>Hak Cipta © 2023 - 2024 Link Medis Sehat</Typography>
</Stack>
</>
);

View File

@@ -0,0 +1,119 @@
// @mui
import { Typography, Container, Grid, Card } from '@mui/material';
// hooks
import useSettings from '@/hooks/useSettings';
// components
import Page from '@/components/Page';
// theme
import CardNotification from '@/sections/dashboard/CardNotification';
import CardSearchMember from '@/sections/dashboard/CardSearchMember'
import { useContext, useEffect, useState } from 'react';
import axios from '@/utils/axios';
import { Stack } from '@mui/system';
import { Input } from '@mui/material';
//sections
import TableList from '@/sections/claim/TableList';
import { fDate } from '@/utils/formatTime';
import DialogDetailClaim from '@/components/dialogs/DialogDetailClaim';
import HeaderBreadcrumbs from "@/components/HeaderBreadcrumbs";
// ----------------------------------------------------------------------
// const [notifications, setNotifications] = useState([])
const itemList = [
{ info: 'Mohon lengkapi dokumen Mahen sadarsa', date: 'Selasa, 20 April 22', time: '08:00 WIB' },
{ info: 'Mohon lengkapi dokumen Mahen sadarsa', date: 'Selasa, 20 April 22', time: '09:00 WIB' },
{ info: 'Mohon lengkapi dokumen Mahen sadarsa', date: 'Selasa, 20 April 22', time: '10:00 WIB' },
{ info: 'Mohon lengkapi dokumen Mahen sadarsa', date: 'Selasa, 20 April 22', time: '11:00 WIB' },
];
// ----------------------------------------------------------------------
/* ---------------------------------- types --------------------------------- */
type PolicyProps = {
myLimit: {
balance: number;
total: number;
percentage: number;
};
lockLimit: {
balance: number;
percentage: number;
};
};
/* -------------------------------------------------------------------------- */
/* ------------------------------ default data ------------------------------ */
const defaultPolicyData = {
myLimit: {
balance: 0,
total: 0,
percentage: 0,
},
lockLimit: {
balance: 0,
percentage: 0,
},
};
/* -------------------------------------------------------------------------- */
export default function Claim() {
const { themeStretch } = useSettings();
// const [tableData, setTableData] = useState([]);
const [policyData, setPolicyData] = useState<PolicyProps>(defaultPolicyData);
// TODO Remove This
//const [itemList, setItemList] = useState([]);
function handleDataLoaded(dataTable:any) {
let dummyData = [];
dataTable.map(function(data:any) {
if (data.status == 'approved') {
dummyData.push({
info: `LOG Approved for member ${data.member.full_name}`,
date: fDate(data.created_at, "dd MMMM"),
time: fDate(data.created_at, "HH:mm")
})
}
})
//setItemList(dummyData);
}
return (
<Page title="Claim">
<Container maxWidth={themeStretch ? false : 'xl'}>
<Grid container spacing={2}>
{/* <Grid item xs={12} lg={12} md={12}>
<CardSearchMember/>
</Grid> */}
{/*<Grid item xs={12} lg={6} md={6}>
<CardNotification data={itemList} />
</Grid>*/}
<Grid item xs={12} lg={12} md={12}>
<HeaderBreadcrumbs
heading={'Claim'}
links={[
{
name: 'Dashboard',
href: '/dashboard',
},
{
name: 'Claim',
href: '/claim',
},
]}
/>
<Card>
<TableList/>
</Card>
</Grid>
</Grid>
</Container>
</Page>
);
}

View File

@@ -82,6 +82,27 @@ export default function Router() {
},
],
},
{
path: '/',
element: (
<AuthProvider>
<AuthGuard>
<DashboardLayout />
</AuthGuard>
</AuthProvider>
),
children: [
{ element: <Navigate to="/claim" replace />, index: true },
{
path: 'claim',
element: <Claim />,
},
{
path: '/detail/:id',
element: <DetailClaimReport />,
},
],
},
{
path: '*',
@@ -101,6 +122,7 @@ const ForgetPassword = Loadable(lazy(() => import('@/pages/auth/ForgetPassword')
// Dashboard
const Dashboard = Loadable(lazy(() => import('@/pages/Dashboard')));
const Claim = Loadable(lazy(() => import('@/pages/Claim')));
const NotFound = Loadable(lazy(() => import('@/pages/Page404')));
const DetailClaimReport = Loadable(lazy(()=> import('@/sections/dashboard/Detail')));

View File

@@ -0,0 +1,365 @@
/* ---------------------------------- @mui ---------------------------------- */
import { Stack, Button, MenuItem, SelectChangeEvent, Tab, Tabs, Card, Box } from '@mui/material';
/* ---------------------------------- axios --------------------------------- */
// import axios from 'axios';
import axios from '../../utils/axios';
import { styled } from '@mui/material/styles';
/* ---------------------------------- react --------------------------------- */
import { useContext, useEffect, useState } from 'react';
/* -------------------------------- component ------------------------------- */
import Iconify from '../../components/Iconify';
import TableComponent from '../../components/Table';
/* ---------------------------------- theme --------------------------------- */
import palette from '../../theme/palette';
//import { UserCurrentCorporateContext } from '../../contexts/UserCurrentCorporate';
import { HeadCell, Order, PaginationTableProps } from '../../@types/table';
import { useSearchParams, useNavigate } from 'react-router-dom';
import { fDate, fDateSuffix } from '../../utils/formatTime';
import Typography from '@mui/material/Typography';
import { format } from 'date-fns';
import TableMoreMenu from '../../components/table/TableMoreMenu';
import VisibilityOutlinedIcon from '@mui/icons-material/VisibilityOutlined';
import HistoryIcon from '@mui/icons-material/History';
import SearchIcon from '@mui/icons-material/Search';
import Label from '../../components/Label';
import { enqueueSnackbar } from 'notistack';
import { LoadingButton, TabPanel } from "@mui/lab";
import { LanguageContext } from '@/contexts/LanguageContext';
import MuiDialog from '@/components/MuiDialog';
import DialogMember from '@/sections/dashboard/DialogMember';
import DialogClaimSubmit from '@/sections/dashboard/DialogClaimSubmit';
import { fPostFormat } from '@/utils/formatTime';
export default function TableList() {
const navigate = useNavigate();
const { localeData }: any = useContext(LanguageContext);
const [data, setData] = useState([]);
// Download LOG
async function handleDownloadLog(claimRequest:any) {
return axios
.get(`claim-requests/${claimRequest}/log`, {
responseType: 'blob',
})
.then((response) => {
window.open(URL.createObjectURL(response.data));
// setLoadingLog(false);
})
// .then((blobFile) => {
// new File([blobFile], 'asdads.pdf', { type: blobFile.type })
// setLoadingLog(false);
// })
.catch((response) => {
console.log(response);
enqueueSnackbar(response.message, { variant: 'error' });
// setLoadingLog(false);
});
}
/* -------------------------------------------------------------------------- */
/* setting up for the table */
/* -------------------------------------------------------------------------- */
const [isLoading, setIsLoading] = useState(true);
const loadings = {
isLoading: isLoading,
setIsLoading: setIsLoading,
};
/* ------------------------------ handle params ----------------------------- */
const [searchParams, setSearchParams] = useSearchParams();
const [appliedParams, setAppliedParams] = useState({});
const params = {
searchParams: searchParams,
setSearchParams: setSearchParams,
appliedParams: appliedParams,
setAppliedParams: setAppliedParams,
};
/* -------------------------------------------------------------------------- */
/* ------------------------------ handle order ------------------------------ */
const [order, setOrder] = useState<Order>('desc');
const [orderBy, setOrderBy] = useState('submission_date');
const orders = {
order: order,
setOrder: setOrder,
orderBy: orderBy,
setOrderBy: setOrderBy,
};
/* -------------------------------------------------------------------------- */
/* ---------------------------- handle pagination --------------------------- */
const [page, setPage] = useState(0);
const [rowsPerPage, setRowsPerPage] = useState(10);
const [paginationTable, setPaginationTable] = useState<PaginationTableProps>({
current_page: 0,
from: 0,
last_page: 0,
links: [],
path: '',
per_page: 0,
to: 0,
total: 0,
});
const paginations = {
page: page,
setPage: setPage,
rowsPerPage: rowsPerPage,
setRowsPerPage: setRowsPerPage,
paginationTable: paginationTable,
setPaginationTable: setPaginationTable,
};
/* -------------------------------------------------------------------------- */
/* ------------------------------ handle search ----------------------------- */
const [searchText, setSearchText] = useState('');
const handleSearchSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
if (searchText === '') {
searchParams.delete('search');
const params = Object.fromEntries([...searchParams.entries()]);
setAppliedParams(params);
} else {
const params = Object.fromEntries([...searchParams.entries(), ['search', searchText]]);
setAppliedParams(params);
}
};
const searchs = {
useSearchs: true,
searchText: searchText,
setSearchText: setSearchText,
handleSearchSubmit: handleSearchSubmit,
};
/* ------------------------------ handle filter ----------------------------- */
const [statusValue, setStatusValue] = useState('all');
const [filterData, setStatusData] = useState([]);
// handle status
const handleStatusChanges = (event: SelectChangeEvent) => {
setStatusValue(event.target.value as string);
if (event.target.value === 'all') {
searchParams.delete('status');
const params = Object.fromEntries([...searchParams.entries()]);
setAppliedParams(params);
} else {
const params = Object.fromEntries([
...searchParams.entries(),
['status', event.target.value as string],
]);
setAppliedParams(params);
}
};
const filterStatus = {
useFilter: true,
config: {
label: 'Status',
statusValue: statusValue,
filterData: filterData,
handleStatusChange: handleStatusChanges,
},
};
// handle start date
const [startDateValue, setStartDateValue] = useState('');
const handleStartDateChanges = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
const newStartDateValue = event.currentTarget.elements['date-input'].value;
setStartDateValue(newStartDateValue);
if (newStartDateValue === '') {
searchParams.delete('start_date');
const params = Object.fromEntries([...searchParams.entries()]);
setAppliedParams(params);
} else {
const params = Object.fromEntries([...searchParams.entries(), ['start_date', newStartDateValue]]);
setAppliedParams(params);
}
};
const filterStartDate = {
useFilter: true,
startDate: startDateValue,
setStartDate: setStartDateValue,
handleStartDateChange: handleStartDateChanges,
};
// handle end date
const [endDateValue, setEndDateValue] = useState('');
const handleEndDateChanges = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
const newEndDateValue = event.currentTarget.elements['date-input'].value;
setEndDateValue(newEndDateValue);
if (newEndDateValue === '') {
searchParams.delete('end_date');
const params = Object.fromEntries([...searchParams.entries()]);
setAppliedParams(params);
} else {
const params = Object.fromEntries([...searchParams.entries(), ['end_date', newEndDateValue]]);
setAppliedParams(params);
}
};
const filterEndDate = {
useFilter: true,
endDate: endDateValue,
setEndDate: setEndDateValue,
handleEndDateChange: handleEndDateChanges,
};
/* -------------------------------- headCell Claim -------------------------------- */
const headCells: HeadCell<never>[] = [
{
id: 'code',
align: 'left',
label: localeData.txtRequestCode,
isSort: true,
},
{
id: 'full_name',
align: 'left',
label: localeData.txtName,
isSort: true,
},
{
id: 'submission_date',
align: 'center',
label: localeData.txtSubmissionDate,
isSort: true,
},
{
id: 'service_type',
align: 'center',
label: localeData.txtServiceType,
isSort: true,
},
{
id: 'status',
align: 'center',
label: localeData.txtStatus,
isSort: true,
},
{
id: 'action',
align: 'right',
label: '',
isSort: false,
},
];
useEffect(() => {
getData();
}, [appliedParams, searchParams, order, orderBy, setSearchParams]);
function getData()
{
(async () => {
setIsLoading(true);
await new Promise((resolve) => setTimeout(resolve, 250));
const parameters =
Object.keys(appliedParams).length !== 0
? appliedParams
: Object.fromEntries([...searchParams.entries(), ['order', order], ['orderBy', orderBy]]);
const response = await axios.get(`/get-claim-requests`, {
params: { ...parameters, type: 'final-log' },
});
setData(
response.data.data.map((obj: any) => ({
...obj,
status:
obj.status === 'requested' ? (
<Label color='primary'>
Request
</Label>
) : obj.status === 'approved' ? (
<Label color='success' >
Approval
</Label>
) : obj.status === 'declined' ? (
<Label color='error'>
Decline
</Label>
) : obj.status === 'reviewed' ? (
<Label color='info'>
Review
</Label>
) : (
<Label color='primary'>
Pending
</Label>
),
submission_date:
<Label>
{obj.submission_date ? fDateSuffix(obj.submission_date) : ''}
</Label>
,
action:
<TableMoreMenu actions={
<>
<MenuItem>
<Iconify icon="eva:eye-fill" />
View
</MenuItem>
</>
} />
}))
);
setPaginationTable(response.data);
setRowsPerPage(response.data.per_page);
if (searchParams.get('page')) {
//@ts-ignore
const currentPage = parseInt(searchParams.get('page')) - 1;
paginationTable.current_page = currentPage;
setPage(currentPage);
}
const status:any = [
{"id": "requested", "name": "Request" },
{"id": "reviewed", "name": "Review" },
{"id": "approved", "name": "Approval" },
{"id": "declined", "name": "Decline" },
];
setStatusData(status)
setIsLoading(false);
})();
}
return (
<>
<TableComponent
headCells={headCells}
rows={data}
orders={orders}
paginations={paginations}
loadings={loadings}
params={params}
searchs={searchs}
filterStatus={filterStatus}
// filterStartDate={filterStartDate}
// filterEndDate={filterEndDate}
/>
</>
);
}

View File

@@ -46,8 +46,8 @@ const ItemNotificationStyle = styled(Card)(({ theme }) => ({
// ----------------------------------------------------------------------
export default function CardSearchMember(handleSubmitSuccess) {
const { localeData } = useContext(LanguageContext);
export default function CardSearchMember(handleSubmitSuccess:()=> void) {
const { localeData }: any = useContext(LanguageContext);
const {enqueueSnackbar} = useSnackbar();
const [noPolis, setNoPolis] = useState('AW001-01');
@@ -112,7 +112,7 @@ export default function CardSearchMember(handleSubmitSuccess) {
<DatePicker
label={localeData.txtCardSearchMember3}
value={birthDate}
onChange={(newValue) => {
onChange={(newValue:any) => {
setBirthDate( (newValue));
}}
inputFormat="dd-MM-yyyy"
@@ -144,7 +144,7 @@ export default function CardSearchMember(handleSubmitSuccess) {
openDialog={openDialogBenefit}
setOpenDialog={setOpenDialogBenefit}
content={DialogMember(currentMember, () => {setOpenDialogBenefit(false); handleSubmitSuccess()})}
maxWidth="md"
maxWidth="sm"
/>
</div>
);

View File

@@ -0,0 +1,164 @@
import { styled } from '@mui/material/styles';
import Iconify from '@/components/Iconify';
import { fCurrency } from '@/utils/formatNumber';
import { LoadingButton } from '@mui/lab';
import { Avatar, Button, Divider, LinearProgress, linearProgressClasses, ButtonBase, Box } from '@mui/material';
import { Card } from '@mui/material';
import { Stack, Typography } from '@mui/material';
import { fPostFormat } from '@/utils/formatTime';
import axios from '@/utils/axios';
import { enqueueSnackbar } from 'notistack';
import { useRef, useState, useContext } from 'react';
import { makeFormData } from '@/utils/jsonToFormData';
import { format } from 'date-fns';
import { LanguageContext } from '@/contexts/LanguageContext';
export default function DialogClaimSubmit({ member, getData, onClose, handleSubmitSuccess }: any) {
const { localeData }: any = useContext(LanguageContext);
// ----------------------------------------------------------------------
// Files Result Tambahan
const fileAdditionalInput = useRef<HTMLInputElement>(null);
const [fileAdditionals, setFileAdditionals] = useState<any>([]);
const handleKondisiInputChange = (event:any) => {
if (event.target.files[0]) {
setFileAdditionals([...fileAdditionals, ...event.target.files]);
} else {
console.log('NO FILE');
}
};
const removeKondisiFiles = (filesState:any, index:any) => {
setFileAdditionals(
filesState.filter((file:any, fileIndex:any) => {
return fileIndex != index;
})
);
};
// --------------------------------------------------------------
// Submit Form
const [submitLoading, setSubmitLoading] = useState(false);
function submitRequestClaim() {
setSubmitLoading(true);
const formData = makeFormData({
request_logs_id: member.id,
service_code: member.service_code,
member_id: member.member_id,
additional_files: fileAdditionals
});
axios
.post('/claim-requests', formData)
.then((response) => {
enqueueSnackbar(response.data.meta.message ?? 'Berhasil membuat data', { variant: 'success' });
handleSubmitSuccess();
onClose({ someData: 'example data' }, getData);
})
.catch(({ response }) => {
enqueueSnackbar(response.data.meta.message ?? 'Something Went Wrong', { variant: 'error' });
})
.then(() => {
setSubmitLoading(false);
});
}
return (
<Stack>
<Stack direction="row" justifyContent={'end'} sx={{ marginBottom: 2, marginTop: 2 }} spacing={2}>
<Typography variant='body2' sx={{color: '#757575'}}>
{localeData.txtDialogMember5}
</Typography>
<Typography variant='body2' sx={{fontWeight:'bold'}}>{format(member?.submission_date ? new Date(member.submission_date) : new Date(), "d MMM yyyy")}</Typography>
</Stack>
<Card sx={{ p: 1, background: '#f4f6f8'}}>
<Stack direction="row">
<Avatar
src="https://minimal-assets-api.vercel.app/assets/images/avatars/avatar_5.jpg"
alt={member?.full_name ?? ''}
sx={{ marginTop: 1, width: 48, height: 48 }}
/>
<Stack sx={{ p: 1 }}>
<Typography variant="body2">{member?.full_name ?? ''}</Typography>
<Typography variant="body2" sx={{color:'#637381'}}>{member?.no_polis ?? ''}</Typography>
</Stack>
</Stack>
</Card>
<Stack
divider={<Divider orientation="horizontal" flexItem />}
spacing={4}
sx={{ marginY: 2, marginBottom: 6 }}
>
{/* -------------------------------Upload Dokumen Tambahan------------------------------- */}
<Stack sx={{ marginTop: 2 }}>
<Typography variant="body1" sx={{fontWeight:'bold'}}>
{localeData.txtAdditionalDocuments}
</Typography>
{/* <Typography variant="body2">Hasil Lab, </Typography> */}
<Stack
divider={<Divider orientation="horizontal" flexItem />}
spacing={1}
sx={{ marginY: 2 }}
>
{fileAdditionals &&
fileAdditionals.map((file:any, index:any) => (
<Stack direction="row" justifyContent={'space-between'} key={index}>
<Typography sx={{ color: "text.secondary" }}>{file.name}</Typography>
<Iconify
icon="eva:trash-2-outline"
color={'darkred'}
onClick={() => {
removeKondisiFiles(fileAdditionals, index);
}}
></Iconify>
</Stack>
))}
</Stack>
<ButtonBase sx={{ p: 4, border: '2px dashed #F9FAFB',
bgcolor: '#919EAB52',
borderRadius: '8px',
width: '100%', height: '60px'}} onClick={() => fileAdditionalInput.current?.click()}>
<Box
sx={{
display: 'flex',
placeItems: 'center',
gap: 1,
placeContent: 'center',
}}
>
<Iconify icon="icon-park-outline:upload-one" fontSize="3em" />
<Typography variant="body1" fontWeight="bold">
{localeData.txtAddResult}
</Typography>
</Box>
<input
type="file"
id="file"
ref={fileAdditionalInput}
style={{ display: 'none' }}
multiple
onChange={handleKondisiInputChange}
accept="application/pdf"
/>
</ButtonBase>
</Stack>
</Stack>
<LoadingButton
variant="contained"
sx={{ marginTop: 2, p: 2, backgroundColor: '#19BBBB' }}
onClick={() => {
submitRequestClaim();
}}
loading={submitLoading}
>
Submit Claim
</LoadingButton>
</Stack>
);
}

View File

@@ -0,0 +1,328 @@
import { styled } from '@mui/material/styles';
import Iconify from '@/components/Iconify';
import { fCurrency } from '@/utils/formatNumber';
import { LoadingButton } from '@mui/lab';
import { Avatar, Button, Divider, LinearProgress, linearProgressClasses, ButtonBase, Box } from '@mui/material';
import { Card } from '@mui/material';
import { Stack, Typography } from '@mui/material';
import { fPostFormat } from '@/utils/formatTime';
import axios from '@/utils/axios';
import { enqueueSnackbar } from 'notistack';
import { useRef, useState, useContext } from 'react';
import { makeFormData } from '@/utils/jsonToFormData';
import { format } from 'date-fns';
import { LanguageContext } from '@/contexts/LanguageContext';
export default function DialogFinalLog({ member, getData, onClose, handleSubmitSuccess }: any) {
const { localeData }: any = useContext(LanguageContext);
// ----------------------------------------------------------------------
// Files Diagnosa
const fileDiagnosaInput = useRef<HTMLInputElement>(null);
const [fileDiagnosas, setFileDiagnosas] = useState<any>([]);
const handleDiagnosaInputChange = (event:any) => {
if (event.target.files[0]) {
setFileDiagnosas([...fileDiagnosas, ...event.target.files]);
} else {
console.log('NO FILE');
}
};
const removeDiagnosaFiles = (filesState:any, index:any) => {
setFileDiagnosas(
filesState.filter((file:any, fileIndex:any) => {
return fileIndex != index;
})
);
};
// ----------------------------------------------------------------------
// Files Result Kondisi
const fileKondisiInput = useRef<HTMLInputElement>(null);
const [fileKondisis, setFileKondisis] = useState<any>([]);
const handleKondisiInputChange = (event:any) => {
if (event.target.files[0]) {
setFileKondisis([...fileKondisis, ...event.target.files]);
} else {
console.log('NO FILE');
}
};
const removeKondisiFiles = (filesState:any, index:any) => {
setFileKondisis(
filesState.filter((file:any, fileIndex:any) => {
return fileIndex != index;
})
);
};
// ----------------------------------------------------------------------
// Files Result Hasil Penunjang
const fileHasilPenunjangInput = useRef<HTMLInputElement>(null);
const [fileHasilPenunjangs, setFileHasilPenunjangs] = useState<any>([]);
const handleResultInputChange = (event:any) => {
if (event.target.files[0]) {
setFileHasilPenunjangs([...fileHasilPenunjangs, ...event.target.files]);
} else {
console.log('NO FILE');
}
};
const removeFiles = (filesState:any, index:any) => {
setFileHasilPenunjangs(
filesState.filter((file:any, fileIndex:any) => {
return fileIndex != index;
})
);
};
// --------------------------------------------------------------
// Submit Form
const [submitLoading, setSubmitLoading] = useState(false);
function submitRequestFinalLog() {
setSubmitLoading(true);
const formData = makeFormData({
request_logs_id: member.id,
result_files: fileHasilPenunjangs,
diagnosa_files: fileDiagnosas,
kondisi_files: fileKondisis
});
axios
.post('/request-final-log', formData)
.then((response) => {
enqueueSnackbar(response.data.meta.message ?? 'Berhasil membuat data', { variant: 'success' });
handleSubmitSuccess();
onClose({ someData: 'example data' }, getData);
})
.catch(({ response }) => {
enqueueSnackbar(response.data.meta.message ?? 'Something Went Wrong', { variant: 'error' });
})
.then(() => {
setSubmitLoading(false);
});
}
return (
<Stack>
<Stack direction="row" justifyContent={'end'} sx={{ marginBottom: 2, marginTop: 2 }} spacing={2}>
<Typography variant='body2' sx={{color: '#757575'}}>
{localeData.txtDialogMember5}
</Typography>
<Typography variant='body2' sx={{fontWeight:'bold'}}>{format(member?.submission_date ? new Date(member.submission_date) : new Date(), "d MMM yyyy")}</Typography>
</Stack>
<Card sx={{ p: 1, background: '#f4f6f8'}}>
<Stack direction="row">
<Avatar
src="https://minimal-assets-api.vercel.app/assets/images/avatars/avatar_5.jpg"
alt={member?.full_name ?? ''}
sx={{ marginTop: 1, width: 48, height: 48 }}
/>
<Stack sx={{ p: 1 }}>
<Typography variant="body2">{member?.full_name ?? ''}</Typography>
<Typography variant="body2" sx={{color:'#637381'}}>{member?.no_polis ?? ''}</Typography>
</Stack>
</Stack>
</Card>
<Stack
divider={<Divider orientation="horizontal" flexItem />}
spacing={4}
sx={{ marginY: 2, marginBottom: 6 }}
>
{/* -------------------------------Upload Dokumen Kondisi------------------------------- */}
<Stack sx={{ marginTop: 2 }}>
<Typography variant="body1" sx={{fontWeight:'bold'}}>
{localeData.txtConditionDocument}
</Typography>
{/* <Typography variant="body2">Hasil Lab, </Typography> */}
<Stack
divider={<Divider orientation="horizontal" flexItem />}
spacing={1}
sx={{ marginY: 2 }}
>
{fileKondisis &&
fileKondisis.map((file:any, index:any) => (
<Stack direction="row" justifyContent={'space-between'} key={index}>
<Typography sx={{ color: "text.secondary" }}>{file.name}</Typography>
<Iconify
icon="eva:trash-2-outline"
color={'darkred'}
onClick={() => {
removeKondisiFiles(fileKondisis, index);
}}
></Iconify>
</Stack>
))}
</Stack>
<ButtonBase sx={{ p: 4, border: '2px dashed #F9FAFB',
bgcolor: '#919EAB52',
borderRadius: '8px',
width: '100%', height: '60px'}} onClick={() => fileKondisiInput.current?.click()}>
<Box
sx={{
display: 'flex',
placeItems: 'center',
gap: 1,
placeContent: 'center',
}}
>
<Iconify icon="icon-park-outline:upload-one" fontSize="3em" />
<Typography variant="body1" fontWeight="bold">
{localeData.txtAddResult}
</Typography>
</Box>
<input
type="file"
id="file"
ref={fileKondisiInput}
style={{ display: 'none' }}
multiple
onChange={handleKondisiInputChange}
accept="application/pdf"
/>
</ButtonBase>
</Stack>
{/* -------------------------------Upload Dokumen Diagnosa------------------------------- */}
<Stack sx={{ marginTop: 2 }}>
<Typography variant="body1" sx={{fontWeight:'bold'}}>
{localeData.txtDiagnosisDokument}
</Typography>
{/* <Typography variant="body2">Hasil Lab, </Typography> */}
<Stack
divider={<Divider orientation="horizontal" flexItem />}
spacing={1}
sx={{ marginY: 2 }}
>
{fileDiagnosas &&
fileDiagnosas.map((file:any, index:any) => (
<Stack direction="row" justifyContent={'space-between'} key={index}>
<Typography sx={{ color: "text.secondary" }}>{file.name}</Typography>
<Iconify
icon="eva:trash-2-outline"
color={'darkred'}
onClick={() => {
removeDiagnosaFiles(fileDiagnosas, index);
}}
></Iconify>
</Stack>
))}
{/* <Stack direction="row" justifyContent={'space-between'}>
<Typography>Nama File .pdf</Typography>
<Iconify icon="eva:trash-2-outline" color={'darkred'}></Iconify>
</Stack> */}
</Stack>
{/* { JSON.stringify(filesResult) } */}
<ButtonBase sx={{ p: 4, border: '2px dashed #F9FAFB',
bgcolor: '#919EAB52',
borderRadius: '8px',
width: '100%', height: '60px'}} onClick={() => fileDiagnosaInput.current?.click()}>
<Box
sx={{
display: 'flex',
placeItems: 'center',
gap: 1,
placeContent: 'center',
}}
>
<Iconify icon="icon-park-outline:upload-one" fontSize="3em" />
<Typography variant="body1" fontWeight="bold">
{localeData.txtAddResult}
</Typography>
</Box>
<input
type="file"
id="file"
ref={fileDiagnosaInput}
style={{ display: 'none' }}
multiple
onChange={handleDiagnosaInputChange}
accept="application/pdf"
/>
</ButtonBase>
</Stack>
{/* -------------------------------Upload Dokumen Hasil Penunjang------------------------------- */}
<Stack sx={{ marginTop: 2 }}>
<Typography variant="body1" sx={{fontWeight:'bold'}}>
{localeData.txtSupportingResultDocument}
</Typography>
{/* <Typography variant="body2">Hasil Lab, </Typography> */}
<Stack
divider={<Divider orientation="horizontal" flexItem />}
spacing={1}
sx={{ marginY: 2 }}
>
{fileHasilPenunjangs &&
fileHasilPenunjangs.map((file:any, index:any) => (
<Stack direction="row" justifyContent={'space-between'} key={index}>
<Typography sx={{ color: "text.secondary" }}>{file.name}</Typography>
<Iconify
icon="eva:trash-2-outline"
color={'darkred'}
onClick={() => {
removeFiles(fileHasilPenunjangs, index);
}}
></Iconify>
</Stack>
))}
{/* <Stack direction="row" justifyContent={'space-between'}>
<Typography>Nama File .pdf</Typography>
<Iconify icon="eva:trash-2-outline" color={'darkred'}></Iconify>
</Stack> */}
</Stack>
{/* { JSON.stringify(filesResult) } */}
<ButtonBase sx={{ p: 4, border: '2px dashed #F9FAFB',
bgcolor: '#919EAB52',
borderRadius: '8px',
width: '100%', height: '60px'}} onClick={() => fileHasilPenunjangInput.current?.click()}>
<Box
sx={{
display: 'flex',
placeItems: 'center',
gap: 1,
placeContent: 'center',
}}
>
<Iconify icon="icon-park-outline:upload-one" fontSize="3em" />
<Typography variant="body1" fontWeight="bold">
{localeData.txtAddResult}
</Typography>
</Box>
<input
type="file"
id="file"
ref={fileHasilPenunjangInput}
style={{ display: 'none' }}
multiple
onChange={handleResultInputChange}
accept="application/pdf"
/>
</ButtonBase>
</Stack>
</Stack>
<LoadingButton
variant="contained"
sx={{ marginTop: 2, p: 2, backgroundColor: '#19BBBB' }}
onClick={() => {
submitRequestFinalLog();
}}
loading={submitLoading}
>
Request Final LOG
</LoadingButton>
</Stack>
);
}

View File

@@ -1,7 +1,22 @@
// mui
import { styled } from '@mui/material/styles';
import { LoadingButton, TabPanel } from "@mui/lab";
import { Button, Card, Divider, Grid, LinearProgress, linearProgressClasses, Typography } from "@mui/material";
import {
Button,
Card,
Divider,
Grid,
LinearProgress,
linearProgressClasses,
Typography,
Paper,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
Collapse, } from "@mui/material";
import { Tab, Tabs } from "@mui/material";
import { Box, Stack } from "@mui/material";
import React, { useEffect, useState, useContext } from "react";
@@ -10,12 +25,15 @@ import { fPostFormat } from '@/utils/formatTime';
import { Avatar } from '@mui/material';
import Iconify from '@/components/Iconify';
import FormRequestClaim from './FormRequestClaim';
import FormRequestLog from './FormRequestLog';
import { LanguageContext } from '@/contexts/LanguageContext';
import { format } from 'date-fns';
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight';
export default function DialogMember(member, handleSubmitSuccess) {
const { localeData } = useContext(LanguageContext);
const [currentTab, setCurrentTab] = useState('request')
export default function DialogMember(member:any, handleSubmitSuccess:() => void) {
const { localeData }: any = useContext(LanguageContext);
const [currentTab, setCurrentTab] = useState('request');
// ----------------------------------------------------------------------
@@ -41,7 +59,7 @@ export default function DialogMember(member, handleSubmitSuccess) {
},
}));
function TabPanel(props) {
function TabPanel(props:any) {
const { children, value, index, ...other } = props;
return (
<div
@@ -59,6 +77,15 @@ export default function DialogMember(member, handleSubmitSuccess) {
</div>
);
}
const [openRows, setOpenRows] = useState<any>({});
const handleRowToggle = (index:number) => {
setOpenRows((prevOpenRows:any) => ({
...prevOpenRows,
[index]: !prevOpenRows[index],
}));
};
return (
<div>
@@ -69,8 +96,10 @@ export default function DialogMember(member, handleSubmitSuccess) {
aria-label="wrapped label tabs example"
>
<Tab value="detail" label={localeData.txtDialogMember3} />
<Tab value="benefit" label={localeData.txtDialogMember1} />
<Tab value="request" label={localeData.txtDialogMember2} />
<Tab value="service" label={localeData.txtDialogMember1} />
{member?.type !== 'view' ? (
<Tab value="request" label={localeData.txtDialogMember2} />
) : ''}
</Tabs>
<TabPanel value={currentTab} index={'detail'}>
@@ -96,19 +125,19 @@ export default function DialogMember(member, handleSubmitSuccess) {
<Typography sx={{width:'50%', fontWeight: 'bold'}} variant="body2">{member?.members.email ?? '-'}</Typography>
</Stack>
<Stack direction="row" justifyContent="space-between">
<Typography sx={{width:'50%'}} variant="body2">Date of Birth</Typography>
<Typography sx={{width:'50%'}} variant="body2">{localeData.txtDateBirth}</Typography>
<Typography sx={{width:'50%', fontWeight: 'bold'}} variant="body2">{member?.members.birth_date ? format(new Date(member.members.birth_date), "d MMM yyyy") : '-'}</Typography>
</Stack>
<Stack direction="row" justifyContent="space-between">
<Typography sx={{width:'50%'}} variant="body2">Gender</Typography>
<Typography sx={{width:'50%'}} variant="body2">{localeData.txtGender}</Typography>
<Typography sx={{width:'50%', fontWeight: 'bold'}} variant="body2">{member?.members.gender ?? '-'}</Typography>
</Stack>
<Stack direction="row" justifyContent="space-between">
<Typography sx={{width:'50%'}} variant="body2">Marital Status</Typography>
<Typography sx={{width:'50%'}} variant="body2">{localeData.txtMaritalStatus}</Typography>
<Typography sx={{width:'50%', fontWeight: 'bold'}} variant="body2">{member?.members.marital_status ?? '-'}</Typography>
</Stack>
<Stack direction="row" justifyContent="space-between">
<Typography sx={{width:'50%'}} variant="body2">Language</Typography>
<Typography sx={{width:'50%'}} variant="body2">{localeData.txtLanguage}</Typography>
<Typography sx={{width:'50%', fontWeight: 'bold'}} variant="body2">{member?.members.language ?? '-'}</Typography>
</Stack>
<Stack direction="row" justifyContent="space-between">
@@ -116,29 +145,51 @@ export default function DialogMember(member, handleSubmitSuccess) {
<Typography sx={{width:'50%', fontWeight: 'bold'}} variant="body2">{member?.members.race ?? '-'}</Typography>
</Stack>
<Stack direction="row" justifyContent="space-between">
<Typography sx={{width:'50%'}} variant="body2">Relationship</Typography>
<Typography sx={{width:'50%'}} variant="body2">{localeData.txtRelationship}</Typography>
<Typography sx={{width:'50%', fontWeight: 'bold'}} variant="body2">{member?.members.relation_with_principal != '' ? member?.members.relation_with_principal : '-'}</Typography>
</Stack>
</Stack>
</TabPanel>
<TabPanel value={currentTab} index={'benefit'}>
<Grid container spacing={2}>
{ member && member?.benefits?.map((corporateBenefit, index) => {return (
<Grid item sm={6} key={index}>
<Card sx={{p: 2}}>
<Typography variant="body2" sx={{fontWeight: 'bold'}}>{corporateBenefit.description}</Typography>
<Typography variant="body2" sx={{color: '#919EAB'}}>{corporateBenefit.code}</Typography>
</Card>
</Grid>
)})}
</Grid>
<TabPanel value={currentTab} index={'service'}>
<TableContainer component={Paper}>
<Table aria-label="collapsible table">
{member && member.groupServices && Object.keys(member.groupServices).map((serviceCode, index) => (
<TableBody key={index}>
<TableRow sx={{backgroundColor: '#FFFFFF', borderBottom: openRows[index] ? '' : '1px solid #e0e0e0'}}>
<TableCell align="left" sx={{fontWeight: 'bold', width: '95%'}}><Typography variant="subtitle1">{serviceCode}</Typography></TableCell>
<TableCell align="left" sx={{width: '5%'}}>
{openRows[index] ? (
<KeyboardArrowDownIcon sx={{ cursor: 'pointer' }} onClick={() => handleRowToggle(index)} />
) : (
<KeyboardArrowRightIcon sx={{ cursor: 'pointer' }} onClick={() => handleRowToggle(index)} />
)}
</TableCell>
</TableRow>
<TableRow sx={{display: openRows[index] ? '' : 'none', borderBottom: openRows[index] ? '1px solid #e0e0e0' : ''}}>
<TableCell colSpan={2}>
{/* COLLAPSIBLE ROW */}
<Collapse in={openRows[index]} timeout="auto" unmountOnExit>
<Grid container spacing={2}>
{/* Loop through the array for the current serviceCode */}
{member.groupServices[serviceCode].map((item:any, innerIndex:number) => (
<Grid item sm={6} key={innerIndex}>
<Card sx={{ p: 2 }}>
<Typography variant="body2" sx={{ fontWeight: 'bold' }}>{item.description}</Typography>
<Typography variant="body2" sx={{ color: '#919EAB' }}>{item.code}</Typography>
</Card>
</Grid>
))}
</Grid>
</Collapse>
</TableCell>
</TableRow>
</TableBody>
))}
</Table>
</TableContainer>
</TabPanel>
<TabPanel value={currentTab} index={'request'}>
<FormRequestClaim member={member} handleSubmitSuccess={handleSubmitSuccess} />
<FormRequestLog member={member} handleSubmitSuccess={handleSubmitSuccess} />
</TabPanel>
</Box>
</div>

View File

@@ -0,0 +1,128 @@
import { LoadingButton } from '@mui/lab';
import
{
Avatar,
FormControl,
InputLabel,
Select,
FormHelperText,
MenuItem
} from '@mui/material';
import { Card } from '@mui/material';
import { Stack, Typography } from '@mui/material';
import axios from '@/utils/axios';
import { enqueueSnackbar } from 'notistack';
import { useRef, useState, useContext } from 'react';
import { makeFormData } from '@/utils/jsonToFormData';
import { format } from 'date-fns';
import { LanguageContext } from '@/contexts/LanguageContext';
interface MemberType {
members: any;
services: any;
}
interface FormRequestClaimProps {
member: MemberType;
handleSubmitSuccess: () => void;
}
export default function FormRequestClaim({ member, handleSubmitSuccess }: FormRequestClaimProps) {
const { localeData }: any = useContext(LanguageContext);
const [serviceCode, setServiceCode] = useState<string>('');
const [submitLoading, setSubmitLoading] = useState<boolean>(false);
function submitRequest() {
if(serviceCode == '')
{
enqueueSnackbar(localeData.txtDialogMember4, { variant: 'warning' });
return false;
}
setSubmitLoading(true);
const formData = {
member_id: member.members.id,
service_code: serviceCode
};
axios
.post('/request-log', formData)
.then((response) => {
console.log(response);
if (response && response.data && response.data.meta) {
enqueueSnackbar(response.data.meta.message, { variant: 'success' });
handleSubmitSuccess();
}
})
.catch(({ response }) => {
if (response && response.data && response.data.meta) {
enqueueSnackbar(response.data.meta.message, { variant: 'error' });
}
})
.then(() => {
setSubmitLoading(false);
});
}
interface MemberService {
service_code: string;
name: string;
}
return (
<Stack direction="column" spacing={4}>
<Stack direction="row" justifyContent={'end'} sx={{ marginBottom: 2 }} spacing={2}>
<Typography variant='body2' sx={{color: '#757575'}}>
{localeData.txtDialogMember5}
</Typography>
<Typography variant='body2' sx={{fontWeight:'bold'}}>{format(new Date(), "d MMM yyyy")}</Typography>
</Stack>
<Stack direction="row" spacing={2}>
<Stack spacing={2} sx={{width:'100%'}}>
<Typography variant='subtitle1'>{localeData.txtDialogMember1}*</Typography>
<FormControl>
<InputLabel htmlFor="service_type">
{localeData.txtDialogMember1}
</InputLabel>
<Select
id="service_type"
value={serviceCode}
fullWidth
label={localeData.txtDialogMember1}
onChange={(e) => {
setServiceCode(e.target.value);
}}
>
{member && member?.services?.map((item: MemberService, index:number) => (
<MenuItem key={index} value={item.service_code}>{item.name}</MenuItem>
))}
</Select>
<FormHelperText style={{ color: 'red' }}></FormHelperText>
</FormControl>
</Stack>
</Stack>
<Card sx={{ p: 1, background: '#f4f6f8'}}>
<Stack direction="row">
<Avatar
src="https://minimal-assets-api.vercel.app/assets/images/avatars/avatar_5.jpg"
alt={member?.members.name ?? ''}
sx={{ marginTop: 1, width: 48, height: 48 }}
/>
<Stack sx={{ p: 1 }}>
<Typography variant="body2">{member?.members.name ?? ''}</Typography>
<Typography variant="body2" sx={{color:'#637381'}}>{member?.members.member_id ?? ''}</Typography>
</Stack>
</Stack>
</Card>
<LoadingButton
variant="contained"
sx={{ marginTop: 2, p: 2, backgroundColor: '#19BBBB' }}
onClick={() => {
submitRequest();
}}
loading={submitLoading}
>
{localeData.txtDialogMember2}
</LoadingButton>
</Stack>
);
}

View File

@@ -1,8 +1,9 @@
/* ---------------------------------- @mui ---------------------------------- */
import { Stack, Button, MenuItem, SelectChangeEvent } from '@mui/material';
import { Stack, Button, MenuItem, SelectChangeEvent, Tab, Tabs, Card, Box } from '@mui/material';
/* ---------------------------------- axios --------------------------------- */
// import axios from 'axios';
import axios from '../../utils/axios';
import { styled } from '@mui/material/styles';
/* ---------------------------------- react --------------------------------- */
import { useContext, useEffect, useState } from 'react';
@@ -23,9 +24,26 @@ import HistoryIcon from '@mui/icons-material/History';
import SearchIcon from '@mui/icons-material/Search';
import Label from '../../components/Label';
import { enqueueSnackbar } from 'notistack';
import { LoadingButton, TabPanel } from "@mui/lab";
import { LanguageContext } from '@/contexts/LanguageContext';
import MuiDialog from '@/components/MuiDialog';
import DialogMember from './DialogMember';
import DialogFinalLog from './DialogFinalLog';
import { fPostFormat } from '@/utils/formatTime';
import TableListFinalLog from './TableListFinalLog';
export default function TableList2() {
export default function TableList() {
const navigate = useNavigate();
const { localeData }: any = useContext(LanguageContext);
const [currentTab, setCurrentTab] = useState<string>('request_log');
useEffect(() => {
setCurrentTab('request_log')
}, [])
function handleChangeTab(event: React.SyntheticEvent, newValue: string) {
setCurrentTab(newValue)
}
//const { corporateValue } = useContext(UserCurrentCorporateContext);
//const { corporateValue } = useContext(null);
@@ -33,7 +51,7 @@ export default function TableList2() {
const [data, setData] = useState([]);
// Download LOG
async function handleDownloadLog(claimRequest) {
async function handleDownloadLog(claimRequest:any) {
return axios
.get(`claim-requests/${claimRequest}/log`, {
responseType: 'blob',
@@ -215,36 +233,30 @@ export default function TableList2() {
handleEndDateChange: handleEndDateChanges,
};
/* -------------------------------- headCell -------------------------------- */
/* -------------------------------- headCell Request LOG -------------------------------- */
const headCells: HeadCell<never>[] = [
{
id: 'submission_date',
align: 'center',
label: 'Request Date',
isSort: true,
},
{
id: 'member_id',
align: 'left',
label: 'Member ID',
isSort: true,
},
{
id: 'code',
align: 'left',
label: 'Claim Code',
label: localeData.txtRequestCode,
isSort: true,
},
{
id: 'full_name',
align: 'left',
label: 'Name',
label: localeData.txtName,
isSort: true,
},
{
id: 'submission_date',
align: 'center',
label: localeData.txtSubmissionDate,
isSort: true,
},
{
id: 'status',
align: 'center',
label: 'Status',
label: localeData.txtStatus,
isSort: true,
},
{
@@ -254,8 +266,47 @@ export default function TableList2() {
isSort: false,
},
];
function handleSearchMember(noPolis:any, birthDate:any) {
setLoadingClaim(false)
axios.post('/search-member', {
no_polis: noPolis,
birth_date: birthDate ? fPostFormat(birthDate, 'yyyy-MM-dd') : null,
type: 'view'
})
.then((response) => {
setOpenDialogBenefit(true)
setCurrentMember(response.data.data)
setNameMember(response.data.data.members.name);
})
.catch(({response}) => {
enqueueSnackbar(response.data.errors ? response.data.errors[0] : (response.data ? response.data.meta.message : 'Opps, Something went Wrong!'), {variant : "error"})
})
.then(() => {
});
}
function handleRequestFinalLog(id:any, full_name:any, no_polis:any, submission_date:any)
{
setOpenDialogFinalLog(true);
const datas_view = {
'id' : id,
'full_name' : full_name,
'no_polis' : no_polis,
'submission_date' : submission_date
};
setDataViewFinalDialog(datas_view);
}
useEffect(() => {
getData();
}, [appliedParams, searchParams, order, orderBy, setSearchParams]);
function getData()
{
(async () => {
setIsLoading(true);
@@ -266,10 +317,9 @@ export default function TableList2() {
? appliedParams
: Object.fromEntries([...searchParams.entries(), ['order', order], ['orderBy', orderBy]]);
const response = await axios.get(`/get-claim-requests`, {
params: { ...parameters, type: 'claim-request' },
const response = await axios.get(`/get-request-log`, {
params: { ...parameters, type: 'request-log' },
});
setData(
response.data.data.map((obj: any) => ({
...obj,
@@ -303,14 +353,22 @@ export default function TableList2() {
action:
<TableMoreMenu actions={
<>
<MenuItem onClick={() => navigate ('/detail/'+obj.claim_request_id)}>
<MenuItem onClick={() => handleSearchMember(obj.no_polis, obj.birth_date) }>
<Iconify icon="eva:eye-fill" />
View
</MenuItem>
{obj.status === 'approved' ? (
<MenuItem onClick={() => handleDownloadLog(obj.claim_request_id)}>
<Iconify icon="eva:download-fill" />
Download LOG
</MenuItem>
):''}
{obj.final_log === 0 ? (
<MenuItem onClick={() => handleRequestFinalLog(obj.id, obj.full_name, obj.no_polis, obj.submission_date) }>
<Iconify icon="fa:file-text" />
Request Final LOG
</MenuItem>
):''}
</>
} />
}))
@@ -327,32 +385,116 @@ export default function TableList2() {
setPage(currentPage);
}
const status = [
const status:any = [
{"id": "requested", "name": "Request" },
{"id": "reviewed", "name": "Review" },
{"id": "approved", "name": "Approval" },
{"id": "declined", "name": "Decline" },
]
];
setStatusData(status)
setIsLoading(false);
})();
}, [appliedParams, searchParams, order, orderBy, setSearchParams]);
}
const RootNotificationStyle = styled(Card)(({ theme }) => ({
boxShadow: 'none',
padding: '1rem 0.5rem',
color: 'black',
borderRadius: 0,
backgroundColor: theme.palette.grey[200],
// maxHeight: '240px',
}));
function TabPanel(props:any) {
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 sx={{ p: 3 }}>
<div>{children}</div>
</Box>
)}
</div>
);
}
// const [noPolis, setNoPolis] = useState('AW001-01');
//const [birthDate, setBirthDate] = useState('1991-01-10');
const [loadingBenefit, setLoadingBenefit] = useState(false);
const [loadingClaim, setLoadingClaim] = useState(false);
const [openDialogBenefit, setOpenDialogBenefit] = useState(false);
const [openDialogFinalLog, setOpenDialogFinalLog] = useState(false);
const [openDialogClaim, setOpenDialogClaim] = useState(false);
const [currentMember, setCurrentMember] = useState(null);
const [nameMember, setNameMember] = useState('');
const [setIsRequestFinalLog, isRequestFinalLog] = useState(false);
const [dataViewFinalDialog, setDataViewFinalDialog] = useState<any>(null);
return (
<Stack>
<TableComponent
headCells={headCells}
rows={data}
orders={orders}
paginations={paginations}
loadings={loadings}
params={params}
searchs={searchs}
filterStatus={filterStatus}
// filterStartDate={filterStartDate}
// filterEndDate={filterEndDate}
/>
</Stack>
<Card>
<RootNotificationStyle sx={{ p: 2, height: 'auto' }}>
<Tabs
value={currentTab}
onChange={handleChangeTab}
aria-label="wrapped label tabs example"
>
<Tab value="request_log" label= "Request LOG" />
<Tab value="final_log" label= "Final LOG" />
</Tabs>
</RootNotificationStyle>
<TabPanel value={currentTab} index={'request_log'}>
<TableComponent
headCells={headCells}
rows={data}
orders={orders}
paginations={paginations}
loadings={loadings}
params={params}
searchs={searchs}
filterStatus={filterStatus}
// filterStartDate={filterStartDate}
// filterEndDate={filterEndDate}
/>
</TabPanel>
<TabPanel value={currentTab} index={'final_log'}>
<TableListFinalLog/>
</TabPanel>
<MuiDialog
title={{name: nameMember}}
openDialog={openDialogBenefit}
setOpenDialog={setOpenDialogBenefit}
content={
DialogMember(currentMember, () => setOpenDialogBenefit(false))
}
maxWidth="sm"
/>
<MuiDialog
title={{name: dataViewFinalDialog?.full_name}}
openDialog={openDialogFinalLog}
setOpenDialog={setOpenDialogFinalLog}
content={
<DialogFinalLog
member={dataViewFinalDialog}
getData={getData}
onClose={(data:any, getData:any) => {
console.log('Data returned:', data);
getData();
setOpenDialogFinalLog(false);
}}
handleSubmitSuccess={() => {
}}
/>
}
maxWidth="sm"
/>
</Card>
);
}

View File

@@ -0,0 +1,441 @@
/* ---------------------------------- @mui ---------------------------------- */
import { Stack, Button, MenuItem, SelectChangeEvent, Tab, Tabs, Card, Box } from '@mui/material';
/* ---------------------------------- axios --------------------------------- */
// import axios from 'axios';
import axios from '../../utils/axios';
import { styled } from '@mui/material/styles';
/* ---------------------------------- react --------------------------------- */
import { useContext, useEffect, useState } from 'react';
/* -------------------------------- component ------------------------------- */
import Iconify from '../../components/Iconify';
import TableComponent from '../../components/Table';
/* ---------------------------------- theme --------------------------------- */
import palette from '../../theme/palette';
//import { UserCurrentCorporateContext } from '../../contexts/UserCurrentCorporate';
import { HeadCell, Order, PaginationTableProps } from '../../@types/table';
import { useSearchParams, useNavigate } from 'react-router-dom';
import { fDate, fDateSuffix } from '../../utils/formatTime';
import Typography from '@mui/material/Typography';
import { format } from 'date-fns';
import TableMoreMenu from '../../components/table/TableMoreMenu';
import VisibilityOutlinedIcon from '@mui/icons-material/VisibilityOutlined';
import HistoryIcon from '@mui/icons-material/History';
import SearchIcon from '@mui/icons-material/Search';
import Label from '../../components/Label';
import { enqueueSnackbar } from 'notistack';
import { LoadingButton, TabPanel } from "@mui/lab";
import { LanguageContext } from '@/contexts/LanguageContext';
import MuiDialog from '@/components/MuiDialog';
import DialogMember from './DialogMember';
import DialogClaimSubmit from './DialogClaimSubmit';
import { fPostFormat } from '@/utils/formatTime';
export default function TableListFinalLog() {
const navigate = useNavigate();
const { localeData }: any = useContext(LanguageContext);
const [data, setData] = useState([]);
// Download LOG
async function handleDownloadLog(claimRequest:any) {
return axios
.get(`claim-requests/${claimRequest}/log`, {
responseType: 'blob',
})
.then((response) => {
window.open(URL.createObjectURL(response.data));
// setLoadingLog(false);
})
// .then((blobFile) => {
// new File([blobFile], 'asdads.pdf', { type: blobFile.type })
// setLoadingLog(false);
// })
.catch((response) => {
console.log(response);
enqueueSnackbar(response.message, { variant: 'error' });
// setLoadingLog(false);
});
}
/* -------------------------------------------------------------------------- */
/* setting up for the table */
/* -------------------------------------------------------------------------- */
const [isLoading, setIsLoading] = useState(true);
const loadings = {
isLoading: isLoading,
setIsLoading: setIsLoading,
};
/* ------------------------------ handle params ----------------------------- */
const [searchParams, setSearchParams] = useSearchParams();
const [appliedParams, setAppliedParams] = useState({});
const params = {
searchParams: searchParams,
setSearchParams: setSearchParams,
appliedParams: appliedParams,
setAppliedParams: setAppliedParams,
};
/* -------------------------------------------------------------------------- */
/* ------------------------------ handle order ------------------------------ */
const [order, setOrder] = useState<Order>('desc');
const [orderBy, setOrderBy] = useState('submission_date');
const orders = {
order: order,
setOrder: setOrder,
orderBy: orderBy,
setOrderBy: setOrderBy,
};
/* -------------------------------------------------------------------------- */
/* ---------------------------- handle pagination --------------------------- */
const [page, setPage] = useState(0);
const [rowsPerPage, setRowsPerPage] = useState(10);
const [paginationTable, setPaginationTable] = useState<PaginationTableProps>({
current_page: 0,
from: 0,
last_page: 0,
links: [],
path: '',
per_page: 0,
to: 0,
total: 0,
});
const paginations = {
page: page,
setPage: setPage,
rowsPerPage: rowsPerPage,
setRowsPerPage: setRowsPerPage,
paginationTable: paginationTable,
setPaginationTable: setPaginationTable,
};
/* -------------------------------------------------------------------------- */
/* ------------------------------ handle search ----------------------------- */
const [searchText, setSearchText] = useState('');
const handleSearchSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
if (searchText === '') {
searchParams.delete('search');
const params = Object.fromEntries([...searchParams.entries()]);
setAppliedParams(params);
} else {
const params = Object.fromEntries([...searchParams.entries(), ['search', searchText]]);
setAppliedParams(params);
}
};
const searchs = {
useSearchs: true,
searchText: searchText,
setSearchText: setSearchText,
handleSearchSubmit: handleSearchSubmit,
};
/* ------------------------------ handle filter ----------------------------- */
const [statusValue, setStatusValue] = useState('all');
const [filterData, setStatusData] = useState([]);
// handle status
const handleStatusChanges = (event: SelectChangeEvent) => {
setStatusValue(event.target.value as string);
if (event.target.value === 'all') {
searchParams.delete('status');
const params = Object.fromEntries([...searchParams.entries()]);
setAppliedParams(params);
} else {
const params = Object.fromEntries([
...searchParams.entries(),
['status', event.target.value as string],
]);
setAppliedParams(params);
}
};
const filterStatus = {
useFilter: true,
config: {
label: 'Status',
statusValue: statusValue,
filterData: filterData,
handleStatusChange: handleStatusChanges,
},
};
// handle start date
const [startDateValue, setStartDateValue] = useState('');
const handleStartDateChanges = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
const newStartDateValue = event.currentTarget.elements['date-input'].value;
setStartDateValue(newStartDateValue);
if (newStartDateValue === '') {
searchParams.delete('start_date');
const params = Object.fromEntries([...searchParams.entries()]);
setAppliedParams(params);
} else {
const params = Object.fromEntries([...searchParams.entries(), ['start_date', newStartDateValue]]);
setAppliedParams(params);
}
};
const filterStartDate = {
useFilter: true,
startDate: startDateValue,
setStartDate: setStartDateValue,
handleStartDateChange: handleStartDateChanges,
};
// handle end date
const [endDateValue, setEndDateValue] = useState('');
const handleEndDateChanges = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
const newEndDateValue = event.currentTarget.elements['date-input'].value;
setEndDateValue(newEndDateValue);
if (newEndDateValue === '') {
searchParams.delete('end_date');
const params = Object.fromEntries([...searchParams.entries()]);
setAppliedParams(params);
} else {
const params = Object.fromEntries([...searchParams.entries(), ['end_date', newEndDateValue]]);
setAppliedParams(params);
}
};
const filterEndDate = {
useFilter: true,
endDate: endDateValue,
setEndDate: setEndDateValue,
handleEndDateChange: handleEndDateChanges,
};
/* -------------------------------- headCell Final LOG -------------------------------- */
const headCells: HeadCell<never>[] = [
{
id: 'code',
align: 'left',
label: localeData.txtRequestCode,
isSort: true,
},
{
id: 'full_name',
align: 'left',
label: localeData.txtName,
isSort: true,
},
{
id: 'submission_date',
align: 'center',
label: localeData.txtSubmissionDate,
isSort: true,
},
{
id: 'service_type',
align: 'center',
label: localeData.txtServiceType,
isSort: true,
},
{
id: 'status',
align: 'center',
label: localeData.txtStatus,
isSort: true,
},
{
id: 'action',
align: 'right',
label: '',
isSort: false,
},
];
function handleSearchMember(noPolis:any, birthDate:any) {
setLoadingClaim(false)
axios.post('/search-member', {
no_polis: noPolis,
birth_date: birthDate ? fPostFormat(birthDate, 'yyyy-MM-dd') : null,
type: 'view'
})
.then((response) => {
setOpenDialogBenefit(true)
setCurrentMember(response.data.data)
setNameMember(response.data.data.members.name);
})
.catch(({response}) => {
enqueueSnackbar(response.data.errors ? response.data.errors[0] : (response.data ? response.data.meta.message : 'Opps, Something went Wrong!'), {variant : "error"})
})
.then(() => {
});
}
const [openDialogClaimSubmit, setOpenDialogClaimSubmit] = useState(false);
const [dataViewClaimSubmit, setDataViewClaimSubmit] = useState<any>(null);
function handleRequestClaimSubmit(member_id:any, service_code:any, id:any, full_name:any, no_polis:any, submission_date:any)
{
setOpenDialogClaimSubmit(true);
const datas_view = {
'member_id' : member_id,
'service_code' : service_code,
'id' : id,
'full_name' : full_name,
'no_polis' : no_polis,
'submission_date' : submission_date
};
setDataViewClaimSubmit(datas_view);
}
useEffect(() => {
getData();
}, [appliedParams, searchParams, order, orderBy, setSearchParams]);
function getData()
{
(async () => {
setIsLoading(true);
await new Promise((resolve) => setTimeout(resolve, 250));
const parameters =
Object.keys(appliedParams).length !== 0
? appliedParams
: Object.fromEntries([...searchParams.entries(), ['order', order], ['orderBy', orderBy]]);
const response = await axios.get(`/get-final-log`, {
params: { ...parameters, type: 'final-log' },
});
setData(
response.data.data.map((obj: any) => ({
...obj,
status:
obj.status === 'requested' ? (
<Label color='primary'>
Request
</Label>
) : obj.status === 'approved' ? (
<Label color='success' >
Approval
</Label>
) : obj.status === 'declined' ? (
<Label color='error'>
Decline
</Label>
) : obj.status === 'reviewed' ? (
<Label color='info'>
Review
</Label>
) : (
<Label color='primary'>
Pending
</Label>
),
submission_date:
<Label>
{obj.submission_date ? fDateSuffix(obj.submission_date) : ''}
</Label>
,
action:
<TableMoreMenu actions={
<>
<MenuItem onClick={() => handleSearchMember(obj.no_polis, obj.birth_date) }>
<Iconify icon="eva:eye-fill" />
View
</MenuItem>
{obj.status === 'approved' ? (
<MenuItem onClick={() => handleDownloadLog(obj.claim_request_id)}>
<Iconify icon="eva:download-fill" />
Download LOG
</MenuItem>
):''}
{!obj.check_claim ? (
<MenuItem onClick={() => handleRequestClaimSubmit(obj.member_id, obj.service_code, obj.id, obj.full_name, obj.no_polis, obj.submission_date) }>
<Iconify icon="fa:file-text" />
Submit Claim
</MenuItem>
):''}
</>
} />
}))
);
setPaginationTable(response.data);
setRowsPerPage(response.data.per_page);
if (searchParams.get('page')) {
//@ts-ignore
const currentPage = parseInt(searchParams.get('page')) - 1;
paginationTable.current_page = currentPage;
setPage(currentPage);
}
const status:any = [
{"id": "requested", "name": "Request" },
{"id": "reviewed", "name": "Review" },
{"id": "approved", "name": "Approval" },
{"id": "declined", "name": "Decline" },
];
setStatusData(status)
setIsLoading(false);
})();
}
const [loadingClaim, setLoadingClaim] = useState(false);
const [openDialogBenefit, setOpenDialogBenefit] = useState(false);
const [currentMember, setCurrentMember] = useState(null);
const [nameMember, setNameMember] = useState('');
return (
<>
<TableComponent
headCells={headCells}
rows={data}
orders={orders}
paginations={paginations}
loadings={loadings}
params={params}
searchs={searchs}
filterStatus={filterStatus}
// filterStartDate={filterStartDate}
// filterEndDate={filterEndDate}
/>
<MuiDialog
title={{name: nameMember}}
openDialog={openDialogBenefit}
setOpenDialog={setOpenDialogBenefit}
content={
DialogMember(currentMember, () => setOpenDialogBenefit(false))
}
maxWidth="sm"
/>
<MuiDialog
title={{name: dataViewClaimSubmit?.full_name}}
openDialog={openDialogClaimSubmit}
setOpenDialog={setOpenDialogClaimSubmit}
content={
<DialogClaimSubmit
member={dataViewClaimSubmit}
getData={getData}
onClose={(data:any, getData:any) => {
console.log('Data returned:', data);
getData();
setOpenDialogClaimSubmit(false);
}}
handleSubmitSuccess={() => {
}}
/>
}
maxWidth="sm"
/>
</>
);
}

View File

@@ -0,0 +1,425 @@
/* ---------------------------------- @mui ---------------------------------- */
import { Stack, Button, MenuItem, SelectChangeEvent, Tab, Tabs, Card, Box } from '@mui/material';
/* ---------------------------------- axios --------------------------------- */
// import axios from 'axios';
import axios from '../../utils/axios';
import { styled } from '@mui/material/styles';
/* ---------------------------------- react --------------------------------- */
import { useContext, useEffect, useState } from 'react';
/* -------------------------------- component ------------------------------- */
import Iconify from '../../components/Iconify';
import TableComponent from '../../components/Table';
/* ---------------------------------- theme --------------------------------- */
import palette from '../../theme/palette';
//import { UserCurrentCorporateContext } from '../../contexts/UserCurrentCorporate';
import { HeadCell, Order, PaginationTableProps } from '../../@types/table';
import { useSearchParams, useNavigate } from 'react-router-dom';
import { fDate, fDateSuffix } from '../../utils/formatTime';
import Typography from '@mui/material/Typography';
import { format } from 'date-fns';
import TableMoreMenu from '../../components/table/TableMoreMenu';
import VisibilityOutlinedIcon from '@mui/icons-material/VisibilityOutlined';
import HistoryIcon from '@mui/icons-material/History';
import SearchIcon from '@mui/icons-material/Search';
import Label from '../../components/Label';
import { enqueueSnackbar } from 'notistack';
import { LoadingButton, TabPanel } from "@mui/lab";
import { LanguageContext } from '@/contexts/LanguageContext';
export default function TableList() {
const navigate = useNavigate();
const { localeData }: any = useContext(LanguageContext);
const [currentTab, setCurrentTab] = useState<string>('request_log');
useEffect(() => {
setCurrentTab('request_log')
}, [])
function handleChangeTab(event: React.SyntheticEvent, newValue: string) {
setCurrentTab(newValue)
}
//const { corporateValue } = useContext(UserCurrentCorporateContext);
//const { corporateValue } = useContext(null);
const [data, setData] = useState([]);
// Download LOG
async function handleDownloadLog(claimRequest) {
return axios
.get(`claim-requests/${claimRequest}/log`, {
responseType: 'blob',
})
.then((response) => {
window.open(URL.createObjectURL(response.data));
// setLoadingLog(false);
})
// .then((blobFile) => {
// new File([blobFile], 'asdads.pdf', { type: blobFile.type })
// setLoadingLog(false);
// })
.catch((response) => {
console.log(response);
enqueueSnackbar(response.message, { variant: 'error' });
// setLoadingLog(false);
});
}
/* -------------------------------------------------------------------------- */
/* setting up for the table */
/* -------------------------------------------------------------------------- */
const [isLoading, setIsLoading] = useState(true);
const loadings = {
isLoading: isLoading,
setIsLoading: setIsLoading,
};
/* ------------------------------ handle params ----------------------------- */
const [searchParams, setSearchParams] = useSearchParams();
const [appliedParams, setAppliedParams] = useState({});
const params = {
searchParams: searchParams,
setSearchParams: setSearchParams,
appliedParams: appliedParams,
setAppliedParams: setAppliedParams,
};
/* -------------------------------------------------------------------------- */
/* ------------------------------ handle order ------------------------------ */
const [order, setOrder] = useState<Order>('desc');
const [orderBy, setOrderBy] = useState('submission_date');
const orders = {
order: order,
setOrder: setOrder,
orderBy: orderBy,
setOrderBy: setOrderBy,
};
/* -------------------------------------------------------------------------- */
/* ---------------------------- handle pagination --------------------------- */
const [page, setPage] = useState(0);
const [rowsPerPage, setRowsPerPage] = useState(10);
const [paginationTable, setPaginationTable] = useState<PaginationTableProps>({
current_page: 0,
from: 0,
last_page: 0,
links: [],
path: '',
per_page: 0,
to: 0,
total: 0,
});
const paginations = {
page: page,
setPage: setPage,
rowsPerPage: rowsPerPage,
setRowsPerPage: setRowsPerPage,
paginationTable: paginationTable,
setPaginationTable: setPaginationTable,
};
/* -------------------------------------------------------------------------- */
/* ------------------------------ handle search ----------------------------- */
const [searchText, setSearchText] = useState('');
const handleSearchSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
if (searchText === '') {
searchParams.delete('search');
const params = Object.fromEntries([...searchParams.entries()]);
setAppliedParams(params);
} else {
const params = Object.fromEntries([...searchParams.entries(), ['search', searchText]]);
setAppliedParams(params);
}
};
const searchs = {
useSearchs: true,
searchText: searchText,
setSearchText: setSearchText,
handleSearchSubmit: handleSearchSubmit,
};
/* ------------------------------ handle filter ----------------------------- */
const [statusValue, setStatusValue] = useState('all');
const [filterData, setStatusData] = useState([]);
// handle status
const handleStatusChanges = (event: SelectChangeEvent) => {
setStatusValue(event.target.value as string);
if (event.target.value === 'all') {
searchParams.delete('status');
const params = Object.fromEntries([...searchParams.entries()]);
setAppliedParams(params);
} else {
const params = Object.fromEntries([
...searchParams.entries(),
['status', event.target.value as string],
]);
setAppliedParams(params);
}
};
const filterStatus = {
useFilter: true,
config: {
label: 'Status',
statusValue: statusValue,
filterData: filterData,
handleStatusChange: handleStatusChanges,
},
};
// handle start date
const [startDateValue, setStartDateValue] = useState('');
const handleStartDateChanges = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
const newStartDateValue = event.currentTarget.elements['date-input'].value;
setStartDateValue(newStartDateValue);
if (newStartDateValue === '') {
searchParams.delete('start_date');
const params = Object.fromEntries([...searchParams.entries()]);
setAppliedParams(params);
} else {
const params = Object.fromEntries([...searchParams.entries(), ['start_date', newStartDateValue]]);
setAppliedParams(params);
}
};
const filterStartDate = {
useFilter: true,
startDate: startDateValue,
setStartDate: setStartDateValue,
handleStartDateChange: handleStartDateChanges,
};
// handle end date
const [endDateValue, setEndDateValue] = useState('');
const handleEndDateChanges = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
const newEndDateValue = event.currentTarget.elements['date-input'].value;
setEndDateValue(newEndDateValue);
if (newEndDateValue === '') {
searchParams.delete('end_date');
const params = Object.fromEntries([...searchParams.entries()]);
setAppliedParams(params);
} else {
const params = Object.fromEntries([...searchParams.entries(), ['end_date', newEndDateValue]]);
setAppliedParams(params);
}
};
const filterEndDate = {
useFilter: true,
endDate: endDateValue,
setEndDate: setEndDateValue,
handleEndDateChange: handleEndDateChanges,
};
/* -------------------------------- headCell -------------------------------- */
const headCells: HeadCell<never>[] = [
{
id: 'submission_date',
align: 'center',
label: localeData.txtRequestDate,
isSort: true,
},
{
id: 'member_id',
align: 'left',
label: localeData.txtMemberID,
isSort: true,
},
{
id: 'code',
align: 'left',
label: localeData.txtClaimCode,
isSort: true,
},
{
id: 'full_name',
align: 'left',
label: localeData.txtName,
isSort: true,
},
{
id: 'status',
align: 'center',
label: localeData.txtStatus,
isSort: true,
},
{
id: 'action',
align: 'right',
label: '',
isSort: false,
},
];
useEffect(() => {
(async () => {
setIsLoading(true);
await new Promise((resolve) => setTimeout(resolve, 250));
const parameters =
Object.keys(appliedParams).length !== 0
? appliedParams
: Object.fromEntries([...searchParams.entries(), ['order', order], ['orderBy', orderBy]]);
const response = await axios.get(`/get-claim-requests`, {
params: { ...parameters, type: 'claim-request' },
});
setData(
response.data.data.map((obj: any) => ({
...obj,
status:
obj.status === 'requested' ? (
<Label color='primary'>
Request
</Label>
) : obj.status === 'approved' ? (
<Label color='success' >
Approval
</Label>
) : obj.status === 'declined' ? (
<Label color='error'>
Decline
</Label>
) : obj.status === 'reviewed' ? (
<Label color='info'>
Review
</Label>
) : (
<Label color='primary'>
Pending
</Label>
),
submission_date:
<Label>
{obj.submission_date ? fDateSuffix(obj.submission_date) : ''}
</Label>
,
action:
<TableMoreMenu actions={
<>
<MenuItem onClick={() => navigate ('/detail/'+obj.claim_request_id)}>
<Iconify icon="eva:eye-fill" />
View
</MenuItem>
<MenuItem onClick={() => handleDownloadLog(obj.claim_request_id)}>
<Iconify icon="eva:download-fill" />
Download LOG
</MenuItem>
</>
} />
}))
);
setPaginationTable(response.data);
setRowsPerPage(response.data.per_page);
if (searchParams.get('page')) {
//@ts-ignore
const currentPage = parseInt(searchParams.get('page')) - 1;
paginationTable.current_page = currentPage;
setPage(currentPage);
}
const status = [
{"id": "requested", "name": "Request" },
{"id": "reviewed", "name": "Review" },
{"id": "approved", "name": "Approval" },
{"id": "declined", "name": "Decline" },
]
setStatusData(status)
setIsLoading(false);
})();
}, [appliedParams, searchParams, order, orderBy, setSearchParams]);
const RootNotificationStyle = styled(Card)(({ theme }) => ({
boxShadow: 'none',
padding: '1rem 0.5rem',
color: 'black',
borderRadius: 0,
backgroundColor: theme.palette.grey[200],
// maxHeight: '240px',
}));
function TabPanel(props:any) {
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 sx={{ p: 3 }}>
<div>{children}</div>
</Box>
)}
</div>
);
}
return (
<Card>
<RootNotificationStyle sx={{ p: 2, height: 'auto' }}>
<Tabs
value={currentTab}
onChange={handleChangeTab}
aria-label="wrapped label tabs example"
>
<Tab value="request_log" label= "Request LOG" />
<Tab value="final_log" label= "Final LOG" />
</Tabs>
</RootNotificationStyle>
<TabPanel value={currentTab} index={'request_log'}>
<TableComponent
headCells={headCells}
rows={data}
orders={orders}
paginations={paginations}
loadings={loadings}
params={params}
searchs={searchs}
filterStatus={filterStatus}
// filterStartDate={filterStartDate}
// filterEndDate={filterEndDate}
/>
</TabPanel>
<TabPanel value={currentTab} index={'request_log'}>
<TableComponent
headCells={headCells}
rows={data}
orders={orders}
paginations={paginations}
loadings={loadings}
params={params}
searchs={searchs}
filterStatus={filterStatus}
// filterStartDate={filterStartDate}
// filterEndDate={filterEndDate}
/>
</TabPanel>
</Card>
);
}