Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,7 @@ graphify-out

# Scribe (auto-generated, contains auth tokens)
.scribe/
specs/
.specify/

AGENTS.md
17 changes: 17 additions & 0 deletions app/Http/Controllers/Setting/LogAktivitasController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace App\Http\Controllers\Setting;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

class LogAktivitasController extends Controller
{
public function __invoke(Request $request)
{
$page_title = 'Riwayat Aktivitas';
$page_description = 'Log aktivitas pengguna dan sistem';

return view('setting.log-aktivitas.index', compact('page_title', 'page_description'));
}
}
87 changes: 57 additions & 30 deletions app/Http/Controllers/Setting/PengaturanDatabaseController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,17 @@

namespace App\Http\Controllers\Setting;

use App\Http\Controllers\Controller;
use App\Services\ActivityLogService;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Yajra\DataTables\DataTables;
use Illuminate\Support\Facades\Log;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Storage;
use Spatie\Backup\Tasks\Backup\BackupJobFactory;

use Illuminate\Support\Facades\Artisan;

use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Log;

use Exception;
use Illuminate\Support\Facades\Storage;

use Yajra\DataTables\DataTables;

class PengaturanDatabaseController extends Controller
{
Expand Down Expand Up @@ -80,6 +77,10 @@ public function createBackup()

if ($exitCode !== 0) {
Log::error('Backup process failed with exit code: ' . $exitCode);
ActivityLogService::log('backup database gagal', 'Proses backup database gagal.', [
'user_name' => auth()->user() ? auth()->user()->name : 'Sistem',
'exit_code' => $exitCode,
]);

return response()->json([
'success' => false,
Expand All @@ -88,10 +89,16 @@ public function createBackup()
}

Log::info('Ending backup process.');
ActivityLogService::log('backup database', 'Proses backup database berhasil.', [
'user_name' => auth()->user() ? auth()->user()->name : 'Sistem',
]);

return response()->json(['success' => true, 'message' => 'Backup completed successfully']);
} catch (\Exception $e) {
Log::error('Backup process failed: ' . $e->getMessage(), ['exception' => $e]);
ActivityLogService::logFailed('backup database gagal', 'Proses backup database gagal: ' . $e->getMessage(), [
'user_name' => auth()->user() ? auth()->user()->name : 'Sistem',
]);

return response()->json(['success' => false, 'message' => 'Backup process failed', 'error' => $e->getMessage()], 500);
}
Expand All @@ -103,6 +110,11 @@ public function downloadBackup($file)
$filePath = "{$this->destination}/{$file}";

if ($disk->exists($filePath)) {
ActivityLogService::log('unduh backup database', "Mengunduh file backup: {$file}", [
'user_name' => auth()->user() ? auth()->user()->name : 'Sistem',
'file' => $file,
]);

return $disk->download($filePath);
}

Expand All @@ -116,32 +128,17 @@ public function deleteBackup($file)

if ($disk->exists($filePath)) {
$disk->delete($filePath);
ActivityLogService::log('hapus backup database', "Menghapus file backup: {$file}", [
'user_name' => auth()->user() ? auth()->user()->name : 'Sistem',
'file' => $file,
]);

return redirect()->route('setting.pengaturan-database.backup')->with('success', 'Backup berhasil dihapus');
}

return redirect()->route('setting.pengaturan-database.backup')->with('error', 'Backup tidak ditemukan');
}

/**
* Fungsi untuk format ukuran file
*/
private function formatSizeUnits($bytes)
{
if ($bytes >= 1073741824) {
return number_format($bytes / 1073741824, 2) . ' GB';
} elseif ($bytes >= 1048576) {
return number_format($bytes / 1048576, 2) . ' MB';
} elseif ($bytes >= 1024) {
return number_format($bytes / 1024, 2) . ' KB';
} elseif ($bytes > 1) {
return $bytes . ' bytes';
} elseif ($bytes == 1) {
return $bytes . ' byte';
} else {
return '0 bytes';
}
}

// RESTORE DATABASE

public function restoreDatabase()
Expand All @@ -152,7 +149,6 @@ public function restoreDatabase()
return view('setting.pengaturan_database.table-restore', compact('page_title', 'page_description'));
}


