diff --git a/Modules/Internal/Http/Controllers/Api/CorporateMemberController.php b/Modules/Internal/Http/Controllers/Api/CorporateMemberController.php index df5368ed..25f1a833 100644 --- a/Modules/Internal/Http/Controllers/Api/CorporateMemberController.php +++ b/Modules/Internal/Http/Controllers/Api/CorporateMemberController.php @@ -69,13 +69,14 @@ class CorporateMemberController extends Controller public function activation(Request $request, $member_id) { $request->validate([ - 'active' => 'required' + 'active' => 'required', + 'reason' => 'required', ]); // abort(404); $member = Member::findOrFail($member_id); - $member->active = $request->active == '1'; + $member->active = $request->active; $member->reason = $request->reason; if ($member->save()) { diff --git a/Modules/Internal/Http/Controllers/Api/HospitalController.php b/Modules/Internal/Http/Controllers/Api/HospitalController.php new file mode 100644 index 00000000..63a716f7 --- /dev/null +++ b/Modules/Internal/Http/Controllers/Api/HospitalController.php @@ -0,0 +1,153 @@ +filter($request->all()) + ->where('corporate_id', $corporate_id) + ->orderBy('id', 'DESC') + ->paginate(0) + ->appends($request->all()); + + return $datas; + } + + public function activation(Request $request, $hospital_id) + { + $request->validate([ + 'active' => 'required', + 'reason' => 'required', + ]); + + // abort(404); + + $hostpital = CorporateHospital::findOrFail($hospital_id); + $hostpital->active = $request->active; + $hostpital->reason = $request->reason; + + if ($hostpital->save()) { + return response()->json([ + 'hostpital' => $hostpital, + 'message' => 'Status Updated Successfully' + ]); + } + } + + public function dataHospital(Request $request, $corporate_id) + { + $data = DB::table('organizations') + ->where('type', 'hospital') + ->where('status', 'active') + ->orderBy('id', 'desc') + ->get(); + return $data; + } + + /** + * 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, $corporate_id) + { + $request->validate([ + 'corporate_id' => 'required', + 'code' => 'required', + 'name' => 'required', + 'organization_id' => 'required', + ]); + + $newCorporateHospital = CorporateHospital::create([ + 'corporate_id' => $corporate_id, + 'code' => $request->code, + 'name' => $request->name, + 'organization_id' => $request->organization_id, + 'description' => $request->description ? $request->description : null, + ]); + + return $newCorporateHospital; + } + + /** + * 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($corporate_id, $id) + { + $corporatePlan = CorporateDivision::findOrFail($id); + + return $corporatePlan; + } + + /** + * Update the specified resource in storage. + * @param Request $request + * @param int $id + * @return Renderable + */ + public function update(Request $request, $corporate_id, $id) + { + $corporatePlan = CorporateHospital::findOrFail($id); + $request->validate([ + 'corporate_id' => 'required', + 'code' => 'required', + 'name' => 'required', + 'organization_id' => 'required', + ]); + + $corporatePlan->fill([ + 'corporate_id' => $corporate_id, + 'code' => $request->code, + 'name' => $request->name, + 'organization_id' => $request->organization_id, + 'description' => $request->description ? $request->description : null, + ])->save(); + + return $corporatePlan; + } + + /** + * Remove the specified resource from storage. + * @param int $id + * @return Renderable + */ + public function destroy($id) + { + // + } +} diff --git a/Modules/Internal/Routes/api.php b/Modules/Internal/Routes/api.php index d97f2824..59a0bf04 100644 --- a/Modules/Internal/Routes/api.php +++ b/Modules/Internal/Routes/api.php @@ -19,6 +19,7 @@ use Modules\Internal\Http\Controllers\Api\DiagnosisTemplateController; use Modules\Internal\Http\Controllers\Api\DiagnosisExclusionController; use Modules\Internal\Http\Controllers\Api\DistrictController; use Modules\Internal\Http\Controllers\Api\DivisionController; +use Modules\Internal\Http\Controllers\Api\HospitalController; use Modules\Internal\Http\Controllers\Api\DoctorController; use Modules\Internal\Http\Controllers\Api\DoctorRatingController; use Modules\Internal\Http\Controllers\Api\DrugController; @@ -99,6 +100,12 @@ Route::prefix('internal')->group(function () { Route::get('corporates/{corporate_id}/divisions/{id}/edit', [DivisionController::class, 'edit']); Route::put('corporates/{corporate_id}/divisions/{id}', [DivisionController::class, 'update']); + Route::get('corporates/{corporate_id}/hospitals', [HospitalController::class, 'index']); + Route::put('hospitals/{hospital_id}/activation', [HospitalController::class, 'activation']); + Route::get('corporates/{corporate_id}/hospitals/data', [HospitalController::class, 'dataHospital']); + Route::post('corporates/{corporate_id}/hospitals/save', [HospitalController::class, 'store']); + Route::put('corporates/{corporate_id}/hospitals/{id}/edit', [HospitalController::class, 'update']); + Route::get('corporates/{corporate_id}/members', [CorporateMemberController::class, 'index']); Route::get('corporates/{corporate_id}/members/list', [CorporateMemberController::class, 'generateMemberList']); Route::post('corporates/{corporate_id}/members/import', [CorporateMemberController::class, 'import']); diff --git a/app/Models/CorporateHospital.php b/app/Models/CorporateHospital.php new file mode 100644 index 00000000..f38259e5 --- /dev/null +++ b/app/Models/CorporateHospital.php @@ -0,0 +1,36 @@ +belongsTo(Corporate::class); + } + + public function scopeFilter($query, array $filters) + { + $query->when($filters['search'] ?? false, function ($query, $search) { + return $query + ->where('code', 'like', "%" . $search . "%") + ->orWhere('name', 'like', "%" . $search . "%"); + }); + } +} diff --git a/database/migrations/2023_10_19_132434_create_corporate_hospitals.php b/database/migrations/2023_10_19_132434_create_corporate_hospitals.php new file mode 100644 index 00000000..5b1bb211 --- /dev/null +++ b/database/migrations/2023_10_19_132434_create_corporate_hospitals.php @@ -0,0 +1,42 @@ +id(); + $table->bigInteger('corporate_id'); + $table->bigInteger('organization_id'); + $table->string('code', 255); + $table->string('name', 255); + $table->text('description')->nullable(); + $table->tinyInteger('active')->default(1); + $table->text('reason'); + $table->timestamps(); + $table->softDeletes(); + $table->bigInteger('created_by')->nullable(); + $table->bigInteger('updated_by')->nullable(); + $table->bigInteger('deleted_by')->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('corporate_hospitals'); + } +}; diff --git a/frontend/dashboard/src/@types/corporates.ts b/frontend/dashboard/src/@types/corporates.ts index 8d39037c..8888f822 100644 --- a/frontend/dashboard/src/@types/corporates.ts +++ b/frontend/dashboard/src/@types/corporates.ts @@ -25,6 +25,13 @@ export type Division = { name?: string; } +export type Hospital = { + id: number; + corporate_id: number; + code: string; + name?: string; +} + export type Employee = { id: number; name: string; diff --git a/frontend/dashboard/src/contexts/ConfiguredCorporateContext.tsx b/frontend/dashboard/src/contexts/ConfiguredCorporateContext.tsx index 5fde9420..59270cf0 100644 --- a/frontend/dashboard/src/contexts/ConfiguredCorporateContext.tsx +++ b/frontend/dashboard/src/contexts/ConfiguredCorporateContext.tsx @@ -26,9 +26,6 @@ function ConfiguredCorporateProvider({ children }: ConfiguredCorporateProviderPr const [corporate, setCorporate] = useState(null); useEffect(() => { - // Load Corporate - console.log('calling corporate' + corporate_id); - axios.get(`corporates/${corporate_id}`) .then((res) => { setCorporate(res.data) diff --git a/frontend/dashboard/src/pages/Corporates/Hospital/CreateUpdate.tsx b/frontend/dashboard/src/pages/Corporates/Hospital/CreateUpdate.tsx index d4ad3ea9..b975c1ca 100644 --- a/frontend/dashboard/src/pages/Corporates/Hospital/CreateUpdate.tsx +++ b/frontend/dashboard/src/pages/Corporates/Hospital/CreateUpdate.tsx @@ -1,64 +1,63 @@ - import { useNavigate, useParams } from "react-router-dom"; import HeaderBreadcrumbs from "../../../components/HeaderBreadcrumbs"; import Page from "../../../components/Page"; import useSettings from "../../../hooks/useSettings"; -import { useEffect, useMemo, useState } from 'react'; -import axios from '../../../utils/axios'; -import { useSnackbar } from 'notistack'; -import CorporatePlanForm from './Form'; -import { CorporatePlan } from '../../../@types/corporates'; +import { useContext, useEffect, useMemo, useState } from 'react'; +import CorporateHospitalForm from './Form'; +import { Hospital } from '../../../@types/corporates'; +import { Corporate } from "@/@types/corporates"; +import { ConfiguredCorporateContext } from "@/contexts/ConfiguredCorporateContext"; +import { Stack, Typography } from '@mui/material'; +import ArrowBackIosIcon from '@mui/icons-material/ArrowBackIos'; -export default function PlanCreate() { - const { themeStretch } = useSettings(); +export default function HospitalCreate() { const { corporate_id, id } = useParams(); - const [ currentCorporatePlan, setCurrentCorporatePlan ] = useState(); const navigate = useNavigate(); + const [corporate, setCorporate] = useState(); + + const configuredCorporateContext = useContext(ConfiguredCorporateContext); + const isEdit = !!id; useEffect(() => { - if (isEdit) { - axios.get('/corporates/'+corporate_id+'/divisions/'+id+'/edit') - .then((res) => { - setCurrentCorporatePlan(res.data); - }) - .catch((err) => { - if (err.response.status === 404) { - navigate('/404'); - } - }) - } - }, [corporate_id, id]); + setCorporate(configuredCorporateContext.currentCorporate); + }, [corporate_id, id, configuredCorporateContext]); return ( - - - - + + {isEdit ? ( + + navigate(-1)}/> + Edit Hospital + + ) : ( + + )} + ); } diff --git a/frontend/dashboard/src/pages/Corporates/Hospital/Form.tsx b/frontend/dashboard/src/pages/Corporates/Hospital/Form.tsx index 2e088d92..f31ac177 100644 --- a/frontend/dashboard/src/pages/Corporates/Hospital/Form.tsx +++ b/frontend/dashboard/src/pages/Corporates/Hospital/Form.tsx @@ -1,129 +1,161 @@ -import * as Yup from 'yup'; -import { LoadingButton } from "@mui/lab"; -import { Card, Grid, Stack, Typography } from "@mui/material"; -import { CorporatePlan } from "../../../@types/corporates"; -import { FormProvider, RHFSwitch, RHFTextField } from "../../../components/hook-form"; -import { useEffect, useMemo } from 'react'; -import { useForm } from 'react-hook-form'; -import { yupResolver } from '@hookform/resolvers/yup'; +import { Button, Card, Grid, Stack, Typography, FormControl, InputLabel, Select, FormHelperText, MenuItem } from "@mui/material"; +import { useEffect, useMemo, useState } from 'react'; import { useSnackbar } from 'notistack'; import { useNavigate, useParams } from 'react-router-dom'; import axios from '../../../utils/axios'; type Props = { isEdit: boolean; - currentCorporatePlan?: CorporatePlan; }; -export default function CorporatePlanForm({ isEdit, currentCorporatePlan }: Props) { +export default function CorporateHospitalForm({ isEdit }: Props) { const { enqueueSnackbar } = useSnackbar(); const navigate = useNavigate(); - const { corporate_id } = useParams(); - - const NewCorporatePlanSchema = Yup.object().shape({ - name: Yup.string().required('Name is required'), - code: Yup.string().required('Corporate Code is required'), - }); - - const defaultValues = useMemo( - () => ({ - name: currentCorporatePlan?.name || '', - code: currentCorporatePlan?.code || '', - active: currentCorporatePlan?.active === 1 ? true : false, - }), - [currentCorporatePlan] - ); + const { corporate_id, id, organization_id } = useParams(); + const [dataHospital, setDataHospital] = useState(null); + const [addData, setAddData] = useState(null); + let idHospital = organization_id && isEdit ? organization_id : 0; + const [indexData, setIndexData] = useState(idHospital); + const [updateData, setUpdateData] = useState(null); useEffect(() => { - if (isEdit && currentCorporatePlan) { - reset(defaultValues); + axios.get('/corporates/' + corporate_id + '/hospitals/data') + .then((res) => { + setDataHospital(res.data); + }) + + }, [isEdit]); + + const handlePageChange = (index:any) => { + setIndexData(index); + const data = { + corporate_id : corporate_id ? corporate_id : null, + organization_id : dataHospital ? dataHospital[index].id : null, + code : dataHospital ? dataHospital[index].code : null, + name : dataHospital ? dataHospital[index].name : null, } - if (!isEdit) { - reset(defaultValues); + setAddData(data); + } + const handleSaveData = () => { + //Save data + axios + .post('/corporates/'+corporate_id+'/hospitals/save', addData) + .then((response) => { + if(response.data) + { + enqueueSnackbar('Data saved successfully', { variant: 'success' }); + } + }) + .catch((error) => { + enqueueSnackbar('Failed to add data', { variant: 'error' }); + }); + } + + const handlePageChangeUpdate = (id: any) => { + setIndexData(id); + const foundData = dataHospital?.find(item => item.id === id); + const dataUpdate = { + corporate_id : corporate_id ? corporate_id : null, + organization_id : dataHospital ? foundData.id : null, + code : dataHospital ? foundData.code : null, + name : dataHospital ? foundData.name : null, } - }, [isEdit, currentCorporatePlan]); + setUpdateData(dataUpdate); + } - const methods = useForm({ - resolver: yupResolver(NewCorporatePlanSchema), - defaultValues, - }); - - const { - reset, - watch, - control, - setValue, - getValues, - setError, - handleSubmit, - formState: { isSubmitting }, - } = methods; - - - const onSubmit = async (data: any) => { - if (!isEdit) { - await axios - .post('/corporate/' + corporate_id + '/divisions', data) - .then((res) => { - enqueueSnackbar('Division created successfully', { variant: 'success' }); - }) - .then((res) => { - navigate('/corporate/' + corporate_id + '/divisions', { replace: true }); - }) - .catch(({ response }) => { - if (response.status === 422) { - for (const [key, value] of Object.entries(response.data.errors)) { - setError(key, { message: value[0] }); - enqueueSnackbar(value[0] ?? 'Failed Processing Request', { variant: 'error' }); - } - } - else { - enqueueSnackbar('Create Failed : '+ response.data.message, { variant: 'error' }); + const handleUpdateData = () => { + //Update data + if(updateData) + { + axios + .put('/corporates/'+corporate_id+'/hospitals/'+id+'/edit', updateData) + .then((response) => { + if(response.data) + { + enqueueSnackbar('Data updated successfully', { variant: 'success' }); + navigate(-1); + window.history.replaceState(null, '', '/corporates/'+corporate_id+'/hospitals'); } + }) + .catch((error) => { + enqueueSnackbar('Failed to update data', { variant: 'error' }); }); - } else { - await axios - .put('/corporate/' + corporate_id + '/divisions/' + currentCorporatePlan?.id , data) - .then((res) => { - enqueueSnackbar('Division updated successfully', { variant: 'success' }); - }) - .then((res) => { - navigate('/corporate/' + corporate_id + '/divisions/' , { replace: true }); - }) - .catch(({ response }) => { - enqueueSnackbar('Update Failed : '+ response.data.message, { variant: 'error' }); - }); } - }; + else + { + enqueueSnackbar('Data has not changed.', { variant: 'error' }); + } + + } return ( - - - - - + + + + Hospital * + {dataHospital && dataHospital.length > 0 ? ( + isEdit ? ( + + + Hospital + + + + + ) : ( + + + Hospital + + + + + ) + ) : ( + + Loading + - Division Detail - - - - - - - { isEdit? 'Update' : 'Create' } - - - - - - - - - - - - - + )} + + + + {isEdit ? ( + + ):( + + )} + + + + + ); } diff --git a/frontend/dashboard/src/pages/Corporates/Hospital/Index.tsx b/frontend/dashboard/src/pages/Corporates/Hospital/Index.tsx index d5fa1fa3..bbd1aa3f 100644 --- a/frontend/dashboard/src/pages/Corporates/Hospital/Index.tsx +++ b/frontend/dashboard/src/pages/Corporates/Hospital/Index.tsx @@ -1,32 +1,33 @@ -import { Card, Grid, Typography } from '@mui/material'; -import { useParams } from 'react-router-dom'; -import HeaderBreadcrumbs from '../../../components/HeaderBreadcrumbs'; -import Page from '../../../components/Page'; -import useSettings from '../../../hooks/useSettings'; -import CorporateTabNavigations from '../CorporateTabNavigations'; -import DivisionsList from './List'; +import { Corporate } from "@/@types/corporates"; +import { ConfiguredCorporateContext } from "@/contexts/ConfiguredCorporateContext"; +import { Card } from "@mui/material"; +import { useContext, useEffect, useState } from "react"; +import { useParams } from "react-router-dom"; +import HeaderBreadcrumbs from "../../../components/HeaderBreadcrumbs"; +import Page from "../../../components/Page"; +import useSettings from "../../../hooks/useSettings"; +import CorporateTabNavigations from "../CorporateTabNavigations"; +import List from "./List"; -import { useContext, useEffect, useState } from 'react'; -import { ConfiguredCorporateContext } from '@/contexts/ConfiguredCorporateContext'; -import { Corporate } from '@/@types/corporates'; -export default function Divisions() { - const { themeStretch } = useSettings(); + +export default function hospitals() { const { corporate_id } = useParams(); - - const [corporate, setCorporate] = useState(); + + const [corporate, setCorporate] = useState(); const configuredCorporateContext = useContext(ConfiguredCorporateContext); useEffect(() => { setCorporate(configuredCorporateContext.currentCorporate); - }, [configuredCorporateContext]); + }, [configuredCorporateContext]) return ( - + + - Feature Not Implemented Yet + ); diff --git a/frontend/dashboard/src/pages/Corporates/Hospital/List.tsx b/frontend/dashboard/src/pages/Corporates/Hospital/List.tsx index fb019971..c7f34fb0 100644 --- a/frontend/dashboard/src/pages/Corporates/Hospital/List.tsx +++ b/frontend/dashboard/src/pages/Corporates/Hospital/List.tsx @@ -1,124 +1,158 @@ // @mui -import { Box, Button, Card, Collapse, IconButton, InputLabel, MenuItem, OutlinedInput, Paper, Select, SelectChangeEvent, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, TextField, Typography, Badge, Tab, Tabs, CardHeader, Stack, Menu, ButtonGroup } from '@mui/material'; -import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'; -import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight'; +import { + Button, + Card, + IconButton, + MenuItem, + Paper, + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, + TextField, + Typography, + Stack, + Collapse, + Box, + FormControl, + InputLabel, + Select, + FormHelperText, +} from '@mui/material'; import AddIcon from '@mui/icons-material/Add'; -import UploadIcon from '@mui/icons-material/Upload'; -import CancelIcon from '@mui/icons-material/Cancel'; // hooks -import React, { ChangeEvent, Component, useEffect, useRef, useState } from 'react'; -import useSettings from '../../../hooks/useSettings'; -import { Link, useNavigate, useParams, useSearchParams } from 'react-router-dom'; +import React, { ChangeEvent, useEffect, useRef, useState } from 'react'; +import { useNavigate, useParams, useSearchParams } from 'react-router-dom'; // components import axios from '../../../utils/axios'; import { CorporatePlan } from '../../../@types/corporates'; import { LaravelPaginatedData } from '../../../@types/paginated-data'; import BasePagination from '../../../components/BasePagination'; +import TableMoreMenu from '@/components/table/TableMoreMenu'; +import EditOutlinedIcon from '@mui/icons-material/EditOutlined'; +import HistoryIcon from '@mui/icons-material/History'; +import FindInPageOutlinedIcon from '@mui/icons-material/FindInPageOutlined'; +import CachedOutlinedIcon from '@mui/icons-material/CachedOutlined'; +import { Dialog, DialogTitle, DialogContent, DialogActions } from '@mui/material'; +import CloseIcon from '@mui/icons-material/Close'; +import { enqueueSnackbar } from 'notistack'; +import Label from '../../../components/Label'; export default function PlanList() { - const { themeStretch } = useSettings(); const { corporate_id } = useParams(); const [searchParams, setSearchParams] = useSearchParams(); const navigate = useNavigate(); - + function SearchInput(props: any) { - // SEARCH + // SEARCH const searchInput = useRef(null); - const [searchText, setSearchText] = useState(""); + const [searchText, setSearchText] = useState(''); const handleSearchChange = (event: any) => { - const newSearchText = event.target.value ?? '' + const newSearchText = event.target.value ?? ''; setSearchText(newSearchText); - } + }; const handleSubmit = (event: any) => { event.preventDefault(); props.onSearch(searchText); // Trigger to Parent - } + }; - useEffect(() => { - // console.log('Search Input: useEffect') + useEffect(() => { setSearchText(searchParams.get('search') ?? ''); - }, [searchParams]) + }, [searchParams]); return (
- + ); } // Called on every row to map the data to the columns - function createData( plan: CorporatePlan ): CorporatePlan { + function createData(plan: CorporatePlan): CorporatePlan { return { ...plan, - } + }; } // Generate the every row of the table function Row(props: { row: ReturnType }) { const { row } = props; const [open, setOpen] = React.useState(false); + const style1 = { + color: '#637381' + } return ( - *': { borderBottom: 'unset' } }}> - - setOpen(!open)} - > - {open ? : } - + + {row.code ? row.code : '-'} + {row.name ? row.name : '-'} + + {row.active === 1 ? ( + + ) : ( + + )} + + + + setOpen(!open)}> + + Details + + handleEditData(row)}> + + Edit + + handleEditDataStatus(row)}> + + Update Status + + navigate ('')}> + + History + + + } + /> - {row.id} - {row.code} - {row.name} - {row.description} - - {/* COLLAPSIBLE ROW */} - - + + - - - No Extra Data - - - {false && - - Rules - - - - - Date - Customer - Amount - Total price ($) - - - - {/* {row.history ? row.history.map((historyRow) => ( */} - - {row.start} - {row.end} - {row.start} - {row.start} - {row.start} - - {/* )) - : ( - - No Data - - ) - } */} - -
-
} + + + Detail + + + Code: + {row.code ? row.code : '-'} + + + Hospital Name: + {row.name ? row.name : '-'} + + + +
@@ -131,104 +165,230 @@ export default function PlanList() { const [dataTableData, setDataTableData] = React.useState({ current_page: 1, data: [], - path: "", - first_page_url: "", + path: '', + first_page_url: '', last_page: 1, - last_page_url: "", - next_page_url: "", - prev_page_url: "", + last_page_url: '', + next_page_url: '', + prev_page_url: '', per_page: 10, from: 0, to: 0, - total: 0 + total: 0, }); - const loadDataTableData = async (appliedFilter : any | null = null) => { + const loadDataTableData = async (appliedFilter: any | null = null) => { setDataTableLoading(true); const filter = appliedFilter ? appliedFilter : Object.fromEntries([...searchParams.entries()]); - const response = await axios.get('/corporates/'+corporate_id+'/divisions', { params: filter }); - // console.log(response.data); + // Get Data Hospitals + const response = await axios.get('/corporates/' + corporate_id + '/hospitals', { + params: filter, + }); setDataTableLoading(false); - setDataTableData(response.data); - } - - const headStyle = { - fontWeight: 'bold', }; const applyFilter = async (searchFilter: any) => { - await loadDataTableData({ "search" : searchFilter }); - setSearchParams({ "search" : searchFilter }); - } + await loadDataTableData({ search: searchFilter }); + setSearchParams({ search: searchFilter }); + }; - const handlePageChange = (event : ChangeEvent, value: number) => { - const filter = Object.fromEntries([...searchParams.entries(), ["page", value]]); + const handlePageChange = (event: ChangeEvent, value: number) => { + const filter = Object.fromEntries([...searchParams.entries(), ['page', value]]); loadDataTableData(filter); setSearchParams(filter); - } - + }; useEffect(() => { loadDataTableData(); - }, []) + }, []); + + //validation dialog + const [nameField, setNameField] = useState(''); + const [codeField, setCodeField] = useState(''); + // ID for edit data + const [idField, setIdField] = useState(''); + + const handleAddData = () => { + navigate('/corporates/'+corporate_id+'/hospitals/create'); + } + //Edit data + const handleEditData = (data : any) => { + navigate('/corporates/'+corporate_id+'/hospitals/edit/'+data.id+'/'+data.organization_id); + } + // End dialog for hospitals + + // Dialog for update status hospitals + const [openDialogStatus, setOpenDialogStatus] = useState(false); + const [activeField, setActiveField] = useState(0); + const [reasonUpdate,setReasonUpdate] = useState('Agreement changed'); + + const handleCloseDialogUpdate = () => { + setOpenDialogStatus(false); + setNameField(''); + setCodeField(''); + setIdField(''); + setActiveField(activeField); + } + + const handleSaveUpdateData = () => { + let activeValue = 0; + if(activeField === 1) + { + activeValue = 0; + } + else + { + activeValue = 1; + } + const updateData = { + reason: reasonUpdate, + active : activeValue, + id: idField, + }; + axios + .put('/hospitals/'+idField+'/activation', updateData) + .then((response) => { + enqueueSnackbar('Data updated successfully', { variant: 'success' }); + loadDataTableData(); + handleCloseDialogUpdate(); + }) + .catch((error) => { + enqueueSnackbar('Failed to add data', { variant: 'error' }); + }); + } + + const handleEditDataStatus = (data: any) => { + setIdField(data.id); + setNameField(data.name); + setCodeField(data.code); + setActiveField(data.active); + setOpenDialogStatus(true); + } + // End dialog for update status devisions + + return ( - - - - - - - - + + + + + {/* The Main Table */} - + {/* Table Head */} + - - ID - Code - Name - Description + + Code + + + Hospital + + + Status + + + - - {dataTableIsLoading ? - ( - - - Loading - - - ) : ( - dataTableData.data.length == 0 ? - ( - - - No Data - - - ) : ( - - {dataTableData.data.map(row => ( - - ))} - - ) + + {/* Condition Table Body */} + {dataTableIsLoading ? ( + + + + Loading + + + + ) : dataTableData.data.length == 0 ? ( + + + + No Data + + + + ) : ( + + {dataTableData.data.map((row) => ( + + ))} + )}
- -
+ {/* Paginations */} + +
+ {/* Dialog Update Status */} + + + + + Update Status + + + + + + + + + Are you sure to {activeField == 1 ? 'Inactive' : 'Active'} this hospital ? + + + Code + {nameField} + + + Hospital Name + {codeField} + + + + + Reason for update* + + + Reason for update + + + + + + + + + + + +
); -} +} \ No newline at end of file diff --git a/frontend/dashboard/src/pages/Corporates/Member/List.tsx b/frontend/dashboard/src/pages/Corporates/Member/List.tsx index 4374d949..dc92063c 100644 --- a/frontend/dashboard/src/pages/Corporates/Member/List.tsx +++ b/frontend/dashboard/src/pages/Corporates/Member/List.tsx @@ -29,6 +29,9 @@ import { Grid, Tooltip, Divider, + ButtonBase, + FormControl, + FormHelperText, } from '@mui/material'; import Iconify from '@/components/Iconify'; import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'; @@ -40,7 +43,7 @@ import InsertDriveFileIcon from '@mui/icons-material/InsertDriveFile'; // hooks import React, { ChangeEvent, Component, useEffect, useRef, useState } from 'react'; import useSettings from '../../../hooks/useSettings'; -import {Link, useParams, useSearchParams } from 'react-router-dom'; +import {Link, useParams, useNavigate, useSearchParams } from 'react-router-dom'; // components import axios from '../../../utils/axios'; import { Plan } from '../../../@types/corporates'; @@ -52,8 +55,15 @@ import { LoadingButton } from '@mui/lab'; import DialogLog from './sections/DialogLog'; import HistoryIcon from '@mui/icons-material/History'; import { makeFormData } from '@/utils/jsonToFormData'; +import DownloadIcon from '@mui/icons-material/Download'; +import TableMoreMenu from '@/components/table/TableMoreMenu'; +import FindInPageOutlinedIcon from '@mui/icons-material/FindInPageOutlined'; +import CachedOutlinedIcon from '@mui/icons-material/CachedOutlined'; +import { Dialog, DialogTitle, DialogContent, DialogActions } from '@mui/material'; +import CloseIcon from '@mui/icons-material/Close'; export default function CorporatePlanList({handleSubmitSuccess}) { + const navigate = useNavigate(); // Files MCU const fileMcuInput = useRef(null); const [fileMcus, setFileMcus] = useState([]); @@ -196,17 +206,17 @@ export default function CorporatePlanList({handleSubmitSuccess}) { setTimeout(() => { loadDataTableData(); }, 2000); - enqueueSnackbar(responseData.message ?? 'Berhasil tambah file MemberID '+member_id+', silahkan lihat dilaporan', { variant: 'success' }); + enqueueSnackbar(responseData.message ?? 'Berhasil tambah file Member ID '+member_id+', silahkan lihat dilaporan', { variant: 'success' }); handleSubmitSuccess(); } }) .catch(({ response }) => { const responseData = response?.data; - if(responseData) - { - enqueueSnackbar(responseData.message ?? 'Something Went Wrong', { variant: 'error' }); - } + if(responseData) + { + enqueueSnackbar(responseData.message ?? 'Something Went Wrong', { variant: 'error' }); + } }) .then(() => { setSubmitLoading(false); @@ -319,12 +329,10 @@ export default function CorporatePlanList({handleSubmitSuccess}) { {!currentImportFileName && ( - {/*

