Update Member & Hospital
This commit is contained in:
@@ -12,6 +12,7 @@ use App\Models\CorporateService;
|
||||
use App\Models\CorporatePlan;
|
||||
use App\Models\CorporateBenefit;
|
||||
use App\Models\Member;
|
||||
use App\MOdels\CorporateHospital;
|
||||
use App\Models\ExclusionRules;
|
||||
use App\Models\ExclusionImport;
|
||||
use App\Models\Icd;
|
||||
@@ -69,6 +70,16 @@ class AppServiceProvider extends ServiceProvider
|
||||
$this->logAuditTrail($model, 'deleted');
|
||||
});
|
||||
|
||||
//Hospital
|
||||
CorporateHospital::updated(function ($model) {
|
||||
|
||||
$this->logAuditTrail($model, 'updated');
|
||||
});
|
||||
|
||||
CorporateHospital::deleted(function ($model) {
|
||||
$this->logAuditTrail($model, 'deleted');
|
||||
});
|
||||
|
||||
|
||||
// Corporate Service
|
||||
CorporateService::updated(function ($model) {
|
||||
|
||||
158
frontend/dashboard/src/pages/Corporates/Hospital/History.tsx
Normal file
158
frontend/dashboard/src/pages/Corporates/Hospital/History.tsx
Normal file
@@ -0,0 +1,158 @@
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import HeaderBreadcrumbs from "../../../components/HeaderBreadcrumbs";
|
||||
import Page from "../../../components/Page";
|
||||
import { useContext, useEffect, useState } from 'react';
|
||||
import { Hospital } from '../../../@types/corporates';
|
||||
import { Corporate } from "@/@types/corporates";
|
||||
import { ConfiguredCorporateContext } from "@/contexts/ConfiguredCorporateContext";
|
||||
import {
|
||||
Stack,
|
||||
Typography,
|
||||
Card,
|
||||
Paper,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableContainer,
|
||||
TableHead,
|
||||
TableRow,
|
||||
Collapse,
|
||||
Box,
|
||||
Tab,
|
||||
} from '@mui/material';
|
||||
import axios from '@/utils/axios';
|
||||
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
|
||||
import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight';
|
||||
import { fDate, fDateTime } from '@/utils/formatTime';
|
||||
|
||||
|
||||
|
||||
export default function HospitalHistory() {
|
||||
const { corporate_id, id } = useParams();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [corporate, setCorporate] = useState<Corporate|null>();
|
||||
|
||||
const [ currentHospital, setCurrentHospital ] = useState<Hospital>();
|
||||
|
||||
const configuredCorporateContext = useContext(ConfiguredCorporateContext);
|
||||
|
||||
useEffect(() => {
|
||||
setCorporate(configuredCorporateContext.currentCorporate);
|
||||
const model = 'App\\Models\\CorporateHospital';
|
||||
const url = `/audittrail/${id}?model=${model}`;
|
||||
axios.get(url)
|
||||
.then((res) => {
|
||||
setCurrentHospital(res.data);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Terjadi kesalahan:', error);
|
||||
});
|
||||
}, [corporate_id, id, configuredCorporateContext]);
|
||||
|
||||
const [openRows, setOpenRows] = useState({});
|
||||
|
||||
const handleRowToggle = (index) => {
|
||||
setOpenRows((prevOpenRows) => ({
|
||||
...prevOpenRows,
|
||||
[index]: !prevOpenRows[index],
|
||||
}));
|
||||
};
|
||||
|
||||
return (
|
||||
<Page title="History Hospital">
|
||||
<HeaderBreadcrumbs
|
||||
heading={'History Hospital'}
|
||||
links={[
|
||||
{
|
||||
name: 'Corporates',
|
||||
href: '/corporates',
|
||||
},
|
||||
{
|
||||
name: corporate?.name ?? '-',
|
||||
href: '/corporates/'+corporate_id,
|
||||
},
|
||||
{
|
||||
name: 'Hospital',
|
||||
href: '/corporates/'+corporate_id+'/hospitals',
|
||||
},
|
||||
{
|
||||
name: 'History',
|
||||
href: '/corporates/'+corporate_id+'/hospitals/history',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<Card>
|
||||
<TableContainer component={Paper}>
|
||||
<Table aria-label="collapsible table">
|
||||
{/* Condition Table Body */}
|
||||
{currentHospital?.data.map((item, index) => (
|
||||
<TableBody key={index}>
|
||||
<TableRow sx={{backgroundColor: '#919EAB29'}}>
|
||||
<TableCell align="left" sx={{fontWeight: 'bold', width: '95%'}}><Typography variant="subtitle1">Data has {item.action} by {item.user_id} on {fDateTime(item.updated_at)}</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',}}>
|
||||
<TableCell colSpan={2}>
|
||||
{/* COLLAPSIBLE ROW */}
|
||||
<Collapse in={openRows[index]} timeout="auto" unmountOnExit>
|
||||
<TableContainer component={Paper}>
|
||||
<Table aria-label="collapsible table">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell align="left">
|
||||
<Typography sx={{width: '25%'}} variant="subtitle2">Field</Typography>
|
||||
</TableCell>
|
||||
<TableCell align="left">
|
||||
<Typography sx={{width: '25%'}} variant="subtitle2">Old Value</Typography>
|
||||
</TableCell>
|
||||
<TableCell align="left">
|
||||
<Typography sx={{width: '50%'}} variant="subtitle2">New Value</Typography>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{Object.entries(item.old_values).map(([key, value]) => {
|
||||
let renderedValue;
|
||||
if (key === 'code' || key === 'name') {
|
||||
renderedValue = item.new_values[key];
|
||||
const field = key.charAt(0).toUpperCase() + key.slice(1);
|
||||
return (
|
||||
<TableRow key={key}>
|
||||
<TableCell align="left">
|
||||
<Typography variant="body2">{field ? field : '-'}</Typography>
|
||||
</TableCell>
|
||||
<TableCell align="left">
|
||||
<Typography variant="body2">{value ? value : '-'}</Typography>
|
||||
</TableCell>
|
||||
<TableCell align="left">
|
||||
<Typography variant="body2">{renderedValue ? renderedValue : ''}</Typography>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
})}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</Collapse>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
))}
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</Card>
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
@@ -125,7 +125,7 @@ export default function PlanList() {
|
||||
<CachedOutlinedIcon />
|
||||
Update Status
|
||||
</MenuItem>
|
||||
<MenuItem onClick={() => navigate ('')}>
|
||||
<MenuItem onClick={() => navigate ('/corporates/'+corporate_id+'/hospitals/'+row.id+'/history')}>
|
||||
<HistoryIcon />
|
||||
History
|
||||
</MenuItem>
|
||||
|
||||
166
frontend/dashboard/src/pages/Corporates/Member/History.tsx
Normal file
166
frontend/dashboard/src/pages/Corporates/Member/History.tsx
Normal file
@@ -0,0 +1,166 @@
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import HeaderBreadcrumbs from "../../../components/HeaderBreadcrumbs";
|
||||
import Page from "../../../components/Page";
|
||||
import { useContext, useEffect, useState } from 'react';
|
||||
import { Member } from '../../../@types/corporates';
|
||||
import { Corporate } from "@/@types/corporates";
|
||||
import { ConfiguredCorporateContext } from "@/contexts/ConfiguredCorporateContext";
|
||||
import {
|
||||
Stack,
|
||||
Typography,
|
||||
Card,
|
||||
Paper,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableContainer,
|
||||
TableHead,
|
||||
TableRow,
|
||||
Collapse,
|
||||
Box,
|
||||
Tab,
|
||||
} from '@mui/material';
|
||||
import axios from '@/utils/axios';
|
||||
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
|
||||
import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight';
|
||||
import { fDate, fDateTime } from '@/utils/formatTime';
|
||||
|
||||
|
||||
|
||||
export default function MemberHistory() {
|
||||
const { corporate_id, member_id } = useParams();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [corporate, setCorporate] = useState<Corporate|null>();
|
||||
|
||||
const [ currentMember, setCurrentMember ] = useState<Member>();
|
||||
|
||||
const configuredCorporateContext = useContext(ConfiguredCorporateContext);
|
||||
|
||||
useEffect(() => {
|
||||
setCorporate(configuredCorporateContext.currentCorporate);
|
||||
const model = 'App\\Models\\Member';
|
||||
const url = `/audittrail/${member_id}?model=${model}`;
|
||||
axios.get(url)
|
||||
.then((res) => {
|
||||
setCurrentMember(res.data);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Terjadi kesalahan:', error);
|
||||
});
|
||||
}, [corporate_id, member_id, configuredCorporateContext]);
|
||||
|
||||
const [openRows, setOpenRows] = useState({});
|
||||
|
||||
const handleRowToggle = (index) => {
|
||||
setOpenRows((prevOpenRows) => ({
|
||||
...prevOpenRows,
|
||||
[index]: !prevOpenRows[index],
|
||||
}));
|
||||
};
|
||||
|
||||
return (
|
||||
<Page title="History Member">
|
||||
<HeaderBreadcrumbs
|
||||
heading={'History Member'}
|
||||
links={[
|
||||
{
|
||||
name: 'Corporates',
|
||||
href: '/corporates',
|
||||
},
|
||||
{
|
||||
name: corporate?.name ?? '-',
|
||||
href: '/corporates/'+corporate_id,
|
||||
},
|
||||
{
|
||||
name: 'Member',
|
||||
href: '/corporates/'+corporate_id+'/members',
|
||||
},
|
||||
{
|
||||
name: 'History',
|
||||
href: '/corporates/'+corporate_id+'/members/history',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<Card>
|
||||
<TableContainer component={Paper}>
|
||||
<Table aria-label="collapsible table">
|
||||
{/* Condition Table Body */}
|
||||
{currentMember?.data.map((item, index) => (
|
||||
<TableBody key={index}>
|
||||
<TableRow sx={{backgroundColor: '#919EAB29'}}>
|
||||
<TableCell align="left" sx={{fontWeight: 'bold', width: '95%'}}><Typography variant="subtitle1">Data has {item.action} by {item.user_id} on {fDateTime(item.updated_at)}</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',}}>
|
||||
<TableCell colSpan={2}>
|
||||
{/* COLLAPSIBLE ROW */}
|
||||
<Collapse in={openRows[index]} timeout="auto" unmountOnExit>
|
||||
<TableContainer component={Paper}>
|
||||
<Table aria-label="collapsible table">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell align="left">
|
||||
<Typography sx={{width: '25%'}} variant="subtitle2">Field</Typography>
|
||||
</TableCell>
|
||||
<TableCell align="left">
|
||||
<Typography sx={{width: '25%'}} variant="subtitle2">Old Value</Typography>
|
||||
</TableCell>
|
||||
<TableCell align="left">
|
||||
<Typography sx={{width: '50%'}} variant="subtitle2">New Value</Typography>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{Object.entries(item.old_values).map(([key, value]) => {
|
||||
let renderedValue;
|
||||
if (key === 'reason' || key === 'updated_at') {
|
||||
switch (key) {
|
||||
case 'updated_at':
|
||||
renderedValue = fDateTime(item.new_values[key]);
|
||||
value = fDateTime(value);
|
||||
break;
|
||||
default:
|
||||
renderedValue = item.new_values[key];
|
||||
break;
|
||||
}
|
||||
const field = key.charAt(0).toUpperCase() + key.slice(1);
|
||||
|
||||
return (
|
||||
<TableRow key={key}>
|
||||
<TableCell align="left">
|
||||
<Typography variant="body2">{field ? field : '-'}</Typography>
|
||||
</TableCell>
|
||||
<TableCell align="left">
|
||||
<Typography variant="body2">{value ? value : '-'}</Typography>
|
||||
</TableCell>
|
||||
<TableCell align="left">
|
||||
<Typography variant="body2">{renderedValue ? renderedValue : ''}</Typography>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
}
|
||||
else{
|
||||
return null;
|
||||
}
|
||||
})}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</Collapse>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
))}
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</Card>
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
@@ -500,7 +500,7 @@ export default function CorporatePlanList({handleSubmitSuccess}) {
|
||||
<CachedOutlinedIcon />
|
||||
Update Status
|
||||
</MenuItem>
|
||||
<MenuItem onClick={() => navigate ('')}>
|
||||
<MenuItem onClick={() => navigate ('/corporates/'+corporate_id+'/members/'+row.id+'/history')}>
|
||||
<HistoryIcon />
|
||||
History
|
||||
</MenuItem>
|
||||
|
||||
@@ -190,6 +190,10 @@ export default function Router() {
|
||||
path: ':corporate_id/hospitals/edit/:id/:organization_id',
|
||||
element: <HospitalCreateUpdate />,
|
||||
},
|
||||
{
|
||||
path: ':corporate_id/hospitals/:id/history',
|
||||
element: <HospitalHistory />,
|
||||
},
|
||||
{
|
||||
path: ':corporate_id/claim-history',
|
||||
element: <CorporateClaimHistories />,
|
||||
@@ -441,7 +445,7 @@ const CorporateDivisionsCreate = Loadable(
|
||||
);
|
||||
|
||||
const CorporateMembers = Loadable(lazy(() => import('../pages/Corporates/Member/Index')));
|
||||
const CorporateHistoryMembers = Loadable(lazy(() => import('../pages/Corporates/Member/sections/History')));
|
||||
const CorporateHistoryMembers = Loadable(lazy(() => import('../pages/Corporates/Member/History')));
|
||||
|
||||
const BenefitCreate = Loadable(lazy(() => import('../pages/Corporates/Benefit/Create')));
|
||||
const Benefits = Loadable(lazy(() => import('../pages/Corporates/Benefit/Index')));
|
||||
@@ -523,6 +527,7 @@ const HospitalCreateUpdate = Loadable(lazy(() => import('../pages/Corporates/Hos
|
||||
const CorporateClaimHistories = Loadable(
|
||||
lazy(() => import('../pages/Corporates/ClaimHistory/Index'))
|
||||
);
|
||||
const HospitalHistory = Loadable(lazy(() => import('../pages/Corporates/Hospital/History')));
|
||||
|
||||
const CorporateHistories = Loadable(
|
||||
lazy(() => import('../pages/Corporates/History'))
|
||||
|
||||
Reference in New Issue
Block a user