Merge branch 'staging' of itcorp.primaya.id:rajif/aso into staging
This commit is contained in:
@@ -37,7 +37,10 @@ class CorporateManageController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function show($corporate_id)
|
public function show($corporate_id)
|
||||||
{
|
{
|
||||||
//
|
$userLogin = Auth::user();
|
||||||
|
$corporate = $userLogin->managedCorporates()->where('corporates.id', $corporate_id)->first();
|
||||||
|
|
||||||
|
return response()->json($corporate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
namespace Modules\Client\Http\Controllers\Api;
|
namespace Modules\Client\Http\Controllers\Api;
|
||||||
|
|
||||||
use App\Helpers\Helper;
|
use App\Helpers\Helper;
|
||||||
|
use App\Models\Member;
|
||||||
use App\Services\CorporateMemberService;
|
use App\Services\CorporateMemberService;
|
||||||
use Illuminate\Contracts\Support\Renderable;
|
use Illuminate\Contracts\Support\Renderable;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
@@ -10,6 +11,7 @@ use Illuminate\Routing\Controller;
|
|||||||
use Modules\Client\Transformers\ClaimReport\MemberResources as ClaimReportMemberResources;
|
use Modules\Client\Transformers\ClaimReport\MemberResources as ClaimReportMemberResources;
|
||||||
use Modules\Client\Transformers\Dashboard\MemberResources as DashboardMemberResources;
|
use Modules\Client\Transformers\Dashboard\MemberResources as DashboardMemberResources;
|
||||||
use Modules\Client\Transformers\Dashboard\MemberAlarmCenterResources as DashboardMemberAlarmResources;
|
use Modules\Client\Transformers\Dashboard\MemberAlarmCenterResources as DashboardMemberAlarmResources;
|
||||||
|
use Modules\Client\Transformers\DataMemberResource;
|
||||||
|
|
||||||
class CorporateMemberController extends Controller
|
class CorporateMemberController extends Controller
|
||||||
{
|
{
|
||||||
@@ -41,4 +43,19 @@ class CorporateMemberController extends Controller
|
|||||||
return response()->json(Helper::paginateResources(DashboardMemberResources::collection($members)));
|
return response()->json(Helper::paginateResources(DashboardMemberResources::collection($members)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function show($corporate_id, $person_id)
|
||||||
|
{
|
||||||
|
$data = Member::with(['claims', 'person', 'employeds', 'currentPlan.benefits'])
|
||||||
|
->where('person_id', $person_id)
|
||||||
|
->whereHas('employeds', function ($query) use ($corporate_id) {
|
||||||
|
$query->where('corporate_id', $corporate_id);
|
||||||
|
})
|
||||||
|
->first();
|
||||||
|
|
||||||
|
$totalClaims = $data->claims->sum('total_claim');
|
||||||
|
$data->total_claims = $totalClaims;
|
||||||
|
|
||||||
|
return response()->json(DataMemberResource::make($data));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ use Modules\Client\Http\Controllers\Api\ClaimController;
|
|||||||
use Modules\Client\Http\Controllers\Api\TopUpController;
|
use Modules\Client\Http\Controllers\Api\TopUpController;
|
||||||
use Modules\Internal\Http\Controllers\ClaimEncounterController;
|
use Modules\Internal\Http\Controllers\ClaimEncounterController;
|
||||||
use App\Models\Encounter;
|
use App\Models\Encounter;
|
||||||
|
use Modules\Client\Http\Controllers\Api\DataController;
|
||||||
use Modules\Internal\Transformers\EncounterResource;
|
use Modules\Internal\Transformers\EncounterResource;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -33,12 +34,16 @@ Route::prefix('client')->group(function () {
|
|||||||
Route::middleware('auth:sanctum')->group(function () {
|
Route::middleware('auth:sanctum')->group(function () {
|
||||||
Route::post('logout', [AuthController::class, 'logout'])->name('logout');
|
Route::post('logout', [AuthController::class, 'logout'])->name('logout');
|
||||||
Route::get('user', [UserController::class, 'index']);
|
Route::get('user', [UserController::class, 'index']);
|
||||||
|
Route::get('data/{id}', [DataController::class, 'show']);
|
||||||
|
Route::put('data/{id}', [DataController::class, 'update']);
|
||||||
|
|
||||||
Route::get('corporate-manage', [CorporateManageController::class, 'index']);
|
Route::get('corporate-manage', [CorporateManageController::class, 'index']);
|
||||||
|
Route::get('corporate-manage/{corporate_id}', [CorporateManageController::class, 'show']);
|
||||||
Route::prefix('{corporate_id}')->group(function () {
|
Route::prefix('{corporate_id}')->group(function () {
|
||||||
Route::get('policy', [CorporatePolicyController::class, 'index']);
|
Route::get('policy', [CorporatePolicyController::class, 'index']);
|
||||||
Route::get('division', [CorporateDivisionController::class, 'index']);
|
Route::get('division', [CorporateDivisionController::class, 'index']);
|
||||||
Route::get('members', [CorporateMemberController::class, 'index']);
|
Route::get('members', [CorporateMemberController::class, 'index']);
|
||||||
|
Route::get('members/{id}', [CorporateMemberController::class, 'show']);
|
||||||
Route::get('claims/status', [ClaimController::class, 'status']);
|
Route::get('claims/status', [ClaimController::class, 'status']);
|
||||||
Route::get('claims', [ClaimController::class, 'index']);
|
Route::get('claims', [ClaimController::class, 'index']);
|
||||||
Route::get('claims/{claim_id}/encounters', [ClaimEncounterController::class, 'getEncounterData']);
|
Route::get('claims/{claim_id}/encounters', [ClaimEncounterController::class, 'getEncounterData']);
|
||||||
@@ -47,10 +52,5 @@ Route::prefix('client')->group(function () {
|
|||||||
Route::post('topup', [TopUpController::class, 'store']);
|
Route::post('topup', [TopUpController::class, 'store']);
|
||||||
});
|
});
|
||||||
Route::get('claims/{id}', [ClaimController::class, 'show']);
|
Route::get('claims/{id}', [ClaimController::class, 'show']);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
c<?php
|
<?php
|
||||||
|
|
||||||
namespace Modules\Client\Transformers;
|
namespace Modules\Client\Transformers;
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ class ClaimShowResource extends JsonResource
|
|||||||
$itemData['nominal_dicover'] = $item['nominal_dicover'] ?? 0;
|
$itemData['nominal_dicover'] = $item['nominal_dicover'] ?? 0;
|
||||||
$itemData['nominal_ditagihkan'] = $item['nominal_ditagihkan'] ?? 0;
|
$itemData['nominal_ditagihkan'] = $item['nominal_ditagihkan'] ?? 0;
|
||||||
$itemData['nominal_total'] = $item['nominal_total'] ?? 0;
|
$itemData['nominal_total'] = $item['nominal_total'] ?? 0;
|
||||||
|
|
||||||
// For React Frotnend
|
// For React Frotnend
|
||||||
$itemData['biaya_diajukan'] = $itemData['nominal_ditagihkan'];
|
$itemData['biaya_diajukan'] = $itemData['nominal_ditagihkan'];
|
||||||
$itemData['biaya_disetujui'] = $itemData['nominal_dicover'];
|
$itemData['biaya_disetujui'] = $itemData['nominal_dicover'];
|
||||||
@@ -33,8 +33,12 @@ class ClaimShowResource extends JsonResource
|
|||||||
return $itemData;
|
return $itemData;
|
||||||
});
|
});
|
||||||
|
|
||||||
$data['primary_diagnosis'] = $this->diagnoses->filter(function($diagnosis){ return $diagnosis->type == 'primary';})->values();
|
$data['primary_diagnosis'] = $this->diagnoses->filter(function ($diagnosis) {
|
||||||
$data['secondary_diagnosis'] = $this->diagnoses->filter(function($diagnosis){ return $diagnosis->type == 'secondary';})->values();
|
return $diagnosis->type == 'primary';
|
||||||
|
})->values();
|
||||||
|
$data['secondary_diagnosis'] = $this->diagnoses->filter(function ($diagnosis) {
|
||||||
|
return $diagnosis->type == 'secondary';
|
||||||
|
})->values();
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|||||||
81
Modules/Client/Transformers/DataMemberResource.php
Normal file
81
Modules/Client/Transformers/DataMemberResource.php
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\Client\Transformers;
|
||||||
|
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class DataMemberResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function toArray($request)
|
||||||
|
{
|
||||||
|
// return parent::toArray($request);
|
||||||
|
$data = [
|
||||||
|
'id' => $this->id,
|
||||||
|
'person_id' => $this->person_id,
|
||||||
|
'user_id' => $this->user_id,
|
||||||
|
'member_id' => $this->member_id,
|
||||||
|
'payor_id' => $this->payor_id,
|
||||||
|
'name_prefix' => $this->name_prefix,
|
||||||
|
'name' => $this->name,
|
||||||
|
'name_suffix' => $this->name_suffix,
|
||||||
|
'birth_date' => $this->birth_date,
|
||||||
|
'gender' => $this->gender,
|
||||||
|
'language' => $this->language,
|
||||||
|
'race' => $this->race,
|
||||||
|
'marital_status' => $this->marital_status,
|
||||||
|
'record_type' => $this->record_type,
|
||||||
|
'principal_id' => $this->principal_id,
|
||||||
|
'relation_with_principal' => $this->relation_with_principal,
|
||||||
|
'bpjs_class' => $this->bpjs_class,
|
||||||
|
'nric' => $this->nric,
|
||||||
|
'email' => $this->email,
|
||||||
|
'bank_info' => $this->bank_info,
|
||||||
|
'agent_code' => $this->agent_code,
|
||||||
|
'address1' => $this->address1,
|
||||||
|
'address2' => $this->address2,
|
||||||
|
'address3' => $this->address3,
|
||||||
|
'address4' => $this->address4,
|
||||||
|
'city' => $this->city,
|
||||||
|
'state' => $this->state,
|
||||||
|
'postal_code' => $this->postal_code,
|
||||||
|
'record_mode' => $this->record_mode,
|
||||||
|
'telephone_mobile' => $this->telephone_mobile,
|
||||||
|
'telephone_res' => $this->telephone_res,
|
||||||
|
'telephone_office' => $this->telephone_office,
|
||||||
|
'passport_no' => $this->passport_no,
|
||||||
|
'passport_country' => $this->passport_country,
|
||||||
|
'identification_code' => $this->identification_code,
|
||||||
|
'pre_existing' => $this->pre_existing,
|
||||||
|
'bpjs_id' => $this->bpjs_id,
|
||||||
|
'endorsement_date' => $this->endorsement_date,
|
||||||
|
'members_effective_date' => $this->members_effective_date,
|
||||||
|
'members_expire_date' => $this->members_expire_date,
|
||||||
|
'activation_date' => $this->activation_date,
|
||||||
|
'terminated_date' => $this->terminated_date,
|
||||||
|
'remarks' => $this->remarks,
|
||||||
|
'policy_in_force' => $this->policy_in_force,
|
||||||
|
'start_no_claim' => $this->start_no_claim,
|
||||||
|
'end_no_claim' => $this->end_no_claim,
|
||||||
|
'active' => $this->active,
|
||||||
|
'reason' => $this->reason,
|
||||||
|
'total_claims' => $this->total_claims,
|
||||||
|
'full_name' => $this->full_name,
|
||||||
|
'age' => $this->age,
|
||||||
|
'gender_code' => $this->gender_code,
|
||||||
|
'limit' => [
|
||||||
|
'current' => $this->total_claims ?? 0,
|
||||||
|
'total' => (int)$this->currentPlan->limit_rules ?? 0,
|
||||||
|
'percentage' => (!empty($this->currentPlan->limit_rules ?? 0)) ? (($this->total_claims / $this->currentPlan->limit_rules) * 100) : 0
|
||||||
|
],
|
||||||
|
'benefits' => $this->currentPlan->benefits,
|
||||||
|
|
||||||
|
];
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
21
Modules/HospitalPortal/Helpers/ApiResponse.php
Normal file
21
Modules/HospitalPortal/Helpers/ApiResponse.php
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\HospitalPortal\Helpers;
|
||||||
|
|
||||||
|
class ApiResponse
|
||||||
|
{
|
||||||
|
public static function apiResponse(string $status, array|object $data = null, string|array|object $message = null, int $statusCode)
|
||||||
|
{
|
||||||
|
if ($message instanceof \Illuminate\Support\MessageBag) {
|
||||||
|
$message = $message->first();
|
||||||
|
}
|
||||||
|
return response()->json([
|
||||||
|
'meta' => [
|
||||||
|
'status' => $status,
|
||||||
|
'code' => $statusCode,
|
||||||
|
'message' => $message
|
||||||
|
],
|
||||||
|
'data' => $data,
|
||||||
|
], $statusCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,33 +12,48 @@ use Illuminate\Support\Facades\Hash;
|
|||||||
use Illuminate\Support\Facades\Mail;
|
use Illuminate\Support\Facades\Mail;
|
||||||
use Modules\Internal\Emails\SendVerifyEmail;
|
use Modules\Internal\Emails\SendVerifyEmail;
|
||||||
use Modules\Internal\Events\ForgetPassword;
|
use Modules\Internal\Events\ForgetPassword;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use Modules\HospitalPortal\Helpers\ApiResponse;
|
||||||
|
|
||||||
class AuthController extends Controller
|
class AuthController extends Controller
|
||||||
{
|
{
|
||||||
public function login(Request $request)
|
public function login(Request $request)
|
||||||
{
|
{
|
||||||
$request->validate([
|
$data = [
|
||||||
|
'email' => $request->email,
|
||||||
|
'password' => $request->password
|
||||||
|
];
|
||||||
|
$validator = Validator::make($request->all(), [
|
||||||
'email' => 'required|email',
|
'email' => 'required|email',
|
||||||
'password' => 'required'
|
'password' => 'required'
|
||||||
|
], [
|
||||||
|
'email.required' => trans('validation.required',['attribute' => 'Email']),
|
||||||
|
'email.email' => trans('validation.email'),
|
||||||
|
'password.required' => trans('validation.required',['attribute' => 'Password']),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$user = User::query()
|
if ($validator->fails())
|
||||||
->where('email', $request->email)
|
{
|
||||||
->first();
|
return ApiResponse::apiResponse('Bad Request', $data, $validator->errors(), 400);
|
||||||
|
|
||||||
if (!$user) {
|
|
||||||
return response(['message' => 'User Tidak Ditemukan'], 404);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$user = User::where('email', $request->email)->first();
|
||||||
|
if (!$user) {
|
||||||
|
return ApiResponse::apiResponse('Not Found', $data, trans('message.not_found'), 404);
|
||||||
|
}
|
||||||
|
|
||||||
if (!Hash::check($request->password, $user->password)) {
|
if (!Hash::check($request->password, $user->password)) {
|
||||||
return response(['message' => 'Password Salah'], 403);
|
return ApiResponse::apiResponse('Bad Request', $data, trans('message.password'), 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
$res_data = [
|
||||||
|
'user' => $user,
|
||||||
|
'token' => $user->createToken('app')->plainTextToken
|
||||||
|
];
|
||||||
|
|
||||||
|
return ApiResponse::apiResponse("Success", $res_data, trans('message.success'), 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
return response([
|
|
||||||
'message' => 'Selamat Datang',
|
|
||||||
'user' => $user,
|
|
||||||
'token' => $user->createToken('app')->plainTextToken
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function logout(Request $request)
|
public function logout(Request $request)
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ class ClaimRequestController extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($request->hasFile('result_files')) {
|
if ($request->hasFile('kondisi_files')) {
|
||||||
foreach ($request->result_files as $file) {
|
foreach ($request->result_files as $file) {
|
||||||
$pathFile = File::storeFile('claim-kondisi', $newClaimRequest->id, $file);
|
$pathFile = File::storeFile('claim-kondisi', $newClaimRequest->id, $file);
|
||||||
$newClaimRequest->files()->updateOrCreate([
|
$newClaimRequest->files()->updateOrCreate([
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ use App\Models\Member;
|
|||||||
use Illuminate\Contracts\Support\Renderable;
|
use Illuminate\Contracts\Support\Renderable;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Routing\Controller;
|
use Illuminate\Routing\Controller;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use Modules\HospitalPortal\Helpers\ApiResponse;
|
||||||
|
|
||||||
class MemberController extends Controller
|
class MemberController extends Controller
|
||||||
{
|
{
|
||||||
@@ -16,26 +18,37 @@ class MemberController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function search(Request $request)
|
public function search(Request $request)
|
||||||
{
|
{
|
||||||
$request->validate([
|
$data = [
|
||||||
|
'no_polis' => $request->no_polis,
|
||||||
|
'birth_date' => $request->birth_date
|
||||||
|
];
|
||||||
|
$validator = Validator::make($request->all(), [
|
||||||
'no_polis' => 'required',
|
'no_polis' => 'required',
|
||||||
'birth_date' => 'required'
|
'birth_date' => 'required'
|
||||||
|
], [
|
||||||
|
'no_polis.required' => trans('validation.required',['attribute' => 'Member ID']),
|
||||||
|
'birth_date.required' => trans('validation.required',['attribute' => 'Birth Date']),
|
||||||
]);
|
]);
|
||||||
|
if ($validator->fails())
|
||||||
$member = Member::query()
|
{
|
||||||
->where('member_id', $request->no_polis)
|
return ApiResponse::apiResponse('Bad Request', $data, $validator->errors(), 400);
|
||||||
->where('birth_date', $request->birth_date)
|
}
|
||||||
->with(['person', 'currentCorporate',
|
else
|
||||||
// 'currentCorporate.corporateServices' => function ($corporateService) {
|
{
|
||||||
// $corporateService->where('status', 'active');
|
$res_data = Member::query()
|
||||||
// },
|
->where('member_id', $request->no_polis)
|
||||||
// 'currentCorporate.corporateServices.service'
|
->where('birth_date', $request->birth_date)
|
||||||
// 'currentPlan.benefits',
|
->with(['person', 'currentCorporate',
|
||||||
// 'currentPlan.corporateBenefit.plan',
|
// 'currentCorporate.corporateServices' => function ($corporateService) {
|
||||||
'currentPlan.corporateBenefits.benefit'
|
// $corporateService->where('status', 'active');
|
||||||
])
|
// },
|
||||||
->firstOrFail();
|
// 'currentCorporate.corporateServices.service'
|
||||||
|
// 'currentPlan.benefits',
|
||||||
|
// 'currentPlan.corporateBenefit.plan',
|
||||||
return Helper::responseJson($member);
|
'currentPlan.corporateBenefits.benefit'
|
||||||
|
])
|
||||||
|
->firstOrFail();
|
||||||
|
return ApiResponse::apiResponse("Success", $res_data, trans('message.success'), 200);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
65
Modules/HospitalPortal/Http/Middleware/Authentication.php
Normal file
65
Modules/HospitalPortal/Http/Middleware/Authentication.php
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\HospitalPortal\Http\Middleware;
|
||||||
|
use Modules\HospitalPortal\Helpers\ApiResponse;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Illuminate\Support\Facades\App;
|
||||||
|
|
||||||
|
class Authentication
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Handle an incoming request.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
|
||||||
|
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
|
||||||
|
*/
|
||||||
|
public function handle(Request $request, Closure $next)
|
||||||
|
{
|
||||||
|
$acceptHeader = $request->header('Accept');
|
||||||
|
$contentType = $request->header('Content-Type');
|
||||||
|
$locale = $request->header('Accept-Language');
|
||||||
|
|
||||||
|
// Add language
|
||||||
|
if(!$locale)
|
||||||
|
{
|
||||||
|
return ApiResponse::apiResponse('Unauthorized', null, trans('validation.required', ['attribute' => 'Accept-Language']), 401);
|
||||||
|
}
|
||||||
|
if($locale !== 'en-US' && $locale !== 'id-ID')
|
||||||
|
{
|
||||||
|
return ApiResponse::apiResponse('Bad Request', null, trans('validation.invalid', ['attribute' => 'Accept-Language']), 400);
|
||||||
|
}
|
||||||
|
if ($locale === 'en-US')
|
||||||
|
{
|
||||||
|
App::setLocale('en');
|
||||||
|
} elseif ($locale === 'id-ID')
|
||||||
|
{
|
||||||
|
App::setLocale('id');
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
App::setLocale('en');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate type accept & content type
|
||||||
|
if (!$acceptHeader)
|
||||||
|
{
|
||||||
|
return ApiResponse::apiResponse('Unauthorized', null, trans('validation.required', ['attribute' => 'Accept']), 401);
|
||||||
|
}
|
||||||
|
if (!$contentType)
|
||||||
|
{
|
||||||
|
return ApiResponse::apiResponse('Unauthorized', null, trans('validation.required', ['attribute' => 'Content-Type']), 401);
|
||||||
|
}
|
||||||
|
if ($acceptHeader !== 'application/json')
|
||||||
|
{
|
||||||
|
return ApiResponse::apiResponse('Bad Request', null, trans('validation.invalid', ['attribute' => 'Accept']), 400);
|
||||||
|
}
|
||||||
|
if($contentType !== 'application/json')
|
||||||
|
{
|
||||||
|
return ApiResponse::apiResponse('Bad Request', null, trans('validation.invalid', ['attribute' => 'Content-Type']), 400);
|
||||||
|
}
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
}
|
||||||
71
Modules/HospitalPortal/Http/Middleware/Authorization.php
Normal file
71
Modules/HospitalPortal/Http/Middleware/Authorization.php
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\HospitalPortal\Http\Middleware;
|
||||||
|
use Modules\HospitalPortal\Helpers\ApiResponse;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Illuminate\Support\Facades\App;
|
||||||
|
|
||||||
|
class Authorization
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Handle an incoming request.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
|
||||||
|
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
|
||||||
|
*/
|
||||||
|
public function handle(Request $request, Closure $next)
|
||||||
|
{
|
||||||
|
$acceptHeader = $request->header('Accept');
|
||||||
|
$contentType = $request->header('Content-Type');
|
||||||
|
$locale = $request->header('Accept-Language');
|
||||||
|
$authorization = $request->header('Authorization');
|
||||||
|
|
||||||
|
// Add language
|
||||||
|
if(!$locale)
|
||||||
|
{
|
||||||
|
return ApiResponse::apiResponse('Unauthorized', null, trans('validation.required', ['attribute' => 'Accept-Language']), 401);
|
||||||
|
}
|
||||||
|
if($locale !== 'en-US' && $locale !== 'id-ID')
|
||||||
|
{
|
||||||
|
return ApiResponse::apiResponse('Bad Request', null, trans('validation.invalid', ['attribute' => 'Accept-Language']), 400);
|
||||||
|
}
|
||||||
|
if ($locale === 'en-US')
|
||||||
|
{
|
||||||
|
App::setLocale('en');
|
||||||
|
} elseif ($locale === 'id-ID')
|
||||||
|
{
|
||||||
|
App::setLocale('id');
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
App::setLocale('en');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate authorization
|
||||||
|
if (empty($authorization) || strpos($authorization, 'Bearer ') !== 0) {
|
||||||
|
return ApiResponse::apiResponse('Unauthorized', null, trans('validation.required', ['attribute' => 'Authorization']), 401);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate type accept & content type
|
||||||
|
if (!$acceptHeader)
|
||||||
|
{
|
||||||
|
return ApiResponse::apiResponse('Unauthorized', null, trans('validation.required', ['attribute' => 'Accept']), 401);
|
||||||
|
}
|
||||||
|
if (!$contentType)
|
||||||
|
{
|
||||||
|
return ApiResponse::apiResponse('Unauthorized', null, trans('validation.required', ['attribute' => 'Content-Type']), 401);
|
||||||
|
}
|
||||||
|
if ($acceptHeader !== 'application/json')
|
||||||
|
{
|
||||||
|
return ApiResponse::apiResponse('Bad Request', null, trans('validation.invalid', ['attribute' => 'Accept']), 400);
|
||||||
|
}
|
||||||
|
if($contentType !== 'application/json')
|
||||||
|
{
|
||||||
|
return ApiResponse::apiResponse('Bad Request', null, trans('validation.invalid', ['attribute' => 'Content-Type']), 400);
|
||||||
|
}
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,8 @@ use Modules\HospitalPortal\Http\Controllers\Api\AuthController;
|
|||||||
use Modules\HospitalPortal\Http\Controllers\Api\ClaimRequestController;
|
use Modules\HospitalPortal\Http\Controllers\Api\ClaimRequestController;
|
||||||
use Modules\HospitalPortal\Http\Controllers\Api\MemberController;
|
use Modules\HospitalPortal\Http\Controllers\Api\MemberController;
|
||||||
use Modules\HospitalPortal\Http\Controllers\ClaimController;
|
use Modules\HospitalPortal\Http\Controllers\ClaimController;
|
||||||
|
use Modules\HospitalPortal\Http\Middleware\Authentication;
|
||||||
|
use Modules\HospitalPortal\Http\Middleware\Authorization;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
@@ -16,29 +18,39 @@ use Modules\HospitalPortal\Http\Controllers\ClaimController;
|
|||||||
| is assigned the "api" middleware group. Enjoy building your API!
|
| is assigned the "api" middleware group. Enjoy building your API!
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
Route::prefix('v1')->group(function() {
|
||||||
|
Route::prefix('hospitalportal')->group(function () {
|
||||||
|
|
||||||
Route::prefix('hospitalportal')->group(function () {
|
Route::middleware(Authentication::class)->group(function () {
|
||||||
|
Route::controller(AuthController::class)->group(function () {
|
||||||
Route::post('login', [AuthController::class, 'login'])->name('login');
|
Route::post('login', 'login');
|
||||||
Route::post('forget-password', [AuthController::class, 'forgetPassword'])->name('forget-password');
|
});
|
||||||
Route::post('verify-email', [AuthController::class, 'verifyEmail'])->name('verify-email');
|
|
||||||
|
|
||||||
|
|
||||||
Route::middleware('auth:sanctum')->group(function () {
|
|
||||||
|
|
||||||
Route::post('logout', [AuthController::class, 'logout'])->name('logout');
|
|
||||||
Route::get('/user', function (Request $request) {
|
|
||||||
return $request->user();
|
|
||||||
});
|
});
|
||||||
Route::put('reset-password', [AuthController::class, 'resetPassword'])->name('resetPassword');
|
|
||||||
|
//Route::post('forget-password', [AuthController::class, 'forgetPassword'])->name('forget-password');
|
||||||
|
//Route::post('verify-email', [AuthController::class, 'verifyEmail'])->name('verify-email');
|
||||||
|
|
||||||
Route::get('claims', [ClaimController::class, 'index']);
|
|
||||||
|
|
||||||
Route::post('search-member', [MemberController::class, 'search']);
|
Route::middleware('auth:sanctum')->group(function () {
|
||||||
|
|
||||||
Route::get('claim-requests', [ClaimRequestController::class, 'index'])->name('claim-requests.index');
|
Route::post('logout', [AuthController::class, 'logout'])->name('logout');
|
||||||
Route::post('claim-requests', [ClaimRequestController::class, 'store'])->name('claim-requests.store');
|
Route::get('/user', function (Request $request) {
|
||||||
Route::get('claim-requests/{claim_request_id}/log', [ClaimRequestController::class, 'generateLog'])->name('claim-requests.generate-log');
|
return $request->user();
|
||||||
Route::get('claim-requests/{id}', [ClaimRequestController::class, 'show'])->name('claim-requests.show');
|
});
|
||||||
|
Route::put('reset-password', [AuthController::class, 'resetPassword'])->name('resetPassword');
|
||||||
|
|
||||||
|
Route::get('claims', [ClaimController::class, 'index']);
|
||||||
|
|
||||||
|
Route::middleware(Authorization::class)->group(function () {
|
||||||
|
Route::controller(MemberController::class)->group(function () {
|
||||||
|
Route::post('search-member', 'search');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
Route::get('claim-requests', [ClaimRequestController::class, 'index'])->name('claim-requests.index');
|
||||||
|
Route::post('claim-requests', [ClaimRequestController::class, 'store'])->name('claim-requests.store');
|
||||||
|
Route::get('claim-requests/{claim_request_id}/log', [ClaimRequestController::class, 'generateLog'])->name('claim-requests.generate-log');
|
||||||
|
Route::get('claim-requests/{id}', [ClaimRequestController::class, 'show'])->name('claim-requests.show');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ use Illuminate\Http\Request;
|
|||||||
use Illuminate\Routing\Controller;
|
use Illuminate\Routing\Controller;
|
||||||
use Modules\Internal\Transformers\ClaimRequestResource;
|
use Modules\Internal\Transformers\ClaimRequestResource;
|
||||||
use Modules\Internal\Transformers\ClaimRequestShowResource;
|
use Modules\Internal\Transformers\ClaimRequestShowResource;
|
||||||
|
use App\Models\File;
|
||||||
|
use App\Models\FilesMcu;
|
||||||
|
|
||||||
class ClaimRequestController extends Controller
|
class ClaimRequestController extends Controller
|
||||||
{
|
{
|
||||||
@@ -140,4 +142,29 @@ class ClaimRequestController extends Controller
|
|||||||
return $claimRequest;
|
return $claimRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function filesMcu(Request $request)
|
||||||
|
{
|
||||||
|
$request->validate([
|
||||||
|
'id' => 'required',
|
||||||
|
'memberid' => 'required'
|
||||||
|
]);
|
||||||
|
if ($request->hasFile('result_files')) {
|
||||||
|
$pathFile = File::storeFile('claim-result', $request->id, $request->result_files);
|
||||||
|
$data = [
|
||||||
|
'memberid' => $request->id,
|
||||||
|
'original_name' => $request->result_files->getClientOriginalName(),
|
||||||
|
'path' => $pathFile,
|
||||||
|
'created_by' => auth()->user()->id,
|
||||||
|
'updated_by' => auth()->user()->id
|
||||||
|
];
|
||||||
|
FilesMcu::create($data);
|
||||||
|
return Helper::responseJson(data: $request->toArray(), message: 'Berhasil tambah file MemberID '.$request->memberid.', silahkan lihat dilaporan');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Helper::responseJson(data: $request->toArray(), message: 'Tidak ada file member yang ditambahkan');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ use Illuminate\Routing\Controller;
|
|||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
use Modules\Internal\Services\MemberEnrollmentService;
|
use Modules\Internal\Services\MemberEnrollmentService;
|
||||||
use PDF;
|
use PDF;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
class CorporateMemberController extends Controller
|
class CorporateMemberController extends Controller
|
||||||
{
|
{
|
||||||
@@ -34,9 +35,6 @@ class CorporateMemberController extends Controller
|
|||||||
$members = Member::query()
|
$members = Member::query()
|
||||||
->filter($request->all())
|
->filter($request->all())
|
||||||
// ->where('corporate_id', $corporate_id)
|
// ->where('corporate_id', $corporate_id)
|
||||||
->whereHas('employeds', function ($employeds) use ($corporate_id) {
|
|
||||||
$employeds->where('corporate_id', $corporate_id);
|
|
||||||
})
|
|
||||||
->with([
|
->with([
|
||||||
'employeds',
|
'employeds',
|
||||||
'currentPolicy',
|
'currentPolicy',
|
||||||
|
|||||||
@@ -263,7 +263,7 @@ class ClaimEncounterController extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function x`counters($claim_id)
|
public function xcounters($claim_id)
|
||||||
{
|
{
|
||||||
$claim = Claim::findOrFail($claim_id);
|
$claim = Claim::findOrFail($claim_id);
|
||||||
$encounters = $claim->encounters()->get();
|
$encounters = $claim->encounters()->get();
|
||||||
|
|||||||
@@ -158,7 +158,9 @@ Route::prefix('internal')->group(function () {
|
|||||||
Route::resource('doctors', DoctorController::class);
|
Route::resource('doctors', DoctorController::class);
|
||||||
|
|
||||||
Route::post('generate-log/{member_id}', [CorporateMemberController::class, 'generateLog']);
|
Route::post('generate-log/{member_id}', [CorporateMemberController::class, 'generateLog']);
|
||||||
|
Route::controller(ClaimRequestController::class)->group(function(){
|
||||||
|
Route::post('files-mcu','filesMcu');
|
||||||
|
});
|
||||||
Route::get('claim-requests', [ClaimRequestController::class, 'index'])->name('claim-requests.index');
|
Route::get('claim-requests', [ClaimRequestController::class, 'index'])->name('claim-requests.index');
|
||||||
Route::post('claim-requests/{id}/approve', [ClaimRequestController::class, 'approve'])->name('claim-requests.approve');
|
Route::post('claim-requests/{id}/approve', [ClaimRequestController::class, 'approve'])->name('claim-requests.approve');
|
||||||
Route::get('claim-requests/{id}', [ClaimRequestController::class, 'show'])->name('claim-requests.show');
|
Route::get('claim-requests/{id}', [ClaimRequestController::class, 'show'])->name('claim-requests.show');
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
|
|
||||||
namespace App\Http\Middleware;
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
use Illuminate\Auth\Middleware\Authenticate as Middleware;
|
use Illuminate\Auth\Middleware\Authenticate as Middleware;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
class Authenticate extends Middleware
|
class Authenticate extends Middleware
|
||||||
{
|
{
|
||||||
@@ -18,4 +20,13 @@ class Authenticate extends Middleware
|
|||||||
return route('login');
|
return route('login');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function handle($request, Closure $next, ...$guards)
|
||||||
|
{
|
||||||
|
if (Auth::guard('sanctum')->guest()) {
|
||||||
|
return response()->json(['error' => 'Bearer Authorization is required'], 401);
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::handle($request, $next, ...$guards);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
14
app/Models/FilesMcu.php
Normal file
14
app/Models/FilesMcu.php
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class FilesMcu extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
protected $table = 'files_mcu';
|
||||||
|
protected $primaryKey = 'id';
|
||||||
|
protected $fillable = ['memberid', 'original_name', 'path', 'created_by','updated_by', 'created_at', 'updated_at'];
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('files_mcu', function (Blueprint $table) {
|
||||||
|
$table->increments('id');
|
||||||
|
$table->bigInteger('memberid');
|
||||||
|
$table->string('original_name', 255);
|
||||||
|
$table->string('path', 255);
|
||||||
|
$table->bigInteger('created_by');
|
||||||
|
$table->bigInteger('updated_by');
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('files_mcu');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -21,8 +21,7 @@ import { useState, SyntheticEvent, useContext, useEffect } from 'react';
|
|||||||
import { UserCurrentCorporateContext } from '../../contexts/UserCurrentCorporate';
|
import { UserCurrentCorporateContext } from '../../contexts/UserCurrentCorporate';
|
||||||
import { useNavigate, useParams } from 'react-router-dom';
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
import axios from '../../utils/axios';
|
import axios from '../../utils/axios';
|
||||||
|
import { fDate } from '../../utils/formatTime';
|
||||||
|
|
||||||
|
|
||||||
// sections
|
// sections
|
||||||
// import ListTable from '../../sections/claimreports/ListTable';
|
// import ListTable from '../../sections/claimreports/ListTable';
|
||||||
@@ -107,69 +106,70 @@ const StyledTab = styled((props: StyledTabProps) => <Tab disableRipple {...props
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default function ServiceMonitoring() {
|
export default function ServiceMonitoring() {
|
||||||
const { themeStretch } = useSettings();
|
const { themeStretch } = useSettings();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
|
||||||
const [value, setValue] = useState(0);
|
const [value, setValue] = useState(0);
|
||||||
const handleChange = (event: SyntheticEvent, newValue: number) => {
|
const handleChange = (event: SyntheticEvent, newValue: number) => {
|
||||||
setValue(newValue);
|
setValue(newValue);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const [data, setData] = useState({});
|
const [data, setData] = useState({});
|
||||||
const [data1, setData1] = useState();
|
const [corporate, setCorporate] = useState();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const {corporateValue} = useContext(UserCurrentCorporateContext);
|
const { corporateValue } = useContext(UserCurrentCorporateContext);
|
||||||
const {id} = useParams();
|
const { id } = useParams();
|
||||||
const claimId = '2'
|
const claimId = '2';
|
||||||
console.log('id',id);
|
console.log('id', id);
|
||||||
|
|
||||||
useEffect (() => {
|
useEffect(() => {
|
||||||
|
console.log('fetching data...');
|
||||||
console.log('fetching data...')
|
axios
|
||||||
axios.get('/data/'+id )
|
.get('/data/' + id)
|
||||||
.then(response => {
|
.then((response) => {
|
||||||
console.log('data fetched...', response.data)
|
console.log('data fetched...', response.data);
|
||||||
setData(response.data);
|
setData(response.data);
|
||||||
|
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error) => {
|
||||||
console.error('error fetching data...', error);
|
console.error('error fetching data...', error);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
axios
|
||||||
|
.get('/corporate-manage/' + corporateValue)
|
||||||
|
.then((response) => {
|
||||||
|
console.log('corporate fetched...', response.data);
|
||||||
|
setCorporate(response.data);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('error fetching corporate...', error);
|
||||||
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
console.log('Data:' , data);
|
console.log('Data:', data);
|
||||||
|
|
||||||
const [encounterData, setEncounterData] = useState({});
|
const [encounterData, setEncounterData] = useState({});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log('fetching encounter data...');
|
console.log('fetching encounter data...');
|
||||||
axios.get('/claims/${claim_id}/encounters')
|
axios
|
||||||
.then(response => {
|
.get('/claims/${claim_id}/encounters')
|
||||||
|
.then((response) => {
|
||||||
console.log('encounter data fetched...', response.data);
|
console.log('encounter data fetched...', response.data);
|
||||||
setEncounterData(response.data);
|
setEncounterData(response.data);
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error) => {
|
||||||
console.error('error fetching encounter data...', error);
|
console.error('error fetching encounter data...', error);
|
||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Page title="Service Monitoring 123456">
|
<Page title="Service Monitoring 123456">
|
||||||
<Container maxWidth={themeStretch ? false : 'xl'}>
|
<Container maxWidth={themeStretch ? false : 'xl'}>
|
||||||
<Stack direction="row" alignItems="center" sx={{ marginBottom: 2 }}>
|
<Stack direction="row" alignItems="center" sx={{ marginBottom: 2 }}>
|
||||||
<IconButton onClick={() =>
|
<IconButton
|
||||||
navigate('/alarm-center')
|
onClick={() => navigate('/alarm-center')}
|
||||||
}
|
sx={{ marginRight: '10px', color: '#424242' }}
|
||||||
sx={{ marginRight: '10px', color: '#424242' }}>
|
>
|
||||||
<Iconify icon="heroicons-outline:arrow-narrow-left" />
|
<Iconify icon="heroicons-outline:arrow-narrow-left" />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<Typography variant="h5">Service Monitoring</Typography>
|
<Typography variant="h5">Service Monitoring</Typography>
|
||||||
@@ -206,23 +206,25 @@ export default function ServiceMonitoring() {
|
|||||||
<Stack spacing={2}>
|
<Stack spacing={2}>
|
||||||
<Stack>
|
<Stack>
|
||||||
<Typography variant="caption">Nama perusahaan</Typography>
|
<Typography variant="caption">Nama perusahaan</Typography>
|
||||||
<Typography variant="body2">{corporateValue}</Typography>
|
<Typography variant="body2">{corporate?.name}</Typography>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack>
|
<Stack>
|
||||||
<Typography variant="caption">Nama Lengkap</Typography>
|
<Typography variant="caption">Nama Lengkap</Typography>
|
||||||
<Typography variant="body2">{data.name || 'Loading...'}</Typography>
|
<Typography variant="body2">{data?.name || 'Loading...'}</Typography>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack>
|
<Stack>
|
||||||
<Typography variant="caption">Tanggal lahir</Typography>
|
<Typography variant="caption">Tanggal lahir</Typography>
|
||||||
<Typography variant="body2">{data.birth_date}</Typography>
|
<Typography variant="body2">
|
||||||
|
{data?.birth_date ? fDate(data?.birth_date) : ''}
|
||||||
|
</Typography>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack>
|
<Stack>
|
||||||
<Typography variant="caption">Email</Typography>
|
<Typography variant="caption">Email</Typography>
|
||||||
<Typography variant="body2">{data.email}</Typography>
|
<Typography variant="body2">{data?.email}</Typography>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack>
|
<Stack>
|
||||||
<Typography variant="caption">No telepon</Typography>
|
<Typography variant="caption">No telepon</Typography>
|
||||||
<Typography variant="body2">{data.phone}</Typography>
|
<Typography variant="body2">{data?.phone}</Typography>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack>
|
<Stack>
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ import { useEffect, useState, useContext } from 'react';
|
|||||||
import axios from '../../utils/axios';
|
import axios from '../../utils/axios';
|
||||||
import { UserCurrentCorporateContext } from '../../contexts/UserCurrentCorporate';
|
import { UserCurrentCorporateContext } from '../../contexts/UserCurrentCorporate';
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
export default function UserProfile() {
|
export default function UserProfile() {
|
||||||
@@ -27,23 +26,21 @@ export default function UserProfile() {
|
|||||||
const [data, setData] = useState();
|
const [data, setData] = useState();
|
||||||
const [data1, setData1] = useState();
|
const [data1, setData1] = useState();
|
||||||
|
|
||||||
|
const { corporateValue } = useContext(UserCurrentCorporateContext);
|
||||||
|
const { id } = useParams();
|
||||||
|
|
||||||
const {corporateValue} = useContext(UserCurrentCorporateContext);
|
useEffect(() => {
|
||||||
const {id} = useParams();
|
axios
|
||||||
|
.get(corporateValue + '/members/' + id)
|
||||||
useEffect (() => {
|
.then((response) => {
|
||||||
axios.get('/data/'+id )
|
|
||||||
.then(response => {
|
|
||||||
setData(response.data);
|
setData(response.data);
|
||||||
|
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error) => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
console.log('data', data)
|
console.log('data', data);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Page title="Profile Peserta Jessica Lie">
|
<Page title="Profile Peserta Jessica Lie">
|
||||||
@@ -52,7 +49,7 @@ export default function UserProfile() {
|
|||||||
{/* <IconButton sx={{ marginRight: '10px', color: '#424242' }} onClick={() => navigate()}>
|
{/* <IconButton sx={{ marginRight: '10px', color: '#424242' }} onClick={() => navigate()}>
|
||||||
<Iconify icon="heroicons-outline:arrow-narrow-left" />
|
<Iconify icon="heroicons-outline:arrow-narrow-left" />
|
||||||
</IconButton> */}
|
</IconButton> */}
|
||||||
<ButtonBack/>
|
<ButtonBack />
|
||||||
<Typography variant="h5">Profil Peserta</Typography>
|
<Typography variant="h5">Profil Peserta</Typography>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Grid container spacing={2}>
|
<Grid container spacing={2}>
|
||||||
@@ -74,7 +71,7 @@ export default function UserProfile() {
|
|||||||
<Grid container spacing={2}>
|
<Grid container spacing={2}>
|
||||||
{/* Item 1 */}
|
{/* Item 1 */}
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<CardPolicyNumber />
|
<CardPolicyNumber data={data} />
|
||||||
</Grid>
|
</Grid>
|
||||||
{/* Item 2 */}
|
{/* Item 2 */}
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
|
|||||||
@@ -278,7 +278,7 @@ export default function Index() {
|
|||||||
params: { ...parameters },
|
params: { ...parameters },
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log('member',corporateMembers );
|
console.log('member', corporateMembers);
|
||||||
const corporateTopUpLimit = await axios.get(`${corporateValue}/topup`);
|
const corporateTopUpLimit = await axios.get(`${corporateValue}/topup`);
|
||||||
|
|
||||||
setSearchParams(parameters);
|
setSearchParams(parameters);
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import {
|
|||||||
linearProgressClasses,
|
linearProgressClasses,
|
||||||
Grid,
|
Grid,
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
import { description } from '../../../../../dashboard/src/_mock/text';
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -25,203 +27,49 @@ const BorderLinearProgress = styled(LinearProgress)(({ theme }) => ({
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
export default function CardBenefitSummary() {
|
export default function CardBenefitSummary({ data }) {
|
||||||
|
const [benefits, setBenefits] = useState([]);
|
||||||
|
console.log('data', data);
|
||||||
|
useEffect(() => {
|
||||||
|
setBenefits(data);
|
||||||
|
}, [data]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ marginTop: '1rem' }}>
|
<div style={{ marginTop: '1rem' }}>
|
||||||
<Typography padding={1} variant="subtitle2">
|
<Typography padding={1} variant="subtitle2">
|
||||||
Benefit Summary
|
Benefit Summary
|
||||||
</Typography>
|
</Typography>
|
||||||
<Card>
|
<Card>
|
||||||
|
{/* {Object.entries(benefits?.data).map(([key, value]) => (
|
||||||
|
<div key={key}>
|
||||||
|
<span>Haloo</span>
|
||||||
|
</div>
|
||||||
|
))} */}
|
||||||
|
|
||||||
<Grid container spacing={1} marginTop={1} sx={{ backgroundColor: '#F4F6F8', padding: 1 }}>
|
<Grid container spacing={1} marginTop={1} sx={{ backgroundColor: '#F4F6F8', padding: 1 }}>
|
||||||
{/* Card 1 */}
|
{/* Card 1 */}
|
||||||
<Grid item xs={12} sm={6} md={6} lg={4}>
|
{benefits?.map((item, key) => (
|
||||||
<Card sx={{ padding: 1 }}>
|
<Grid item xs={12} sm={6} md={6} lg={4} key={key}>
|
||||||
<Stack spacing={1}>
|
<Card sx={{ padding: 1 }}>
|
||||||
<Typography variant="subtitle2" sx={{ fontWeight: 500 }}>
|
<Stack spacing={1}>
|
||||||
Rawat Jalan
|
<Typography variant="subtitle2" sx={{ fontWeight: 500 }}>
|
||||||
</Typography>
|
{item?.description}
|
||||||
<Typography variant="body2" color="#0A0A0A">
|
|
||||||
Yearly Limits
|
|
||||||
</Typography>
|
|
||||||
<BorderLinearProgress variant="determinate" value={100} />
|
|
||||||
<Stack direction="row" spacing={0.25}>
|
|
||||||
<Typography variant="body2">10.000.000</Typography>
|
|
||||||
<Typography>/</Typography>
|
|
||||||
<Typography variant="body2" color="#757575">
|
|
||||||
10.000.000
|
|
||||||
</Typography>
|
</Typography>
|
||||||
</Stack>
|
<Typography variant="body2" color="#0A0A0A">
|
||||||
</Stack>
|
Yearly Limits
|
||||||
</Card>
|
|
||||||
</Grid>
|
|
||||||
{/* Card 2 */}
|
|
||||||
<Grid item xs={12} sm={6} md={6} lg={4}>
|
|
||||||
<Card sx={{ padding: 1 }}>
|
|
||||||
<Stack spacing={1}>
|
|
||||||
<Typography variant="subtitle2" sx={{ fontWeight: 500 }}>
|
|
||||||
Rawat Inap
|
|
||||||
</Typography>
|
|
||||||
<Typography variant="body2" color="#0A0A0A">
|
|
||||||
Yearly Limits
|
|
||||||
</Typography>
|
|
||||||
<BorderLinearProgress variant="determinate" value={100} />
|
|
||||||
<Stack direction="row" spacing={0.25}>
|
|
||||||
<Typography variant="body2">10.000.000</Typography>
|
|
||||||
<Typography>/</Typography>
|
|
||||||
<Typography variant="body2" color="#757575">
|
|
||||||
10.000.000
|
|
||||||
</Typography>
|
</Typography>
|
||||||
|
<BorderLinearProgress variant="determinate" value={100} />
|
||||||
|
<Stack direction="row" spacing={0.25}>
|
||||||
|
<Typography variant="body2">0</Typography>
|
||||||
|
<Typography>/</Typography>
|
||||||
|
<Typography variant="body2" color="#757575">
|
||||||
|
{item?.pivot['limit_amount']}
|
||||||
|
</Typography>
|
||||||
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Card>
|
||||||
</Card>
|
</Grid>
|
||||||
</Grid>
|
))}
|
||||||
{/* Card 3 */}
|
|
||||||
<Grid item xs={12} sm={6} md={6} lg={4}>
|
|
||||||
<Card sx={{ padding: 1 }}>
|
|
||||||
<Stack spacing={1}>
|
|
||||||
<Typography variant="subtitle2" sx={{ fontWeight: 500 }}>
|
|
||||||
Manfaat Special
|
|
||||||
</Typography>
|
|
||||||
<Typography variant="body2" color="#0A0A0A">
|
|
||||||
Yearly Limits
|
|
||||||
</Typography>
|
|
||||||
<BorderLinearProgress variant="determinate" value={100} />
|
|
||||||
<Stack direction="row" spacing={0.25}>
|
|
||||||
<Typography variant="body2">10.000.000</Typography>
|
|
||||||
<Typography>/</Typography>
|
|
||||||
<Typography variant="body2" color="#757575">
|
|
||||||
10.000.000
|
|
||||||
</Typography>
|
|
||||||
</Stack>
|
|
||||||
</Stack>
|
|
||||||
</Card>
|
|
||||||
</Grid>
|
|
||||||
{/* Card 4 */}
|
|
||||||
<Grid item xs={12} sm={6} md={6} lg={4}>
|
|
||||||
<Card sx={{ padding: 1 }}>
|
|
||||||
<Stack spacing={1}>
|
|
||||||
<Typography variant="subtitle2" sx={{ fontWeight: 500 }}>
|
|
||||||
Manfaat Special
|
|
||||||
</Typography>
|
|
||||||
<Typography variant="body2" color="#0A0A0A">
|
|
||||||
Yearly Limits
|
|
||||||
</Typography>
|
|
||||||
<BorderLinearProgress variant="determinate" value={100} />
|
|
||||||
<Stack direction="row" spacing={0.25}>
|
|
||||||
<Typography variant="body2">10.000.000</Typography>
|
|
||||||
<Typography>/</Typography>
|
|
||||||
<Typography variant="body2" color="#757575">
|
|
||||||
10.000.000
|
|
||||||
</Typography>
|
|
||||||
</Stack>
|
|
||||||
</Stack>
|
|
||||||
</Card>
|
|
||||||
</Grid>
|
|
||||||
{/* Card 5 */}
|
|
||||||
<Grid item xs={12} sm={6} md={6} lg={4}>
|
|
||||||
<Card sx={{ padding: 1 }}>
|
|
||||||
<Stack spacing={1}>
|
|
||||||
<Typography variant="subtitle2" sx={{ fontWeight: 500 }}>
|
|
||||||
Perobatan Mata
|
|
||||||
</Typography>
|
|
||||||
<Typography variant="body2" color="#0A0A0A">
|
|
||||||
Yearly Limits
|
|
||||||
</Typography>
|
|
||||||
<BorderLinearProgress variant="determinate" value={100} />
|
|
||||||
<Stack direction="row" spacing={0.25}>
|
|
||||||
<Typography variant="body2">10.000.000</Typography>
|
|
||||||
<Typography>/</Typography>
|
|
||||||
<Typography variant="body2" color="#757575">
|
|
||||||
10.000.000
|
|
||||||
</Typography>
|
|
||||||
</Stack>
|
|
||||||
</Stack>
|
|
||||||
</Card>
|
|
||||||
</Grid>
|
|
||||||
{/* Card 6 */}
|
|
||||||
<Grid item xs={12} sm={6} md={6} lg={4}>
|
|
||||||
<Card sx={{ padding: 1 }}>
|
|
||||||
<Stack spacing={1}>
|
|
||||||
<Typography variant="subtitle2" sx={{ fontWeight: 500 }}>
|
|
||||||
Perawatan Gigi
|
|
||||||
</Typography>
|
|
||||||
<Typography variant="body2" color="#0A0A0A">
|
|
||||||
Yearly Limits
|
|
||||||
</Typography>
|
|
||||||
<BorderLinearProgress variant="determinate" value={100} />
|
|
||||||
<Stack direction="row" spacing={0.25}>
|
|
||||||
<Typography variant="body2">10.000.000</Typography>
|
|
||||||
<Typography>/</Typography>
|
|
||||||
<Typography variant="body2" color="#757575">
|
|
||||||
10.000.000
|
|
||||||
</Typography>
|
|
||||||
</Stack>
|
|
||||||
</Stack>
|
|
||||||
</Card>
|
|
||||||
</Grid>
|
|
||||||
{/* Card 7 */}
|
|
||||||
<Grid item xs={12} sm={6} md={6} lg={4}>
|
|
||||||
<Card sx={{ padding: 1 }}>
|
|
||||||
<Stack spacing={1}>
|
|
||||||
<Typography variant="subtitle2" sx={{ fontWeight: 500 }}>
|
|
||||||
Kehamilan
|
|
||||||
</Typography>
|
|
||||||
<Typography variant="body2" color="#0A0A0A">
|
|
||||||
Yearly Limits
|
|
||||||
</Typography>
|
|
||||||
<BorderLinearProgress variant="determinate" value={100} />
|
|
||||||
<Stack direction="row" spacing={0.25}>
|
|
||||||
<Typography variant="body2">10.000.000</Typography>
|
|
||||||
<Typography>/</Typography>
|
|
||||||
<Typography variant="body2" color="#757575">
|
|
||||||
10.000.000
|
|
||||||
</Typography>
|
|
||||||
</Stack>
|
|
||||||
</Stack>
|
|
||||||
</Card>
|
|
||||||
</Grid>
|
|
||||||
{/* Card 8 */}
|
|
||||||
<Grid item xs={12} sm={6} md={6} lg={4}>
|
|
||||||
<Card sx={{ padding: 1 }}>
|
|
||||||
<Stack spacing={1}>
|
|
||||||
<Typography variant="subtitle2" sx={{ fontWeight: 500 }}>
|
|
||||||
Laboratorium
|
|
||||||
</Typography>
|
|
||||||
<Typography variant="body2" color="#0A0A0A">
|
|
||||||
Yearly Limits
|
|
||||||
</Typography>
|
|
||||||
<BorderLinearProgress variant="determinate" value={100} />
|
|
||||||
<Stack direction="row" spacing={0.25}>
|
|
||||||
<Typography variant="body2">10.000.000</Typography>
|
|
||||||
<Typography>/</Typography>
|
|
||||||
<Typography variant="body2" color="#757575">
|
|
||||||
10.000.000
|
|
||||||
</Typography>
|
|
||||||
</Stack>
|
|
||||||
</Stack>
|
|
||||||
</Card>
|
|
||||||
</Grid>
|
|
||||||
{/* Card 9 */}
|
|
||||||
<Grid item xs={12} sm={6} md={6} lg={4}>
|
|
||||||
<Card sx={{ padding: 1 }}>
|
|
||||||
<Stack spacing={1}>
|
|
||||||
<Typography variant="subtitle2" sx={{ fontWeight: 500 }}>
|
|
||||||
Manfaat Farmasi
|
|
||||||
</Typography>
|
|
||||||
<Typography variant="body2" color="#0A0A0A">
|
|
||||||
Yearly Limits
|
|
||||||
</Typography>
|
|
||||||
<BorderLinearProgress variant="determinate" value={100} />
|
|
||||||
<Stack direction="row" spacing={0.25}>
|
|
||||||
<Typography variant="body2">10.000.000</Typography>
|
|
||||||
<Typography>/</Typography>
|
|
||||||
<Typography variant="body2" color="#757575">
|
|
||||||
10.000.000
|
|
||||||
</Typography>
|
|
||||||
</Stack>
|
|
||||||
</Stack>
|
|
||||||
</Card>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -33,10 +33,10 @@ const rows = [
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
export default function CardClaimHistory() {
|
export default function CardClaimHistory(benefitMember) {
|
||||||
const [page, setPage] = useState(0);
|
const [page, setPage] = useState(0);
|
||||||
const [rowsPerPage, setRowsPerPage] = useState(5);
|
const [rowsPerPage, setRowsPerPage] = useState(5);
|
||||||
|
console.log('benefitMember', benefitMember);
|
||||||
const handleChangePage = (event: React.MouseEvent<HTMLButtonElement> | null, newPage: number) => {
|
const handleChangePage = (event: React.MouseEvent<HTMLButtonElement> | null, newPage: number) => {
|
||||||
setPage(newPage);
|
setPage(newPage);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,21 +9,18 @@ import { UserCurrentCorporateContext } from '../../../contexts/UserCurrentCorpor
|
|||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
import { Dialog, DialogTitle, DialogContent, DialogActions } from '@mui/material';
|
import { Dialog, DialogTitle, DialogContent, DialogActions } from '@mui/material';
|
||||||
import { enqueueSnackbar } from 'notistack';
|
import { enqueueSnackbar } from 'notistack';
|
||||||
|
import { fDate } from '../../../utils/formatTime';
|
||||||
|
|
||||||
|
export default function CardPersonalInformation({ data }) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default function CardPersonalInformation({data}) {
|
|
||||||
/* const [data, setData] = useState(); */
|
/* const [data, setData] = useState(); */
|
||||||
const [openDialog, setOpenDialog] = useState(false);
|
const [openDialog, setOpenDialog] = useState(false);
|
||||||
const [editedData, setEditedData] = useState(null);
|
const [editedData, setEditedData] = useState(null);
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
const [weight, setWeight] = useState(data?.last_weight_kg || '');
|
const [weight, setWeight] = useState(data?.last_weight_kg || '');
|
||||||
const [height, setHeight] = useState(data?.last_height_cm || '');
|
const [height, setHeight] = useState(data?.last_height_cm || '');
|
||||||
const [email, setEmail] = useState(data?.email || '' );
|
const [email, setEmail] = useState(data?.email || '');
|
||||||
const [phone, setPhone] = useState(data?.phone || '' );
|
const [phone, setPhone] = useState(data?.phone || '');
|
||||||
const [address, setAddress] = useState(data?.main_address_id || '' );
|
const [address, setAddress] = useState(data?.main_address_id || '');
|
||||||
|
|
||||||
/* const [updatedData, setUpdatedData] = useState(data); */
|
/* const [updatedData, setUpdatedData] = useState(data); */
|
||||||
|
|
||||||
@@ -31,13 +28,11 @@ export default function CardPersonalInformation({data}) {
|
|||||||
setWeight(data?.last_weight_kg || '');
|
setWeight(data?.last_weight_kg || '');
|
||||||
setHeight(data?.last_height_cm || '');
|
setHeight(data?.last_height_cm || '');
|
||||||
setEmail(data?.email || '');
|
setEmail(data?.email || '');
|
||||||
setPhone(data?.phone||'');
|
setPhone(data?.phone || '');
|
||||||
setAddress(data?.main_address_id||'');
|
setAddress(data?.main_address_id || '');
|
||||||
setEditedData(data);
|
setEditedData(data);
|
||||||
setOpenDialog(true);
|
setOpenDialog(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const handleCloseDialog = () => {
|
const handleCloseDialog = () => {
|
||||||
// Close the dialog
|
// Close the dialog
|
||||||
@@ -56,7 +51,7 @@ export default function CardPersonalInformation({data}) {
|
|||||||
phone: phone,
|
phone: phone,
|
||||||
main_address_id: address,
|
main_address_id: address,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Update the data in the database using the updatedData object
|
// Update the data in the database using the updatedData object
|
||||||
axios
|
axios
|
||||||
.put('/data/' + id, updatedData)
|
.put('/data/' + id, updatedData)
|
||||||
@@ -70,17 +65,9 @@ export default function CardPersonalInformation({data}) {
|
|||||||
enqueueSnackbar('Failed to update data', { variant: 'error' });
|
enqueueSnackbar('Failed to update data', { variant: 'error' });
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card sx={{ borderRadius: '6px', paddingY: 2 }}>
|
<Card sx={{ borderRadius: '6px', paddingY: 2 }}>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{/* Stack 1 */}
|
{/* Stack 1 */}
|
||||||
<Stack
|
<Stack
|
||||||
direction="row"
|
direction="row"
|
||||||
@@ -89,7 +76,9 @@ export default function CardPersonalInformation({data}) {
|
|||||||
sx={{ paddingY: 1, paddingX: 3 }}
|
sx={{ paddingY: 1, paddingX: 3 }}
|
||||||
>
|
>
|
||||||
<Typography variant="subtitle2">Informasi Pribadi</Typography>
|
<Typography variant="subtitle2">Informasi Pribadi</Typography>
|
||||||
<Button startIcon={<Iconify icon="heroicons:pencil-solid" />} onClick={handleEditData}>Edit Data</Button>
|
<Button startIcon={<Iconify icon="heroicons:pencil-solid" />} onClick={handleEditData}>
|
||||||
|
Edit Data
|
||||||
|
</Button>
|
||||||
</Stack>
|
</Stack>
|
||||||
{/* Stack 2 */}
|
{/* Stack 2 */}
|
||||||
<Stack direction="row" spacing={2} paddingX={2}>
|
<Stack direction="row" spacing={2} paddingX={2}>
|
||||||
@@ -119,15 +108,15 @@ export default function CardPersonalInformation({data}) {
|
|||||||
<Stack direction="row" paddingY={1} spacing={2} sx={{ flex: '100%' }}>
|
<Stack direction="row" paddingY={1} spacing={2} sx={{ flex: '100%' }}>
|
||||||
<Stack sx={{ width: '60%' }}>
|
<Stack sx={{ width: '60%' }}>
|
||||||
<Typography variant="caption">Nama Lengkap</Typography>
|
<Typography variant="caption">Nama Lengkap</Typography>
|
||||||
<Typography variant="body2"> {data ?. name} </Typography>
|
<Typography variant="body2"> {data?.name} </Typography>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack sx={{ width: '20%' }}>
|
<Stack sx={{ width: '20%' }}>
|
||||||
<Typography variant="caption">Berat Badan </Typography>
|
<Typography variant="caption">Berat Badan </Typography>
|
||||||
<Typography variant="body2">{data ?. last_weight_kg} kg</Typography>
|
<Typography variant="body2">{data?.last_weight_kg} kg</Typography>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack sx={{ width: '20%' }}>
|
<Stack sx={{ width: '20%' }}>
|
||||||
<Typography variant="caption">Tinggi Badan </Typography>
|
<Typography variant="caption">Tinggi Badan </Typography>
|
||||||
<Typography variant="body2">{data ?. last_height_cm} cm</Typography>
|
<Typography variant="body2">{data?.last_height_cm} cm</Typography>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
@@ -139,15 +128,18 @@ export default function CardPersonalInformation({data}) {
|
|||||||
<Stack direction="row" spacing={2} sx={{ flex: '100%' }}>
|
<Stack direction="row" spacing={2} sx={{ flex: '100%' }}>
|
||||||
<Stack sx={{ width: '100%' }}>
|
<Stack sx={{ width: '100%' }}>
|
||||||
<Typography variant="caption">Tempat Lahir</Typography>
|
<Typography variant="caption">Tempat Lahir</Typography>
|
||||||
<Typography variant="body2"> {data ?. birth_place} </Typography>
|
<Typography variant="body2"> {data?.birth_place} </Typography>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack sx={{ width: '100%' }}>
|
<Stack sx={{ width: '100%' }}>
|
||||||
<Typography variant="caption">Tanggal Lahir</Typography>
|
<Typography variant="caption">Tanggal Lahir</Typography>
|
||||||
<Typography variant="body2">{data ?. birth_date}</Typography>
|
<Typography variant="body2">
|
||||||
|
{' '}
|
||||||
|
{data?.birth_date ? fDate(data?.birth_date) : ''}
|
||||||
|
</Typography>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack sx={{ width: '100%' }}>
|
<Stack sx={{ width: '100%' }}>
|
||||||
<Typography variant="caption">Jenis Kelamin</Typography>
|
<Typography variant="caption">Jenis Kelamin</Typography>
|
||||||
<Typography variant="body2">{data ?. gender}</Typography>
|
<Typography variant="body2">{data?.gender}</Typography>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
@@ -157,18 +149,16 @@ export default function CardPersonalInformation({data}) {
|
|||||||
<Stack direction="row" spacing={2} sx={{ flex: '100%' }}>
|
<Stack direction="row" spacing={2} sx={{ flex: '100%' }}>
|
||||||
<Stack sx={{ width: '100%' }}>
|
<Stack sx={{ width: '100%' }}>
|
||||||
<Typography variant="caption">Nomor Telpon</Typography>
|
<Typography variant="caption">Nomor Telpon</Typography>
|
||||||
<Typography variant="body2">{data ?. phone}</Typography>
|
<Typography variant="body2">{data?.phone}</Typography>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack sx={{ width: '100%' }}>
|
<Stack sx={{ width: '100%' }}>
|
||||||
<Typography variant="caption">Email</Typography>
|
<Typography variant="caption">Email</Typography>
|
||||||
<Typography variant="body2">{data?. email}</Typography>
|
<Typography variant="body2">{data?.email}</Typography>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack>
|
<Stack>
|
||||||
<Typography variant="caption">Alamat</Typography>
|
<Typography variant="caption">Alamat</Typography>
|
||||||
<Typography variant="body2">
|
<Typography variant="body2">{data?.main_address_id}</Typography>
|
||||||
{data ?. main_address_id}
|
|
||||||
</Typography>
|
|
||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
{/* Stack 3.3 */}
|
{/* Stack 3.3 */}
|
||||||
@@ -183,7 +173,7 @@ export default function CardPersonalInformation({data}) {
|
|||||||
>
|
>
|
||||||
<Stack>
|
<Stack>
|
||||||
<Typography variant="caption">Nomor NIK</Typography>
|
<Typography variant="caption">Nomor NIK</Typography>
|
||||||
<Typography variant="body2">{data ?. nik}</Typography>
|
<Typography variant="body2">{data?.nik}</Typography>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack>
|
<Stack>
|
||||||
<Button variant="contained" startIcon={<VisibilityIcon />}>
|
<Button variant="contained" startIcon={<VisibilityIcon />}>
|
||||||
@@ -198,65 +188,65 @@ export default function CardPersonalInformation({data}) {
|
|||||||
<Stack direction="row" justifyContent="space-between" spacing={2} sx={{ flex: '100%' }}>
|
<Stack direction="row" justifyContent="space-between" spacing={2} sx={{ flex: '100%' }}>
|
||||||
<Stack>
|
<Stack>
|
||||||
<Typography variant="caption">Agama</Typography>
|
<Typography variant="caption">Agama</Typography>
|
||||||
<Typography variant="body2">{data ?. religion}</Typography>
|
<Typography variant="body2">{data?.religion}</Typography>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack>
|
<Stack>
|
||||||
<Typography variant="caption">Status</Typography>
|
<Typography variant="caption">Status</Typography>
|
||||||
<Typography variant="body2">{data ?. marital_status}</Typography>
|
<Typography variant="body2">{data?.marital_status}</Typography>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack>
|
<Stack>
|
||||||
<Typography variant="caption">Pendidikan</Typography>
|
<Typography variant="caption">Pendidikan</Typography>
|
||||||
<Typography variant="body2">{data ?. last_education}</Typography>
|
<Typography variant="body2">{data?.last_education}</Typography>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack>
|
<Stack>
|
||||||
<Typography variant="caption">Pekerjaan</Typography>
|
<Typography variant="caption">Pekerjaan</Typography>
|
||||||
<Typography variant="body2">{data ?. current_employment}</Typography>
|
<Typography variant="body2">{data?.current_employment}</Typography>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
{/* Dialog */}
|
{/* Dialog */}
|
||||||
<Dialog open={openDialog} onClose={handleCloseDialog}>
|
<Dialog open={openDialog} onClose={handleCloseDialog}>
|
||||||
<DialogTitle>Edit Data</DialogTitle>
|
<DialogTitle>Edit Data</DialogTitle>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<Stack spacing={2}>
|
<Stack spacing={2}>
|
||||||
<TextField
|
<TextField
|
||||||
label="Full Name"
|
label="Full Name"
|
||||||
value={editedData ? editedData.name : ''}
|
value={editedData ? editedData.name : ''}
|
||||||
onChange={(e) => setEditedData({ ...editedData, name: e.target.value })}
|
onChange={(e) => setEditedData({ ...editedData, name: e.target.value })}
|
||||||
fullWidth
|
fullWidth
|
||||||
sx={{ marginTop: '16px' }}
|
sx={{ marginTop: '16px' }}
|
||||||
/>
|
/>
|
||||||
<TextField
|
<TextField
|
||||||
label="Weight (kg)"
|
label="Weight (kg)"
|
||||||
value={weight}
|
value={weight}
|
||||||
onChange={(e) => setWeight(e.target.value)}
|
onChange={(e) => setWeight(e.target.value)}
|
||||||
fullWidth
|
fullWidth
|
||||||
sx={{ marginTop: '16px' }}
|
sx={{ marginTop: '16px' }}
|
||||||
/>
|
/>
|
||||||
<TextField
|
<TextField
|
||||||
label="Height (cm)"
|
label="Height (cm)"
|
||||||
value={height}
|
value={height}
|
||||||
onChange={(e) => setHeight(e.target.value)}
|
onChange={(e) => setHeight(e.target.value)}
|
||||||
fullWidth
|
fullWidth
|
||||||
sx={{ marginTop: '16px' }}
|
sx={{ marginTop: '16px' }}
|
||||||
/>
|
/>
|
||||||
<TextField
|
<TextField
|
||||||
label="Email Address"
|
label="Email Address"
|
||||||
value={email}
|
value={email}
|
||||||
onChange={(e) => setEmail(e.target.value)}
|
onChange={(e) => setEmail(e.target.value)}
|
||||||
fullWidth
|
fullWidth
|
||||||
sx={{ marginTop: '16px' }}
|
sx={{ marginTop: '16px' }}
|
||||||
/>
|
/>
|
||||||
<TextField
|
<TextField
|
||||||
label="Phone No."
|
label="Phone No."
|
||||||
value={phone}
|
value={phone}
|
||||||
onChange={(e) => setPhone(e.target.value)}
|
onChange={(e) => setPhone(e.target.value)}
|
||||||
fullWidth
|
fullWidth
|
||||||
sx={{ marginTop: '16px' }}
|
sx={{ marginTop: '16px' }}
|
||||||
/>
|
/>
|
||||||
{/* <TextField
|
{/* <TextField
|
||||||
label="Address"
|
label="Address"
|
||||||
value={address}
|
value={address}
|
||||||
onChange={(e) => setAddress(e.target.value)}
|
onChange={(e) => setAddress(e.target.value)}
|
||||||
@@ -264,18 +254,17 @@ export default function CardPersonalInformation({data}) {
|
|||||||
sx={{ marginTop: '16px' }}
|
sx={{ marginTop: '16px' }}
|
||||||
/> */}
|
/> */}
|
||||||
|
|
||||||
|
{/* Add more fields as needed */}
|
||||||
|
</Stack>
|
||||||
|
</DialogContent>
|
||||||
|
|
||||||
{/* Add more fields as needed */}
|
<DialogActions>
|
||||||
</Stack>
|
<Button onClick={handleCloseDialog}>Cancel</Button>
|
||||||
</DialogContent>
|
<Button onClick={handleSaveData} variant="contained" color="primary">
|
||||||
|
Save
|
||||||
<DialogActions>
|
</Button>
|
||||||
<Button onClick={handleCloseDialog}>Cancel</Button>
|
</DialogActions>
|
||||||
<Button onClick={handleSaveData} variant="contained" color="primary">
|
</Dialog>
|
||||||
Save
|
|
||||||
</Button>
|
|
||||||
</DialogActions>
|
|
||||||
</Dialog>
|
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ const BorderLinearProgress = styled(LinearProgress)(({ theme }) => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
||||||
type DataMember = {
|
type DataMember = {
|
||||||
id: number;
|
id: number;
|
||||||
fullName: string;
|
fullName: string;
|
||||||
@@ -65,18 +64,17 @@ type CardPolicyProps = {
|
|||||||
members?: DataMember[];
|
members?: DataMember[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
export default function CardPolicyNumber() {
|
|
||||||
|
|
||||||
|
export default function CardPolicyNumber({ data }) {
|
||||||
|
const { corporateValue } = useContext(UserCurrentCorporateContext);
|
||||||
|
const [policyNumber, setPolicyNumber] = useState('');
|
||||||
|
const [policyData, setPolicyData] = useState<CardPolicyProps>();
|
||||||
|
|
||||||
const { corporateValue } = useContext(UserCurrentCorporateContext);
|
const [limitMember, setLimitMember] = useState();
|
||||||
const [policyNumber,setPolicyNumber] = useState('');
|
const [benefitMember, setBenefitMember] = useState();
|
||||||
const [policyData, setPolicyData] = useState<CardPolicyProps>();
|
|
||||||
|
|
||||||
/* axios.get(`${corporateValue}/topup`)
|
/* axios.get(`${corporateValue}/topup`)
|
||||||
.then(response => {
|
.then(response => {
|
||||||
console.log(response.data);
|
console.log(response.data);
|
||||||
})
|
})
|
||||||
@@ -84,63 +82,68 @@ export default function CardPolicyNumber() {
|
|||||||
console.error(error);
|
console.error(error);
|
||||||
}); */
|
}); */
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
axios
|
axios
|
||||||
.get(`${corporateValue}/topup`)
|
.get(`${corporateValue}/topup`)
|
||||||
.then(response => {
|
.then((response) => {
|
||||||
const { data } = response.data; // Access the 'data' object from the response
|
const { data } = response.data; // Access the 'data' object from the response
|
||||||
const { policyNumber } = data; // Access the 'policyNumber' field from the 'data' object
|
const { policyNumber } = data; // Access the 'policyNumber' field from the 'data' object
|
||||||
setPolicyNumber(policyNumber);
|
setPolicyNumber(policyNumber);
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error) => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
});
|
});
|
||||||
|
|
||||||
// const corporatePolicyLimit = axios.get(`${corporateValue}/policy`);
|
setLimitMember(data?.limit);
|
||||||
// const corporateTopUpLimit = axios.get(`${corporateValue}/topup`);
|
setBenefitMember(data?.benefits);
|
||||||
// setPolicyData({
|
|
||||||
// limit: corporatePolicyLimit.data.data,
|
|
||||||
// topUpLimit: corporateTopUpLimit.data.data,
|
|
||||||
// });
|
|
||||||
}, [corporateValue]);
|
|
||||||
|
|
||||||
const calculateProgressValue = (current:number,total:number) => {
|
// const corporatePolicyLimit = axios.get(`${corporateValue}/policy`);
|
||||||
return (current/total) * 100;
|
// const corporateTopUpLimit = axios.get(`${corporateValue}/topup`);
|
||||||
|
// setPolicyData({
|
||||||
|
// limit: corporatePolicyLimit.data.data,
|
||||||
|
// topUpLimit: corporateTopUpLimit.data.data,
|
||||||
|
// });
|
||||||
|
}, [corporateValue, data]);
|
||||||
|
|
||||||
|
const calculateProgressValue = (current: number, total: number) => {
|
||||||
|
return (current / total) * 100;
|
||||||
};
|
};
|
||||||
|
const progressValue = calculateProgressValue(limitMember?.current, limitMember?.total);
|
||||||
|
|
||||||
const getMemberLimitUsage = (memberId: string) => {
|
// const getMemberLimitUsage = (memberId: string) => {
|
||||||
if (policyData?.members) {
|
// if (policyData?.members) {
|
||||||
const member = policyData.members.find(member => member.memberId === memberId);
|
// const member = policyData.members.find((member) => member.memberId === memberId);
|
||||||
if (member) {
|
// if (member) {
|
||||||
return member.limit;
|
// return member.limit;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
return null;
|
// return null;
|
||||||
};
|
// };
|
||||||
|
|
||||||
const renderYearlyLimit = () => {
|
// const renderYearlyLimit = () => {
|
||||||
if (policyData) {
|
// if (policyData) {
|
||||||
const { myLimit } = policyData.limit;
|
// const { myLimit } = policyData.limit;
|
||||||
const { balance, total, percentage } = myLimit;
|
// console.log('myLimit', myLimit);
|
||||||
const progressValue = calculateProgressValue(balance, total);
|
// const { balance, total, percentage } = myLimit;
|
||||||
|
// const progressValue = calculateProgressValue(balance, total);
|
||||||
|
|
||||||
return (
|
// return (
|
||||||
<Stack spacing={1} sx={{ width: '206.5px' }}>
|
// <Stack spacing={1} sx={{ width: '206.5px' }}>
|
||||||
<Typography variant="subtitle2">Yearly Limit</Typography>
|
// <Typography variant="subtitle2">Yearly Limit</Typography>
|
||||||
<BorderLinearProgress variant="determinate" value={progressValue} />
|
// <BorderLinearProgress variant="determinate" value={progressValue} />
|
||||||
<Typography variant="subtitle2" sx={{ fontWeight: 500 }}>
|
// <Typography variant="subtitle2" sx={{ fontWeight: 500 }}>
|
||||||
{balance.toLocaleString()} /{' '}
|
// {balance.toLocaleString()} /{' '}
|
||||||
<Typography variant="body2" color="#757575" component="span">
|
// <Typography variant="body2" color="#757575" component="span">
|
||||||
{total.toLocaleString()}
|
// {total.toLocaleString()}
|
||||||
</Typography>
|
// </Typography>
|
||||||
</Typography>
|
// </Typography>
|
||||||
</Stack>
|
// </Stack>
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
return null;
|
// return null;
|
||||||
};
|
// };
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card sx={{ padding: 2 }}>
|
<Card sx={{ padding: 2 }}>
|
||||||
<Stack>
|
<Stack>
|
||||||
<Stack direction="row" alignItems="center" spacing={1} justifyContent="space-between">
|
<Stack direction="row" alignItems="center" spacing={1} justifyContent="space-between">
|
||||||
@@ -153,17 +156,17 @@ export default function CardPolicyNumber() {
|
|||||||
</Stack>
|
</Stack>
|
||||||
<Stack spacing={1} sx={{ width: '206.5px' }}>
|
<Stack spacing={1} sx={{ width: '206.5px' }}>
|
||||||
<Typography variant="subtitle2">Yearly Limit</Typography>
|
<Typography variant="subtitle2">Yearly Limit</Typography>
|
||||||
<BorderLinearProgress variant="determinate" value={100} />
|
<BorderLinearProgress variant="determinate" value={progressValue} />
|
||||||
<Typography variant="subtitle2" sx={{ fontWeight: 500 }}>
|
<Typography variant="subtitle2" sx={{ fontWeight: 500 }}>
|
||||||
10.000.000 /{' '}
|
{limitMember?.current}/{' '}
|
||||||
<Typography variant="body2" color="#757575" component="span">
|
<Typography variant="body2" color="#757575" component="span">
|
||||||
10.000.000
|
{limitMember?.total}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Typography>
|
</Typography>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
{/* Benefit Summary */}
|
{/* Benefit Summary */}
|
||||||
<CardBenefitSummary />
|
<CardBenefitSummary data={benefitMember} />
|
||||||
</Stack>
|
</Stack>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { format, getTime, formatDistanceToNow } from 'date-fns';
|
import { format,parseISO, getTime, setHours, setMinutes , formatDistanceToNow } from 'date-fns';
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
export function fDate(date: Date | string | number) {
|
export function fDate(date: Date | string | number) {
|
||||||
|
console.log(date);
|
||||||
return format(new Date(date), 'dd MMMM yyyy');
|
return format(new Date(date), 'dd MMMM yyyy');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,3 +24,16 @@ export function fToNow(date: Date | string | number) {
|
|||||||
addSuffix: true
|
addSuffix: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// export function fDateString(date) {
|
||||||
|
// const dateObj = parseISO(date);
|
||||||
|
// const formattedDate = format(dateObj, 'dd MMMM yyyy');
|
||||||
|
// return formattedDate;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// export function fFormattedDateString(date : String) {
|
||||||
|
// console.log(date);
|
||||||
|
// const datePart = date.split(' ')[0]; // Memisahkan bagian tanggal
|
||||||
|
// const formattedDate = fDateString(datePart); // Menggunakan fungsi sebelumnya untuk memformat tanggal
|
||||||
|
// return formattedDate;
|
||||||
|
// }
|
||||||
@@ -2,6 +2,6 @@ GENERATE_SOURCEMAP=false
|
|||||||
|
|
||||||
PORT=8083
|
PORT=8083
|
||||||
|
|
||||||
REACT_APP_HOST_API_URL="http://lms.test"
|
REACT_APP_HOST_API_URL="http://127.0.0.1:8000"
|
||||||
|
|
||||||
VITE_API_URL="http://lms.test/api/internal"
|
VITE_API_URL="http://127.0.0.1:8000/api/internal"
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@ajoelp/json-to-formdata": "^1.5.0",
|
||||||
"@date-io/date-fns": "^2.16.0",
|
"@date-io/date-fns": "^2.16.0",
|
||||||
"@emotion/cache": "^11.10.5",
|
"@emotion/cache": "^11.10.5",
|
||||||
"@emotion/react": "^11.10.5",
|
"@emotion/react": "^11.10.5",
|
||||||
|
|||||||
@@ -28,7 +28,9 @@ import {
|
|||||||
ButtonGroup,
|
ButtonGroup,
|
||||||
Grid,
|
Grid,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
|
Divider,
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
|
import Iconify from '@/components/Iconify';
|
||||||
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
|
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
|
||||||
import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight';
|
import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight';
|
||||||
import AddIcon from '@mui/icons-material/Add';
|
import AddIcon from '@mui/icons-material/Add';
|
||||||
@@ -49,8 +51,34 @@ import { enqueueSnackbar } from 'notistack';
|
|||||||
import { LoadingButton } from '@mui/lab';
|
import { LoadingButton } from '@mui/lab';
|
||||||
import DialogLog from './sections/DialogLog';
|
import DialogLog from './sections/DialogLog';
|
||||||
import HistoryIcon from '@mui/icons-material/History';
|
import HistoryIcon from '@mui/icons-material/History';
|
||||||
|
import { makeFormData } from '@/utils/jsonToFormData';
|
||||||
|
|
||||||
export default function CorporatePlanList() {
|
export default function CorporatePlanList({handleSubmitSuccess}) {
|
||||||
|
// Files MCU
|
||||||
|
const fileMcuInput = useRef<HTMLInputElement>(null);
|
||||||
|
const [fileMcus, setFileMcus] = useState([]);
|
||||||
|
|
||||||
|
const handleMcuInputChange = (id, member_id) => (event) => {
|
||||||
|
if (event.target.files[0]) {
|
||||||
|
const updatedFiles = Array.from(event.target.files).map((file) => ({
|
||||||
|
file,
|
||||||
|
id
|
||||||
|
}));
|
||||||
|
setFileMcus((prevFileMcus) => {
|
||||||
|
const newFileMcus = [...prevFileMcus, ...updatedFiles];
|
||||||
|
submitRequest(id, newFileMcus, member_id);
|
||||||
|
return newFileMcus;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.log('Tidak ada file');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const removeMcuFiles = (id, index) => {
|
||||||
|
setFileMcus((filesState) =>
|
||||||
|
filesState.filter((file, fileIndex) => fileIndex !== index || file.id !== id)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
const [submitLoading, setSubmitLoading] = useState(false);
|
||||||
const { themeStretch } = useSettings();
|
const { themeStretch } = useSettings();
|
||||||
const { corporate_id } = useParams();
|
const { corporate_id } = useParams();
|
||||||
const [searchParams, setSearchParams] = useSearchParams();
|
const [searchParams, setSearchParams] = useSearchParams();
|
||||||
@@ -149,6 +177,47 @@ export default function CorporatePlanList() {
|
|||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
function submitRequest(id, newFileMcus, member_id) {
|
||||||
|
setSubmitLoading(true);
|
||||||
|
if (newFileMcus && newFileMcus.length > 0) {
|
||||||
|
const fileWithId = newFileMcus.find((file) => file.id === id);
|
||||||
|
if (fileWithId) {
|
||||||
|
const formData = makeFormData({
|
||||||
|
id: id,
|
||||||
|
memberid: member_id,
|
||||||
|
result_files: fileWithId.file,
|
||||||
|
});
|
||||||
|
axios
|
||||||
|
.post('/files-mcu', formData)
|
||||||
|
.then((response) => {
|
||||||
|
const responseData = response?.data;
|
||||||
|
if(responseData)
|
||||||
|
{
|
||||||
|
setTimeout(() => {
|
||||||
|
loadDataTableData();
|
||||||
|
}, 2000);
|
||||||
|
enqueueSnackbar(responseData.message ?? 'Berhasil tambah file MemberID '+member_id+', silahkan lihat dilaporan', { variant: 'success' });
|
||||||
|
handleSubmitSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
.catch(({ response }) => {
|
||||||
|
const responseData = response?.data;
|
||||||
|
if(responseData)
|
||||||
|
{
|
||||||
|
enqueueSnackbar(responseData.message ?? 'Something Went Wrong', { variant: 'error' });
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
setSubmitLoading(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
console.log(`File dengan ID ${id} tidak ditemukan`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// End Files MCU
|
||||||
|
|
||||||
function ImportForm(props: any) {
|
function ImportForm(props: any) {
|
||||||
// IMPORT
|
// IMPORT
|
||||||
@@ -178,9 +247,7 @@ export default function CorporatePlanList() {
|
|||||||
|
|
||||||
const handleMemberList = async (appliedFilter = null) => {
|
const handleMemberList = async (appliedFilter = null) => {
|
||||||
axios.get('corporates/' + corporate_id + '/members/list').then((response) => {
|
axios.get('corporates/' + corporate_id + '/members/list').then((response) => {
|
||||||
console.log(response);
|
|
||||||
const link = document.createElement('a');
|
const link = document.createElement('a');
|
||||||
console.log(response.data.data.file_name);
|
|
||||||
link.href = response.data.data.file_url;
|
link.href = response.data.data.file_url;
|
||||||
link.setAttribute('download', response.data.data.file_name);
|
link.setAttribute('download', response.data.data.file_name);
|
||||||
document.body.appendChild(link);
|
document.body.appendChild(link);
|
||||||
@@ -577,21 +644,81 @@ export default function CorporatePlanList() {
|
|||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
<Typography sx={{ fontWeight: '600', mb: 1 }}>File History</Typography>
|
||||||
|
<Grid container sx={{ pb: 2, mb: 2, borderBottom: 1 }}>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Grid container>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
{row.file_mcu_names
|
||||||
|
? row.file_mcu_names.split(',').map((fileName, index) => (
|
||||||
|
<div key={index}>{fileName}</div>
|
||||||
|
))
|
||||||
|
: '-'}
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
<Grid>
|
<Grid spacing={1}>
|
||||||
<LoadingButton
|
<Stack sx={{ marginTop: 1}}>
|
||||||
id="upload-button"
|
<LoadingButton
|
||||||
variant="outlined"
|
id="upload-button"
|
||||||
startIcon={<InsertDriveFileIcon />}
|
variant="outlined"
|
||||||
// sx={{ p: 1.8 }}
|
startIcon={<InsertDriveFileIcon />}
|
||||||
// onClick={() => {handleDownloadLog(row)}}
|
// sx={{ p: 1.8 }}
|
||||||
onClick={() => {
|
// onClick={() => {handleDownloadLog(row)}}
|
||||||
setDialogLogOpen(true);
|
onClick={() => {
|
||||||
}}
|
setDialogLogOpen(true);
|
||||||
loading={loadingLog}
|
}}
|
||||||
>
|
loading={loadingLog}
|
||||||
Download LOG
|
>
|
||||||
</LoadingButton>
|
Download LOG
|
||||||
|
</LoadingButton>
|
||||||
|
</Stack>
|
||||||
|
{/* -------------------------------Upload Dokumen MCU------------------------------- */}
|
||||||
|
<Stack sx={{ marginTop: 1}}>
|
||||||
|
{/*<Stack
|
||||||
|
divider={<Divider orientation="horizontal" flexItem />}
|
||||||
|
spacing={1}
|
||||||
|
sx={{ marginY: 2}}
|
||||||
|
>
|
||||||
|
{fileMcus &&
|
||||||
|
fileMcus
|
||||||
|
.filter((datas) => datas.id === row.id)
|
||||||
|
.map((datas, index) => (
|
||||||
|
<Stack direction="row" justifyContent={'space-between'} key={index}>
|
||||||
|
<Typography sx={{ color: "text.secondary" }}>{datas.file.name}</Typography>
|
||||||
|
<Iconify
|
||||||
|
icon="eva:trash-2-outline"
|
||||||
|
color={'darkred'}
|
||||||
|
onClick={() => {
|
||||||
|
removeMcuFiles(datas.id, index);
|
||||||
|
}}
|
||||||
|
sx={{ cursor: 'pointer' }}
|
||||||
|
></Iconify>
|
||||||
|
</Stack>
|
||||||
|
))}
|
||||||
|
</Stack>*/}
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
id={`file-${row.id}`}
|
||||||
|
ref={fileMcuInput}
|
||||||
|
style={{ display: 'none' }}
|
||||||
|
onChange={(event) => {
|
||||||
|
handleMcuInputChange(row.id, row.member_id)(event);
|
||||||
|
}}
|
||||||
|
accept="application/pdf"
|
||||||
|
/>
|
||||||
|
<LoadingButton
|
||||||
|
variant="outlined"
|
||||||
|
onClick={() => {
|
||||||
|
fileMcuInput.current.click();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Iconify icon="eva:plus-fill" />
|
||||||
|
Add Result
|
||||||
|
</LoadingButton>
|
||||||
|
</Stack>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<DialogLog
|
<DialogLog
|
||||||
|
|||||||
6
frontend/dashboard/src/utils/jsonToFormData.ts
Normal file
6
frontend/dashboard/src/utils/jsonToFormData.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import jsonToFormData from '@ajoelp/json-to-formdata';
|
||||||
|
|
||||||
|
export function makeFormData(object: any) {
|
||||||
|
return jsonToFormData(object)
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
|
|
||||||
REACT_APP_HOST_API_URL="http://localhost:8000"
|
REACT_APP_HOST_API_URL="http://localhost:8000"
|
||||||
|
|
||||||
VITE_API_URL="http://localhost:8000/api/hospitalportal"
|
VITE_API_URL="http://localhost:8000/api/v1/hospitalportal"
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
VITE_API_URL="https://aso-api.linksehat.dev/api/hospitalportal"
|
VITE_API_URL="https://aso-api.linksehat.dev/api/v1/hospitalportal"
|
||||||
27
frontend/hospital-portal/pnpm-lock.yaml
generated
27
frontend/hospital-portal/pnpm-lock.yaml
generated
@@ -1703,6 +1703,7 @@ packages:
|
|||||||
cpu: [arm]
|
cpu: [arm]
|
||||||
os: [android]
|
os: [android]
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@esbuild/linux-loong64/0.15.18:
|
/@esbuild/linux-loong64/0.15.18:
|
||||||
@@ -1711,6 +1712,7 @@ packages:
|
|||||||
cpu: [loong64]
|
cpu: [loong64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@eslint/eslintrc/1.4.1:
|
/@eslint/eslintrc/1.4.1:
|
||||||
@@ -3412,6 +3414,7 @@ packages:
|
|||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [android]
|
os: [android]
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/esbuild-android-arm64/0.15.18:
|
/esbuild-android-arm64/0.15.18:
|
||||||
@@ -3420,6 +3423,7 @@ packages:
|
|||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [android]
|
os: [android]
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/esbuild-darwin-64/0.15.18:
|
/esbuild-darwin-64/0.15.18:
|
||||||
@@ -3428,6 +3432,7 @@ packages:
|
|||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [darwin]
|
os: [darwin]
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/esbuild-darwin-arm64/0.15.18:
|
/esbuild-darwin-arm64/0.15.18:
|
||||||
@@ -3436,6 +3441,7 @@ packages:
|
|||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [darwin]
|
os: [darwin]
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/esbuild-freebsd-64/0.15.18:
|
/esbuild-freebsd-64/0.15.18:
|
||||||
@@ -3444,6 +3450,7 @@ packages:
|
|||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [freebsd]
|
os: [freebsd]
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/esbuild-freebsd-arm64/0.15.18:
|
/esbuild-freebsd-arm64/0.15.18:
|
||||||
@@ -3452,6 +3459,7 @@ packages:
|
|||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [freebsd]
|
os: [freebsd]
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/esbuild-linux-32/0.15.18:
|
/esbuild-linux-32/0.15.18:
|
||||||
@@ -3460,6 +3468,7 @@ packages:
|
|||||||
cpu: [ia32]
|
cpu: [ia32]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/esbuild-linux-64/0.15.18:
|
/esbuild-linux-64/0.15.18:
|
||||||
@@ -3468,6 +3477,7 @@ packages:
|
|||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/esbuild-linux-arm/0.15.18:
|
/esbuild-linux-arm/0.15.18:
|
||||||
@@ -3476,6 +3486,7 @@ packages:
|
|||||||
cpu: [arm]
|
cpu: [arm]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/esbuild-linux-arm64/0.15.18:
|
/esbuild-linux-arm64/0.15.18:
|
||||||
@@ -3484,6 +3495,7 @@ packages:
|
|||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/esbuild-linux-mips64le/0.15.18:
|
/esbuild-linux-mips64le/0.15.18:
|
||||||
@@ -3492,6 +3504,7 @@ packages:
|
|||||||
cpu: [mips64el]
|
cpu: [mips64el]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/esbuild-linux-ppc64le/0.15.18:
|
/esbuild-linux-ppc64le/0.15.18:
|
||||||
@@ -3500,6 +3513,7 @@ packages:
|
|||||||
cpu: [ppc64]
|
cpu: [ppc64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/esbuild-linux-riscv64/0.15.18:
|
/esbuild-linux-riscv64/0.15.18:
|
||||||
@@ -3508,6 +3522,7 @@ packages:
|
|||||||
cpu: [riscv64]
|
cpu: [riscv64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/esbuild-linux-s390x/0.15.18:
|
/esbuild-linux-s390x/0.15.18:
|
||||||
@@ -3516,6 +3531,7 @@ packages:
|
|||||||
cpu: [s390x]
|
cpu: [s390x]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/esbuild-netbsd-64/0.15.18:
|
/esbuild-netbsd-64/0.15.18:
|
||||||
@@ -3524,6 +3540,7 @@ packages:
|
|||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [netbsd]
|
os: [netbsd]
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/esbuild-openbsd-64/0.15.18:
|
/esbuild-openbsd-64/0.15.18:
|
||||||
@@ -3532,6 +3549,7 @@ packages:
|
|||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [openbsd]
|
os: [openbsd]
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/esbuild-sunos-64/0.15.18:
|
/esbuild-sunos-64/0.15.18:
|
||||||
@@ -3540,6 +3558,7 @@ packages:
|
|||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [sunos]
|
os: [sunos]
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/esbuild-windows-32/0.15.18:
|
/esbuild-windows-32/0.15.18:
|
||||||
@@ -3548,6 +3567,7 @@ packages:
|
|||||||
cpu: [ia32]
|
cpu: [ia32]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/esbuild-windows-64/0.15.18:
|
/esbuild-windows-64/0.15.18:
|
||||||
@@ -3556,6 +3576,7 @@ packages:
|
|||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/esbuild-windows-arm64/0.15.18:
|
/esbuild-windows-arm64/0.15.18:
|
||||||
@@ -3564,6 +3585,7 @@ packages:
|
|||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/esbuild/0.15.18:
|
/esbuild/0.15.18:
|
||||||
@@ -3594,6 +3616,7 @@ packages:
|
|||||||
esbuild-windows-32: 0.15.18
|
esbuild-windows-32: 0.15.18
|
||||||
esbuild-windows-64: 0.15.18
|
esbuild-windows-64: 0.15.18
|
||||||
esbuild-windows-arm64: 0.15.18
|
esbuild-windows-arm64: 0.15.18
|
||||||
|
dev: false
|
||||||
|
|
||||||
/escalade/3.1.1:
|
/escalade/3.1.1:
|
||||||
resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
|
resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
|
||||||
@@ -4840,6 +4863,7 @@ packages:
|
|||||||
resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==}
|
resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==}
|
||||||
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
dev: false
|
||||||
|
|
||||||
/natural-compare-lite/1.4.0:
|
/natural-compare-lite/1.4.0:
|
||||||
resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==}
|
resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==}
|
||||||
@@ -5068,6 +5092,7 @@ packages:
|
|||||||
nanoid: 3.3.4
|
nanoid: 3.3.4
|
||||||
picocolors: 1.0.0
|
picocolors: 1.0.0
|
||||||
source-map-js: 1.0.2
|
source-map-js: 1.0.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
/prelude-ls/1.2.1:
|
/prelude-ls/1.2.1:
|
||||||
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
|
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
|
||||||
@@ -5538,6 +5563,7 @@ packages:
|
|||||||
/source-map-js/1.0.2:
|
/source-map-js/1.0.2:
|
||||||
resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
|
resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/source-map-support/0.5.21:
|
/source-map-support/0.5.21:
|
||||||
resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
|
resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
|
||||||
@@ -5974,6 +6000,7 @@ packages:
|
|||||||
rollup: 2.79.1
|
rollup: 2.79.1
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents: 2.3.2
|
fsevents: 2.3.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
/webidl-conversions/4.0.2:
|
/webidl-conversions/4.0.2:
|
||||||
resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==}
|
resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==}
|
||||||
|
|||||||
18
frontend/hospital-portal/public/icons/ic_flag_en.svg
Normal file
18
frontend/hospital-portal/public/icons/ic_flag_en.svg
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<svg height="20" viewBox="0 0 28 20" width="28" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<defs><rect id="a" height="20" rx="3" width="28"/>
|
||||||
|
<mask id="b" fill="#fff">
|
||||||
|
<use fill="#fff" fill-rule="evenodd" xlink:href="#a"/>
|
||||||
|
</mask>
|
||||||
|
</defs>
|
||||||
|
<g fill="none" fill-rule="evenodd">
|
||||||
|
<use fill="#0a17a7" xlink:href="#a"/>
|
||||||
|
<path d="m29.2824692-1.91644623 1.4911811 2.21076686-9.4483006 6.37223314 6.6746503.0001129v6.66666663l-6.6746503-.0007795 9.4483006 6.3731256-1.4911811 2.2107668-11.9501195-8.0608924.0009836 7.4777795h-6.6666666l-.000317-7.4777795-11.9488189 8.0608924-1.49118107-2.2107668 9.448-6.3731256-6.67434973.0007795v-6.66666663l6.67434973-.0001129-9.448-6.37223314 1.49118107-2.21076686 11.9488189 8.06.000317-7.4768871h6.6666666l-.0009836 7.4768871z" fill="#fff" mask="url(#b)"/>
|
||||||
|
<g stroke="#db1f35" stroke-linecap="round" stroke-width=".667">
|
||||||
|
<path d="m18.668 6.332 12.665-8.332" mask="url(#b)"/>
|
||||||
|
<path d="m20.013 21.35 11.354-7.652" mask="url(#b)" transform="matrix(1 0 0 -1 0 35.048)"/>
|
||||||
|
<path d="m8.006 6.31-11.843-7.981" mask="url(#b)"/>
|
||||||
|
<path d="m9.29 22.31-13.127-8.705" mask="url(#b)" transform="matrix(1 0 0 -1 0 35.915)"/>
|
||||||
|
</g>
|
||||||
|
<path d="m0 12h12v8h4v-8h12v-4h-12v-8h-4v8h-12z" fill="#e6273e" mask="url(#b)"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
9
frontend/hospital-portal/public/icons/ic_flag_id.svg
Normal file
9
frontend/hospital-portal/public/icons/ic_flag_id.svg
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<svg height="20" viewBox="0 0 28 20" width="28" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<defs>
|
||||||
|
<rect id="a" height="10" rx="0" width="28"/>
|
||||||
|
</defs>
|
||||||
|
<g fill="none" fill-rule="evenodd">
|
||||||
|
<use fill="#D82028" xlink:href="#a"/>
|
||||||
|
<use fill="#FFF" xlink:href="#a" y="10"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 334 B |
15
frontend/hospital-portal/public/lang/en-US.json
Normal file
15
frontend/hospital-portal/public/lang/en-US.json
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"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"
|
||||||
|
}
|
||||||
15
frontend/hospital-portal/public/lang/id-ID.json
Normal file
15
frontend/hospital-portal/public/lang/id-ID.json
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"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"
|
||||||
|
}
|
||||||
7
frontend/hospital-portal/src/LocalizationUtil.ts
Normal file
7
frontend/hospital-portal/src/LocalizationUtil.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
const getLocalizedData = async (locale) => {
|
||||||
|
const response = await fetch(`../public/lang/${locale}.json`); // Mengambil file lokal berdasarkan bahasa yang dipilih
|
||||||
|
const data = await response.json();
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default getLocalizedData;
|
||||||
38
frontend/hospital-portal/src/contexts/LanguageContext.tsx
Normal file
38
frontend/hospital-portal/src/contexts/LanguageContext.tsx
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import React, { createContext, useState, useEffect, useRef } from 'react';
|
||||||
|
import getLocalizedData from '../LocalizationUtil';
|
||||||
|
export const LanguageContext = createContext();
|
||||||
|
|
||||||
|
export const LanguageProvider = ({ children }) => {
|
||||||
|
const [currentLocale, setCurrentLocale] = useState(localStorage.getItem('currentLocale') ? localStorage.getItem('currentLocale') : 'id-ID');
|
||||||
|
const [localeData, setLocaleData] = useState('id');
|
||||||
|
const cancelToken = useRef(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchData = async () => {
|
||||||
|
const token = { cancelled: false };
|
||||||
|
cancelToken.current = token;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = await getLocalizedData(currentLocale);
|
||||||
|
if (!cancelToken.current.cancelled) {
|
||||||
|
setLocaleData(data);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching localized data:', error);
|
||||||
|
// Tangani kesalahan jika diperlukan
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchData();
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
cancelToken.current.cancelled = true;
|
||||||
|
};
|
||||||
|
}, [currentLocale]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<LanguageContext.Provider value={{ currentLocale, setCurrentLocale, localeData }}>
|
||||||
|
{children}
|
||||||
|
</LanguageContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -122,10 +122,18 @@ function AuthProvider({ children }: AuthProviderProps) {
|
|||||||
initialize();
|
initialize();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const headers = {
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'Content-Type' : 'application/json',
|
||||||
|
'Accept-Language': (localStorage.getItem('currentLocale') ? localStorage.getItem('currentLocale') : 'id-ID'),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
const login = async (email: string, password: string) => axios
|
const login = async (email: string, password: string) => axios
|
||||||
.post('/login', { email, password })
|
.post('/login', { email, password }, headers)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
const { user, token } = response.data;
|
const { user, token } = response.data.data;
|
||||||
setSession(token);
|
setSession(token);
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import { HelmetProvider } from 'react-helmet-async';
|
|||||||
// contexts
|
// contexts
|
||||||
import { SettingsProvider } from './contexts/SettingsContext';
|
import { SettingsProvider } from './contexts/SettingsContext';
|
||||||
import { CollapseDrawerProvider } from './contexts/CollapseDrawerContext';
|
import { CollapseDrawerProvider } from './contexts/CollapseDrawerContext';
|
||||||
|
import { LanguageProvider } from './contexts/LanguageContext';
|
||||||
|
|
||||||
//
|
//
|
||||||
import App from './App';
|
import App from './App';
|
||||||
@@ -23,7 +24,9 @@ ReactDOM.render(
|
|||||||
<SettingsProvider>
|
<SettingsProvider>
|
||||||
<CollapseDrawerProvider>
|
<CollapseDrawerProvider>
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<App />
|
<LanguageProvider>
|
||||||
|
<App />
|
||||||
|
</LanguageProvider>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
</CollapseDrawerProvider>
|
</CollapseDrawerProvider>
|
||||||
</SettingsProvider>
|
</SettingsProvider>
|
||||||
|
|||||||
@@ -1,28 +1,24 @@
|
|||||||
import { useState } from 'react';
|
import React, { useState, useContext } from 'react';
|
||||||
// @mui
|
// @mui
|
||||||
import { MenuItem, Stack } from '@mui/material';
|
import { ButtonBase, Box, Typography, MenuItem, Stack } from '@mui/material';
|
||||||
// components
|
// components
|
||||||
import Image from '@/components/Image';
|
import Image from '@/components/Image';
|
||||||
import MenuPopover from '@/components/MenuPopover';
|
import MenuPopover from '@/components/MenuPopover';
|
||||||
import { IconButtonAnimate } from '@/components/animate';
|
import { IconButtonAnimate } from '@/components/animate';
|
||||||
|
import { LanguageContext } from '@/contexts/LanguageContext';
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
const LANGS = [
|
const LANGS = [
|
||||||
|
{
|
||||||
|
label: 'Bahasa Indonesia',
|
||||||
|
value: 'id-ID',
|
||||||
|
icon: '/icons/ic_flag_id.svg',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: 'English',
|
label: 'English',
|
||||||
value: 'en',
|
value: 'en-US',
|
||||||
icon: 'https://minimal-assets-api.vercel.app/assets/icons/ic_flag_en.svg',
|
icon: '/icons/ic_flag_en.svg',
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'German',
|
|
||||||
value: 'de',
|
|
||||||
icon: 'https://minimal-assets-api.vercel.app/assets/icons/ic_flag_de.svg',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'French',
|
|
||||||
value: 'fr',
|
|
||||||
icon: 'https://minimal-assets-api.vercel.app/assets/icons/ic_flag_fr.svg',
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -39,18 +35,34 @@ export default function LanguagePopover() {
|
|||||||
setOpen(null);
|
setOpen(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const { setCurrentLocale } = useContext(LanguageContext);
|
||||||
|
const handleChangeLanguage = (language) => {
|
||||||
|
localStorage.setItem('currentLocale', language);
|
||||||
|
setCurrentLocale(language);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<IconButtonAnimate
|
<Box display="flex" alignItems="center" border={0} borderColor="grey.300" borderRadius={3} p={1}>
|
||||||
onClick={handleOpen}
|
|
||||||
sx={{
|
<IconButtonAnimate
|
||||||
width: 40,
|
onClick={handleOpen}
|
||||||
height: 40,
|
sx={{
|
||||||
...(open && { bgcolor: 'action.selected' }),
|
width: 35,
|
||||||
}}
|
height: 35,
|
||||||
>
|
...(open && { bgcolor: 'action.selected' }),
|
||||||
<Image disabledEffect src={LANGS[0].icon} alt={LANGS[0].label} />
|
}}
|
||||||
</IconButtonAnimate>
|
>
|
||||||
|
<Image disabledEffect src={!localStorage.getItem('currentLocale') ? LANGS[0].icon : (localStorage.getItem('currentLocale') === 'id-ID' ? LANGS[0].icon : LANGS[1].icon)} alt={!localStorage.getItem('currentLocale') ? LANGS[0].label : (localStorage.getItem('currentLocale') === 'id-ID' ? LANGS[0].label : LANGS[1].label)} />
|
||||||
|
</IconButtonAnimate>
|
||||||
|
|
||||||
|
|
||||||
|
<ButtonBase onClick={handleOpen}>
|
||||||
|
<Typography variant="body2" component="span" marginRight={1} color="textPrimary">
|
||||||
|
Language
|
||||||
|
</Typography>
|
||||||
|
</ButtonBase>
|
||||||
|
</Box>
|
||||||
|
|
||||||
<MenuPopover
|
<MenuPopover
|
||||||
open={Boolean(open)}
|
open={Boolean(open)}
|
||||||
@@ -67,17 +79,22 @@ export default function LanguagePopover() {
|
|||||||
{LANGS.map((option) => (
|
{LANGS.map((option) => (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
key={option.value}
|
key={option.value}
|
||||||
selected={option.value === LANGS[0].value}
|
selected={option.value === localStorage.getItem('currentLocale')}
|
||||||
onClick={handleClose}
|
onClick = {() => {
|
||||||
|
handleClose();
|
||||||
|
handleChangeLanguage(option.value);
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Image
|
<Image
|
||||||
disabledEffect
|
disabledEffect
|
||||||
alt={option.label}
|
alt={option.label}
|
||||||
src={option.icon}
|
src={option.icon}
|
||||||
sx={{ width: 28, mr: 2 }}
|
sx={{ width: 28 }}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<Typography variant="body2" component="span" marginLeft={1} color="textPrimary">
|
||||||
{option.label}
|
{option.label}
|
||||||
|
</Typography>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
))}
|
))}
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|||||||
@@ -93,8 +93,8 @@ export default function DashboardHeader({
|
|||||||
|
|
||||||
<Stack direction="row" alignItems="center" spacing={{ xs: 0.5, sm: 1.5 }}>
|
<Stack direction="row" alignItems="center" spacing={{ xs: 0.5, sm: 1.5 }}>
|
||||||
<LanguagePopover />
|
<LanguagePopover />
|
||||||
<NotificationsPopover />
|
{/*<NotificationsPopover />
|
||||||
<ContactsPopover />
|
<ContactsPopover />*/}
|
||||||
<AccountPopover />
|
<AccountPopover />
|
||||||
</Stack>
|
</Stack>
|
||||||
</Toolbar>
|
</Toolbar>
|
||||||
|
|||||||
@@ -20,12 +20,12 @@ import DialogDetailClaim from '@/components/dialogs/DialogDetailClaim';
|
|||||||
|
|
||||||
// const [notifications, setNotifications] = useState([])
|
// const [notifications, setNotifications] = useState([])
|
||||||
|
|
||||||
// const itemList = [
|
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: '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: '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: '10:00 WIB' },
|
||||||
// // { info: 'Mohon lengkapi dokumen Mahen sadarsa', date: 'Selasa, 20 April 22', time: '11:00 WIB' },
|
{ info: 'Mohon lengkapi dokumen Mahen sadarsa', date: 'Selasa, 20 April 22', time: '11:00 WIB' },
|
||||||
// ];
|
];
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ export default function Dashboard() {
|
|||||||
const [policyData, setPolicyData] = useState<PolicyProps>(defaultPolicyData);
|
const [policyData, setPolicyData] = useState<PolicyProps>(defaultPolicyData);
|
||||||
|
|
||||||
// TODO Remove This
|
// TODO Remove This
|
||||||
const [itemList, setItemList] = useState([]);
|
//const [itemList, setItemList] = useState([]);
|
||||||
function handleDataLoaded(dataTable) {
|
function handleDataLoaded(dataTable) {
|
||||||
let dummyData = [];
|
let dummyData = [];
|
||||||
dataTable.map(function(data) {
|
dataTable.map(function(data) {
|
||||||
@@ -79,7 +79,7 @@ export default function Dashboard() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
setItemList(dummyData);
|
//setItemList(dummyData);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import React, { useContext, useRef, useState, useEffect } from 'react';
|
||||||
import { capitalCase } from "change-case";
|
import { capitalCase } from "change-case";
|
||||||
import { Link as RouterLink } from "react-router-dom";
|
import { Link as RouterLink } from "react-router-dom";
|
||||||
// @mui
|
// @mui
|
||||||
@@ -23,6 +24,7 @@ import Logo from "@/components/Logo";
|
|||||||
import Image from "@/components/Image";
|
import Image from "@/components/Image";
|
||||||
// sections
|
// sections
|
||||||
import { LoginForm } from "@/sections/auth/login";
|
import { LoginForm } from "@/sections/auth/login";
|
||||||
|
import { LanguageContext } from '@/contexts/LanguageContext';
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -70,6 +72,7 @@ const ContentStyle = styled("div")(({ theme }) => ({
|
|||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
export default function Login() {
|
export default function Login() {
|
||||||
|
const { localeData } = useContext(LanguageContext);
|
||||||
const { method } = useAuth();
|
const { method } = useAuth();
|
||||||
|
|
||||||
const smUp = useResponsive("up", "sm");
|
const smUp = useResponsive("up", "sm");
|
||||||
@@ -80,7 +83,7 @@ export default function Login() {
|
|||||||
<Page title="Login">
|
<Page title="Login">
|
||||||
<RootStyle>
|
<RootStyle>
|
||||||
<HeaderStyle>
|
<HeaderStyle>
|
||||||
<Logo sx={{ width: 150, height: 150 }} />
|
{/*<Logo sx={{ width: 150, height: 150 }} />
|
||||||
{smUp && (
|
{smUp && (
|
||||||
<Typography variant="body2" sx={{ mt: { md: -2 } }}>
|
<Typography variant="body2" sx={{ mt: { md: -2 } }}>
|
||||||
Has problem with your account? {""}
|
Has problem with your account? {""}
|
||||||
@@ -97,7 +100,7 @@ export default function Login() {
|
|||||||
Contact Us
|
Contact Us
|
||||||
</Link>
|
</Link>
|
||||||
</Typography>
|
</Typography>
|
||||||
)}
|
)}*/}
|
||||||
</HeaderStyle>
|
</HeaderStyle>
|
||||||
|
|
||||||
{/* {mdUp && (
|
{/* {mdUp && (
|
||||||
@@ -121,16 +124,17 @@ export default function Login() {
|
|||||||
alignItems="center"
|
alignItems="center"
|
||||||
sx={{ mb: 5 }}
|
sx={{ mb: 5 }}
|
||||||
>
|
>
|
||||||
|
<Logo sx={{ width: 90, height: 90 }} />
|
||||||
<Box sx={{ flexGrow: 1 }}>
|
<Box sx={{ flexGrow: 1 }}>
|
||||||
<Typography variant="h4" gutterBottom>
|
<Typography variant="h4" gutterBottom>
|
||||||
Sign in to LinkSehat
|
{localeData.txtLogin1}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography sx={{ color: "text.secondary" }}>
|
<Typography variant="body1" sx={{ color: 'text.secondary' }}>
|
||||||
Enter your details below.
|
{localeData.txtLogin2}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Tooltip
|
{/*<Tooltip
|
||||||
title={capitalCase(method)}
|
title={capitalCase(method)}
|
||||||
placement="right"
|
placement="right"
|
||||||
>
|
>
|
||||||
@@ -141,12 +145,12 @@ export default function Login() {
|
|||||||
sx={{ width: 32, height: 32 }}
|
sx={{ width: 32, height: 32 }}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
</Tooltip>
|
</Tooltip>*/}
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
<LoginForm />
|
<LoginForm />
|
||||||
|
|
||||||
{false && !smUp && (
|
{/*{false && !smUp && (
|
||||||
<Typography
|
<Typography
|
||||||
variant="body2"
|
variant="body2"
|
||||||
align="center"
|
align="center"
|
||||||
@@ -161,7 +165,7 @@ export default function Login() {
|
|||||||
Get started
|
Get started
|
||||||
</Link>
|
</Link>
|
||||||
</Typography>
|
</Typography>
|
||||||
)}
|
)}*/}
|
||||||
</ContentStyle>
|
</ContentStyle>
|
||||||
</Container>
|
</Container>
|
||||||
</RootStyle>
|
</RootStyle>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as Yup from 'yup';
|
import * as Yup from 'yup';
|
||||||
import { useState } from 'react';
|
import React, { useContext, useRef, useState, useEffect } from 'react';
|
||||||
import { Link as RouterLink, useNavigate } from 'react-router-dom';
|
import { Link as RouterLink, useNavigate } from 'react-router-dom';
|
||||||
// form
|
// form
|
||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
@@ -15,6 +15,7 @@ import useIsMountedRef from '@/hooks/useIsMountedRef';
|
|||||||
// components
|
// components
|
||||||
import Iconify from '@/components/Iconify';
|
import Iconify from '@/components/Iconify';
|
||||||
import { FormProvider, RHFTextField, RHFCheckbox } from '@/components/hook-form';
|
import { FormProvider, RHFTextField, RHFCheckbox } from '@/components/hook-form';
|
||||||
|
import { LanguageContext } from '@/contexts/LanguageContext';
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -26,6 +27,7 @@ type FormValuesProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default function LoginForm() {
|
export default function LoginForm() {
|
||||||
|
const { localeData } = useContext(LanguageContext);
|
||||||
const { login } = useAuth();
|
const { login } = useAuth();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
@@ -34,8 +36,8 @@ export default function LoginForm() {
|
|||||||
const [showPassword, setShowPassword] = useState(false);
|
const [showPassword, setShowPassword] = useState(false);
|
||||||
|
|
||||||
const LoginSchema = Yup.object().shape({
|
const LoginSchema = Yup.object().shape({
|
||||||
email: Yup.string().email('Email must be a valid email address').required('Email is required'),
|
email: Yup.string().email('Format email tidak valid').required('Email harus diisi'),
|
||||||
password: Yup.string().required('Password is required'),
|
password: Yup.string().required('Password harus diisi'),
|
||||||
});
|
});
|
||||||
|
|
||||||
const defaultValues = {
|
const defaultValues = {
|
||||||
@@ -75,10 +77,10 @@ export default function LoginForm() {
|
|||||||
return (
|
return (
|
||||||
<FormProvider methods={methods} onSubmit={handleSubmit(onSubmit)}>
|
<FormProvider methods={methods} onSubmit={handleSubmit(onSubmit)}>
|
||||||
<Stack spacing={3}>
|
<Stack spacing={3}>
|
||||||
<Alert severity="info">Email : admin@linksehat.dev & Password : password</Alert>
|
<Alert severity="info">{localeData.infoLogin}</Alert>
|
||||||
{!!errors.afterSubmit && <Alert severity="error">{errors.afterSubmit.message}</Alert>}
|
{!!errors.afterSubmit && <Alert severity="error">{errors.afterSubmit.data.meta.message}</Alert>}
|
||||||
|
|
||||||
<RHFTextField name="email" label="Email address" />
|
<RHFTextField name="email" label="Email" required/>
|
||||||
|
|
||||||
<RHFTextField
|
<RHFTextField
|
||||||
name="password"
|
name="password"
|
||||||
@@ -93,14 +95,15 @@ export default function LoginForm() {
|
|||||||
</InputAdornment>
|
</InputAdornment>
|
||||||
),
|
),
|
||||||
}}
|
}}
|
||||||
|
required
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
<Stack direction="row" alignItems="center" justifyContent="space-between" sx={{ my: 2 }}>
|
<Stack direction="row" alignItems="center" justifyContent="space-between" sx={{ my: 2 }}>
|
||||||
<RHFCheckbox name="remember" label="Remember me" />
|
{/*<RHFCheckbox name="remember" label="Remember me" />
|
||||||
<Link component={RouterLink} variant="subtitle2" to={PATH_AUTH.resetPassword}>
|
<Link component={RouterLink} variant="subtitle2" to={PATH_AUTH.resetPassword}>
|
||||||
Forgot password?
|
Forgot password?
|
||||||
</Link>
|
</Link>*/}
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
<LoadingButton
|
<LoadingButton
|
||||||
@@ -109,6 +112,7 @@ export default function LoginForm() {
|
|||||||
type="submit"
|
type="submit"
|
||||||
variant="contained"
|
variant="contained"
|
||||||
loading={isSubmitting}
|
loading={isSubmitting}
|
||||||
|
sx={{ marginTop: 2 }}
|
||||||
>
|
>
|
||||||
Login
|
Login
|
||||||
</LoadingButton>
|
</LoadingButton>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import {
|
|||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import { ChevronRight } from '@mui/icons-material';
|
import { ChevronRight } from '@mui/icons-material';
|
||||||
// React
|
// React
|
||||||
import React, { useState } from 'react';
|
import React, { useContext, useState } from 'react';
|
||||||
import { LoadingButton } from '@mui/lab';
|
import { LoadingButton } from '@mui/lab';
|
||||||
import Iconify from '@/components/Iconify';
|
import Iconify from '@/components/Iconify';
|
||||||
import { DatePicker, LocalizationProvider, MobileDatePicker } from '@mui/x-date-pickers';
|
import { DatePicker, LocalizationProvider, MobileDatePicker } from '@mui/x-date-pickers';
|
||||||
@@ -25,6 +25,7 @@ import MuiDialog from '@/components/MuiDialog';
|
|||||||
import axios from '@/utils/axios';
|
import axios from '@/utils/axios';
|
||||||
import { useSnackbar } from 'notistack';
|
import { useSnackbar } from 'notistack';
|
||||||
import DialogMember from './DialogMember';
|
import DialogMember from './DialogMember';
|
||||||
|
import { LanguageContext } from '@/contexts/LanguageContext';
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -46,29 +47,32 @@ const ItemNotificationStyle = styled(Card)(({ theme }) => ({
|
|||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
export default function CardSearchMember(handleSubmitSuccess) {
|
export default function CardSearchMember(handleSubmitSuccess) {
|
||||||
|
const { localeData } = useContext(LanguageContext);
|
||||||
const {enqueueSnackbar} = useSnackbar();
|
const {enqueueSnackbar} = useSnackbar();
|
||||||
|
|
||||||
const [noPolis, setNoPolis] = useState('AW001-01');
|
const [noPolis, setNoPolis] = useState('AW001-01');
|
||||||
const [tanggalLahir, setTanggalLahir] = useState('1991-01-10');
|
const [birthDate, setBirthDate] = useState('1991-01-10');
|
||||||
const [loadingBenefit, setLoadingBenefit] = useState(false);
|
const [loadingBenefit, setLoadingBenefit] = useState(false);
|
||||||
const [loadingClaim, setLoadingClaim] = useState(false);
|
const [loadingClaim, setLoadingClaim] = useState(false);
|
||||||
const [openDialogBenefit, setOpenDialogBenefit] = useState(false);
|
const [openDialogBenefit, setOpenDialogBenefit] = useState(false);
|
||||||
const [openDialogClaim, setOpenDialogClaim] = useState(false);
|
const [openDialogClaim, setOpenDialogClaim] = useState(false);
|
||||||
const [currentMember, setCurrentMember] = useState(null);
|
const [currentMember, setCurrentMember] = useState(null);
|
||||||
|
const [nameMember, setNameMember] = useState('');
|
||||||
|
|
||||||
function handleSearchMember() {
|
function handleSearchMember() {
|
||||||
setLoadingBenefit(true)
|
setLoadingBenefit(true)
|
||||||
|
|
||||||
axios.post('/search-member', {
|
axios.post('/search-member', {
|
||||||
no_polis: noPolis,
|
no_polis: noPolis,
|
||||||
birth_date: tanggalLahir ? fPostFormat(tanggalLahir, 'yyyy-MM-dd') : null
|
birth_date: birthDate ? fPostFormat(birthDate, 'yyyy-MM-dd') : null
|
||||||
})
|
})
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
setOpenDialogBenefit(true)
|
setOpenDialogBenefit(true)
|
||||||
setCurrentMember(response.data.data)
|
setCurrentMember(response.data.data)
|
||||||
|
setNameMember(response.data.data.name);
|
||||||
})
|
})
|
||||||
.catch(({response}) => {
|
.catch(({response}) => {
|
||||||
enqueueSnackbar(response.data.errors ? response.data.errors[0] : (response.data ? response.data.message : 'Opps, Something went Wrong!'), {variant : "error"})
|
enqueueSnackbar(response.data.errors ? response.data.errors[0] : (response.data ? response.data.meta.message : 'Opps, Something went Wrong!'), {variant : "error"})
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
setLoadingBenefit(false)
|
setLoadingBenefit(false)
|
||||||
@@ -90,23 +94,23 @@ export default function CardSearchMember(handleSubmitSuccess) {
|
|||||||
component="span"
|
component="span"
|
||||||
sx={{ display: 'flex', alignItems: 'center' }}
|
sx={{ display: 'flex', alignItems: 'center' }}
|
||||||
>
|
>
|
||||||
Pengajuan Jaminan
|
{localeData.txtCardSearchMember1}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Typography>
|
</Typography>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack gap={2}>
|
<Stack gap={2}>
|
||||||
<TextField variant="outlined" label="Member ID" value={noPolis} onChange={(event) => {
|
<TextField variant="outlined" label={localeData.txtCardSearchMember4} value={noPolis} onChange={(event) => {
|
||||||
setNoPolis(event.target.value)
|
setNoPolis(event.target.value)
|
||||||
}}></TextField>
|
}} required></TextField>
|
||||||
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
||||||
<DatePicker
|
<DatePicker
|
||||||
label="Tanggal Lahir"
|
label={localeData.txtCardSearchMember3}
|
||||||
value={tanggalLahir}
|
value={birthDate}
|
||||||
onChange={(newValue) => {
|
onChange={(newValue) => {
|
||||||
setTanggalLahir( (newValue));
|
setTanggalLahir( (newValue));
|
||||||
}}
|
}}
|
||||||
inputFormat="dd-MM-yyyy"
|
inputFormat="dd-MM-yyyy"
|
||||||
renderInput={(params) => <TextField {...params} />}
|
renderInput={(params) => <TextField {...params} required/>}
|
||||||
/>
|
/>
|
||||||
</LocalizationProvider>
|
</LocalizationProvider>
|
||||||
|
|
||||||
@@ -124,7 +128,7 @@ export default function CardSearchMember(handleSubmitSuccess) {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Iconify icon="eva:eye-fill" marginRight={0.75} />
|
<Iconify icon="eva:eye-fill" marginRight={0.75} />
|
||||||
Cari Member
|
{localeData.txtCardSearchMember2}
|
||||||
</LoadingButton>
|
</LoadingButton>
|
||||||
{/* <LoadingButton
|
{/* <LoadingButton
|
||||||
variant="contained"
|
variant="contained"
|
||||||
@@ -142,7 +146,7 @@ export default function CardSearchMember(handleSubmitSuccess) {
|
|||||||
{/*
|
{/*
|
||||||
<DialogBenefit open={openDialogBenefit} setOpen={setOpenDialogBenefit}></DialogBenefit> */}
|
<DialogBenefit open={openDialogBenefit} setOpen={setOpenDialogBenefit}></DialogBenefit> */}
|
||||||
<MuiDialog
|
<MuiDialog
|
||||||
title={{name: "Member"}}
|
title={{name: nameMember}}
|
||||||
openDialog={openDialogBenefit}
|
openDialog={openDialogBenefit}
|
||||||
setOpenDialog={setOpenDialogBenefit}
|
setOpenDialog={setOpenDialogBenefit}
|
||||||
content={DialogMember(currentMember, () => {setOpenDialogBenefit(false); handleSubmitSuccess()})}
|
content={DialogMember(currentMember, () => {setOpenDialogBenefit(false); handleSubmitSuccess()})}
|
||||||
|
|||||||
@@ -4,20 +4,22 @@ 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 } from "@mui/material";
|
||||||
import { Tab, Tabs } from "@mui/material";
|
import { Tab, Tabs } from "@mui/material";
|
||||||
import { Box, Stack } from "@mui/material";
|
import { Box, Stack } from "@mui/material";
|
||||||
import { useEffect, useState } from "react";
|
import React, { useEffect, useState, useContext } from "react";
|
||||||
import { fCurrency } from '@/utils/formatNumber';
|
import { fCurrency } from '@/utils/formatNumber';
|
||||||
import { fPostFormat } from '@/utils/formatTime';
|
import { fPostFormat } from '@/utils/formatTime';
|
||||||
import { Avatar } from '@mui/material';
|
import { Avatar } from '@mui/material';
|
||||||
import Iconify from '@/components/Iconify';
|
import Iconify from '@/components/Iconify';
|
||||||
import FormRequestClaim from './FormRequestClaim';
|
import FormRequestClaim from './FormRequestClaim';
|
||||||
|
import { LanguageContext } from '@/contexts/LanguageContext';
|
||||||
|
|
||||||
export default function DialogMember(member, handleSubmitSuccess) {
|
export default function DialogMember(member, handleSubmitSuccess) {
|
||||||
|
const { localeData } = useContext(LanguageContext);
|
||||||
const [currentTab, setCurrentTab] = useState('request')
|
const [currentTab, setCurrentTab] = useState('request')
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setCurrentTab('benefit')
|
setCurrentTab('detail')
|
||||||
}, [member])
|
}, [member])
|
||||||
|
|
||||||
function handleChangeTab(event: React.SyntheticEvent, newValue: string) {
|
function handleChangeTab(event: React.SyntheticEvent, newValue: string) {
|
||||||
@@ -67,13 +69,93 @@ export default function DialogMember(member, handleSubmitSuccess) {
|
|||||||
onChange={handleChangeTab}
|
onChange={handleChangeTab}
|
||||||
aria-label="wrapped label tabs example"
|
aria-label="wrapped label tabs example"
|
||||||
>
|
>
|
||||||
<Tab
|
<Tab value="detail" label={localeData.txtDialogMember3} />
|
||||||
value="benefit"
|
<Tab value="benefit" label={localeData.txtDialogMember1} />
|
||||||
label="Benefit Summary"
|
<Tab value="request" label={localeData.txtDialogMember2} />
|
||||||
/>
|
|
||||||
<Tab value="request" label="Request Penjaminan" />
|
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
|
<TabPanel value={currentTab} index={'detail'}>
|
||||||
|
<Stack spacing={2}>
|
||||||
|
<Grid container sx={{ pb: 2, mb: 2, borderBottom: 0 }}>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
<Grid container>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
Mapping ID
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
: {1 ?? '-'}
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
Policy Number
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
: {1 ?? '-'}
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
NRIC
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
: {1 ?? '-'}
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Grid item xs={6}>
|
||||||
|
NIK
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
: {1 ?? '-'}
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
Email
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
: {1 ?? '-'}
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
<Grid container>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
Birth Date
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
: {1 ?? '-'}
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
Gender
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
: {1 ?? '-'}
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
Marital Status
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
: {1 ?? '-'}
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
Language
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
: {1 ?? '-'}
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
Race
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
: {1 ?? '-'}
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
Relationship
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
: {1 ?? '-'}
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Stack>
|
||||||
|
</TabPanel>
|
||||||
|
|
||||||
<TabPanel value={currentTab} index={'benefit'}>
|
<TabPanel value={currentTab} index={'benefit'}>
|
||||||
<Grid container spacing={2}>
|
<Grid container spacing={2}>
|
||||||
{ member && member?.current_plan?.corporate_benefits?.map((corporateBenefit, index) => {return (
|
{ member && member?.current_plan?.corporate_benefits?.map((corporateBenefit, index) => {return (
|
||||||
|
|||||||
@@ -29,12 +29,18 @@ const setSession = (accessToken: string | null) => {
|
|||||||
if (accessToken) {
|
if (accessToken) {
|
||||||
localStorage.setItem('accessToken', accessToken);
|
localStorage.setItem('accessToken', accessToken);
|
||||||
axios.defaults.headers.common.Authorization = `Bearer ${accessToken}`;
|
axios.defaults.headers.common.Authorization = `Bearer ${accessToken}`;
|
||||||
|
axios.defaults.headers.common['Accept-Language'] = (localStorage.getItem('currentLocale') ? localStorage.getItem('currentLocale') : 'id-ID');
|
||||||
|
axios.defaults.headers.common['Accept'] = 'application/json';
|
||||||
|
axios.defaults.headers.common['Content-Type'] = 'application/json';
|
||||||
// This function below will handle when token is expired
|
// This function below will handle when token is expired
|
||||||
// const { exp } = jwtDecode(accessToken);
|
// const { exp } = jwtDecode(accessToken);
|
||||||
// handleTokenExpired(exp);
|
// handleTokenExpired(exp);
|
||||||
} else {
|
} else {
|
||||||
localStorage.removeItem('accessToken');
|
localStorage.removeItem('accessToken');
|
||||||
delete axios.defaults.headers.common.Authorization;
|
delete axios.defaults.headers.common.Authorization;
|
||||||
|
delete axios.defaults.headers.common['Accept-Language'];
|
||||||
|
delete axios.defaults.headers.common['Accept'];
|
||||||
|
delete axios.defaults.headers.common['Content-Type'];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
4723
pnpm-lock.yaml
generated
4723
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
8
resources/lang/en/Message.php
Normal file
8
resources/lang/en/Message.php
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'success' => 'Request has been successfully processed.',
|
||||||
|
'server_error' => 'Internal server error.',
|
||||||
|
'not_found' => 'Data not found',
|
||||||
|
'password' => 'Password wrong. Please try again.'
|
||||||
|
];
|
||||||
8
resources/lang/en/Validation.php
Normal file
8
resources/lang/en/Validation.php
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'required' => 'The :attribute field is required.',
|
||||||
|
'invalid' => 'The :attribute field is invalid.',
|
||||||
|
'max' => ':attribute cannot exceed :length characters.',
|
||||||
|
'email' => 'Invalid email format.'
|
||||||
|
];
|
||||||
8
resources/lang/id/Message.php
Normal file
8
resources/lang/id/Message.php
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'success' => 'Request berhasil dilakukan.',
|
||||||
|
'server_error' => 'Internal server error.',
|
||||||
|
'not_found' => 'Data tidak ditemukan.',
|
||||||
|
'password' => 'Password salah. Silakan coba lagi.'
|
||||||
|
];
|
||||||
8
resources/lang/id/Validation.php
Normal file
8
resources/lang/id/Validation.php
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'required' => 'Kolom :attribute harus diisi.',
|
||||||
|
'invalid' => 'Kolom :attribute tidak valid.',
|
||||||
|
'max' => ':attribute tidak boleh melebihi :length karakter.',
|
||||||
|
'email' => 'Format email salah.'
|
||||||
|
];
|
||||||
@@ -31,8 +31,9 @@ Route::prefix('client')->group(function () {
|
|||||||
Route::middleware('auth:sanctum')->group(function () {
|
Route::middleware('auth:sanctum')->group(function () {
|
||||||
Route::post('logout', [AuthController::class, 'logout'])->name('logout');
|
Route::post('logout', [AuthController::class, 'logout'])->name('logout');
|
||||||
Route::get('user', [UserController::class, 'index']);
|
Route::get('user', [UserController::class, 'index']);
|
||||||
Route::get('data/{id}', [DataController::class, 'show']);
|
// Route::get('data/{id}', [DataController::class, 'show']);
|
||||||
Route::put('data/{id}', [DataController::class, 'update' ]);
|
// Route::put('data/{id}', [DataController::class, 'update']);
|
||||||
|
|
||||||
|
|
||||||
Route::get('corporate-manage', [CorporateManageController::class, 'index']);
|
Route::get('corporate-manage', [CorporateManageController::class, 'index']);
|
||||||
Route::prefix('{corporate_id}')->group(function () {
|
Route::prefix('{corporate_id}')->group(function () {
|
||||||
|
|||||||
Reference in New Issue
Block a user