From 7a834090287c6d6e289190ea1aacf9b0562f9653 Mon Sep 17 00:00:00 2001 From: Tb Fajri Date: Tue, 6 Jun 2023 09:28:22 +0700 Subject: [PATCH] Update reason benefit --- .../Api/CorporateBenefitController.php | 1 + .../Controllers/Api/CorporateController.php | 4 + .../Api/CorporateMemberController.php | 1 + Modules/Internal/Routes/api.php | 1 + app/Models/Corporate.php | 1 + app/Models/CorporateBenefit.php | 1 + app/Providers/AppServiceProvider.php | 21 ++ ...add_reason_to_corporate_benefits_table.php | 34 ++ ..._05_125604_add_reason_to_members_table.php | 33 ++ ...45003_add_payor_id_to_corporates_table.php | 34 ++ .../src/pages/Corporates/Benefit/List.tsx | 39 +- .../Corporates/Benefit/sections/DialogLog.tsx | 3 +- .../Corporates/Benefit/sections/History.tsx | 6 +- .../dashboard/src/pages/Corporates/Form.tsx | 42 ++- .../src/pages/Corporates/Member/List.tsx | 44 ++- .../Corporates/Member/sections/DialogLog.tsx | 339 +++++++++--------- .../Corporates/Member/sections/History.tsx | 177 +++++++++ frontend/dashboard/src/routes/index.tsx | 13 +- 18 files changed, 608 insertions(+), 186 deletions(-) create mode 100644 database/migrations/2023_06_05_093311_add_reason_to_corporate_benefits_table.php create mode 100644 database/migrations/2023_06_05_125604_add_reason_to_members_table.php create mode 100644 database/migrations/2023_06_05_145003_add_payor_id_to_corporates_table.php create mode 100644 frontend/dashboard/src/pages/Corporates/Member/sections/History.tsx diff --git a/Modules/Internal/Http/Controllers/Api/CorporateBenefitController.php b/Modules/Internal/Http/Controllers/Api/CorporateBenefitController.php index 18598017..3648c21f 100755 --- a/Modules/Internal/Http/Controllers/Api/CorporateBenefitController.php +++ b/Modules/Internal/Http/Controllers/Api/CorporateBenefitController.php @@ -34,6 +34,7 @@ class CorporateBenefitController extends Controller $benefit = CorporateBenefit::findOrFail($benefit_id); $benefit->active = $request->active == '1'; + $benefit->reason = $request->reason; if ($benefit->save()) { return response()->json([ diff --git a/Modules/Internal/Http/Controllers/Api/CorporateController.php b/Modules/Internal/Http/Controllers/Api/CorporateController.php index 5aa3e3d3..d5f46f4e 100755 --- a/Modules/Internal/Http/Controllers/Api/CorporateController.php +++ b/Modules/Internal/Http/Controllers/Api/CorporateController.php @@ -82,6 +82,7 @@ class CorporateController extends Controller $request->validate([ 'code' => 'required|regex:/^[a-zA-Z0-9]+$/', 'name' => 'required', + 'payor_id' => 'required', // 'logo' => 'required', 'policy_code' => 'required_with:policy_id', 'policy_total_premi' => 'required_with:policy_code', @@ -101,6 +102,7 @@ class CorporateController extends Controller if ($request->has('policy_code') && !empty($request->policy_code)) { $newCorporate->policies()->create([ 'code' => $request->policy_code ?? NULL, + 'payor_id' => $request->payor_id ?? NULL, 'total_premi' => $request->policy_total_premi ?? NULL, 'minimal_deposit_percentage' => $request->policy_minimal_deposit_percentage ?? NULL, 'minimal_deposit_net' => $request->policy_minimal_deposit_net ?? NULL, @@ -302,6 +304,7 @@ class CorporateController extends Controller { $request->validate([ 'code' => 'required|regex:/^[a-zA-Z0-9]+$/', + 'payor_id' => 'required', 'name' => 'required', 'policy_code' => 'required_with:policy_id', 'policy_total_premi' => 'required_with:policy_code', @@ -328,6 +331,7 @@ class CorporateController extends Controller ['id' => $request->policy_id], [ 'code' => $request->policy_code ?? NULL, + 'payor_id' => $request->payor_id ?? NULL, 'total_premi' => $request->policy_total_premi ?? NULL, 'minimal_deposit_percentage' => $request->policy_minimal_deposit_percentage ?? NULL, 'minimal_deposit_net' => $request->policy_minimal_deposit_net ?? NULL, diff --git a/Modules/Internal/Http/Controllers/Api/CorporateMemberController.php b/Modules/Internal/Http/Controllers/Api/CorporateMemberController.php index dec12249..4da01d8c 100755 --- a/Modules/Internal/Http/Controllers/Api/CorporateMemberController.php +++ b/Modules/Internal/Http/Controllers/Api/CorporateMemberController.php @@ -69,6 +69,7 @@ class CorporateMemberController extends Controller $member = Member::findOrFail($member_id); $member->active = $request->active == '1'; + $member->reason = $request->reason; if ($member->save()) { return response()->json([ diff --git a/Modules/Internal/Routes/api.php b/Modules/Internal/Routes/api.php index ac4f01d9..b2d46b2a 100755 --- a/Modules/Internal/Routes/api.php +++ b/Modules/Internal/Routes/api.php @@ -69,6 +69,7 @@ Route::prefix('internal')->group(function () { Route::post('corporates/{corporate_id}/import-plan-benefit', [CorporateController::class, 'importPlanBenefit']); Route::get('corporates/{corporate_id}/data-plan-benefit', [CorporateController::class, 'dataPlanBenefit']); Route::get('corporates/{corporate_id}/code', [CorporateController::class, 'corporateCode']); + Route::get('corporates/{corporate_id}/payor_id', [CorporateController::class, 'corporatePayorId']); Route::get('corporates/{corporate_id}/corporate-plans', [CorporatePlanController::class, 'index']); Route::post('corporates/{corporate_id}/corporate-plans', [CorporatePlanController::class, 'store']); diff --git a/app/Models/Corporate.php b/app/Models/Corporate.php index f6b922a7..c53c7aed 100755 --- a/app/Models/Corporate.php +++ b/app/Models/Corporate.php @@ -17,6 +17,7 @@ class Corporate extends Model 'parent_id', 'code', 'name', + 'payor_id', 'reason', 'welcome_message', 'help_text', diff --git a/app/Models/CorporateBenefit.php b/app/Models/CorporateBenefit.php index 09f30fdc..fadf3470 100755 --- a/app/Models/CorporateBenefit.php +++ b/app/Models/CorporateBenefit.php @@ -69,6 +69,7 @@ class CorporateBenefit extends Model 'show_benefit_item', 'show_benefit_value', 'active', + 'reason' ]; public static $doc_headers_to_field_map = [ diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index aa2dcd17..d56e97c2 100755 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -9,6 +9,8 @@ use Illuminate\Support\ServiceProvider; use App\Models\Corporate; use App\Models\CorporateService; use App\Models\CorporatePlan; +use App\Models\CorporateBenefit; +use App\Models\Member; use App\Models\AuditTrail; use Illuminate\Support\Facades\Auth; use Str; @@ -52,6 +54,15 @@ class AppServiceProvider extends ServiceProvider $this->logAuditTrail($model, 'deleted'); }); + Member::updated(function ($model) { + + $this->logAuditTrail($model, 'updated'); + }); + + Member::deleted(function ($model) { + $this->logAuditTrail($model, 'deleted'); + }); + // Corporate Service CorporateService::updated(function ($model) { @@ -73,6 +84,16 @@ class AppServiceProvider extends ServiceProvider $this->logAuditTrail($model, 'deleted'); }); + // Corporate Benefits + CorporateBenefit::updated(function ($model) { + + $this->logAuditTrail($model, 'updated'); + }); + + CorporateBenefit::deleted(function ($model) { + $this->logAuditTrail($model, 'deleted'); + }); + } diff --git a/database/migrations/2023_06_05_093311_add_reason_to_corporate_benefits_table.php b/database/migrations/2023_06_05_093311_add_reason_to_corporate_benefits_table.php new file mode 100644 index 00000000..fa018458 --- /dev/null +++ b/database/migrations/2023_06_05_093311_add_reason_to_corporate_benefits_table.php @@ -0,0 +1,34 @@ +string('reason')->after('active')->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('corporate_benefits', function (Blueprint $table) { + // + $table->dropColumn('reason'); + }); + } +}; diff --git a/database/migrations/2023_06_05_125604_add_reason_to_members_table.php b/database/migrations/2023_06_05_125604_add_reason_to_members_table.php new file mode 100644 index 00000000..e67550ae --- /dev/null +++ b/database/migrations/2023_06_05_125604_add_reason_to_members_table.php @@ -0,0 +1,33 @@ +string('reason')->after('active')->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('members', function (Blueprint $table) { + // + $table->dropColumn('reason'); + }); + } +}; diff --git a/database/migrations/2023_06_05_145003_add_payor_id_to_corporates_table.php b/database/migrations/2023_06_05_145003_add_payor_id_to_corporates_table.php new file mode 100644 index 00000000..73bd2eb6 --- /dev/null +++ b/database/migrations/2023_06_05_145003_add_payor_id_to_corporates_table.php @@ -0,0 +1,34 @@ +string('payor_id')->after('parent_id')->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('corporates', function (Blueprint $table) { + // + $table->dropColumn('payor_id'); + }); + } +}; diff --git a/frontend/dashboard/src/pages/Corporates/Benefit/List.tsx b/frontend/dashboard/src/pages/Corporates/Benefit/List.tsx index 0989a5cd..caebf727 100755 --- a/frontend/dashboard/src/pages/Corporates/Benefit/List.tsx +++ b/frontend/dashboard/src/pages/Corporates/Benefit/List.tsx @@ -33,11 +33,12 @@ import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight'; import AddIcon from '@mui/icons-material/Add'; import UploadIcon from '@mui/icons-material/Upload'; import CancelIcon from '@mui/icons-material/Cancel'; +import HistoryIcon from '@mui/icons-material/History'; // hooks import React, { ChangeEvent, Component, useEffect, useRef, useState } from 'react'; import useSettings from '../../../hooks/useSettings'; -import { useParams, useSearchParams } from 'react-router-dom'; +import {Link, useParams, useSearchParams } from 'react-router-dom'; // components import { @@ -61,12 +62,27 @@ import { LaravelPaginatedData } from '../../../@types/paginated-data'; import BasePagination from '../../../components/BasePagination'; import { enqueueSnackbar } from 'notistack'; import { LoadingButton } from '@mui/lab'; +import DialogLog from './sections/DialogLog'; export default function PlanList() { const { themeStretch } = useSettings(); const { corporate_id } = useParams(); const [searchParams, setSearchParams] = useSearchParams(); const [importResult, setImportResult] = useState(null); + + const [openDialog, setOpenDialog] = useState(false); + const [isDialog, setIsDialog] = useState(''); + const [edit, setEdit] = useState({}); + const clickHandler = (isDialog: string) => { + switch (isDialog) { + case 'edit': + setIsDialog(isDialog); + setOpenDialog(true); + break; + default: + break; + } + }; function SearchInput(props: any) { // SEARCH @@ -339,7 +355,9 @@ export default function PlanList() { color="success" size="small" onClick={() => { - handleActivate(row, 'inactive'); + // handleActivate(row, 'inactive'); + clickHandler('edit'); + setEdit({id: row.id, service_code: row.service_code, status: 'inactive'}); }} > Active @@ -351,7 +369,9 @@ export default function PlanList() { color="error" size="small" onClick={() => { - handleActivate(row, 'active'); + // handleActivate(row, 'active'); + clickHandler('edit'); + setEdit({id: row.id, service_code: row.service_code, status: 'active'}); }} > Inactive @@ -372,6 +392,11 @@ export default function PlanList() { > {openEdit ? 'Save' : 'Edit'} + + + {/* COLLAPSIBLE ROW */} @@ -832,6 +857,14 @@ export default function PlanList() { + {isDialog === 'edit' && ( + + )} ); } diff --git a/frontend/dashboard/src/pages/Corporates/Benefit/sections/DialogLog.tsx b/frontend/dashboard/src/pages/Corporates/Benefit/sections/DialogLog.tsx index 1b5c4b25..3994b49a 100755 --- a/frontend/dashboard/src/pages/Corporates/Benefit/sections/DialogLog.tsx +++ b/frontend/dashboard/src/pages/Corporates/Benefit/sections/DialogLog.tsx @@ -103,7 +103,7 @@ const DialogTopUpLimit = ({ title, openDialog, setOpenDialog, data }: MuiDialogP // const { plan_id } = useParams(); const handleActivate = (model: any, status: string) => { axios - .put(`/plans/${id}/activation`, { + .put(`/benefits/${id}/activation`, { // service_code: service.service_code, active: status == 'active', reason: model.reason @@ -135,7 +135,6 @@ const DialogTopUpLimit = ({ title, openDialog, setOpenDialog, data }: MuiDialogP reason : row.reason, id : id, } - console.log(data) handleActivate(data, status) } catch (error: any) { console.log('data gagal', data); diff --git a/frontend/dashboard/src/pages/Corporates/Benefit/sections/History.tsx b/frontend/dashboard/src/pages/Corporates/Benefit/sections/History.tsx index c1f372cf..fd329b53 100644 --- a/frontend/dashboard/src/pages/Corporates/Benefit/sections/History.tsx +++ b/frontend/dashboard/src/pages/Corporates/Benefit/sections/History.tsx @@ -89,7 +89,7 @@ export default function CustomizedAccordions() { const { themeStretch } = useSettings(); - const { corporate_id, plan_id } = useParams(); + const { corporate_id, benefit_id } = useParams(); const [corporate, setCorporate] = useState(); const [currentCorporate, setCurrentCorporate ] = useState(); @@ -98,8 +98,8 @@ export default function CustomizedAccordions() { useEffect(() => { setCorporate(configuredCorporateContext.currentCorporate); - const model = 'App\\Models\\CorporatePlan'; - const url = `/audittrail/${plan_id}?model=${model}`; + const model = 'App\\Models\\CorporateBenefit'; + const url = `/audittrail/${benefit_id}?model=${model}`; axios.get(url) .then((res) => { setCurrentCorporate(res.data); diff --git a/frontend/dashboard/src/pages/Corporates/Form.tsx b/frontend/dashboard/src/pages/Corporates/Form.tsx index a1a8b935..8219eee3 100755 --- a/frontend/dashboard/src/pages/Corporates/Form.tsx +++ b/frontend/dashboard/src/pages/Corporates/Form.tsx @@ -74,14 +74,7 @@ export default function CorporateForm({ isEdit, currentCorporate }: Props) { NewCorporateSchema = Yup.object().shape({ isEdited: Yup.boolean(), name: Yup.string().required('Name is required'), - code: Yup.string().required('Corporate Code is required').test( - 'unique-code', - 'Code must be unique', - async function (value) { - const existingCodes = await getExistingCodes(); - return !existingCodes.includes(value); - } - ), + code: Yup.string().required('Corporate Code is required'), active: Yup.boolean().required('Corporate Status is required'), type: Yup.string().required('Type is required'), welcome_message: Yup.string().required('Welcome Message is required'), @@ -200,11 +193,41 @@ export default function CorporateForm({ isEdit, currentCorporate }: Props) { } } + async function getExistingPayorId() { + // axios + // .get('/corporates/create') + // .then((res) => { + // setCorporateGroups(res.data.corporate_groups); + // }) + // .catch((err) => { + // enqueueSnackbar('Opps, failed to get Corporate Group List', { variant: 'error' }); + // }); + + try { + let response = await axios.get('/corporates/1/code'); // get data all corporate + let codeCurrent = "" + if (isEdit){ + let responseCodeCurrent = await axios.get(`/corporates/${currentCorporate?.id}/edit`); // get data current corporate + codeCurrent = responseCodeCurrent.data.payor_id; // get data code corporate current + } + // console.log(response.data); + let existingCodes = response.data.map(item => item); // get data code corporate all + + let filteredArray = existingCodes.filter(e => e != codeCurrent) + console.log(filteredArray); + return filteredArray; + } catch (error) { + console.error(error); + enqueueSnackbar('Failed to fetch existing codes', { variant: 'error' }); + } + } + const defaultValues = useMemo( () => ({ code: currentCorporate?.code || '', name: currentCorporate?.name || '', reason: currentCorporate?.reason || '', + payor_id: currentCorporate?.payor_id || '', welcome_message: currentCorporate?.welcome_message || '', help_text: currentCorporate?.help_text || '', active: currentCorporate?.id ? currentCorporate?.active === 1 : true, @@ -285,6 +308,7 @@ export default function CorporateForm({ isEdit, currentCorporate }: Props) { formData.append('reason', data.reason); formData.append('help_text', data.help_text); formData.append('policy_id', data.policy_id); + formData.append('payor_id', data.payor_id); formData.append('policy_code', data.policy_code); formData.append('policy_total_premi', data.policy_total_premi); formData.append('policy_minimal_deposit_percentage', data.policy_minimal_deposit_percentage); @@ -494,6 +518,8 @@ export default function CorporateForm({ isEdit, currentCorporate }: Props) { + + {isEdit && ( diff --git a/frontend/dashboard/src/pages/Corporates/Member/List.tsx b/frontend/dashboard/src/pages/Corporates/Member/List.tsx index 38678411..014d880a 100755 --- a/frontend/dashboard/src/pages/Corporates/Member/List.tsx +++ b/frontend/dashboard/src/pages/Corporates/Member/List.tsx @@ -37,7 +37,7 @@ import InsertDriveFileIcon from '@mui/icons-material/InsertDriveFile'; // hooks import React, { ChangeEvent, Component, useEffect, useRef, useState } from 'react'; import useSettings from '../../../hooks/useSettings'; -import { useParams, useSearchParams } from 'react-router-dom'; +import {Link, useParams, useSearchParams } from 'react-router-dom'; // components import axios from '../../../utils/axios'; import { Plan } from '../../../@types/corporates'; @@ -47,6 +47,7 @@ import BasePagination from '../../../components/BasePagination'; import { enqueueSnackbar } from 'notistack'; import { LoadingButton } from '@mui/lab'; import DialogLog from './sections/DialogLog'; +import HistoryIcon from '@mui/icons-material/History'; export default function CorporatePlanList() { const { themeStretch } = useSettings(); @@ -54,6 +55,20 @@ export default function CorporatePlanList() { const [searchParams, setSearchParams] = useSearchParams(); const [importResult, setImportResult] = useState(null); + const [openDialog, setOpenDialog] = useState(false); + const [isDialog, setIsDialog] = useState(''); + const [edit, setEdit] = useState({}); + const clickHandler = (isDialog: string) => { + switch (isDialog) { + case 'edit': + setIsDialog(isDialog); + setOpenDialog(true); + break; + default: + break; + } + }; + // Dummy Default Data const [dataTableIsLoading, setDataTableLoading] = React.useState(true); const [dataTableData, setDataTableData] = React.useState({ @@ -405,7 +420,9 @@ export default function CorporatePlanList() { color="success" size="small" onClick={() => { - handleActivate(row, 'inactive'); + // handleActivate(row, 'inactive'); + clickHandler('edit'); + setEdit({id: row.id, service_code: row.service_code, status: 'inactive'}); }} > Active @@ -417,14 +434,22 @@ export default function CorporatePlanList() { color="error" size="small" onClick={() => { - handleActivate(row, 'active'); + // handleActivate(row, 'active'); + clickHandler('edit'); + setEdit({id: row.id, service_code: row.service_code, status: 'active'}); }} > Inactive )} - {/* */} + + + + + {/* COLLAPSIBLE ROW */} @@ -606,6 +631,9 @@ export default function CorporatePlanList() { Status + + Action + {/* Action */} @@ -639,6 +667,14 @@ export default function CorporatePlanList() { + {isDialog === 'edit' && ( + + )} ); } diff --git a/frontend/dashboard/src/pages/Corporates/Member/sections/DialogLog.tsx b/frontend/dashboard/src/pages/Corporates/Member/sections/DialogLog.tsx index 03a4b8f2..b421e6af 100755 --- a/frontend/dashboard/src/pages/Corporates/Member/sections/DialogLog.tsx +++ b/frontend/dashboard/src/pages/Corporates/Member/sections/DialogLog.tsx @@ -1,33 +1,36 @@ -// react -import { ReactElement, useEffect, useState } from 'react'; -// mui -import { - Card, - Checkbox, - Divider, - Grid, - Input, - Link, - Stack, - Table, - TableCell, - TableContainer, - TableRow, - Typography, -} from '@mui/material'; +import * as Yup from 'yup'; +import { enqueueSnackbar, useSnackbar } from 'notistack'; +import { useNavigate } from 'react-router-dom'; +import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import { useForm } from 'react-hook-form'; +import { yupResolver } from '@hookform/resolvers/yup'; +// @mui import { styled } from '@mui/material/styles'; -// Component -import MuiDialog from '@/components/MuiDialog'; -import { Box } from '@mui/material'; -import { TextField } from '@mui/material'; -import { DesktopDatePicker, LocalizationProvider } from '@mui/x-date-pickers'; -import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns'; -import { fPostFormat } from '@/utils/formatTime'; import { LoadingButton } from '@mui/lab'; -import InsertDriveFileIcon from '@mui/icons-material/InsertDriveFile'; -import axios from '@/utils/axios'; -import { enqueueSnackbar } from 'notistack'; +import { Box, Button, Grid, Stack, Typography, Chip, Autocomplete } from '@mui/material'; +import { CorporateService } from '../../../../@types/corporates'; +// components +import { FormProvider, RHFTextField, RHFSwitch } from '../../../../components/hook-form'; +import axios from '../../../../utils/axios'; +import { LaravelPaginatedData } from '../../../../@types/paginated-data'; +// import { Contact } from '../../../../@types/contact'; +import { Link, useParams, useSearchParams } from 'react-router-dom'; + +// @mui +// components +import MuiDialog from '../../../../components/MuiDialog'; +// React +import { ReactElement } from 'react'; + +// ---------------------------------------------------------------------- + +const HeaderStyle = styled('header')(({ theme }) => ({ + display: 'flex', + alignItems: 'center', + padding: theme.spacing(2), + justifyContent: 'space-between', +})); type DataContent = { info: string; date: string; @@ -45,159 +48,165 @@ type MuiDialogProps = { data?: DataContent[]; }; -const ItemNotificationStyle = styled(Card)(({ theme }) => ({ - boxShadow: 'none', - padding: theme.spacing(1), - borderRadius: 0.5, - color: 'black', -})); +type FormValuesProps = { + value: string; + active: boolean; +}; -const DialogLog = ({ title, openDialog, setOpenDialog, data }: MuiDialogProps) => { - const [openDialogClaim, setOpenDialogClaim] = useState(false); - const [dialogTitleClaim, setDialogTitleClaim] = useState(''); - const [dateOfAdmission, setDateOfAdmission] = useState(new Date()); - const [checkedBenefitIds, setCheckedBenefitIds] = useState([]); - const [benefitIds, setBenefitIds] = useState([]); - const [loadingLog, setLoadingLog] = useState(false); +// ---------------------------------------------------------------------- +// ---------------------------------------------------------------------- + +const DialogTopUpLimit = ({ title, openDialog, setOpenDialog, data }: MuiDialogProps) => { + const navigate = useNavigate(); + const [dataTableData, setDataTableData] = useState({ + current_page: 1, + data: [], + path: '', + first_page_url: '', + last_page: 1, + last_page_url: '', + next_page_url: '', + prev_page_url: '', + per_page: 10, + from: 0, + to: 0, + total: 0, + }); + + const { id, service_code, status } = data; + + const isEdit = id ? true : false; + + const NewCorporateSchema = Yup.object().shape({ + reason: Yup.string().required('Corporate Status is required'), + }); + + + const methods = useForm({ + resolver: yupResolver(NewCorporateSchema), + }); + const { + reset, + watch, + handleSubmit, + formState: { isSubmitting }, + } = methods; + + const values = watch(); useEffect(() => { - setBenefitIds(data.member.current_plan?.benefits.filter((benefit) => benefit.pivot.active == 1).map((benefit) => benefit.id)) - setCheckedBenefitIds(benefitIds) - console.log('Check All', benefitIds, 'X', data.member.current_plan?.benefits.map((benefit) => benefit.id)) - }, []) + if (openDialog === false) { + reset(); + } + }, [openDialog, reset]); - const clickHandler = () => { - setDialogTitleClaim('Claim Details'); - setOpenDialogClaim(true); + // const { plan_id } = useParams(); + const handleActivate = (model: any, status: string) => { + axios + .put(`/members/${id}/activation`, { + // service_code: service.service_code, + active: status == 'active', + reason: model.reason + }) + .then((res) => { + // Memuat ulang halaman saat ini + setOpenDialog(false) + window.location.reload(); + // setDataTableData({ + // ...dataTableData, + // data: dataTableData.data.map((service) => { + // let updatedService = service; + // if (id == service.id) { + // updatedService.status = res.data.status; + // } + // return updatedService; + // }), + // }); + }) + .catch((error) => { + console.log(error); + }); }; - const handleCheckAll = (event) => { - if (event.target.checked) { - setCheckedBenefitIds(benefitIds) - } else { - setCheckedBenefitIds([]) + const onSubmit = async (row : ReturnType) => { + try { + const data = { + service_code : service_code, + reason : row.reason, + id : id, + } + handleActivate(data, status) + } catch (error: any) { + console.log('data gagal', data); } - } - const handleCheckChange = (event, benefit) => { - if ( event.target.checked ) { - setCheckedBenefitIds([...checkedBenefitIds, benefit.id]) - } else { - // setCheckedBenefitIds([]) - setCheckedBenefitIds(checkedBenefitIds.filter((benefitId) => benefitId !== benefit.id)) + const ascent = document?.querySelector('ascent'); + if (ascent != null) { + ascent.innerHTML = ''; } - } + }; - const handleDownloadLog = (row) => { - setLoadingLog(true); - axios - .post(`generate-log/${row.id}`, { - date_of_admission : dateOfAdmission, - benefit_ids : checkedBenefitIds - }, { - responseType: 'blob', - }) - .then((response) => { - window.open(URL.createObjectURL(response.data)); - setLoadingLog(false); - setOpenDialog(false); - }) - .catch((response) => { - enqueueSnackbar(response.message, { variant: 'error' }); - setLoadingLog(false); - }); + function createData(corporateService: CorporateService): CorporateService { + return { + ...corporateService, + }; } - - const getContent = () => ( - - - - - - - { - setDateOfAdmission(new Date(fPostFormat(value))); - // console.log('value') - }} - renderInput={(params) => ( - - )} - /> - - - - - List Of Benefit - - - All - - - - - - }> - { data.member.current_plan?.benefits && ( - data.member.current_plan?.benefits.filter((benefit) => benefit.pivot.active == 1).map((benefit, index) => ( - - - {benefit.code} {benefit.description ? ` - ${benefit.description} ` : ''} - - {handleCheckChange(event, benefit)} } /> - - )) - )} - - {/* - - - - ASD - - - ASD - - -
-
*/} -
- - - } - onClick={() => {handleDownloadLog(data.member)}} - loading={loadingLog} - > - Download LOG - - + + const getContent = (props: { row: ReturnType }) => ( + + + + + - -
-
+ + + + + + + Save + + + + + + + ); return ( - <> - - + ); }; -export default DialogLog; +export default DialogTopUpLimit; \ No newline at end of file diff --git a/frontend/dashboard/src/pages/Corporates/Member/sections/History.tsx b/frontend/dashboard/src/pages/Corporates/Member/sections/History.tsx new file mode 100644 index 00000000..afbebf13 --- /dev/null +++ b/frontend/dashboard/src/pages/Corporates/Member/sections/History.tsx @@ -0,0 +1,177 @@ +// @mui +import { + Box, + Button, + Card, + Collapse, + Container, + FormControl, + Grid, + IconButton, + InputLabel, + MenuItem, + OutlinedInput, + Paper, + Select, + SelectChangeEvent, + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, + TextField, + Typography, + Badge, + Stack, +} from '@mui/material'; +import * as React from 'react'; +import { useParams } from 'react-router-dom'; +import { styled } from '@mui/material/styles'; +import ArrowForwardIosSharpIcon from '@mui/icons-material/ArrowForwardIosSharp'; +import MuiAccordion, { AccordionProps } from '@mui/material/Accordion'; +import { useContext, useEffect, useState } from 'react'; +import MuiAccordionSummary, { + AccordionSummaryProps, +} from '@mui/material/AccordionSummary'; +import useSettings from '../../../../hooks/useSettings'; +import axios from '../../../../utils/axios'; +import { ConfiguredCorporateContext } from '@/contexts/ConfiguredCorporateContext'; +import MuiAccordionDetails from '@mui/material/AccordionDetails'; +import HeaderBreadcrumbs from '../../../../components/HeaderBreadcrumbs'; +import { Corporate } from '@/@types/corporates'; +import { fDate, fDateTime } from '@/utils/formatTime'; + +const Accordion = styled((props: AccordionProps) => ( + +))(({ theme }) => ({ + border: `1px solid ${theme.palette.divider}`, + '&:not(:last-child)': { + borderBottom: 0, + }, + '&:before': { + display: 'none', + }, +})); + +const AccordionSummary = styled((props: AccordionSummaryProps) => ( + } + {...props} + /> +))(({ theme }) => ({ + backgroundColor: + theme.palette.mode === 'dark' + ? 'rgba(255, 255, 255, .05)' + : 'rgba(0, 0, 0, .03)', + flexDirection: 'row-reverse', + '& .MuiAccordionSummary-expandIconWrapper.Mui-expanded': { + transform: 'rotate(90deg)', + }, + '& .MuiAccordionSummary-content': { + marginLeft: theme.spacing(1), + }, +})); + +const AccordionDetails = styled(MuiAccordionDetails)(({ theme }) => ({ + padding: theme.spacing(2), + borderTop: '1px solid rgba(0, 0, 0, .125)', +})); + +export default function CustomizedAccordions() { + const [expanded, setExpanded] = React.useState('panel1'); + + const handleChange = + (panel: string) => (event: React.SyntheticEvent, newExpanded: boolean) => { + setExpanded(newExpanded ? panel : false); + }; + const pageTitle = 'Audittrail Corporate'; + + const { themeStretch } = useSettings(); + + const { corporate_id, member_id } = useParams(); + + const [corporate, setCorporate] = useState(); + const [currentCorporate, setCurrentCorporate ] = useState(); + + 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) => { + setCurrentCorporate(res.data); + }) + .catch((error) => { + console.error('Terjadi kesalahan:', error); + }); + + }, [configuredCorporateContext]); + + return ( +
+ + {currentCorporate?.data.map((item, index) => ( + + + {`Data has ${item.action} by ${item.user_id} on ${fDateTime(item.updated_at)}`} + + + + + Field + Old Value + New Values + + + + {Object.entries(item.old_values).map(([key, value]) => { + let renderedValue; + if (key !== 'reason') { + return null; // Melewati iterasi saat key adalah 'deleted_by' + } + renderedValue = item.new_values[key]; + + const field = key.charAt(0).toUpperCase() + key.slice(1); + + return ( + + {`${field}`} + {`${value}`} + {renderedValue} + + ); + })} + + + + + ))} +
+ ); +} diff --git a/frontend/dashboard/src/routes/index.tsx b/frontend/dashboard/src/routes/index.tsx index 78129fe1..3c0a4ec1 100755 --- a/frontend/dashboard/src/routes/index.tsx +++ b/frontend/dashboard/src/routes/index.tsx @@ -129,11 +129,18 @@ export default function Router() { path: ':corporate_id/benefits', element: , }, - + { + path: ':corporate_id/benefits/:benefit_id/history', + element: , + }, { path: ':corporate_id/members', element: , }, + { + path: ':corporate_id/members/:member_id/history', + element: , + }, { path: ':corporate_id/divisions', @@ -363,6 +370,7 @@ const CorporateDivisionsCreate = Loadable( ); const CorporateMembers = Loadable(lazy(() => import('../pages/Corporates/Member/Index'))); +const CorporateHistoryMembers = Loadable(lazy(() => import('../pages/Corporates/Member/sections/History'))); const BenefitCreate = Loadable(lazy(() => import('../pages/Corporates/Benefit/Create'))); const Benefits = Loadable(lazy(() => import('../pages/Corporates/Benefit/Index'))); @@ -373,6 +381,9 @@ const CorporateBenefitsCreate = Loadable( const CorporateBenefits = Loadable( lazy(() => import('../pages/Corporates/CorporateBenefit/Index')) ); +const CorporateBenefitsHistory = Loadable( + lazy(() => import('../pages/Corporates/Benefit/sections/History')) +); const CorporatePlanCreate = Loadable( lazy(() => import('../pages/Corporates/CorporatePlan/CreateUpdate'))