kjasndkjandskjasndkjansdkjansd

*/} - )} - {row.active != 1 && ( - - )} + {row.member_id ? row.member_id : '-'}
- - - - - - + + {row.members_effective_date ? row.members_effective_date : '-'} + + + {row.name ? row.name : '-'} + + + {row.current_plan?.code} + + + {row.activation_date ? row.activation_date : '-'} + + + {row.terminated_date ? row.terminated_date : '-'} + + + + setOpen(!open)}> + + Details + + handleEditDataStatus(row)}> + + Update Status + + navigate ('')}> + + History + + + } + />
{/* COLLAPSIBLE ROW */} - - - + + - - Detail - - - - - Mapping ID - - - : {row.principal_id ?? '-'} - - - Policy Number - - - : {row.current_policy?.code ?? '-'} - - - NRIC - - - : {row.nric ?? '-'} - - - - NIK - - - : {row.employeds[0]?.nik ?? '-'} - - - Email - - - : {row.email ?? '-'} - - - Phone - - - : {row.person?.phone ?? '-'} - - - - - - - Birth Date - - - : {row.birth_date ?? '-'} - - - Gender - - - : {row.gender ?? '-'} - - - Marital Status - - - : {row.marital_status ?? '-'} - - - Language - - - : {row.language ?? '-'} - - - Race - - - : {row.race ?? '-'} - - - Relationship - - - : {row.relation_with_principal ?? '-'} - - - - - Claim History - - - - - Requested - - - : {row.total_claims?.requested} - - - - Pending - - - : {row.total_claims?.received} - - - - Approved - - - : {row.total_claims?.approved} - - - - Declined - - - : {row.total_claims?.declined} - - - - Paid - - - : {row.total_claims?.paid} - - - - - File History - - - - - {row.file_mcu_names - ? row.file_mcu_names.split(',').map((fileName, index) => ( -
{fileName}
- )) - : '-'} -
-
-
-
- - - - } - // sx={{ p: 1.8 }} - // onClick={() => {handleDownloadLog(row)}} - onClick={() => { - setDialogLogOpen(true); - }} - loading={loadingLog} - > - Download LOG - + + + Detail + + + Mapping ID: + {row.principal_id ? row.principal_id : '-'} + Birth Date: + {row.birth_date ? row.birth_date : '-'} - {/* -------------------------------Upload Dokumen MCU------------------------------- */} - - {/*} - spacing={1} - sx={{ marginY: 2}} - > - {fileMcus && - fileMcus - .filter((datas) => datas.id === row.id) - .map((datas, index) => ( - - {datas.file.name} - { - removeMcuFiles(datas.id, index); - }} - sx={{ cursor: 'pointer' }} - > - - ))} - */} - { - handleMcuInputChange(row.id, row.member_id)(event); - }} - accept="application/pdf" - /> - { - fileMcuInput.current.click(); - }} - > - - Add Result - + + Policy Number: + {row.current_policy?.code ? row.current_policy?.code : '-'} + Gender: + {row.gender ? row.gender : '-'} - + + NRIC: + {row.nric ? row.nric : '-'} + Marital Status: + {row.marital_status ? row.marital_status : '-'} + + + NIK: + {row.employeds[0]?.nik ? row.employeds[0]?.nik : '-'} + Language: + {row.language ? row.language : '-'} + + + Email: + {row.email ? row.email : '-'} + Race: + {row.race ? row.race : '-'} + + + Phone Number: + {row.person?.phone ? row.person?.phone : '-'} + Relationship: + {row.relation_with_principal ? row.relation_with_principal : '-'} + + + Claim History + + + Requested: + {row.total_claims?.requested ? row.total_claims?.requested : '-'} + + + Pending: + {row.total_claims?.received ? row.total_claims?.received : '-'} + + + Approved: + {row.total_claims?.approved ? row.total_claims?.approved : '-'} + + + Declined: + {row.total_claims?.declined ? row.total_claims?.declined : '-'} + + + Paid: + {row.total_claims?.paid ? row.total_claims?.paid : '-'} + + + Files History + + + {row.file_mcu_names + ? row.file_mcu_names.split(',').map((fileName, index) => ( + <> + + + {fileName} + + + )) + : '-'} + + + + fileMcuInput.current?.click()}> + + + + Upload Result + + + { + handleMcuInputChange(row.id, row.member_id)(event); + }} + accept="application/pdf" + /> + + + +
+ + + + } + // sx={{ p: 1.8 }} + // onClick={() => {handleDownloadLog(row)}} + onClick={() => { + setDialogLogOpen(true); + }} + loading={loadingLog} + > + Download LOG + + + + + - -
@@ -746,33 +664,73 @@ export default function CorporatePlanList({handleSubmitSuccess}) { const headStyle = { fontWeight: 'bold', }; + const [reasonUpdate,setReasonUpdate] = useState('Agreement changed'); + const [nameUpdate, setNameUpdate] = useState(''); + const [memberIdUpdate, setMemberIdUpdate] = useState(''); + const [activeUpdate, setActiveUpdate] = useState(0); + const [idUpdate, setIdUpdate] = useState(''); + + const [openDialogStatus, setOpenDialogStatus] = useState(false); + + const handleCloseDialogUpdate = () => { + setNameUpdate(''); + setMemberIdUpdate(''); + setActiveUpdate(activeUpdate); + setIdUpdate(''); + setOpenDialogStatus(false); + } + + const handleSaveUpdateData = () => { + let activeValue = 0; + if(activeUpdate === 1) + { + activeValue = 0; + } + else + { + activeValue = 1; + } + const updateData = { + reason: reasonUpdate, + active : activeValue, + id: idUpdate, + }; + axios + .put('/members/'+idUpdate+'/activation', updateData) + .then((response) => { + enqueueSnackbar('Data updated successfully', { variant: 'success' }); + loadDataTableData(); + handleCloseDialogUpdate(); + }) + .catch((error) => { + enqueueSnackbar('Failed to add data', { variant: 'error' }); + }); + } + + const handleEditDataStatus = (data:any) => { + setNameUpdate(data.name); + setMemberIdUpdate(data.member_id); + setActiveUpdate(data.active); + setIdUpdate(data.id); + setOpenDialogStatus(true); + } return ( - {/* The Main Table */} - + - {columns.map((column, index) => ( - - {column.label} + + {column.label} ))} - - Status - - - Action - - {/* - Action - */} + - + {dataTableIsLoading ? ( @@ -801,6 +759,62 @@ export default function CorporatePlanList({handleSubmitSuccess}) { + {/* Dialog Update Status */} + + + + + Update Status + + + + + + + + + Are you sure to {activeUpdate == 1 ? 'Inactive' : 'Active'} this member ? + + + Member ID + {memberIdUpdate} + + + Name + {nameUpdate} + + + + + Reason for update* + + + Reason for update + + + + + + + + + + + {isDialog === 'edit' && ( { axios - .put(`/members/${id}/activation`, { + .put(`/members/${memberId}/activation`, { // service_code: service.service_code, active: status == 'active', - reason: model.reason + reason: model.reason, + id: memberId, }) .then((res) => { // Memuat ulang halaman saat ini @@ -133,7 +136,7 @@ const DialogTopUpLimit = ({ title, openDialog, setOpenDialog, data }: MuiDialogP const data = { service_code : service_code, reason : row.reason, - id : id, + id : memberId, } handleActivate(data, status) } catch (error: any) { @@ -157,18 +160,18 @@ const DialogTopUpLimit = ({ title, openDialog, setOpenDialog, data }: MuiDialogP + Reason for update* - - - - - - + name="reason" + label="Reason for update" + > + + + + + + - , }, - + { + path: ':corporate_id/hospitals/create', + element: , + }, + { + path: ':corporate_id/hospitals/edit/:id/:organization_id', + element: , + }, { path: ':corporate_id/claim-history', element: , @@ -505,6 +512,7 @@ const CorporateServicesCreate = Loadable(lazy(() => import('../pages/Corporates/ const CorporateServicesHistory = Loadable(lazy(() => import('../pages/Corporates/Services/sections/History'))); const CorporateHospitals = Loadable(lazy(() => import('../pages/Corporates/Hospital/Index'))); +const HospitalCreateUpdate = Loadable(lazy(() => import('../pages/Corporates/Hospital/CreateUpdate'))); const CorporateClaimHistories = Loadable( lazy(() => import('../pages/Corporates/ClaimHistory/Index')) );