FEAT : Update Dashboard DONE

This commit is contained in:
Ramanda Syahputra 2025-05-02 16:41:13 +07:00
parent c1b1a00c90
commit a8bd400753
4 changed files with 186 additions and 125 deletions

View File

@ -1,4 +1,5 @@
<?php <?php
use Carbon\Carbon; use Carbon\Carbon;
if (!function_exists('formatTanggalWaktu')) { if (!function_exists('formatTanggalWaktu')) {
@ -20,3 +21,15 @@
} }
} }
} }
function formatNotifikasi($notifikasi)
{
$data = json_decode(json_encode($notifikasi->data));
$message = $data->message;
$data = $data->data;
$notifikasi = [
'title' => $message->title,
'message' => $message->message,
];
return $notifikasi;
}

View File

@ -15,12 +15,13 @@
"intervention/image": "^3.10", "intervention/image": "^3.10",
"joshbrw/laravel-module-installer": "^2.0", "joshbrw/laravel-module-installer": "^2.0",
"laravel/framework": "^12.0", "laravel/framework": "^12.0",
"jackiedo/log-reader": "^2.4",
"laravel/pulse": "^1.2", "laravel/pulse": "^1.2",
"laravel/tinker": "^2.9", "laravel/tinker": "^2.9",
"maatwebsite/excel": "^3.1", "maatwebsite/excel": "^3.1",
"nwidart/laravel-modules": "^11.0", "nwidart/laravel-modules": "^11.0",
"opcodesio/log-viewer": "^3.10", "opcodesio/log-viewer": "^3.10",
"rasyahroel/itsecurity": "dev-main", "rasyahroel/itsecurity-module": "dev-main",
"rasyahroel/usermanagement-module": "dev-master", "rasyahroel/usermanagement-module": "dev-master",
"spatie/laravel-activitylog": "^4.8", "spatie/laravel-activitylog": "^4.8",
"spatie/laravel-pdf": "^1.5", "spatie/laravel-pdf": "^1.5",
@ -41,7 +42,10 @@
"App\\": "app/", "App\\": "app/",
"Database\\Factories\\": "database/factories/", "Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/" "Database\\Seeders\\": "database/seeders/"
} },
"files": [
"app/Helpers/helpers.php"
]
}, },
"autoload-dev": { "autoload-dev": {
"psr-4": { "psr-4": {
@ -106,9 +110,14 @@
"url": "https://git.putrakuningan.com/daengdeni/authentication" "url": "https://git.putrakuningan.com/daengdeni/authentication"
}, },
{ {
"name": "rasyahroel/itsecurity", "name": "rasyahroel/itsecurity-module",
"type": "vcs", "type": "vcs",
"url": "https://git.putrakuningan.com/rasyahroel/itsecurity" "url": "https://git.putrakuningan.com/rasyahroel/itsecurity"
},
{
"name": "jackiedo/log-reader",
"type": "vcs",
"url": "https://github.com/daengdeni/Laravel-Log-Reader.git"
} }
] ]
} }

View File