public function restoreBackup(Request $request)
{
$request->validate([
Expand All @@ -179,7 +175,7 @@ public function restoreBackup(Request $request)
$filename = basename($path);
$allowedChars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789._-';

if (! preg_match("/^[" . $allowedChars . "]+$/", $filename)) {
if (! preg_match('/^[' . $allowedChars . ']+$/', $filename)) {
return response()->json([
'success' => false,
'message' => 'Nama file tidak valid. Hanya boleh mengandung huruf (a-z/A-Z), angka (0-9), titik (.), dan garis bawah (_).',
Expand Down Expand Up @@ -209,12 +205,19 @@ public function restoreBackup(Request $request)
Log::info('Restore from ZIP: ' . $finalPath);
$result = $this->restoreFromZip($finalPath);

ActivityLogService::log('restore database', "Restore database berhasil. {$result['files_restored']} file asset dipulihkan.", [
'user_name' => auth()->user() ? auth()->user()->name : 'Sistem',
]);

return response()->json([
'success' => true,
'message' => "Restore berhasil. Database dan {$result['files_restored']} file asset telah dipulihkan.",
], 200);
} catch (\Exception $e) {
Log::error('Restore error: ' . $e->getMessage());
ActivityLogService::logFailed('restore database gagal', 'Restore database gagal: ' . $e->getMessage(), [
'user_name' => auth()->user() ? auth()->user()->name : 'Sistem',
]);

return response()->json([
'success' => false,
Expand All @@ -226,6 +229,30 @@ public function restoreBackup(Request $request)
}
}

/**
* Fungsi untuk format ukuran file.
*/
private function formatSizeUnits($bytes)
{
if ($bytes >= 1073741824) {
return number_format($bytes / 1073741824, 2) . ' GB';
}
if ($bytes >= 1048576) {
return number_format($bytes / 1048576, 2) . ' MB';
}
if ($bytes >= 1024) {
return number_format($bytes / 1024, 2) . ' KB';
}
if ($bytes > 1) {
return $bytes . ' bytes';
}
if ($bytes == 1) {
return $bytes . ' byte';
}
return '0 bytes';

}

private function runRestoreDatabase($sqlFilePath)
{
// Ambil konfigurasi database
Expand Down
93 changes: 93 additions & 0 deletions app/Http/Livewire/Pengaturan/LogAktivitasTable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?php

namespace App\Http\Livewire\Pengaturan;

use App\Services\ActivityLogService;
use Livewire\Component;
use Spatie\Activitylog\Models\Activity;

class LogAktivitasTable extends Component
{
public $dateFrom;

public $dateTo;

public $userId;

public $event;

public $keyword;

public $selectedActivityId = null;

public $selectedActivity = null;

protected $queryString = [
'dateFrom' => ['except' => ''],
'dateTo' => ['except' => ''],
'userId' => ['except' => ''],
'event' => ['except' => ''],
'keyword' => ['except' => ''],
];

public function mount(): void
{
$this->dateFrom = now()->subDays(30)->format('Y-m-d');
$this->dateTo = now()->format('Y-m-d');
}

public function render()
{
$activities = app(ActivityLogService::class)
->getFilteredActivities($this->dateFrom, $this->dateTo, $this->userId, $this->event, $this->keyword)
->latest()
->paginate(25);

$users = \App\Models\User::orderBy('name')->get();
$events = Activity::select('event')->distinct()->pluck('event');

return view('livewire.pengaturan.log-aktivitas-table', compact('activities', 'users', 'events'));
}

public function showDetail(int $id): void
{
$this->selectedActivityId = $id;
$this->selectedActivity = Activity::with('causer')->findOrFail($id);
$this->showModal = true;
}

public function closeDetail(): void
{
$this->selectedActivityId = null;
$this->selectedActivity = null;
$this->showModal = false;
}

/**
* Cek apakah aktivitas merupakan kegagalan (failed login atau error).
*/
public function isActivityFailed($activity): bool
{
// Cek flag 'failed' di properties
if (isset($activity->properties['failed']) && $activity->properties['failed']) {
return true;
}

// Cek nama event yang mengandung kata 'gagal'
if (in_array(strtolower($activity->event), ['login gagal', 'gagal'])) {
return true;
}

return false;
}

public function resetFilters(): void
{
$this->dateFrom = now()->subDays(30)->format('Y-m-d');
$this->dateTo = now()->format('Y-m-d');
$this->userId = '';
$this->event = '';
$this->keyword = '';
$this->closeDetail();
}
}
9 changes: 8 additions & 1 deletion app/Models/DataUmum.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use App\Observers\DataUmumObserver;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class DataUmum extends Model
{
use HasFactory;

// Attributes
protected $table = 'das_data_umum';

Expand Down Expand Up @@ -114,4 +116,9 @@ public function setPathAttribute($value)

$this->attributes['path'] = $value;
}

protected static function booted(): void
{
static::observe(DataUmumObserver::class);
}
}
11 changes: 9 additions & 2 deletions app/Models/Komplain.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@

namespace App\Models;

use App\Observers\KomplainObserver;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Komplain extends Model
{
use HasFactory;

protected $table = 'das_komplain';

protected $fillable = [
Expand Down Expand Up @@ -76,12 +78,17 @@ public static function generateID()
$id = mt_rand(100000, 999999);
$pid = '';

if (! Komplain::where('komplain_id', '=', $id)->exists()) {
if (! self::where('komplain_id', '=', $id)->exists()) {
$pid = $id;
} else {
self::generateID();
return self::generateID();
}

return $pid;
}

protected static function booted(): void
{
static::observe(KomplainObserver::class);
}
}
7 changes: 4 additions & 3 deletions app/Models/Profil.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use App\Observers\ProfilObserver;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;

class Profil extends Model
Expand Down Expand Up @@ -93,9 +94,9 @@ public function strukturOrganisasi()
// return $this->hasMany(Penduduk::class, 'kecamatan_id', 'kecamatan_id')->where('status_dasar', 1);
// }

protected static function boot()
protected static function booted(): void
{
parent::boot();
static::observe(ProfilObserver::class);

static::saved(function () {
Cache::forget('profil');
Expand Down
Loading