feat: Add initial implementation for vehicle and device management, including dedicated controllers and views, and a new reports controller.

This commit is contained in:
Pringgosutono
2025-12-16 14:07:21 +07:00
parent c3abd60868
commit 9940e6722d
5 changed files with 3772 additions and 3648 deletions

View File

@ -119,6 +119,7 @@ class DevicesController extends Controller
"assigned" => $req->assigned, "assigned" => $req->assigned,
"vid" => $req->vid, "vid" => $req->vid,
"available" => $req->available, "available" => $req->available,
"protocol" => $req->protocol,
]; ];
$rulesInput = [ $rulesInput = [
"device_id" => "required|numeric", "device_id" => "required|numeric",
@ -129,6 +130,7 @@ class DevicesController extends Controller
"assigned" => "required|numeric", "assigned" => "required|numeric",
"vid" => "nullable|numeric", "vid" => "nullable|numeric",
"available" => "required|numeric", "available" => "required|numeric",
"protocol" => "string",
]; ];
// validasi input // validasi input
@ -173,6 +175,7 @@ class DevicesController extends Controller
"crt_by" => $req->auth->uid, "crt_by" => $req->auth->uid,
"updt" => $now, "updt" => $now,
"updt_by" => $req->auth->uid, "updt_by" => $req->auth->uid,
"protocol" => $req->protocol,
]; ];
$id = Devices::addDevice($insDevice); $id = Devices::addDevice($insDevice);
@ -215,7 +218,7 @@ class DevicesController extends Controller
$log = [ $log = [
"module" => "Device", "module" => "Device",
"action" => "Create", "action" => "Create",
"desc" => "Add new device: ".$device_id, "desc" => "Add new device: " . $device_id,
]; ];
UserLogs::insert(Auth::user()->id, $log); UserLogs::insert(Auth::user()->id, $log);
return new Response($apiResp, $apiResp["meta"]["code"]); return new Response($apiResp, $apiResp["meta"]["code"]);
@ -241,6 +244,7 @@ class DevicesController extends Controller
"assigned" => $req->assigned, "assigned" => $req->assigned,
"vid" => $req->vid, "vid" => $req->vid,
"available" => $req->available, "available" => $req->available,
"protocol" => $req->protocol,
]; ];
$rulesInput = [ $rulesInput = [
"id" => "required|integer|not_in:0", "id" => "required|integer|not_in:0",
@ -252,6 +256,7 @@ class DevicesController extends Controller
"assigned" => "required|numeric", "assigned" => "required|numeric",
"vid" => "nullable|numeric", "vid" => "nullable|numeric",
"available" => "required|numeric", "available" => "required|numeric",
"protocol" => "string",
]; ];
// validasi input // validasi input
@ -364,6 +369,7 @@ class DevicesController extends Controller
"is_available" => $req->available, "is_available" => $req->available,
"updt" => $now, "updt" => $now,
"updt_by" => $req->auth->uid, "updt_by" => $req->auth->uid,
"protocol" => $req->protocol,
]; ];
Devices::updateDevice($id, $updtDevice); Devices::updateDevice($id, $updtDevice);
@ -374,7 +380,7 @@ class DevicesController extends Controller
$log = [ $log = [
"module" => "Device", "module" => "Device",
"action" => "Update", "action" => "Update",
"desc" => "Edit device: ".$device_id, "desc" => "Edit device: " . $device_id,
]; ];
UserLogs::insert(Auth::user()->id, $log); UserLogs::insert(Auth::user()->id, $log);
return new Response($apiResp, $apiResp["meta"]["code"]); return new Response($apiResp, $apiResp["meta"]["code"]);
@ -430,7 +436,7 @@ class DevicesController extends Controller
$log = [ $log = [
"module" => "Device", "module" => "Device",
"action" => "Delete", "action" => "Delete",
"desc" => "Delete device : ".$device[0]->device_id, "desc" => "Delete device : " . $device[0]->device_id,
]; ];
UserLogs::insert(Auth::user()->id, $log); UserLogs::insert(Auth::user()->id, $log);
return new Response($apiResp, $apiResp["meta"]["code"]); return new Response($apiResp, $apiResp["meta"]["code"]);

View File