@ -50,11 +50,10 @@
</div> </div>
</div> </div>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-5 lg:gap-7.5 items-stretch">
{{-- Report History User --}} {{-- Report History User --}}
<div class="grid my-5 gap-5 lg:gap-7.5"> <div class="grid my-5 gap-5 lg:gap-7.5">
<div class="card border border-agi-100 card-grid min-w-full" data-datatable="false" <div class="card border border-agi-100 card-grid min-w-full" data-datatable="false" data-datatable-page-size="5"
data-datatable-page-size="5" data-datatable-state-save="false" id="dashboardreport-table" data-datatable-state-save="false" id="dashboardreport-table"
data-api-url="{{ route('report.laporanhistory.datatables') }}"> data-api-url="{{ route('report.laporanhistory.datatables') }}">
<div class="card-header bg-agi-50 py-5 flex-wrap"> <div class="card-header bg-agi-50 py-5 flex-wrap">
<h3 class="card-title"> <h3 class="card-title">
@ -109,14 +108,50 @@
</div> </div>
</div> </div>
{{-- Audit Rail --}} <div class="grid grid-cols-1 lg:grid-cols-2 gap-5 lg:gap-7.5 items-stretch">
{{-- History User --}}
<div class="grid my-5 gap-5 lg:gap-7.5"> <div class="grid my-5 gap-5 lg:gap-7.5">
<div class="card border border-agi-100 card-grid min-w-full" data-datatable="false" <div class="card border border-agi-100 card-grid min-w-full" id="dashboardhistory">
data-datatable-page-size="5" data-datatable-state-save="false" id="audit-table"
data-api-url="{{ route('auditrail.datatables') }}">
<div class="card-header bg-agi-50 py-5 flex-wrap"> <div class="card-header bg-agi-50 py-5 flex-wrap">
<h3 class="card-title"> <h3 class="card-title">
Audit Trail History User Akses
</h3>
</div>
<div class="card-body">
@foreach (auth()->user()->unreadNotifications->take(5) as $notification)
<div class="flex items-center grow gap-2.5 px-5 py-4">
<div
class="flex items-center justify-center size-8 bg-success-light rounded-full border border-success-clarity">
<i class="ki-filled ki-check text-lg text-success">
</i>
</div>
<div class="flex flex-col gap-1">
<span class="text-2sm font-medium text-gray-700">
{{ formatNotifikasi($notification)['title'] }}<br>
{{ formatNotifikasi($notification)['message'] }}<br>
</span>
<span class="font-medium text-gray-500 text-2xs">
{{ $notification->created_at->diffForHumans() }}
</span>
</div>
</div>
@if (!$loop->last)
<div class="border-b border-b-gray-200"></div>
@endif
@endforeach
</div>
</div>
</div>
{{-- Audit Rail --}}
<div class="grid my-5 gap-5 lg:gap-7.5">
<div class="card border-agi-100 card-grid min-w-full" data-datatable="false" data-datatable-page-size="5"
data-datatable-state-save="false" id="audit-logs-table"
data-api-url="{{ route('logs.audit.datatables') }}">
<div class="card-header bg-agi-50 py-5 flex-wrap">
<h3 class="card-title">
Audit Logs
</h3> </h3>
</div> </div>
<div class="scrollable-x-auto"> <div class="scrollable-x-auto">
@ -124,28 +159,24 @@
data-datatable-table="true"> data-datatable-table="true">
<thead> <thead>
<tr> <tr>
<th class="min-w-[100px]" data-datatable-column="nik"> <th class="min-w-[100px]" data-datatable-column="log_name">
<span class="sort"> <span class="sort-label"> NIK </span> <span class="sort"> <span class="sort-label"> Log Type </span>
<span class="sort-icon"> </span> </span> <span class="sort-icon"> </span> </span>
</th> </th>
<th class="min-w-[100px]" data-datatable-column="name"> <th class="min-w-[100px]" data-datatable-column="subject_type">
<span class="sort"> <span class="sort-label"> Name </span> <span class="sort"> <span class="sort-label"> Subject Type </span>
<span class="sort-icon"> </span> </span> <span class="sort-icon"> </span> </span>
</th> </th>
<th class="min-w-[100px]" data-datatable-column="action_type"> <th class="min-w-[100px]" data-datatable-column="description">
<span class="sort"> <span class="sort-label"> Action Type </span> <span class="sort"> <span class="sort-label"> Description </span>
<span class="sort-icon"> </span> </span> <span class="sort-icon"> </span> </span>
</th> </th>
<th class="min-w-[100px]" data-datatable-column="action_description"> <th class="min-w-[100px]" data-datatable-column="causer_id">
<span class="sort"> <span class="sort-label"> Action Description</span> <span class="sort"> <span class="sort-label"> Causer ID </span>
<span class="sort-icon"> </span> </span> <span class="sort-icon"> </span> </span>
</th> </th>
<th class="min-w-[100px]" data-datatable-column="target_table"> <th class="min-w-[150px]" data-datatable-column="created_at">
<span class="sort"> <span class="sort-label"> Target Table </span> <span class="sort"> <span class="sort-label"> Date/Time </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[100px]" data-datatable-column="target_record_id">
<span class="sort"> <span class="sort-label"> Target Record Id </span>
<span class="sort-icon"> </span> </span> <span class="sort-icon"> </span> </span>
</th> </th>
</tr> </tr>
@ -157,8 +188,7 @@
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
Show Show
<select class="select select-sm w-16" data-datatable-size="true" name="perpage"> </select> <select class="select select-sm w-16" data-datatable-size="true" name="perpage"> </select>
per per page
page
</div> </div>
<div class="flex items-center gap-4"> <div class="flex items-center gap-4">
<span data-datatable-info="true"> </span> <span data-datatable-info="true"> </span>
@ -182,7 +212,7 @@
const ctx = document.getElementById('dashboardChart').getContext('2d'); const ctx = document.getElementById('dashboardChart').getContext('2d');
new Chart(ctx, { new Chart(ctx, {
type: 'pie', // tipe chart type: 'pie',
data: { data: {
labels: labels, labels: labels,
datasets: [{ datasets: [{
@ -276,34 +306,43 @@
}; };
const datatableReport = new KTDataTable(elementReport, dataTableReportOptions); const datatableReport = new KTDataTable(elementReport, dataTableReportOptions);
const elementAudit = document.querySelector('#audit-table'); const elementAudit = document.querySelector('#audit-logs-table');
const apiUrlAudit = elementAudit.getAttribute('data-api-url'); const apiUrlAudit = elementAudit.getAttribute('data-api-url');
// Inisialisasi DataTable // Inisialisasi DataTable Audit
const dataTableAuditOptions = { const dataTableAuditOptions = {
apiEndpoint: apiUrlAudit, apiEndpoint: apiUrlAudit,
pageSize: 5, pageSize: 5,
columns: { columns: {
nik: { log_name: {
title: 'nik', title: 'Log Type',
render: (item, data) => data?.user?.nik || 'Unknown', render: (item, data) => {
return `<span class="badge badge-light-primary">${data.log_name || 'N/A'}</span>`;
}
}, },
name: { description: {
title: 'name', title: 'Description',
render: (item, data) => data?.user?.name || 'Unknown',
}, },
action_type: { subject_type: {
title: 'action_type', title: 'Subject Type',
render: (item, data) => {
if (!data.subject_type) return 'N/A';
return data.subject_type.split('\\').pop();
}
}, },
action_description: { causer_id: {
title: 'action_description', title: 'Causer ID',
}, render: (item, data) => {
target_table: { return data.creator_name || 'System';
title: 'target_table', }
},
target_record_id: {
title: 'target_record_id',
}, },
created_at: {
title: 'Date/Time',
render: (item, data) => {
const date = new Date(data.created_at);
return window.formatTanggalWaktuIndonesia(date)
}
}
}, },
}; };
const datatableAudit = new KTDataTable(elementAudit, dataTableAuditOptions); const datatableAudit = new KTDataTable(elementAudit, dataTableAuditOptions);

View File

@ -1,15 +1,15 @@
<?php <?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\DashboardController; use App\Http\Controllers\DashboardController;
use Illuminate\Support\Facades\Route;
Route::middleware(['auth'])->group(function () {
Route::get('/notifications/count', function () { Route::get('/notifications/count', function () {
return response()->json([ return response()->json([
'count' => auth()->user()->unreadNotifications->count() 'count' => auth()->user()->unreadNotifications->count()
]); ]);
})->name('notifications.count')->middleware('auth'); })->name('notifications.count')->middleware('auth');
});
Route::middleware(['auth'])->group(function () {
Route::get('/', [DashboardController::class, 'index'])->name('dashboard'); Route::get('/', [DashboardController::class, 'index'])->name('dashboard');
}); });