@ -366,7 +366,7 @@ class ReportsController extends Controller
public function api_view_trip_detail(Request $req, $token) public function api_view_trip_detail(Request $req, $token)
{ {
// token = base64_encode(tgl0 + '|' + tgl1 + '|' + nopol1 + '|' + now_unix()) // token = base64(unix(start_time) + '|' + unix(end_time) + '|' + nopol + '|' + unix(now()))
// $token = "1759686805|1759693045|B.10-517|1765845676"; // $token = "1759686805|1759693045|B.10-517|1765845676";
$token = base64_decode($token); $token = base64_decode($token);
$token = explode('|', $token); $token = explode('|', $token);

View File

@ -74,7 +74,7 @@ class VehiclesController extends Controller
$list = DB::select("SELECT $list = DB::select("SELECT
v.id, v.name, v.device_id, nopol1, nopol2, nopol3, v.sum_milleage, v.id, v.name, v.device_id, nopol1, nopol2, nopol3, v.sum_milleage,
fvhc_img, vyear, t.`desc` type_name, c_name company_name, rltm.crt_d, rltm.crt crt_rltm, fvhc_img, vyear, t.`desc` type_name, c_name company_name, rltm.crt_d, rltm.crt crt_rltm,
dvc.crt, dvc.simcard, fuel_curr dvc.crt, dvc.simcard, fuel_curr, dvc.protocol
FROM t_vehicles as v FROM t_vehicles as v
INNER JOIN t_vehicles_detail AS vd ON v.id = vd.vid INNER JOIN t_vehicles_detail AS vd ON v.id = vd.vid
LEFT JOIN t_vehicles_types AS t ON v.type_id = t.id LEFT JOIN t_vehicles_types AS t ON v.type_id = t.id
@ -375,7 +375,7 @@ class VehiclesController extends Controller
$log = [ $log = [
"module" => "Vehicle", "module" => "Vehicle",
"action" => "Create", "action" => "Create",
"desc" => "Add new vehicle: ".$req->vhc_name, "desc" => "Add new vehicle: " . $req->vhc_name,
]; ];
UserLogs::insert(Auth::user()->id, $log); UserLogs::insert(Auth::user()->id, $log);
@ -642,7 +642,7 @@ class VehiclesController extends Controller
$log = [ $log = [
"module" => "Vehicle", "module" => "Vehicle",
"action" => "Update", "action" => "Update",
"desc" => "Update vehicle: ".$req->vhc_name, "desc" => "Update vehicle: " . $req->vhc_name,
]; ];
UserLogs::insert(Auth::user()->id, $log); UserLogs::insert(Auth::user()->id, $log);
return new Response($apiResp, $apiResp["meta"]["code"]); return new Response($apiResp, $apiResp["meta"]["code"]);
@ -706,7 +706,7 @@ class VehiclesController extends Controller
$log = [ $log = [
"module" => "Vehicle", "module" => "Vehicle",
"action" => "Delete", "action" => "Delete",
"desc" => "Delete vehicle: ".$vehicle[0]->name, "desc" => "Delete vehicle: " . $vehicle[0]->name,
]; ];
UserLogs::insert(Auth::user()->id, $log); UserLogs::insert(Auth::user()->id, $log);
return new Response($apiResp, $apiResp["meta"]["code"]); return new Response($apiResp, $apiResp["meta"]["code"]);

View File

@ -41,6 +41,7 @@
<th class="">#</th> <th class="">#</th>
<th class="text-center">Action</th> <th class="text-center">Action</th>
<th class="">Device ID</th> <th class="">Device ID</th>
<th class="">Device Type</th>
<th class="">Name</th> <th class="">Name</th>
<th class="text-end">SIM Card</th> <th class="text-end">SIM Card</th>
<th class="text-end">Type</th> <th class="text-end">Type</th>
@ -60,7 +61,8 @@
</div> </div>
</div> </div>
<div class="modal fade" data-bs-backdrop="static" data-bs-keyboard="false" id="mdlNewDevice" aria-labelledby="mdlNewDeviceLabel" aria-hidden="true"> <div class="modal fade" data-bs-backdrop="static" data-bs-keyboard="false" id="mdlNewDevice"
aria-labelledby="mdlNewDeviceLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog modal-dialog-centered modal-dialog-scrollable modal-xl"> <div class="modal-dialog modal-dialog modal-dialog-centered modal-dialog-scrollable modal-xl">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
@ -76,19 +78,23 @@
</div> </div>
<div class="row"> <div class="row">
<div class="col-sm-6"> <div class="col-sm-6">
<label for="add-device_id" class="col-form-label">Device ID<span class="text-danger">*</span></label> <label for="add-device_id" class="col-form-label">Device ID<span
class="text-danger">*</span></label>
<input type="number" name="add-device_id" id="add-device_id" class="form-control"> <input type="number" name="add-device_id" id="add-device_id" class="form-control">
</div> </div>
<div class="col-sm-6"> <div class="col-sm-6">
<label for="add-name" class="col-form-label">Name<span class="text-danger">*</span></label> <label for="add-name" class="col-form-label">Name<span
class="text-danger">*</span></label>
<input type="text" name="add-name" id="add-name" class="form-control"> <input type="text" name="add-name" id="add-name" class="form-control">
</div> </div>
<div class="col-sm-6"> <div class="col-sm-6">
<label for="add-simcard" class="col-form-label">Simcard<span class="text-danger">*</span></label> <label for="add-simcard" class="col-form-label">Simcard<span
class="text-danger">*</span></label>
<input type="number" name="add-simcard" id="add-simcard" class="form-control"> <input type="number" name="add-simcard" id="add-simcard" class="form-control">
</div> </div>
<div class="col-sm-6"> <div class="col-sm-6">
<label for="add-type" class="col-form-label">Type<span class="text-danger">*</span></label> <label for="add-type" class="col-form-label">Type<span
class="text-danger">*</span></label>
<select name="add-type" id="add-type" class="form-control" style="width:100%;"> <select name="add-type" id="add-type" class="form-control" style="width:100%;">
<option value="" selected disabled>Select Type</option> <option value="" selected disabled>Select Type</option>
<option value="{{ \App\Models\Devices::TYPE_BUILT_IN }}">Built-in</option> <option value="{{ \App\Models\Devices::TYPE_BUILT_IN }}">Built-in</option>
@ -96,7 +102,7 @@
</select> </select>
</div> </div>
<div class="col-sm-6"> <div class="col-sm-6">
<label for="add-protocol" class="col-form-label">Protocol</label> <label for="add-protocol" class="col-form-label">Device Type</label>
<input type="text" name="add-protocol" id="add-protocol" class="form-control"> <input type="text" name="add-protocol" id="add-protocol" class="form-control">
</div> </div>
</div> </div>
@ -108,36 +114,47 @@
</div> </div>
<div class="row"> <div class="row">
<div class="col-sm-6 col-md-3"> <div class="col-sm-6 col-md-3">
<label for="add-status" class="form-label">Status<span class="text-danger">*</span></label> <label for="add-status" class="form-label">Status<span
class="text-danger">*</span></label>
<div class="form-check form-switch"> <div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="add-status"> <input class="form-check-input" type="checkbox" id="add-status">
<label class="form-check-label" for="add-status"><span class="text-dark" id="add-txtStatus">Inactive</span></label> <label class="form-check-label" for="add-status"><span class="text-dark"
id="add-txtStatus">Inactive</span></label>
</div> </div>
</div> </div>
<div class="col-sm-6 col-md-3"> <div class="col-sm-6 col-md-3">
<div class="form-group"> <div class="form-group">
<label for="add-assigned" class="form-label">Installed ? <span class="text-danger">*</span></label> <label for="add-assigned" class="form-label">Installed ? <span
class="text-danger">*</span></label>
<div class="form-check form-switch"> <div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="add-assigned"> <input class="form-check-input" type="checkbox" id="add-assigned">
<label class="form-check-label" for="add-assigned"><span class="text-dark" id="add-txtAssigned">Released</span></label> <label class="form-check-label" for="add-assigned"><span class="text-dark"
id="add-txtAssigned">Released</span></label>
</div> </div>
</div> </div>
<div class="form-group vhcAssignGroup d-none"> <div class="form-group vhcAssignGroup d-none">
<label for="add-vhc_assigned" class="col-form-label">Vehicle<span class="text-danger">*</span></label> <label for="add-vhc_assigned" class="col-form-label">Vehicle<span
<select name="add-vhc_assigned" id="add-vhc_assigned" class="form-control" style="width:100%;"> class="text-danger">*</span></label>
<select name="add-vhc_assigned" id="add-vhc_assigned" class="form-control"
style="width:100%;">
<option value="" selected disabled>Select Type</option> <option value="" selected disabled>Select Type</option>
@foreach ($vhcs as $vhc) @foreach ($vhcs as $vhc)
<option value="{{ $vhc->vid }}" data-vid="{{ $vhc->vid }}" data-nopol="{{ $vhc->nopol1 . ' ' . $vhc->nopol2 . ' ' . $vhc->nopol3 }}">{{ $vhc->nopol1 . ' ' . $vhc->nopol2 . ' ' . $vhc->nopol3 }}</option> <option value="{{ $vhc->vid }}" data-vid="{{ $vhc->vid }}"
data-nopol="{{ $vhc->nopol1 . ' ' . $vhc->nopol2 . ' ' . $vhc->nopol3 }}">
{{ $vhc->nopol1 . ' ' . $vhc->nopol2 . ' ' . $vhc->nopol3 }}
</option>
@endforeach @endforeach
</select> </select>
</div> </div>
</div> </div>
<div class="col-sm-6 col-md-3"> <div class="col-sm-6 col-md-3">
<div class="form-group"> <div class="form-group">
<label for="add-available" class="form-label">Available Status ? <span class="text-danger">*</span></label> <label for="add-available" class="form-label">Available Status ? <span
class="text-danger">*</span></label>
<div class="form-check form-switch"> <div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="add-available"> <input class="form-check-input" type="checkbox" id="add-available">
<label class="form-check-label" for="add-available"><span class="text-dark" id="add-txtAvailable">Not Available</span></label> <label class="form-check-label" for="add-available"><span class="text-dark"
id="add-txtAvailable">Not Available</span></label>
</div> </div>
</div> </div>
</div> </div>
@ -153,7 +170,8 @@
</div> </div>
</div> </div>
<div class="modal fade" data-bs-backdrop="static" data-bs-keyboard="false" id="mdlUpdtDevice" aria-labelledby="mdlUpdtDeviceLabel" aria-hidden="true"> <div class="modal fade" data-bs-backdrop="static" data-bs-keyboard="false" id="mdlUpdtDevice"
aria-labelledby="mdlUpdtDeviceLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog modal-dialog-centered modal-dialog-scrollable modal-xl"> <div class="modal-dialog modal-dialog modal-dialog-centered modal-dialog-scrollable modal-xl">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
@ -169,19 +187,23 @@
</div> </div>
<div class="row"> <div class="row">
<div class="col-sm-6"> <div class="col-sm-6">
<label for="updt-device_id" class="col-form-label">Device ID<span class="text-danger">*</span></label> <label for="updt-device_id" class="col-form-label">Device ID<span
class="text-danger">*</span></label>
<input type="number" name="updt-device_id" id="updt-device_id" class="form-control"> <input type="number" name="updt-device_id" id="updt-device_id" class="form-control">
</div> </div>
<div class="col-sm-6"> <div class="col-sm-6">
<label for="updt-name" class="col-form-label">Name<span class="text-danger">*</span></label> <label for="updt-name" class="col-form-label">Name<span
class="text-danger">*</span></label>
<input type="text" name="updt-name" id="updt-name" class="form-control"> <input type="text" name="updt-name" id="updt-name" class="form-control">
</div> </div>
<div class="col-sm-6"> <div class="col-sm-6">
<label for="updt-simcard" class="col-form-label">Simcard<span class="text-danger">*</span></label> <label for="updt-simcard" class="col-form-label">Simcard<span
class="text-danger">*</span></label>
<input type="number" name="updt-simcard" id="updt-simcard" class="form-control"> <input type="number" name="updt-simcard" id="updt-simcard" class="form-control">
</div> </div>
<div class="col-sm-6"> <div class="col-sm-6">
<label for="updt-type" class="col-form-label">Type<span class="text-danger">*</span></label> <label for="updt-type" class="col-form-label">Type<span
class="text-danger">*</span></label>
<select name="updt-type" id="updt-type" class="form-control" style="width:100%;"> <select name="updt-type" id="updt-type" class="form-control" style="width:100%;">
<option value="" selected disabled>Select Type</option> <option value="" selected disabled>Select Type</option>
<option value="{{ \App\Models\Devices::TYPE_BUILT_IN }}">Built-in</option> <option value="{{ \App\Models\Devices::TYPE_BUILT_IN }}">Built-in</option>
@ -189,7 +211,7 @@
</select> </select>
</div> </div>
<div class="col-sm-6"> <div class="col-sm-6">
<label for="updt-protocol" class="col-form-label">Protocol</label> <label for="updt-protocol" class="col-form-label">Device Type</label>
<input type="text" name="updt-protocol" id="updt-protocol" class="form-control"> <input type="text" name="updt-protocol" id="updt-protocol" class="form-control">
</div> </div>
</div> </div>
@ -201,36 +223,47 @@
</div> </div>
<div class="row"> <div class="row">
<div class="col-sm-6 col-md-3"> <div class="col-sm-6 col-md-3">
<label for="updt-status" class="form-label">Status<span class="text-danger">*</span></label> <label for="updt-status" class="form-label">Status<span
class="text-danger">*</span></label>
<div class="form-check form-switch"> <div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="updt-status"> <input class="form-check-input" type="checkbox" id="updt-status">
<label class="form-check-label" for="updt-status"><span class="text-dark" id="updt-txtStatus">Inactive</span></label> <label class="form-check-label" for="updt-status"><span class="text-dark"
id="updt-txtStatus">Inactive</span></label>
</div> </div>
</div> </div>
<div class="col-sm-6 col-md-3"> <div class="col-sm-6 col-md-3">
<div class="form-group"> <div class="form-group">
<label for="updt-assigned" class="form-label">Installed ? <span class="text-danger">*</span></label> <label for="updt-assigned" class="form-label">Installed ? <span
class="text-danger">*</span></label>
<div class="form-check form-switch"> <div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="updt-assigned"> <input class="form-check-input" type="checkbox" id="updt-assigned">
<label class="form-check-label" for="updt-assigned"><span class="text-dark" id="updt-txtAssigned">Released</span></label> <label class="form-check-label" for="updt-assigned"><span class="text-dark"
id="updt-txtAssigned">Released</span></label>
</div> </div>
</div> </div>
<div class="form-group vhcAssignGroup d-none"> <div class="form-group vhcAssignGroup d-none">
<label for="updt-vhc_assigned" class="col-form-label">Vehicle<span class="text-danger">*</span></label> <label for="updt-vhc_assigned" class="col-form-label">Vehicle<span
<select name="updt-vhc_assigned" id="updt-vhc_assigned" class="form-control" style="width:100%;"> class="text-danger">*</span></label>
<select name="updt-vhc_assigned" id="updt-vhc_assigned" class="form-control"
style="width:100%;">
<option value="" selected disabled>Select Type</option> <option value="" selected disabled>Select Type</option>
@foreach ($vhcs as $vhc) @foreach ($vhcs as $vhc)
<option value="{{ $vhc->vid }}" data-vid="{{ $vhc->vid }}" data-nopol="{{ $vhc->nopol1 . ' ' . $vhc->nopol2 . ' ' . $vhc->nopol3 }}">{{ $vhc->nopol1 . ' ' . $vhc->nopol2 . ' ' . $vhc->nopol3 }}</option> <option value="{{ $vhc->vid }}" data-vid="{{ $vhc->vid }}"
data-nopol="{{ $vhc->nopol1 . ' ' . $vhc->nopol2 . ' ' . $vhc->nopol3 }}">
{{ $vhc->nopol1 . ' ' . $vhc->nopol2 . ' ' . $vhc->nopol3 }}
</option>
@endforeach @endforeach
</select> </select>
</div> </div>
</div> </div>
<div class="col-sm-6 col-md-3"> <div class="col-sm-6 col-md-3">
<div class="form-group"> <div class="form-group">
<label for="updt-available" class="form-label">Available Status ? <span class="text-danger">*</span></label> <label for="updt-available" class="form-label">Available Status ? <span
class="text-danger">*</span></label>
<div class="form-check form-switch"> <div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="updt-available"> <input class="form-check-input" type="checkbox" id="updt-available">
<label class="form-check-label" for="updt-available"><span class="text-dark" id="updt-txtAvailable">Not Available</span></label> <label class="form-check-label" for="updt-available"><span class="text-dark"
id="updt-txtAvailable">Not Available</span></label>
</div> </div>
</div> </div>
</div> </div>
@ -251,7 +284,8 @@
</div> </div>
</div> </div>
<div class="modal fade" data-bs-backdrop="static" data-bs-keyboard="false" id="mdlDelDevice" aria-labelledby="mdlDelDeviceLabel" aria-hidden="true"> <div class="modal fade" data-bs-backdrop="static" data-bs-keyboard="false" id="mdlDelDevice"
aria-labelledby="mdlDelDeviceLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-sm"> <div class="modal-dialog modal-dialog-centered modal-sm">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
@ -305,27 +339,27 @@
}; };
const Wrapper = { const Wrapper = {
activate: function() { activate: function () {
Wrapper.event(); Wrapper.event();
DTable.activate(); DTable.activate();
ANew.activate(); ANew.activate();
AUpdt.activate(); AUpdt.activate();
ADel.activate(); ADel.activate();
}, },
event: function() { event: function () {
$('#add-status').bind('change', function() { $('#add-status').bind('change', function () {
if ($(this).is(':checked')) if ($(this).is(':checked'))
$('#add-txtStatus').html('Active') $('#add-txtStatus').html('Active')
else else
$('#add-txtStatus').html('Inactive') $('#add-txtStatus').html('Inactive')
}); });
$('#updt-status').bind('change', function() { $('#updt-status').bind('change', function () {
if ($(this).is(':checked')) if ($(this).is(':checked'))
$('#updt-txtStatus').html('Active') $('#updt-txtStatus').html('Active')
else else
$('#updt-txtStatus').html('Inactive') $('#updt-txtStatus').html('Inactive')
}); });
$('#add-assigned').bind('change', function() { $('#add-assigned').bind('change', function () {
if ($(this).is(':checked')) { if ($(this).is(':checked')) {
$('#add-txtAssigned').html('Installed') $('#add-txtAssigned').html('Installed')
$('.vhcAssignGroup').removeClass('d-none'); $('.vhcAssignGroup').removeClass('d-none');
@ -334,7 +368,7 @@
$('.vhcAssignGroup').addClass('d-none'); $('.vhcAssignGroup').addClass('d-none');
} }
}); });
$('#updt-assigned').bind('change', function() { $('#updt-assigned').bind('change', function () {
if ($(this).is(':checked')) { if ($(this).is(':checked')) {
$('#updt-txtAssigned').html('Installed') $('#updt-txtAssigned').html('Installed')
$('.vhcAssignGroup').removeClass('d-none'); $('.vhcAssignGroup').removeClass('d-none');
@ -343,13 +377,13 @@
$('.vhcAssignGroup').addClass('d-none'); $('.vhcAssignGroup').addClass('d-none');
} }
}); });
$('#add-available').bind('change', function() { $('#add-available').bind('change', function () {
if ($(this).is(':checked')) if ($(this).is(':checked'))
$('#add-txtAvailable').html('Tersedia') $('#add-txtAvailable').html('Tersedia')
else else
$('#add-txtAvailable').html('Not Available') $('#add-txtAvailable').html('Not Available')
}); });
$('#updt-available').bind('change', function() { $('#updt-available').bind('change', function () {
if ($(this).is(':checked')) if ($(this).is(':checked'))
$('#updt-txtAvailable').html('Tersedia') $('#updt-txtAvailable').html('Tersedia')
else else
@ -372,10 +406,10 @@
}; };
const DTable = { const DTable = {
activate: function() { activate: function () {
DTable.reload(); DTable.reload();
}, },
reload: function() { reload: function () {
// $('#tDevices').DataTable(); // $('#tDevices').DataTable();
// if (Driver.Table.firstInitDataTable == 1) { loadTableSkeletonLoading() } else { Driver.Table.firstInitDataTable = 1; } // if (Driver.Table.firstInitDataTable == 1) { loadTableSkeletonLoading() } else { Driver.Table.firstInitDataTable = 1; }
$('#tDevices').DataTable({ $('#tDevices').DataTable({
@ -387,7 +421,7 @@
ajax: { ajax: {
url: "{{ route('api_list_devices') }}", url: "{{ route('api_list_devices') }}",
type: 'GET', type: 'GET',
complete: function(jqXHR, textStatus, c) { complete: function (jqXHR, textStatus, c) {
let count = jqXHR.responseJSON.count; let count = jqXHR.responseJSON.count;
if (typeof count != 'undefined') { if (typeof count != 'undefined') {
$('#count_devices').text(count); $('#count_devices').text(count);
@ -409,7 +443,7 @@
visible: true, visible: true,
orderable: true, orderable: true,
searchable: true, searchable: true,
render: function(data, type, row, meta) { render: function (data, type, row, meta) {
let action = ` let action = `
<a href="#" class="text-decoration-none me-1 btnUpdtDevice"> <a href="#" class="text-decoration-none me-1 btnUpdtDevice">
<span class="icon ion-eye fz-16"></span> <span class="icon ion-eye fz-16"></span>
@ -427,15 +461,22 @@
visible: true, visible: true,
orderable: true, orderable: true,
searchable: true, searchable: true,
createdCell: function(td, cellData, rowData, row, col) { createdCell: function (td, cellData, rowData, row, col) {
$(td).attr('data-id', rowData.id); $(td).attr('data-id', rowData.id);
$(td).attr('data-device_id', rowData.device_id); $(td).attr('data-device_id', rowData.device_id);
$(td).attr('data-simcard', rowData.simcard); $(td).attr('data-simcard', rowData.simcard);
}, },
render: function(data, type, row, meta) { render: function (data, type, row, meta) {
return `<span class="d-none">${data}</span>` + Helper.splitEvery4Char(`${data}`); return `<span class="d-none">${data}</span>` + Helper.splitEvery4Char(`${data}`);
}, },
}, },
{
data: 'protocol',
className: 'text-end text-nowrap',
visible: true,
orderable: true,
searchable: true,
},
{ {
data: 'name', data: 'name',
className: 'text-end text-nowrap', className: 'text-end text-nowrap',
@ -449,7 +490,7 @@
visible: true, visible: true,
orderable: true, orderable: true,
searchable: true, searchable: true,
render: function(data, type, row, meta) { render: function (data, type, row, meta) {
return `<span class="d-none">${data}</span>` + Helper.splitEvery4Char(`${data}`); return `<span class="d-none">${data}</span>` + Helper.splitEvery4Char(`${data}`);
}, },
}, },
@ -459,7 +500,7 @@
visible: true, visible: true,
orderable: true, orderable: true,
searchable: true, searchable: true,
render: function(data, type, row, meta) { render: function (data, type, row, meta) {
if (data == State.type.built_in) return 'Built-In'; if (data == State.type.built_in) return 'Built-In';
return 'Portable'; return 'Portable';
}, },
@ -470,7 +511,7 @@
visible: true, visible: true,
orderable: true, orderable: true,
searchable: true, searchable: true,
render: function(data, type, row, meta) { render: function (data, type, row, meta) {
if (data == State.stts_isact.active) return '<span class="badge rounded-pill bg-success">Active</span>'; if (data == State.stts_isact.active) return '<span class="badge rounded-pill bg-success">Active</span>';
return '<span class="badge rounded-pill bg-danger">Inactive</span>'; return '<span class="badge rounded-pill bg-danger">Inactive</span>';
} }
@ -492,7 +533,7 @@
visible: true, visible: true,
orderable: true, orderable: true,
searchable: true, searchable: true,
render: function(data, type, row, meta) { render: function (data, type, row, meta) {
if (data == State.stts_assigned.assigned) { if (data == State.stts_assigned.assigned) {
return '<span class="badge rounded-pill bg-success">Installed</span>' return '<span class="badge rounded-pill bg-success">Installed</span>'
} else { } else {
@ -513,7 +554,7 @@
visible: true, visible: true,
orderable: true, orderable: true,
searchable: true, searchable: true,
render: function(data, type, row, meta) { render: function (data, type, row, meta) {
if (data == State.stts_available.available) { if (data == State.stts_available.available) {
return '<span class="badge rounded-pill bg-success">Available</span>' return '<span class="badge rounded-pill bg-success">Available</span>'
} else { } else {
@ -527,24 +568,24 @@
}; };
const ANew = { const ANew = {
activate: function() { activate: function () {
ANew.event(); ANew.event();
}, },
event: function() { event: function () {
// modal // modal
$('#btnMdlNewDevice').on('click', function() { $('#btnMdlNewDevice').on('click', function () {
$('#mdlNewDevice').modal('show'); $('#mdlNewDevice').modal('show');
}); });
$('#mdlNewDevice').on('shown.bs.modal', function() { $('#mdlNewDevice').on('shown.bs.modal', function () {
}); });
// button // button
$('#btnSubmitNewDevice').on('click', function() { $('#btnSubmitNewDevice').on('click', function () {
let data = ANew.getData(); let data = ANew.getData();
ANew.submitData(data); ANew.submitData(data);
}); });
}, },
getData: function() { getData: function () {
let data = {}; let data = {};
data.device_id = $('#add-device_id').val(); data.device_id = $('#add-device_id').val();
data.name = $('#add-name').val(); data.name = $('#add-name').val();
@ -573,7 +614,7 @@
return data; return data;
}, },
submitData: async function(data) { submitData: async function (data) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (typeof $('#btnSubmitNewDevice').attr('disabed') != 'undefined') { if (typeof $('#btnSubmitNewDevice').attr('disabed') != 'undefined') {
resolve({ resolve({
@ -626,12 +667,12 @@
} }
const AUpdt = { const AUpdt = {
activate: function() { activate: function () {
AUpdt.event(); AUpdt.event();
}, },
event: function() { event: function () {
// modal // modal
$('#tDevices').on('click', '.btnUpdtDevice', async function(e) { $('#tDevices').on('click', '.btnUpdtDevice', async function (e) {
let id = $(e.target).closest('tr').find('td[data-id]').data('id'); let id = $(e.target).closest('tr').find('td[data-id]').data('id');
let resp = await AUpdt.reqData({ let resp = await AUpdt.reqData({
id id
@ -642,16 +683,16 @@
} }
AUpdt.passDataToView(resp.data); AUpdt.passDataToView(resp.data);
}); });
$('#mdlUpdtDevice').on('shown.bs.modal', function() { $('#mdlUpdtDevice').on('shown.bs.modal', function () {
}); });
// button // button
$('#btnSubmitUpdtDevices').on('click', function() { $('#btnSubmitUpdtDevices').on('click', function () {
let data = AUpdt.getData(); let data = AUpdt.getData();
AUpdt.submitData(data); AUpdt.submitData(data);
}); });
}, },
reqData: function(params) { reqData: function (params) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
$.ajax({ $.ajax({
url: "{{ route('api_show_device', '') }}/" + params.id, url: "{{ route('api_show_device', '') }}/" + params.id,
@ -689,7 +730,7 @@
}) })
}); });
}, },
passDataToView: async function(data) { passDataToView: async function (data) {
$('#updt-device_id').val(data.device_id); $('#updt-device_id').val(data.device_id);
$('#updt-name').val(data.name); $('#updt-name').val(data.name);
$('#updt-simcard').val(data.simcard); $('#updt-simcard').val(data.simcard);
@ -708,9 +749,9 @@
$('#updt-assigned').prop('checked', false).trigger('change'); $('#updt-assigned').prop('checked', false).trigger('change');
} }
let vhc_id = (data?.vhc_id) ? data?.vhc_id : ''; let vhc_id = (data?.vhc_id) ? data?.vhc_id : '';
if (vhc_id == 0 || vhc_id == '') {} else { if (vhc_id == 0 || vhc_id == '') { } else {
if ($(`#updt-vhc_assigned option[value='${vhc_id}']`).length < 1) { if ($(`#updt-vhc_assigned option[value='${vhc_id}']`).length < 1) {
$('#updt-vhc_assigned').append(`<option value="${vhc_id }}" data-vid="${vhc_id }}" data-nopol="${data.vhc_nopol1} ${data.vhc_nopol2} ${data.vhc_nopol3}</option>`); $('#updt-vhc_assigned').append(`<option value="${vhc_id}}" data-vid="${vhc_id}}" data-nopol="${data.vhc_nopol1} ${data.vhc_nopol2} ${data.vhc_nopol3}</option>`);
$('#updt-vhc_assigned').select2({ $('#updt-vhc_assigned').select2({
dropdownParent: $('#mdlUpdtDevice'), dropdownParent: $('#mdlUpdtDevice'),
}); });
@ -727,7 +768,7 @@
$('#mdlUpdtDevice').data('id', data.id); $('#mdlUpdtDevice').data('id', data.id);
$('#mdlUpdtDevice').modal('show'); $('#mdlUpdtDevice').modal('show');
}, },
getData: function() { getData: function () {
let data = {}; let data = {};
data.id = $('#mdlUpdtDevice').data('id'); data.id = $('#mdlUpdtDevice').data('id');
@ -758,7 +799,7 @@
return data; return data;
}, },
submitData: async function(data) { submitData: async function (data) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (typeof $('#btnSubmitUpdtDevices').attr('disabed') != 'undefined') { if (typeof $('#btnSubmitUpdtDevices').attr('disabed') != 'undefined') {
resolve({ resolve({
@ -811,12 +852,12 @@
} }
const ADel = { const ADel = {
activate: function() { activate: function () {
ADel.event(); ADel.event();
}, },
event: function() { event: function () {
// on table // on table
$('#tDevices').on('click', '.btnDelDevice', function(e) { $('#tDevices').on('click', '.btnDelDevice', function (e) {
let row = $(e.target).closest('tr'); let row = $(e.target).closest('tr');
let id = row.find('td[data-id]').data('id'); let id = row.find('td[data-id]').data('id');
let device_id = row.find('td[data-device_id]').data('device_id'); let device_id = row.find('td[data-device_id]').data('device_id');
@ -829,14 +870,14 @@
$('#mdlDelDevice').data('id', id); $('#mdlDelDevice').data('id', id);
$('#mdlDelDevice').modal('show'); $('#mdlDelDevice').modal('show');
}); });
$('#btnSubmitDelDevice').on('click', function() { $('#btnSubmitDelDevice').on('click', function () {
let data = { let data = {
id: $('#mdlDelDevice').data('id'), id: $('#mdlDelDevice').data('id'),
}; };
ADel.submitData(data); ADel.submitData(data);
}); });
// on modal update // on modal update
$('#btnDelDevice_updt').on('click', function(e) { $('#btnDelDevice_updt').on('click', function (e) {
const { const {
id, id,
device_id, device_id,
@ -851,11 +892,11 @@
$('#mdlDelDevice').modal('show'); $('#mdlDelDevice').modal('show');
}); });
}, },
passDataToView: function(data) { passDataToView: function (data) {
$('#del-device_id').text(data.device_id); $('#del-device_id').text(data.device_id);
$('#del-simcard').text(data.simcard); $('#del-simcard').text(data.simcard);
}, },
submitData: async function(data) { submitData: async function (data) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (typeof $('#btnSubmitDelDevice').attr('disabed') != 'undefined') { if (typeof $('#btnSubmitDelDevice').attr('disabed') != 'undefined') {
resolve({ resolve({

View File

@ -49,12 +49,15 @@
<th class="">Type</th> <th class="">Type</th>
<th class="">Service Start</th> <th class="">Service Start</th>
@if ($user_role != \App\Models\Users::ROLE_VENDOR) @if ($user_role != \App\Models\Users::ROLE_VENDOR)
<th class="">Device ID</th> <th class="">Device</th>
<th class="">SIM Card</th> <th class="">SIM Card</th>
<th class="">Last Update</th> <th class="">Last Update</th>
@endif @endif
<th class=""><span class="text-nowrap">Mileage <span class="text-lowercase">(km)</span></span></th> <th class=""><span class="text-nowrap">Mileage <spanm class="text-lowercase">
<th class=""><span class="text-nowrap">Fuel <span class="text-lowercase">(L)</span></span></th> (km)</span></span></th>
<th class=""><span class="text-nowrap">Fuel <span
class="text-lowercase">(L)</span></span></th>
<th class=""><span class="text-nowrap">Fuel Support</span></th>
<th class="">Company</th> <th class="">Company</th>
</tr> </tr>
</thead> </thead>
@ -68,7 +71,8 @@
</div> </div>
</div> </div>
<div class="modal fade" data-bs-backdrop="static" data-bs-keyboard="false" id="mdlNewVhc" aria-labelledby="mdlNewVhcLabel" aria-hidden="true"> <div class="modal fade" data-bs-backdrop="static" data-bs-keyboard="false" id="mdlNewVhc"
aria-labelledby="mdlNewVhcLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog modal-dialog-centered modal-dialog-scrollable modal-xl"> <div class="modal-dialog modal-dialog modal-dialog-centered modal-dialog-scrollable modal-xl">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
@ -87,15 +91,21 @@
<div class="col-5"> <div class="col-5">
<label for="add-fvhc-img" class="col-form-label">Front Vehicle Photo:</label> <label for="add-fvhc-img" class="col-form-label">Front Vehicle Photo:</label>
<br> <br>
<img id="add-fvhc-img" class="img-fluid landscape-photo" style="max-height: 19.6vh" src="https://products.unitedtractors.com/wp-content/uploads/2021/03/udtruck-GWE370.png" alt="add-fvhc-img"> <img id="add-fvhc-img" class="img-fluid landscape-photo" style="max-height: 19.6vh"
src="https://products.unitedtractors.com/wp-content/uploads/2021/03/udtruck-GWE370.png"
alt="add-fvhc-img">
<div id="add-group_fvhc_spinner" class="d-none"> <div id="add-group_fvhc_spinner" class="d-none">
<div class="spinner-border" role="status"> <div class="spinner-border" role="status">
<span class="visually-hidden">Loading...</span> <span class="visually-hidden">Loading...</span>
</div> </div>
</div> </div>
<div id="add-group_rotate_fvhc" class="pt-2 d-flex justify-content-start d-none"> <div id="add-group_rotate_fvhc" class="pt-2 d-flex justify-content-start d-none">
<button type="button" class="btnRotateLeft btn btn-sm btn-outline-primary ml-1" style="padding:0.25rem 0.5rem;border-radius:0.25rem;"><i class="icon ion-arrow-return-left"></i></button> <button type="button" class="btnRotateLeft btn btn-sm btn-outline-primary ml-1"
<button type="button" class="btnRotateRight btn btn-sm btn-outline-primary ml-1" style="padding:0.25rem 0.5rem;border-radius:0.25rem;"><i class="icon ion-arrow-return-right"></i></button> style="padding:0.25rem 0.5rem;border-radius:0.25rem;"><i
class="icon ion-arrow-return-left"></i></button>
<button type="button" class="btnRotateRight btn btn-sm btn-outline-primary ml-1"
style="padding:0.25rem 0.5rem;border-radius:0.25rem;"><i
class="icon ion-arrow-return-right"></i></button>
</div> </div>
<input type="file" id="add-fvhc-file" class="form-control mt-3"> <input type="file" id="add-fvhc-file" class="form-control mt-3">
<input type="text" id="add-fvhc-base64" class="form-control" hidden> <input type="text" id="add-fvhc-base64" class="form-control" hidden>
@ -110,7 +120,10 @@
<select id="add-deviceid" class="form-control" style="width:100%;"> <select id="add-deviceid" class="form-control" style="width:100%;">
<option value="">Tidak dipilih</option> <option value="">Tidak dipilih</option>
@foreach ($devices as $device) @foreach ($devices as $device)
<option value="{{ $device->id }}" data-device_id="{{ $device->device_id }}" data-simcard="{{ $device->simcard }}" data-type="{{ $device->type }}">{{ $device->name . ' (' . implode(' ', str_split($device->device_id, 4)) . ')' }}</option> <option value="{{ $device->id }}" data-device_id="{{ $device->device_id }}"
data-simcard="{{ $device->simcard }}" data-type="{{ $device->type }}">{{
$device->name . ' (' . implode(' ', str_split($device->device_id, 4)) .
')' }}</option>
@endforeach @endforeach
</select> </select>
</div> --}} </div> --}}
@ -139,7 +152,8 @@
<div class="row"> <div class="row">
<div class="col-sm-6"> <div class="col-sm-6">
<div class="mb-0"> <div class="mb-0">
<label for="add-speedlimit" class="col-form-label">Speed Limit (kph):</label> <label for="add-speedlimit" class="col-form-label">Speed Limit
(kph):</label>
<input type="number" id="add-speedlimit" class="form-control"> <input type="number" id="add-speedlimit" class="form-control">
</div> </div>
</div> </div>
@ -153,11 +167,14 @@
<div class="row"> <div class="row">
<div class="col-sm-6"> <div class="col-sm-6">
<div class="mb-0"> <div class="mb-0">
<label for="add-dc_code" class="col-form-label">Distribution Category:</label> <label for="add-dc_code" class="col-form-label">Distribution
Category:</label>
<select id="add-dc_code" class="form-control" style="width:100%;"> <select id="add-dc_code" class="form-control" style="width:100%;">
<option value="">Choose</option> <option value="">Choose</option>
@foreach ($listDistribution as $distribution) @foreach ($listDistribution as $distribution)
<option value="{{ $distribution->dc_code }}">{{ $distribution->dc_code }} - {{ $distribution->dc_name }}</option> <option value="{{ $distribution->dc_code }}">
{{ $distribution->dc_code }} - {{ $distribution->dc_name }}
</option>
@endforeach @endforeach
</select> </select>
</div> </div>
@ -168,7 +185,9 @@
<select id="add-pool_code" class="form-control" style="width:100%;"> <select id="add-pool_code" class="form-control" style="width:100%;">
<option value="">Choose</option> <option value="">Choose</option>
@foreach ($listPool as $pool) @foreach ($listPool as $pool)
<option value="{{ $pool->pool_code }}">{{ $pool->pool_code }} - {{ $pool->pool_name }}</option> <option value="{{ $pool->pool_code }}">{{ $pool->pool_code }} -
{{ $pool->pool_name }}
</option>
@endforeach @endforeach
</select> </select>
</div> </div>
@ -189,7 +208,8 @@
<option value="">Choose</option> <option value="">Choose</option>
@foreach ($drivers as $driver) @foreach ($drivers as $driver)
<option value="{{ $driver->id }}"> <option value="{{ $driver->id }}">
{{ $driver->fullname . ' (+' . $driver->phone_code . implode(' ', str_split($driver->phone, 4)) . ')' }} {{ $driver->fullname . ' (+' . $driver->phone_code . implode(' ',
str_split($driver->phone, 4)) . ')' }}
</option> </option>
@endforeach @endforeach
</select> </select>
@ -200,7 +220,8 @@
<option value="">Choose</option> <option value="">Choose</option>
@foreach ($drivers as $driver) @foreach ($drivers as $driver)
<option value="{{ $driver->id }}"> <option value="{{ $driver->id }}">
{{ $driver->fullname . ' (+' . $driver->phone_code . implode(' ', str_split($driver->phone, 4)) . ')' }} {{ $driver->fullname . ' (+' . $driver->phone_code . implode(' ',
str_split($driver->phone, 4)) . ')' }}
</option> </option>
@endforeach @endforeach
</select> </select>
@ -216,15 +237,21 @@
<div class="col-5"> <div class="col-5">
<label for="add-stnk-img" class="col-form-label">CoV Photo:</label> <label for="add-stnk-img" class="col-form-label">CoV Photo:</label>
<br> <br>
<img id="add-stnk-img" class="img-fluid landscape-photo" src="https://cdn-2.tstatic.net/kaltim/foto/bank/images/ilustrasi-surat-tanda-nomor-kendaraan-bermotor-stnk.jpg" alt="add-stnk-img"> <img id="add-stnk-img" class="img-fluid landscape-photo"
src="https://cdn-2.tstatic.net/kaltim/foto/bank/images/ilustrasi-surat-tanda-nomor-kendaraan-bermotor-stnk.jpg"
alt="add-stnk-img">
<div id="add-group_stnk_spinner" class="d-none"> <div id="add-group_stnk_spinner" class="d-none">
<div class="spinner-border" role="status"> <div class="spinner-border" role="status">
<span class="visually-hidden">Loading...</span> <span class="visually-hidden">Loading...</span>
</div> </div>
</div> </div>
<div id="add-group_rotate_stnk" class="pt-2 d-flex justify-content-start d-none"> <div id="add-group_rotate_stnk" class="pt-2 d-flex justify-content-start d-none">
<button type="button" class="btnRotateLeft btn btn-sm btn-outline-primary ml-1" style="padding:0.25rem 0.5rem;border-radius:0.25rem;"><i class="icon ion-arrow-return-left"></i></button> <button type="button" class="btnRotateLeft btn btn-sm btn-outline-primary ml-1"
<button type="button" class="btnRotateRight btn btn-sm btn-outline-primary ml-1" style="padding:0.25rem 0.5rem;border-radius:0.25rem;"><i class="icon ion-arrow-return-right"></i></button> style="padding:0.25rem 0.5rem;border-radius:0.25rem;"><i
class="icon ion-arrow-return-left"></i></button>
<button type="button" class="btnRotateRight btn btn-sm btn-outline-primary ml-1"
style="padding:0.25rem 0.5rem;border-radius:0.25rem;"><i
class="icon ion-arrow-return-right"></i></button>
</div> </div>
<input type="file" id="add-stnk-file" class="form-control mt-3"> <input type="file" id="add-stnk-file" class="form-control mt-3">
<input type="text" id="add-stnk-base64" class="form-control" hidden> <input type="text" id="add-stnk-base64" class="form-control" hidden>
@ -246,13 +273,16 @@
<label for="add-nopol1" class="colr-form-label">License Plate Number</label> <label for="add-nopol1" class="colr-form-label">License Plate Number</label>
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<input type="text" id="add-nopol1" class="form-control" placeholder="ex: A-25-391"> <input type="text" id="add-nopol1" class="form-control"
placeholder="ex: A-25-391">
</div> </div>
<div class="col d-none"> <div class="col d-none">
<input type="number" id="add-nopol2" class="form-control" placeholder="ex: 3633"> <input type="number" id="add-nopol2" class="form-control"
placeholder="ex: 3633">
</div> </div>
<div class="col d-none"> <div class="col d-none">
<input type="text" id="add-nopol3" class="form-control" placeholder="ex: EEV"> <input type="text" id="add-nopol3" class="form-control"
placeholder="ex: EEV">
</div> </div>
</div> </div>
</div> </div>
@ -266,7 +296,8 @@
<input type="number" id="add-stnk-cc" class="form-control"> <input type="number" id="add-stnk-cc" class="form-control">
</div> </div>
<div class="col-6"> <div class="col-6">
<label for="add-stnk-vin" class="col-form-label">Vehicle Identity Number:</label> <label for="add-stnk-vin" class="col-form-label">Vehicle Identity
Number:</label>
<input type="string" id="add-stnk-vin" class="form-control"> <input type="string" id="add-stnk-vin" class="form-control">
</div> </div>
<div class="col-6"> <div class="col-6">
@ -282,11 +313,13 @@
<input type="string" id="add-stnk-fueltype" class="form-control"> <input type="string" id="add-stnk-fueltype" class="form-control">
</div> </div>
<div class="col-6"> <div class="col-6">
<label for="add-stnk-tnkbcolor" class="col-form-label">License Plat Color:</label> <label for="add-stnk-tnkbcolor" class="col-form-label">License Plat
Color:</label>
<input type="string" id="add-stnk-tnkbcolor" class="form-control"> <input type="string" id="add-stnk-tnkbcolor" class="form-control">
</div> </div>
<div class="col-6"> <div class="col-6">
<label for="add-stnk-regisyear" class="col-form-label">Registration Year:</label> <label for="add-stnk-regisyear" class="col-form-label">Registration
Year:</label>
<input type="number" id="add-stnk-regisyear" class="form-control"> <input type="number" id="add-stnk-regisyear" class="form-control">
</div> </div>
</div> </div>
@ -308,7 +341,8 @@
</div> </div>
</div> </div>
<div class="modal fade" data-bs-backdrop="static" data-bs-keyboard="false" id="mdlEdtVhc" aria-labelledby="mdlEdtVhcLabel" aria-hidden="true"> <div class="modal fade" data-bs-backdrop="static" data-bs-keyboard="false" id="mdlEdtVhc"
aria-labelledby="mdlEdtVhcLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog modal-dialog-centered modal-dialog-scrollable modal-xl"> <div class="modal-dialog modal-dialog modal-dialog-centered modal-dialog-scrollable modal-xl">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
@ -326,15 +360,21 @@
<div class="col-5"> <div class="col-5">
<label for="edt-fvhc-img" class="col-form-label">Front Vehicle Photo:</label> <label for="edt-fvhc-img" class="col-form-label">Front Vehicle Photo:</label>
<br> <br>
<img id="edt-fvhc-img" class="img-fluid landscape-photo" style="max-height: 19.6vh" src="https://products.unitedtractors.com/wp-content/uploads/2021/03/udtruck-GWE370.png" alt="edt-fvhc-img"> <img id="edt-fvhc-img" class="img-fluid landscape-photo" style="max-height: 19.6vh"
src="https://products.unitedtractors.com/wp-content/uploads/2021/03/udtruck-GWE370.png"
alt="edt-fvhc-img">
<div id="edt-group_fvhc_spinner" class="d-none"> <div id="edt-group_fvhc_spinner" class="d-none">
<div class="spinner-border" role="status"> <div class="spinner-border" role="status">
<span class="visually-hidden">Loading...</span> <span class="visually-hidden">Loading...</span>
</div> </div>
</div> </div>
<div id="edt-group_rotate_fvhc" class="pt-2 d-flex justify-content-start d-none"> <div id="edt-group_rotate_fvhc" class="pt-2 d-flex justify-content-start d-none">
<button type="button" class="btnRotateLeft btn btn-sm btn-outline-primary ml-1" style="padding:0.25rem 0.5rem;border-radius:0.25rem;"><i class="icon ion-arrow-return-left"></i></button> <button type="button" class="btnRotateLeft btn btn-sm btn-outline-primary ml-1"
<button type="button" class="btnRotateRight btn btn-sm btn-outline-primary ml-1" style="padding:0.25rem 0.5rem;border-radius:0.25rem;"><i class="icon ion-arrow-return-right"></i></button> style="padding:0.25rem 0.5rem;border-radius:0.25rem;"><i
class="icon ion-arrow-return-left"></i></button>
<button type="button" class="btnRotateRight btn btn-sm btn-outline-primary ml-1"
style="padding:0.25rem 0.5rem;border-radius:0.25rem;"><i
class="icon ion-arrow-return-right"></i></button>
</div> </div>
<input type="file" id="edt-fvhc-file" class="form-control mt-3"> <input type="file" id="edt-fvhc-file" class="form-control mt-3">
<input type="text" id="edt-fvhc-base64" class="form-control" hidden> <input type="text" id="edt-fvhc-base64" class="form-control" hidden>
@ -349,7 +389,10 @@
<select id="edt-deviceid" class="form-control" style="width:100%;"> <select id="edt-deviceid" class="form-control" style="width:100%;">
<option value="">Tidak dipilih</option> <option value="">Tidak dipilih</option>
@foreach ($devices as $device) @foreach ($devices as $device)
<option value="{{ $device->id }}" data-device_id="{{ $device->device_id }}" data-simcard="{{ $device->simcard }}" data-type="{{ $device->type }}">{{ $device->name . ' (' . implode(' ', str_split($device->device_id, 4)) . ')' }}</option> <option value="{{ $device->id }}" data-device_id="{{ $device->device_id }}"
data-simcard="{{ $device->simcard }}" data-type="{{ $device->type }}">
{{ $device->name . ' (' . implode(' ', str_split($device->device_id, 4)) . ')' }}
</option>
@endforeach @endforeach
</select> </select>
</div> </div>
@ -378,7 +421,8 @@
<div class="row"> <div class="row">
<div class="col-sm-6"> <div class="col-sm-6">
<div class="mb-0"> <div class="mb-0">
<label for="edt-speedlimit" class="col-form-label">Speed Limit (kph):</label> <label for="edt-speedlimit" class="col-form-label">Speed Limit
(kph):</label>
<input type="number" id="edt-speedlimit" class="form-control"> <input type="number" id="edt-speedlimit" class="form-control">
</div> </div>
</div> </div>
@ -394,11 +438,14 @@
<div class="row"> <div class="row">
<div class="col-sm-6"> <div class="col-sm-6">
<div class="mb-0"> <div class="mb-0">
<label for="edt-dc_code" class="col-form-label">Distribution Category:</label> <label for="edt-dc_code" class="col-form-label">Distribution
Category:</label>
<select id="edt-dc_code" class="form-control" style="width:100%;"> <select id="edt-dc_code" class="form-control" style="width:100%;">
<option value="">Choose</option> <option value="">Choose</option>
@foreach ($listDistribution as $distribution) @foreach ($listDistribution as $distribution)
<option value="{{ $distribution->dc_code }}">{{ $distribution->dc_code }} - {{ $distribution->dc_name }}</option> <option value="{{ $distribution->dc_code }}">
{{ $distribution->dc_code }} - {{ $distribution->dc_name }}
</option>
@endforeach @endforeach
</select> </select>
</div> </div>
@ -409,7 +456,9 @@
<select id="edt-pool_code" class="form-control" style="width:100%;"> <select id="edt-pool_code" class="form-control" style="width:100%;">
<option value="">Choose</option> <option value="">Choose</option>
@foreach ($listPool as $pool) @foreach ($listPool as $pool)
<option value="{{ $pool->pool_code }}">{{ $pool->pool_code }} - {{ $pool->pool_name }}</option> <option value="{{ $pool->pool_code }}">{{ $pool->pool_code }} -
{{ $pool->pool_name }}
</option>
@endforeach @endforeach
</select> </select>
</div> </div>
@ -431,7 +480,8 @@
<option value="">Choose</option> <option value="">Choose</option>
@foreach ($drivers as $driver) @foreach ($drivers as $driver)
<option value="{{ $driver->id }}"> <option value="{{ $driver->id }}">
{{ $driver->fullname . ' (+' . $driver->phone_code . implode(' ', str_split($driver->phone, 4)) . ')' }} {{ $driver->fullname . ' (+' . $driver->phone_code . implode(' ',
str_split($driver->phone, 4)) . ')' }}
</option> </option>
@endforeach @endforeach
</select> </select>
@ -442,7 +492,8 @@
<option value="">Choose</option> <option value="">Choose</option>
@foreach ($drivers as $driver) @foreach ($drivers as $driver)
<option value="{{ $driver->id }}"> <option value="{{ $driver->id }}">
{{ $driver->fullname . ' (+' . $driver->phone_code . implode(' ', str_split($driver->phone, 4)) . ')' }} {{ $driver->fullname . ' (+' . $driver->phone_code . implode(' ',
str_split($driver->phone, 4)) . ')' }}
</option> </option>
@endforeach @endforeach
</select> </select>
@ -458,15 +509,21 @@
<div class="col-5"> <div class="col-5">
<label for="edt-stnk-img" class="col-form-label">CoV Photo:</label> <label for="edt-stnk-img" class="col-form-label">CoV Photo:</label>
<br> <br>
<img id="edt-stnk-img" class="img-fluid landscape-photo" src="https://cdn-2.tstatic.net/kaltim/foto/bank/images/ilustrasi-surat-tanda-nomor-kendaraan-bermotor-stnk.jpg" alt="edt-stnk-img"> <img id="edt-stnk-img" class="img-fluid landscape-photo"
src="https://cdn-2.tstatic.net/kaltim/foto/bank/images/ilustrasi-surat-tanda-nomor-kendaraan-bermotor-stnk.jpg"
alt="edt-stnk-img">
<div id="edt-group_stnk_spinner" class="d-none"> <div id="edt-group_stnk_spinner" class="d-none">
<div class="spinner-border" role="status"> <div class="spinner-border" role="status">
<span class="visually-hidden">Loading...</span> <span class="visually-hidden">Loading...</span>
</div> </div>
</div> </div>
<div id="edt-group_rotate_stnk" class="pt-2 d-flex justify-content-start d-none"> <div id="edt-group_rotate_stnk" class="pt-2 d-flex justify-content-start d-none">
<button type="button" class="btnRotateLeft btn btn-sm btn-outline-primary ml-1" style="padding:0.25rem 0.5rem;border-radius:0.25rem;"><i class="icon ion-arrow-return-left"></i></button> <button type="button" class="btnRotateLeft btn btn-sm btn-outline-primary ml-1"
<button type="button" class="btnRotateRight btn btn-sm btn-outline-primary ml-1" style="padding:0.25rem 0.5rem;border-radius:0.25rem;"><i class="icon ion-arrow-return-right"></i></button> style="padding:0.25rem 0.5rem;border-radius:0.25rem;"><i
class="icon ion-arrow-return-left"></i></button>
<button type="button" class="btnRotateRight btn btn-sm btn-outline-primary ml-1"
style="padding:0.25rem 0.5rem;border-radius:0.25rem;"><i
class="icon ion-arrow-return-right"></i></button>
</div> </div>
<input type="file" id="edt-stnk-file" class="form-control mt-3"> <input type="file" id="edt-stnk-file" class="form-control mt-3">
<input type="text" id="edt-stnk-base64" class="form-control" hidden> <input type="text" id="edt-stnk-base64" class="form-control" hidden>
@ -491,10 +548,12 @@
<input type="text" id="edt-nopol1" class="form-control" placeholder="ex: B"> <input type="text" id="edt-nopol1" class="form-control" placeholder="ex: B">
</div> </div>
<div class="col d-none"> <div class="col d-none">
<input type="number" id="edt-nopol2" class="form-control" placeholder="ex: 3633"> <input type="number" id="edt-nopol2" class="form-control"
placeholder="ex: 3633">
</div> </div>
<div class="col d-none"> <div class="col d-none">
<input type="text" id="edt-nopol3" class="form-control" placeholder="ex: EEV"> <input type="text" id="edt-nopol3" class="form-control"
placeholder="ex: EEV">
</div> </div>
</div> </div>
</div> </div>
@ -508,7 +567,8 @@
<input type="number" id="edt-stnk-cc" class="form-control"> <input type="number" id="edt-stnk-cc" class="form-control">
</div> </div>
<div class="col-6"> <div class="col-6">
<label for="edt-stnk-vin" class="col-form-label">Vehicle Identity Number:</label> <label for="edt-stnk-vin" class="col-form-label">Vehicle Identity
Number:</label>
<input type="string" id="edt-stnk-vin" class="form-control"> <input type="string" id="edt-stnk-vin" class="form-control">
</div> </div>
<div class="col-6"> <div class="col-6">
@ -524,11 +584,13 @@
<input type="string" id="edt-stnk-fueltype" class="form-control"> <input type="string" id="edt-stnk-fueltype" class="form-control">
</div> </div>
<div class="col-6"> <div class="col-6">
<label for="edt-stnk-tnkbcolor" class="col-form-label">License Plat Color:</label> <label for="edt-stnk-tnkbcolor" class="col-form-label">License Plat
Color:</label>
<input type="string" id="edt-stnk-tnkbcolor" class="form-control"> <input type="string" id="edt-stnk-tnkbcolor" class="form-control">
</div> </div>
<div class="col-6"> <div class="col-6">
<label for="edt-stnk-regisyear" class="col-form-label">Registration Year:</label> <label for="edt-stnk-regisyear" class="col-form-label">Registration
Year:</label>
<input type="number" id="edt-stnk-regisyear" class="form-control"> <input type="number" id="edt-stnk-regisyear" class="form-control">
</div> </div>
</div> </div>
@ -548,7 +610,8 @@
<option value="0">Vendor belum dipilih</option> <option value="0">Vendor belum dipilih</option>
@foreach ($vendors as $vendor) @foreach ($vendors as $vendor)
<option value="{{ $vendor->id }}"> <option value="{{ $vendor->id }}">
{{ $vendor->first_name . ' (+' . $vendor->phone_code . implode(' ', str_split($vendor->phone, 4)) . ')' }} {{ $vendor->first_name . ' (+' . $vendor->phone_code . implode(' ',
str_split($vendor->phone, 4)) . ')' }}
</option> </option>
@endforeach @endforeach
</select> </select>
@ -576,7 +639,8 @@
</div> </div>
</div> </div>
<div class="modal fade" data-bs-backdrop="static" data-bs-keyboard="false" id="mdlDelVhc" aria-labelledby="mdlDelVhcLabel" aria-hidden="true"> <div class="modal fade" data-bs-backdrop="static" data-bs-keyboard="false" id="mdlDelVhc"
aria-labelledby="mdlDelVhcLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-sm"> <div class="modal-dialog modal-dialog-centered modal-sm">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
@ -621,7 +685,7 @@
}; };
const Wrapper = { const Wrapper = {
activate: function() { activate: function () {
Wrapper.event(); Wrapper.event();
DTable.activate(); DTable.activate();
VNew.activate(); VNew.activate();
@ -634,7 +698,7 @@
DUploadEdt.activate('fvhc'); DUploadEdt.activate('fvhc');
DUploadEdt.activate('stnk'); DUploadEdt.activate('stnk');
}, },
event: function() { event: function () {
$('#add-device_id').select2({ $('#add-device_id').select2({
dropdownParent: $('#mdlNewVhc'), dropdownParent: $('#mdlNewVhc'),
}); });
@ -678,17 +742,17 @@
$('#edt-vendor_id').select2({ $('#edt-vendor_id').select2({
dropdownParent: $('#mdlEdtVhc'), dropdownParent: $('#mdlEdtVhc'),
}); });
$('#btnDownload').on('click', function() { $('#btnDownload').on('click', function () {
DTable.table.button('.buttons-excel').trigger(); DTable.table.button('.buttons-excel').trigger();
}); });
}, },
}; };
const DTable = { const DTable = {
activate: function() { activate: function () {
DTable.reload(); DTable.reload();
}, },
reload: function() { reload: function () {
let table let table
// $('#tVehicles').DataTable(); // $('#tVehicles').DataTable();
// if (Driver.Table.firstInitDataTable == 1) { loadTableSkeletonLoading() } else { Driver.Table.firstInitDataTable = 1; } // if (Driver.Table.firstInitDataTable == 1) { loadTableSkeletonLoading() } else { Driver.Table.firstInitDataTable = 1; }
@ -701,7 +765,7 @@
ajax: { ajax: {
url: "{{ route('api_list_vehicles1') }}?cptid=" + AppState.current_company, url: "{{ route('api_list_vehicles1') }}?cptid=" + AppState.current_company,
type: 'GET', type: 'GET',
complete: function() { complete: function () {
// removeTableSkeletonLoading() // removeTableSkeletonLoading()
}, },
}, },
@ -719,7 +783,7 @@
visible: true, visible: true,
orderable: true, orderable: true,
searchable: true, searchable: true,
render: function(data, type, row, meta) { render: function (data, type, row, meta) {
let action = ` let action = `
<a href="#" class="text-decoration-none me-1 btnEdtVhc" data-vid="${data}"> <a href="#" class="text-decoration-none me-1 btnEdtVhc" data-vid="${data}">
<span class="icon ion-eye fz-16"></span> <span class="icon ion-eye fz-16"></span>
@ -737,13 +801,13 @@
visible: true, visible: true,
orderable: true, orderable: true,
searchable: true, searchable: true,
render: function(data, type, row, meta) { render: function (data, type, row, meta) {
return ` return `
<img src="${State.storage_lara}${row.fvhc_img}" class="img-fluid thumb-img-table" /><br> <img src="${State.storage_lara}${row.fvhc_img}" class="img-fluid thumb-img-table" /><br>
${row.nopol1} ${row.nopol2} ${row.nopol3} ${row.nopol1} ${row.nopol2} ${row.nopol3}
`; `;
}, },
createdCell: function(td, cellData, rowData, row, col) { createdCell: function (td, cellData, rowData, row, col) {
$(td).attr('data-vid', rowData.vid); $(td).attr('data-vid', rowData.vid);
$(td).attr('data-name', rowData.name); $(td).attr('data-name', rowData.name);
$(td).attr('data-nopol1', rowData.nopol1); $(td).attr('data-nopol1', rowData.nopol1);
@ -758,7 +822,7 @@
visible: true, visible: true,
orderable: true, orderable: true,
searchable: true, searchable: true,
render: function(data, type, row, meta) { render: function (data, type, row, meta) {
return (`${(data || '-')}`); return (`${(data || '-')}`);
}, },
}, },
@ -768,7 +832,7 @@
visible: true, visible: true,
orderable: true, orderable: true,
searchable: true, searchable: true,
render: function(data, type, row, meta) { render: function (data, type, row, meta) {
// return (`${row.brand_name}<br>-<br>${data}`); // return (`${row.brand_name}<br>-<br>${data}`);
return data; return data;
}, },
@ -779,7 +843,7 @@
visible: true, visible: true,
orderable: true, orderable: true,
searchable: true, searchable: true,
render: function(data, type, row, meta) { render: function (data, type, row, meta) {
// return moment.unix(data).format('DD MMM YYYY'); // return moment.unix(data).format('DD MMM YYYY');
return data ? moment.unix(data).format('DD MMM YYYY') : '-'; return data ? moment.unix(data).format('DD MMM YYYY') : '-';
}, },
@ -791,8 +855,11 @@
visible: true, visible: true,
orderable: true, orderable: true,
searchable: true, searchable: true,
render: function(data, type, row, meta) { render: function (data, type, row, meta) {
return data ? Helper.splitEvery4Char(data) : '-'; const device_id = Helper.splitEvery4Char(data);
const protocol = " " + row.protocol || '';
return device_id + '<br>' + protocol;
// return `<span class="d-none">${data}</span>` + Helper.splitEvery4Char(`${data}`); // return `<span class="d-none">${data}</span>` + Helper.splitEvery4Char(`${data}`);
}, },
}, },
@ -802,7 +869,7 @@
visible: true, visible: true,
orderable: true, orderable: true,
searchable: true, searchable: true,
render: function(data, type, row, meta) { render: function (data, type, row, meta) {
return data ? Helper.splitEvery4Char(data) : '-'; return data ? Helper.splitEvery4Char(data) : '-';
// return `<span class="d-none">${data}</span>` + Helper.splitEvery4Char(`${data}`); // return `<span class="d-none">${data}</span>` + Helper.splitEvery4Char(`${data}`);
}, },
@ -813,7 +880,7 @@
visible: true, visible: true,
orderable: true, orderable: true,
searchable: true, searchable: true,
render: function(data, type, row, meta) { render: function (data, type, row, meta) {
return data ? moment.unix(data).format('DD MMM YYYY HH:mm') : '-'; return data ? moment.unix(data).format('DD MMM YYYY HH:mm') : '-';
}, },
}, },
@ -824,7 +891,7 @@
visible: true, visible: true,
orderable: true, orderable: true,
searchable: true, searchable: true,
render: function(data, type, row, meta) { render: function (data, type, row, meta) {
return Number(data).toFixed(2); return Number(data).toFixed(2);
} }
}, },
@ -834,8 +901,18 @@
visible: true, visible: true,
orderable: true, orderable: true,
searchable: true, searchable: true,
render: function(data, type, row, meta) { render: function (data, type, row, meta) {
return Number(data/10).toFixed(1); return Number(data / 10).toFixed(1);
}
},
{
data: 'fuel_curr',
className: 'text-end',
visible: true,
orderable: true,
searchable: true,
render: function (data, type, row, meta) {
return data ? 'Yes' : 'No';
} }
}, },
{ {
@ -844,11 +921,11 @@
visible: true, visible: true,
orderable: true, orderable: true,
searchable: true, searchable: true,
render: function(data, type, row, meta) { render: function (data, type, row, meta) {
return data || '-'; return data || '-';
} }
}, },
{ data: 'device_id', visible: false}, { data: 'device_id', visible: false },
], ],
buttons: [ buttons: [
{ {
@ -872,12 +949,12 @@
} }
const VNew = { const VNew = {
activate: function() { activate: function () {
VNew.event(); VNew.event();
}, },
event: function() { event: function () {
// Tampilkan modal saat tombol diklik // Tampilkan modal saat tombol diklik
$('#btnMdlNewVhc').on('click', function() { $('#btnMdlNewVhc').on('click', function () {
$('#mdlNewVhc').modal('show'); $('#mdlNewVhc').modal('show');
}); });
@ -893,20 +970,20 @@
}); });
// Reset input file saat diklik // Reset input file saat diklik
$('#add-fvhc-file').on('click', function() { $('#add-fvhc-file').on('click', function () {
$(this).val(''); $(this).val('');
}); });
$('#add-stnk-file').on('click', function() { $('#add-stnk-file').on('click', function () {
$(this).val(''); $(this).val('');
}); });
// Submit form // Submit form
$('#btnSubmitNewVhc').on('click', function() { $('#btnSubmitNewVhc').on('click', function () {
let data = VNew.getData(); let data = VNew.getData();
VNew.submitData(data); VNew.submitData(data);
}); });
}, },
getData: function() { getData: function () {
let data = new FormData(); let data = new FormData();
data.append('vhc_name', safeVal('#add-vhcname')); data.append('vhc_name', safeVal('#add-vhcname'));
@ -960,7 +1037,7 @@
return data; return data;
}, },
submitData: function(data) { submitData: function (data) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if ($('#btnSubmitNewVhc').is('[disabled]')) { if ($('#btnSubmitNewVhc').is('[disabled]')) {
resolve({ resolve({
@ -1024,18 +1101,18 @@
}; };
$(function() { $(function () {
VNew.activate(); VNew.activate();
}); });
const VEdt = { const VEdt = {
activate: function() { activate: function () {
VEdt.event(); VEdt.event();
}, },
event: function() { event: function () {
// modal // modal
$('#tVehicles').on('click', '.btnEdtVhc', async function(e) { $('#tVehicles').on('click', '.btnEdtVhc', async function (e) {
// let vid = $(e.target).closest('tr').find('td[data-vid]').data('vid'); // let vid = $(e.target).closest('tr').find('td[data-vid]').data('vid');
const vid = $(this).data('vid'); const vid = $(this).data('vid');
VEdt.removeOptionDevice(State.dvc_type.portable); VEdt.removeOptionDevice(State.dvc_type.portable);
@ -1048,10 +1125,10 @@
} }
VEdt.passDataToView(resp.data); VEdt.passDataToView(resp.data);
}); });
$('#mdlEdtVhc').on('shown.bs.modal', function() { $('#mdlEdtVhc').on('shown.bs.modal', function () {
}); });
$('#btnSubmitEdtVhc').on('click', function() { $('#btnSubmitEdtVhc').on('click', function () {
let data = VEdt.getData(); let data = VEdt.getData();
VEdt.submitData(data); VEdt.submitData(data);
}); });
@ -1070,14 +1147,14 @@
startDate: moment().add(1, 'days').toDate(), startDate: moment().add(1, 'days').toDate(),
endDate: moment().add(1, 'year').toDate(), endDate: moment().add(1, 'year').toDate(),
}); });
$('#edt-fvhc-file').on('click', function() { $('#edt-fvhc-file').on('click', function () {
$('#edt-fvhc-file').val(''); $('#edt-fvhc-file').val('');
}); });
$('#edt-stnk-file').on('click', function() { $('#edt-stnk-file').on('click', function () {
$('#edt-stnk-file').val(''); $('#edt-stnk-file').val('');
}); });
}, },
reqData: function(params) { reqData: function (params) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
$.ajax({ $.ajax({
url: "{{ route('api_show_vehicle', '') }}/" + params.vid, url: "{{ route('api_show_vehicle', '') }}/" + params.vid,
@ -1115,7 +1192,7 @@
}) })
}); });
}, },
passDataToView: function(data) { passDataToView: function (data) {
$('#edt-fvhc-filesize').html(''); $('#edt-fvhc-filesize').html('');
$('#edt-fvhc-status').html(''); $('#edt-fvhc-status').html('');
$('#edt-fvhc-base64').val(''); $('#edt-fvhc-base64').val('');
@ -1124,7 +1201,7 @@
$('#edt-vhcname').val(data?.name); $('#edt-vhcname').val(data?.name);
let dvc_id = (data?.dvc_id) ? data?.dvc_id : ''; let dvc_id = (data?.dvc_id) ? data?.dvc_id : '';
if (dvc_id == 0 || dvc_id == '') {} else { if (dvc_id == 0 || dvc_id == '') { } else {
if ($(`#edt-deviceid option[value='${dvc_id}']`).length < 1) { if ($(`#edt-deviceid option[value='${dvc_id}']`).length < 1) {
$('#edt-deviceid').append(`<option value="${data?.dvc_id}" data-device_id="${data?.device_id}" data-simcard="${data?.simcard}" data-type="${data?.dvc_type}">${data?.dvc_name} (${Helper.splitEvery4Char(data?.device_id)})</option>`); $('#edt-deviceid').append(`<option value="${data?.dvc_id}" data-device_id="${data?.device_id}" data-simcard="${data?.simcard}" data-type="${data?.dvc_type}">${data?.dvc_name} (${Helper.splitEvery4Char(data?.device_id)})</option>`);
$('#edt-device_id').select2({ $('#edt-device_id').select2({
@ -1177,13 +1254,13 @@
$('#edt-dc_code').val(data?.dc_code).trigger('change'); $('#edt-dc_code').val(data?.dc_code).trigger('change');
$('#edt-pool_code').val(data?.pool_code).trigger('change'); $('#edt-pool_code').val(data?.pool_code).trigger('change');
}, },
removeOptionDevice: function(type) { removeOptionDevice: function (type) {
$(`#edt-deviceid option[data-type='${type}']`).remove(); $(`#edt-deviceid option[data-type='${type}']`).remove();
$('#edt-device_id').select2({ $('#edt-device_id').select2({
dropdownParent: $('#mdlEdtVhc'), dropdownParent: $('#mdlEdtVhc'),
}); });
}, },
getData: function() { getData: function () {
let data = {}; let data = {};
data.vid = $('#mdlEdtVhc').data('id'); data.vid = $('#mdlEdtVhc').data('id');
data.fvhc_base64 = $('#edt-fvhc-base64').val().replace(/^data:image\/(png|jpg|jpeg);base64,/, ''); data.fvhc_base64 = $('#edt-fvhc-base64').val().replace(/^data:image\/(png|jpg|jpeg);base64,/, '');
@ -1230,7 +1307,7 @@
data.pool_code = $('#edt-pool_code').val(); data.pool_code = $('#edt-pool_code').val();
return data; return data;
}, },
submitData: async function(data) { submitData: async function (data) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (typeof $('#btnSubmitEdtVhc').attr('disabed') != 'undefined') { if (typeof $('#btnSubmitEdtVhc').attr('disabed') != 'undefined') {
resolve({ resolve({
@ -1289,12 +1366,12 @@
} }
const VDel = { const VDel = {
activate: function() { activate: function () {
VDel.event(); VDel.event();
}, },
event: function() { event: function () {
// on table // on table
$('#tVehicles').on('click', '.btnDelVhc', function(e) { $('#tVehicles').on('click', '.btnDelVhc', function (e) {
let row = $(e.target).closest('tr'); let row = $(e.target).closest('tr');
let vid = row.find('td[data-vid]').data('vid'); let vid = row.find('td[data-vid]').data('vid');
let name = row.find('td[data-name]').data('name'); let name = row.find('td[data-name]').data('name');
@ -1311,14 +1388,14 @@
$('#mdlDelVhc').data('id', vid); $('#mdlDelVhc').data('id', vid);
$('#mdlDelVhc').modal('show'); $('#mdlDelVhc').modal('show');
}); });
$('#btnSubmitDelVhc').on('click', function() { $('#btnSubmitDelVhc').on('click', function () {
let data = { let data = {
vid: $('#mdlDelVhc').data('id'), vid: $('#mdlDelVhc').data('id'),
}; };
VDel.submitData(data); VDel.submitData(data);
}); });
// on modal update // on modal update
$('#btnDelVhc_updt').on('click', function(e) { $('#btnDelVhc_updt').on('click', function (e) {
let data = VEdt.getData(); let data = VEdt.getData();
VDel.passDataToView({ VDel.passDataToView({
vid: data.vid, vid: data.vid,
@ -1331,11 +1408,11 @@
$('#mdlDelVhc').modal('show'); $('#mdlDelVhc').modal('show');
}); });
}, },
passDataToView: function(data) { passDataToView: function (data) {
$('#del-name').text(data.name); $('#del-name').text(data.name);
$('#del-nopol').text(`${data.nopol1} ${data.nopol2} ${data.nopol3}`); $('#del-nopol').text(`${data.nopol1} ${data.nopol2} ${data.nopol3}`);
}, },
submitData: async function(data) { submitData: async function (data) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (typeof $('#btnSubmitDelVhc').attr('disabed') != 'undefined') { if (typeof $('#btnSubmitDelVhc').attr('disabed') != 'undefined') {
resolve({ resolve({
@ -1389,11 +1466,11 @@
} }
const Filter = { const Filter = {
activate: function() { activate: function () {
Filter.event(); Filter.event();
}, },
event: function() {}, event: function () { },
triggerFilterCompany: function() { triggerFilterCompany: function () {
DTable.reload(); DTable.reload();
}, },
} }
@ -1446,9 +1523,9 @@
const JimpWorkerAdd = { const JimpWorkerAdd = {
worker_fvhc: null, worker_fvhc: null,
worker_stnk: null, worker_stnk: null,
activate: function(x) { activate: function (x) {
let linkWorker = State.file_jimp_worker let linkWorker = State.file_jimp_worker
this.setWorker(linkWorker, x, function(res) { this.setWorker(linkWorker, x, function (res) {
if (res.stts) { if (res.stts) {
let pureDataURL = res.data.replace(/^data:image\/(png|jpg|jpeg);base64,/, '') let pureDataURL = res.data.replace(/^data:image\/(png|jpg|jpeg);base64,/, '')
let fileSize = window.atob(pureDataURL).length // in Byte let fileSize = window.atob(pureDataURL).length // in Byte
@ -1465,7 +1542,7 @@
$('.page-loader-wrapper').fadeOut() $('.page-loader-wrapper').fadeOut()
}); });
}, },
runWorker: function(dataURL, x) { runWorker: function (dataURL, x) {
$('#add-group_' + x + '_spinner').removeClass('d-none'); $('#add-group_' + x + '_spinner').removeClass('d-none');
$('#add-' + x + '-img').addClass('d-none'); $('#add-' + x + '-img').addClass('d-none');
if (x == 'fvhc') { if (x == 'fvhc') {
@ -1474,9 +1551,9 @@
this.worker_stnk.postMessage(dataURL) this.worker_stnk.postMessage(dataURL)
} }
}, },
setWorker: function(urlFileJs, x, cbFinish) { setWorker: function (urlFileJs, x, cbFinish) {
let worker = new Worker(urlFileJs); let worker = new Worker(urlFileJs);
worker.onmessage = function(e) { worker.onmessage = function (e) {
// e = {status:(true,false), data:(dataURL)} // e = {status:(true,false), data:(dataURL)}
// append a new img element using the base 64 image // append a new img element using the base 64 image
@ -1494,21 +1571,21 @@
} }
} }
const DUploadAdd = { const DUploadAdd = {
activate: function(x) { activate: function (x) {
this.initReader(x) this.initReader(x)
JimpWorkerAdd.activate(x) JimpWorkerAdd.activate(x)
this.event(x) this.event(x)
DRotateImgAdd.activate(x) DRotateImgAdd.activate(x)
}, },
event: function(x) { event: function (x) {
$('#add-' + x + '-choose').on('click', function(e) { $('#add-' + x + '-choose').on('click', function (e) {
$('#add-' + x + '-file').trigger('click') $('#add-' + x + '-file').trigger('click')
}) })
}, },
initReader: function(x) { initReader: function (x) {
let reader = new FileReader(); let reader = new FileReader();
reader = this.setEventFile(reader, x); reader = this.setEventFile(reader, x);
$('#add-' + x + '-file').on('change', async function(e) { $('#add-' + x + '-file').on('change', async function (e) {
try { try {
if (browserBack()) return false; if (browserBack()) return false;
let file = e.target.files[0]; let file = e.target.files[0];
@ -1539,8 +1616,8 @@
} }
}) })
}, },
setEventFile: function(reader, x) { setEventFile: function (reader, x) {
reader.onload = function(e) { reader.onload = function (e) {
let data = e.target.result; let data = e.target.result;
$('#add-' + x + '-img-old').attr('src', $('#add-' + x + '-img-old').attr('src',
data) // preview, -old mungkin kedepannya bakal diganti jadi -new data) // preview, -old mungkin kedepannya bakal diganti jadi -new
@ -1550,42 +1627,42 @@
DRotateImgAdd.toggleBtnRotate(x, 'show'); DRotateImgAdd.toggleBtnRotate(x, 'show');
}; };
reader.onerror = function(err) { reader.onerror = function (err) {
$('.page-loader-wrapper').fadeOut() $('.page-loader-wrapper').fadeOut()
$('#' + x).attr('hidden', true) $('#' + x).attr('hidden', true)
console.error(err); console.error(err);
}; };
reader.onabort = function(err) { reader.onabort = function (err) {
console.log(err); console.log(err);
} }
return reader; return reader;
}, },
readFile: function(reader, file) { readFile: function (reader, file) {
// reader.readAsArrayBuffer(file); // reader.readAsArrayBuffer(file);
reader.readAsDataURL(file); reader.readAsDataURL(file);
}, },
} }
const DRotateImgAdd = { const DRotateImgAdd = {
activate: function(id) { activate: function (id) {
this.event(id) this.event(id)
}, },
event: function(id) { event: function (id) {
$('#add-group_rotate_' + id).on('click', '.btnRotateRight', function(e) { $('#add-group_rotate_' + id).on('click', '.btnRotateRight', function (e) {
DRotateImgAdd.rotateBase64Image($('#add-' + id + '-base64').val(), 90).then( DRotateImgAdd.rotateBase64Image($('#add-' + id + '-base64').val(), 90).then(
function(base64) { function (base64) {
DRotateImgAdd.updateImg(id, base64) DRotateImgAdd.updateImg(id, base64)
}) })
}) })
$('#add-group_rotate_' + id).on('click', '.btnRotateLeft', function(e) { $('#add-group_rotate_' + id).on('click', '.btnRotateLeft', function (e) {
DRotateImgAdd.rotateBase64Image($('#add-' + id + '-base64').val(), -90).then( DRotateImgAdd.rotateBase64Image($('#add-' + id + '-base64').val(), -90).then(
function(base64) { function (base64) {
DRotateImgAdd.updateImg(id, base64) DRotateImgAdd.updateImg(id, base64)
}) })
}) })
}, },
rotateBase64Image: function(base64data, degrees) { rotateBase64Image: function (base64data, degrees) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
try { try {
let x = 0, let x = 0,
@ -1595,7 +1672,7 @@
let canvas = document.createElement("canvas"); let canvas = document.createElement("canvas");
let image = document.createElement("img"); // new Image(); let image = document.createElement("img"); // new Image();
image.src = base64data; // image.src = 'data:image/jpg;base64,' + base64data; image.src = base64data; // image.src = 'data:image/jpg;base64,' + base64data;
image.onload = function() { image.onload = function () {
// current image size for processing rotate // current image size for processing rotate
w = image.width; w = image.width;
h = image.height; h = image.height;
@ -1643,7 +1720,7 @@
} }
}); });
}, },
updateImg: function(id, base64) { updateImg: function (id, base64) {
// update data // update data
let pureDataURL = base64.replace(/^data:image\/(png|jpg|jpeg);base64,/, '') let pureDataURL = base64.replace(/^data:image\/(png|jpg|jpeg);base64,/, '')
let fileSize = window.atob(pureDataURL).length // in Byte let fileSize = window.atob(pureDataURL).length // in Byte
@ -1661,7 +1738,7 @@
// JimpWorkerAdd.worker_stnk.postMessage(base64) // JimpWorkerAdd.worker_stnk.postMessage(base64)
// } // }
}, },
toggleBtnRotate: function(id, hide = 'hidden') { toggleBtnRotate: function (id, hide = 'hidden') {
if (hide == 'show') { if (hide == 'show') {
$('#add-group_rotate_' + id).removeClass('d-none') $('#add-group_rotate_' + id).removeClass('d-none')
return true; return true;
@ -1674,9 +1751,9 @@
const JimpWorkerEdt = { const JimpWorkerEdt = {
worker_fvhc: null, worker_fvhc: null,
worker_stnk: null, worker_stnk: null,
activate: function(x) { activate: function (x) {
let linkWorker = State.file_jimp_worker let linkWorker = State.file_jimp_worker
this.setWorker(linkWorker, x, function(res) { this.setWorker(linkWorker, x, function (res) {
if (res.stts) { if (res.stts) {
let pureDataURL = res.data.replace(/^data:image\/(png|jpg|jpeg);base64,/, '') let pureDataURL = res.data.replace(/^data:image\/(png|jpg|jpeg);base64,/, '')
let fileSize = window.atob(pureDataURL).length // in Byte let fileSize = window.atob(pureDataURL).length // in Byte
@ -1693,7 +1770,7 @@
$('.page-loader-wrapper').fadeOut() $('.page-loader-wrapper').fadeOut()
}); });
}, },
runWorker: function(dataURL, x) { runWorker: function (dataURL, x) {
$('#edt-group_' + x + '_spinner').removeClass('d-none'); $('#edt-group_' + x + '_spinner').removeClass('d-none');
$('#edt-' + x + '-img').addClass('d-none'); $('#edt-' + x + '-img').addClass('d-none');
if (x == 'fvhc') { if (x == 'fvhc') {
@ -1702,9 +1779,9 @@
this.worker_stnk.postMessage(dataURL) this.worker_stnk.postMessage(dataURL)
} }
}, },
setWorker: function(urlFileJs, x, cbFinish) { setWorker: function (urlFileJs, x, cbFinish) {
let worker = new Worker(urlFileJs); let worker = new Worker(urlFileJs);
worker.onmessage = function(e) { worker.onmessage = function (e) {
// e = {status:(true,false), data:(dataURL)} // e = {status:(true,false), data:(dataURL)}
// append a new img element using the base 64 image // append a new img element using the base 64 image
@ -1722,21 +1799,21 @@
} }
} }
const DUploadEdt = { const DUploadEdt = {
activate: function(x) { activate: function (x) {
this.initReader(x) this.initReader(x)
JimpWorkerEdt.activate(x) JimpWorkerEdt.activate(x)
this.event(x) this.event(x)
DRotateImgEdt.activate(x) DRotateImgEdt.activate(x)
}, },
event: function(x) { event: function (x) {
$('#edt-' + x + '-choose').on('click', function(e) { $('#edt-' + x + '-choose').on('click', function (e) {
$('#edt-' + x + '-file').trigger('click') $('#edt-' + x + '-file').trigger('click')
}) })
}, },
initReader: function(x) { initReader: function (x) {
let reader = new FileReader(); let reader = new FileReader();
reader = this.setEventFile(reader, x); reader = this.setEventFile(reader, x);
$('#edt-' + x + '-file').on('change', async function(e) { $('#edt-' + x + '-file').on('change', async function (e) {
try { try {
if (browserBack()) return false; if (browserBack()) return false;
let file = e.target.files[0]; let file = e.target.files[0];
@ -1767,8 +1844,8 @@
} }
}) })
}, },
setEventFile: function(reader, x) { setEventFile: function (reader, x) {
reader.onload = function(e) { reader.onload = function (e) {
let data = e.target.result; let data = e.target.result;
$('#edt-' + x + '-img-old').attr('src', $('#edt-' + x + '-img-old').attr('src',
data) // preview, -old mungkin kedepannya bakal diganti jadi -new data) // preview, -old mungkin kedepannya bakal diganti jadi -new
@ -1778,42 +1855,42 @@
DRotateImgEdt.toggleBtnRotate(x, 'show'); DRotateImgEdt.toggleBtnRotate(x, 'show');
}; };
reader.onerror = function(err) { reader.onerror = function (err) {
$('.page-loader-wrapper').fadeOut() $('.page-loader-wrapper').fadeOut()
$('#' + x).attr('hidden', true) $('#' + x).attr('hidden', true)
console.error(err); console.error(err);
}; };
reader.onabort = function(err) { reader.onabort = function (err) {
console.log(err); console.log(err);
} }
return reader; return reader;
}, },
readFile: function(reader, file) { readFile: function (reader, file) {
// reader.readAsArrayBuffer(file); // reader.readAsArrayBuffer(file);
reader.readAsDataURL(file); reader.readAsDataURL(file);
}, },
} }
const DRotateImgEdt = { const DRotateImgEdt = {
activate: function(id) { activate: function (id) {
this.event(id) this.event(id)
}, },
event: function(id) { event: function (id) {
$('#edt-group_rotate_' + id).on('click', '.btnRotateRight', function(e) { $('#edt-group_rotate_' + id).on('click', '.btnRotateRight', function (e) {
DRotateImgEdt.rotateBase64Image($('#edt-' + id + '-base64').val(), 90).then( DRotateImgEdt.rotateBase64Image($('#edt-' + id + '-base64').val(), 90).then(
function(base64) { function (base64) {
DRotateImgEdt.updateImg(id, base64) DRotateImgEdt.updateImg(id, base64)
}) })
}) })
$('#edt-group_rotate_' + id).on('click', '.btnRotateLeft', function(e) { $('#edt-group_rotate_' + id).on('click', '.btnRotateLeft', function (e) {
DRotateImgEdt.rotateBase64Image($('#edt-' + id + '-base64').val(), -90).then( DRotateImgEdt.rotateBase64Image($('#edt-' + id + '-base64').val(), -90).then(
function(base64) { function (base64) {
DRotateImgEdt.updateImg(id, base64) DRotateImgEdt.updateImg(id, base64)
}) })
}) })
}, },
rotateBase64Image: function(base64data, degrees) { rotateBase64Image: function (base64data, degrees) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
try { try {
let x = 0, let x = 0,
@ -1823,7 +1900,7 @@
let canvas = document.createElement("canvas"); let canvas = document.createElement("canvas");
let image = document.createElement("img"); // new Image(); let image = document.createElement("img"); // new Image();
image.src = base64data; // image.src = 'data:image/jpg;base64,' + base64data; image.src = base64data; // image.src = 'data:image/jpg;base64,' + base64data;
image.onload = function() { image.onload = function () {
// current image size for processing rotate // current image size for processing rotate
w = image.width; w = image.width;
h = image.height; h = image.height;
@ -1871,7 +1948,7 @@
} }
}); });
}, },
updateImg: function(id, base64) { updateImg: function (id, base64) {
// update data // update data
let pureDataURL = base64.replace(/^data:image\/(png|jpg|jpeg);base64,/, '') let pureDataURL = base64.replace(/^data:image\/(png|jpg|jpeg);base64,/, '')
let fileSize = window.atob(pureDataURL).length // in Byte let fileSize = window.atob(pureDataURL).length // in Byte
@ -1889,7 +1966,7 @@
// JimpWorkerEdt.worker_stnk.postMessage(base64) // JimpWorkerEdt.worker_stnk.postMessage(base64)
// } // }
}, },
toggleBtnRotate: function(id, hide = 'hidden') { toggleBtnRotate: function (id, hide = 'hidden') {
if (hide == 'show') { if (hide == 'show') {
$('#edt-group_rotate_' + id).removeClass('d-none') $('#edt-group_rotate_' + id).removeClass('d-none')
return true; return true;