From f141b0ad2d60b57fa419513ed3174a9553b58e48 Mon Sep 17 00:00:00 2001 From: hasanlq69 Date: Tue, 23 Sep 2025 16:31:30 +0700 Subject: [PATCH 1/5] Fitur: Menghapus file-file yang tidak diperlukan --- app/Http/Controllers/Auth/LoginController.php | 57 ++++ .../Controllers/Data/ProfilController.php | 13 + app/Http/Controllers/LogViewerController.php | 106 +++++++ .../Setting/AplikasiController.php | 25 +- app/Http/Controllers/User/UserController.php | 84 +++++- app/Models/User.php | 14 + composer.json | 1 + composer.lock | 99 ++++++- config/activitylog.php | 52 ++++ ...09_22_061449_create_activity_log_table.php | 27 ++ ...add_event_column_to_activity_log_table.php | 22 ++ ...atch_uuid_column_to_activity_log_table.php | 22 ++ .../layouts/dashboard_template.blade.php | 7 + .../activity-logs.blade.php | 267 ++++++++++++++++++ .../vendor/laravel-log-viewer/index.blade.php | 4 + routes/web.php | 6 +- 16 files changed, 791 insertions(+), 15 deletions(-) create mode 100644 config/activitylog.php create mode 100644 database/migrations/2025_09_22_061449_create_activity_log_table.php create mode 100644 database/migrations/2025_09_22_061450_add_event_column_to_activity_log_table.php create mode 100644 database/migrations/2025_09_22_061451_add_batch_uuid_column_to_activity_log_table.php create mode 100644 resources/views/vendor/laravel-log-viewer/activity-logs.blade.php diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index e94158aa3..96021310d 100644 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -134,6 +134,13 @@ protected function validateLogin(Request $request) } protected function authenticated(Request $request, $user) { + // Log successful login + activity() + ->causedBy($user) + ->performedOn($user) + ->event('login') + ->log('Pengguna berhasil masuk ke sistem'); + if (($this->settings['login_2fa'] ?? false)) { return $this->startTwoFactorAuthProcess($request, $user); } @@ -141,6 +148,56 @@ protected function authenticated(Request $request, $user) return redirect()->intended($this->redirectPath()); } + /** + * Handle a failed authentication attempt. + * + * @param \Illuminate\Http\Request $request + * @return void + * + * @throws \Illuminate\Validation\ValidationException + */ + protected function sendFailedLoginResponse(Request $request) + { + // Log failed login attempt + activity() + ->withProperties(['email' => $request->input($this->username())]) + ->log('Percobaan login gagal'); + + return parent::sendFailedLoginResponse($request); + } + + /** + * The user has logged out of the application. + * + * @param \Illuminate\Http\Request $request + * @return mixed + */ + public function logout(Request $request) + { + // Log the logout event before logging out + if (auth()->check()) { + activity() + ->causedBy(auth()->user()) + ->performedOn(auth()->user()) + ->event('logout') + ->log('Pengguna keluar dari sistem'); + } + + $this->guard()->logout(); + + $request->session()->invalidate(); + + $request->session()->regenerateToken(); + + return $this->loggedOut($request) ?: redirect('/'); + } + + protected function loggedOut(Request $request) + { + // This method can be used for additional logic after logout + // For example, flashing a session message. + } + /** * Log out the user and start the two factor authentication state. * diff --git a/app/Http/Controllers/Data/ProfilController.php b/app/Http/Controllers/Data/ProfilController.php index fa223ee04..c021592c3 100644 --- a/app/Http/Controllers/Data/ProfilController.php +++ b/app/Http/Controllers/Data/ProfilController.php @@ -110,11 +110,24 @@ public function update(ProfilRequest $request, $id) $profil->update(); $dataumum->update(); + // Log activity + activity() + ->causedBy(auth()->user()) + ->performedOn($profil) + ->event('updated') + ->log("Mengubah data profil kecamatan: {$profil->nama_kecamatan}"); + // Clear cache setelah update data kecamatan $this->clearProfilCache(); } catch (\Exception $e) { report($e); + // Log failed activity + activity() + ->causedBy(auth()->user()) + ->withProperties(['error' => $e->getMessage(), 'profil_id' => $id]) + ->log('Gagal mengubah profil kecamatan'); + return back()->withInput()->with('error', 'Update Profil gagal!'); } diff --git a/app/Http/Controllers/LogViewerController.php b/app/Http/Controllers/LogViewerController.php index 741b512e2..e73e65055 100644 --- a/app/Http/Controllers/LogViewerController.php +++ b/app/Http/Controllers/LogViewerController.php @@ -34,12 +34,15 @@ use App\Http\Requests\EmailSmtpRequest; use App\Mail\SmtpTestEmail; use App\Models\EmailSmtp; +use Illuminate\Http\Request; use Illuminate\Support\Facades\Artisan; use Illuminate\Support\Facades\Crypt; use Illuminate\Support\Facades\Mail; use RachidLaasri\LaravelInstaller\Helpers\RequirementsChecker; use Rap2hpoutre\LaravelLogViewer\LaravelLogViewer; +use Spatie\Activitylog\Models\Activity; use Symfony\Component\HttpFoundation\Response; +use Yajra\DataTables\DataTables; /** * Class LogViewerController @@ -273,4 +276,107 @@ public function sendTestEmailSmtp($email) 'success' => true, ], Response::HTTP_OK); } + + /** + * Menampilkan data activity logs untuk DataTables + */ + public function getActivityLogs(Request $request) + { + $query = Activity::with('causer')->latest(); + + // Filter berdasarkan event/description + if ($request->filled('action')) { + $query->where('event', $request->action); + } + + // Filter berdasarkan user + if ($request->filled('user_id')) { + $query->where('causer_id', $request->user_id); + } + + // Filter berdasarkan tanggal + if ($request->filled('date_from') && $request->filled('date_to')) { + $query->whereBetween('created_at', [ + $request->date_from . ' 00:00:00', + $request->date_to . ' 23:59:59' + ]); + } + + return DataTables::of($query) + ->addIndexColumn() + ->addColumn('user_display', function ($log) { + return $log->causer ? $log->causer->name : 'System'; + }) + ->addColumn('action_badge', function ($log) { + $badges = [ + 'login' => 'success', + 'logout' => 'info', + 'created' => 'primary', + 'updated' => 'warning', + 'deleted' => 'danger', + 'retrieved' => 'secondary' + ]; + $badge = $badges[$log->event] ?? 'secondary'; + return '' . ucfirst($log->event ?? 'N/A') . ''; + }) + ->addColumn('subject_display', function ($log) { + $subjectType = $log->subject_type ? class_basename($log->subject_type) : 'N/A'; + return $subjectType . ($log->subject_id ? " (ID: {$log->subject_id})" : ''); + }) + ->addColumn('formatted_date', function ($log) { + return $log->created_at->format('d/m/Y H:i:s'); + }) + ->addColumn('aksi', function ($log) { + return ''; + }) + ->rawColumns(['action_badge', 'aksi']) + ->make(true); + } + + /** + * Menampilkan detail activity log + */ + public function getActivityLogDetail($id) + { + $log = Activity::with('causer')->findOrFail($id); + + return response()->json([ + 'success' => true, + 'data' => [ + 'id' => $log->id, + 'user' => $log->causer ? $log->causer->name : 'System', + 'event' => $log->event, + 'description' => $log->description, + 'subject_type' => $log->subject_type, + 'subject_id' => $log->subject_id, + 'properties' => $log->properties, + 'created_at' => $log->created_at->format('d/m/Y H:i:s'), + ] + ]); + } + + /** + * Menghapus activity logs lama (cleanup) + */ + public function cleanupActivityLogs(Request $request) + { + try { + $days = $request->input('days', 30); // Default 30 hari + $cutoffDate = now()->subDays($days); + + $deletedCount = Activity::where('created_at', '<', $cutoffDate)->delete(); + + return response()->json([ + 'success' => true, + 'message' => "Berhasil menghapus {$deletedCount} log aktivitas yang lebih dari {$days} hari." + ]); + } catch (\Exception $e) { + return response()->json([ + 'success' => false, + 'message' => 'Gagal menghapus log aktivitas: ' . $e->getMessage() + ], Response::HTTP_INTERNAL_SERVER_ERROR); + } + } } diff --git a/app/Http/Controllers/Setting/AplikasiController.php b/app/Http/Controllers/Setting/AplikasiController.php index 8fa4806ad..59fb1ef61 100644 --- a/app/Http/Controllers/Setting/AplikasiController.php +++ b/app/Http/Controllers/Setting/AplikasiController.php @@ -61,14 +61,33 @@ public function update(Request $request, $id) ]); try { - $penyakit = SettingAplikasi::findOrFail($id); - $penyakit->fill($request->only(['value'])); - $penyakit->save(); + $setting = SettingAplikasi::findOrFail($id); + $oldValue = $setting->value; + $setting->fill($request->only(['value'])); + $setting->save(); + + // Log activity + activity() + ->causedBy(auth()->user()) + ->performedOn($setting) + ->withProperties([ + 'setting_name' => $setting->key, + 'old_value' => $oldValue, + 'new_value' => $request->input('value') + ]) + ->event('updated') + ->log("Mengubah pengaturan {$setting->key}"); $this->browser_title = $request->input('value'); } catch (\Exception $e) { report($e); + // Log failed activity + activity() + ->causedBy(auth()->user()) + ->withProperties(['error' => $e->getMessage(), 'setting_id' => $id]) + ->log('Gagal mengubah pengaturan aplikasi'); + return back()->with('error', 'Pengaturan aplikasi gagal diubah!'); } diff --git a/app/Http/Controllers/User/UserController.php b/app/Http/Controllers/User/UserController.php index 1cdee03ae..20b6cd54c 100644 --- a/app/Http/Controllers/User/UserController.php +++ b/app/Http/Controllers/User/UserController.php @@ -91,10 +91,24 @@ public function store(UserRequest $request) $roles = $request->input('role') ? $request->input('role') : []; $user->assignRole($roles); + // Log activity - Spatie akan otomatis log karena model User menggunakan LogsActivity trait + activity() + ->causedBy(auth()->user()) + ->performedOn($user) + ->withProperties(['roles' => $roles]) + ->event('created') + ->log("Membuat pengguna baru: {$user->name} ({$user->email})"); + return redirect()->route('setting.user.index')->with('success', 'User berhasil ditambahkan!'); } catch (\Exception $e) { report($e); + // Log failed activity + activity() + ->causedBy(auth()->user()) + ->withProperties(['error' => $e->getMessage(), 'input_data' => $request->except(['password', '_token'])]) + ->log('Gagal membuat pengguna baru'); + return back()->withInput()->with('error', $e->getMessage()); } } @@ -141,6 +155,7 @@ public function update(UserRequest $request, $id) try { $input = $request->validated(); $user = User::findOrFail($id); + $this->handleFileUpload($request, $input, 'image', 'user', false); $user->update($input); if (! empty($request->role)) { @@ -148,10 +163,24 @@ public function update(UserRequest $request, $id) $user->syncRoles($roles); } + // Log activity + activity() + ->causedBy(auth()->user()) + ->performedOn($user) + ->withProperties(['roles' => $roles ?? []]) + ->event('updated') + ->log("Mengubah data pengguna: {$user->name} ({$user->email})"); + return redirect()->route('setting.user.index')->with('success', 'User berhasil diperbarui!'); } catch (\Exception $e) { report($e); + // Log failed activity + activity() + ->causedBy(auth()->user()) + ->withProperties(['error' => $e->getMessage(), 'user_id' => $id]) + ->log('Gagal mengubah data pengguna'); + return back()->withInput()->with('error', $e->getMessage()); } } @@ -169,16 +198,29 @@ public function updatePassword(UserUpdateRequest $request, $id) $user_find = User::findOrFail($id); $user = $user_find->update($request->all()); - $user->update([ + $user_find->update([ 'password' => bcrypt($request->password), ]); - flash()->success(trans('message.user.update-success')); + // Log activity + activity() + ->causedBy(auth()->user()) + ->performedOn($user_find) + ->log("Mengubah password pengguna: {$user_find->name} ({$user_find->email})"); + + flash()->success('Password pengguna berhasil diperbarui'); return redirect()->route('setting.user.index'); } catch (\Exception $e) { report($e); - flash()->error(trans('message.user.update-error')); + + // Log failed activity + activity() + ->causedBy(auth()->user()) + ->withProperties(['error' => $e->getMessage(), 'user_id' => $id]) + ->log('Gagal mengubah password pengguna'); + + flash()->error('Gagal mengubah password pengguna'); return back()->withInput(); } @@ -197,12 +239,26 @@ public function destroy($id) $user->status = 0; $user->save(); - flash()->success(trans('general.suspend-success')); + // Log activity + activity() + ->causedBy(auth()->user()) + ->performedOn($user) + ->withProperties(['action' => 'suspend', 'previous_status' => 1, 'new_status' => 0]) + ->log("Menonaktifkan pengguna: {$user->name} ({$user->email})"); + + flash()->success('Pengguna berhasil dinonaktifkan'); return redirect()->route('setting.user.index'); } catch (\Exception $e) { report($e); - flash()->success(trans('general.suspend-error')); + + // Log failed activity + activity() + ->causedBy(auth()->user()) + ->withProperties(['error' => $e->getMessage(), 'user_id' => $id]) + ->log('Gagal menonaktifkan pengguna'); + + flash()->error('Gagal menonaktifkan pengguna'); return redirect()->route('setting.user.index'); } @@ -221,12 +277,26 @@ public function active($id) $user->status = 1; $user->save(); - flash()->success(trans('general.active-success')); + // Log activity + activity() + ->causedBy(auth()->user()) + ->performedOn($user) + ->withProperties(['action' => 'activate', 'previous_status' => 0, 'new_status' => 1]) + ->log("Mengaktifkan pengguna: {$user->name} ({$user->email})"); + + flash()->success('Pengguna berhasil diaktifkan'); return redirect()->route('setting.user.index'); } catch (\Exception $e) { report($e); - flash()->success(trans('general.active-error')); + + // Log failed activity + activity() + ->causedBy(auth()->user()) + ->withProperties(['error' => $e->getMessage(), 'user_id' => $id]) + ->log('Gagal mengaktifkan pengguna'); + + flash()->error('Gagal mengaktifkan pengguna'); return redirect()->route('setting.user.index'); } diff --git a/app/Models/User.php b/app/Models/User.php index 307ef6025..08cc1dd29 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -43,6 +43,8 @@ use Illuminate\Auth\Authenticatable as AuthenticableTrait; use Illuminate\Database\Eloquent\Factories\HasFactory; use MichaelDzjap\TwoFactorAuth\TwoFactorAuthenticable; +use Spatie\Activitylog\Traits\LogsActivity; +use Spatie\Activitylog\LogOptions; class User extends Authenticatable implements JWTSubject { @@ -52,6 +54,7 @@ class User extends Authenticatable implements JWTSubject use Notifiable; use HandlesResourceDeletion; use TwoFactorAuthenticable; + use LogsActivity; /** * Default password. @@ -60,6 +63,17 @@ class User extends Authenticatable implements JWTSubject */ public const DEFAULT_PASSWORD = '12345678'; + /** + * Configure activity logging options + */ + public function getActivitylogOptions(): LogOptions + { + return LogOptions::defaults() + ->logOnly(['name', 'email', 'status', 'address', 'phone']) + ->logOnlyDirty() + ->dontSubmitEmptyLogs(); + } + /** * {@inheritDoc} */ diff --git a/composer.json b/composer.json index 24d22bf8c..c7dff826f 100644 --- a/composer.json +++ b/composer.json @@ -32,6 +32,7 @@ "rachidlaasri/laravel-installer": "^4.1", "rap2hpoutre/laravel-log-viewer": "^2.0", "sentry/sentry-laravel": "^3.8", + "spatie/laravel-activitylog": "^4.10", "spatie/laravel-backup": "^8.2", "spatie/laravel-permission": "^5.5", "stevebauman/purify": "^6.2", diff --git a/composer.lock b/composer.lock index d31840473..306801c68 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e78ec08298d7f3ac82d7e052b4c71aa7", + "content-hash": "071c319bbe4f1461f70f18201414bcc9", "packages": [ { "name": "bensampo/laravel-enum", @@ -6655,6 +6655,97 @@ ], "time": "2025-02-14T15:04:22+00:00" }, + { + "name": "spatie/laravel-activitylog", + "version": "4.10.2", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-activitylog.git", + "reference": "bb879775d487438ed9a99e64f09086b608990c10" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-activitylog/zipball/bb879775d487438ed9a99e64f09086b608990c10", + "reference": "bb879775d487438ed9a99e64f09086b608990c10", + "shasum": "" + }, + "require": { + "illuminate/config": "^8.0 || ^9.0 || ^10.0 || ^11.0 || ^12.0", + "illuminate/database": "^8.69 || ^9.27 || ^10.0 || ^11.0 || ^12.0", + "illuminate/support": "^8.0 || ^9.0 || ^10.0 || ^11.0 || ^12.0", + "php": "^8.1", + "spatie/laravel-package-tools": "^1.6.3" + }, + "require-dev": { + "ext-json": "*", + "orchestra/testbench": "^6.23 || ^7.0 || ^8.0 || ^9.0 || ^10.0", + "pestphp/pest": "^1.20 || ^2.0 || ^3.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Spatie\\Activitylog\\ActivitylogServiceProvider" + ] + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Spatie\\Activitylog\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + }, + { + "name": "Sebastian De Deyne", + "email": "sebastian@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + }, + { + "name": "Tom Witkowski", + "email": "dev.gummibeer@gmail.com", + "homepage": "https://gummibeer.de", + "role": "Developer" + } + ], + "description": "A very simple activity logger to monitor the users of your website or application", + "homepage": "https://github.com/spatie/activitylog", + "keywords": [ + "activity", + "laravel", + "log", + "spatie", + "user" + ], + "support": { + "issues": "https://github.com/spatie/laravel-activitylog/issues", + "source": "https://github.com/spatie/laravel-activitylog/tree/4.10.2" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + }, + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2025-06-15T06:59:49+00:00" + }, { "name": "spatie/laravel-backup", "version": "8.8.2", @@ -13348,15 +13439,15 @@ ], "aliases": [], "minimum-stability": "dev", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": true, "prefer-lowest": false, "platform": { "php": "^8.1" }, - "platform-dev": [], + "platform-dev": {}, "platform-overrides": { "php": "8.1" }, - "plugin-api-version": "2.2.0" + "plugin-api-version": "2.6.0" } diff --git a/config/activitylog.php b/config/activitylog.php new file mode 100644 index 000000000..f1262f542 --- /dev/null +++ b/config/activitylog.php @@ -0,0 +1,52 @@ + env('ACTIVITY_LOGGER_ENABLED', true), + + /* + * When the clean-command is executed, all recording activities older than + * the number of days specified here will be deleted. + */ + 'delete_records_older_than_days' => 365, + + /* + * If no log name is passed to the activity() helper + * we use this default log name. + */ + 'default_log_name' => 'default', + + /* + * You can specify an auth driver here that gets user models. + * If this is null we'll use the current Laravel auth driver. + */ + 'default_auth_driver' => null, + + /* + * If set to true, the subject returns soft deleted models. + */ + 'subject_returns_soft_deleted_models' => false, + + /* + * This model will be used to log activity. + * It should implement the Spatie\Activitylog\Contracts\Activity interface + * and extend Illuminate\Database\Eloquent\Model. + */ + 'activity_model' => \Spatie\Activitylog\Models\Activity::class, + + /* + * This is the name of the table that will be created by the migration and + * used by the Activity model shipped with this package. + */ + 'table_name' => env('ACTIVITY_LOGGER_TABLE_NAME', 'activity_log'), + + /* + * This is the database connection that will be used by the migration and + * the Activity model shipped with this package. In case it's not set + * Laravel's database.default will be used instead. + */ + 'database_connection' => env('ACTIVITY_LOGGER_DB_CONNECTION'), +]; diff --git a/database/migrations/2025_09_22_061449_create_activity_log_table.php b/database/migrations/2025_09_22_061449_create_activity_log_table.php new file mode 100644 index 000000000..7c05bc892 --- /dev/null +++ b/database/migrations/2025_09_22_061449_create_activity_log_table.php @@ -0,0 +1,27 @@ +create(config('activitylog.table_name'), function (Blueprint $table) { + $table->bigIncrements('id'); + $table->string('log_name')->nullable(); + $table->text('description'); + $table->nullableMorphs('subject', 'subject'); + $table->nullableMorphs('causer', 'causer'); + $table->json('properties')->nullable(); + $table->timestamps(); + $table->index('log_name'); + }); + } + + public function down() + { + Schema::connection(config('activitylog.database_connection'))->dropIfExists(config('activitylog.table_name')); + } +} diff --git a/database/migrations/2025_09_22_061450_add_event_column_to_activity_log_table.php b/database/migrations/2025_09_22_061450_add_event_column_to_activity_log_table.php new file mode 100644 index 000000000..7b797fd5e --- /dev/null +++ b/database/migrations/2025_09_22_061450_add_event_column_to_activity_log_table.php @@ -0,0 +1,22 @@ +table(config('activitylog.table_name'), function (Blueprint $table) { + $table->string('event')->nullable()->after('subject_type'); + }); + } + + public function down() + { + Schema::connection(config('activitylog.database_connection'))->table(config('activitylog.table_name'), function (Blueprint $table) { + $table->dropColumn('event'); + }); + } +} diff --git a/database/migrations/2025_09_22_061451_add_batch_uuid_column_to_activity_log_table.php b/database/migrations/2025_09_22_061451_add_batch_uuid_column_to_activity_log_table.php new file mode 100644 index 000000000..8f7db6654 --- /dev/null +++ b/database/migrations/2025_09_22_061451_add_batch_uuid_column_to_activity_log_table.php @@ -0,0 +1,22 @@ +table(config('activitylog.table_name'), function (Blueprint $table) { + $table->uuid('batch_uuid')->nullable()->after('properties'); + }); + } + + public function down() + { + Schema::connection(config('activitylog.database_connection'))->table(config('activitylog.table_name'), function (Blueprint $table) { + $table->dropColumn('batch_uuid'); + }); + } +} diff --git a/resources/views/layouts/dashboard_template.blade.php b/resources/views/layouts/dashboard_template.blade.php index e4d2cca63..c3abe0005 100644 --- a/resources/views/layouts/dashboard_template.blade.php +++ b/resources/views/layouts/dashboard_template.blade.php @@ -21,6 +21,8 @@ + + @stack('css') @@ -98,6 +100,11 @@ + + + + + @stack('scripts') diff --git a/resources/views/vendor/laravel-log-viewer/activity-logs.blade.php b/resources/views/vendor/laravel-log-viewer/activity-logs.blade.php new file mode 100644 index 000000000..be0f9c9e8 --- /dev/null +++ b/resources/views/vendor/laravel-log-viewer/activity-logs.blade.php @@ -0,0 +1,267 @@ +
+
+

Log Aktivitas

+
+ +
+
+ +
+ +
+
+ +
+
+ +
+
+ +
+
+ + +
+
+ + +
+ + + + + + + + + + + + +
NoPenggunaEventDeskripsiSubjectTanggalAksi
+
+
+
+ + + + + + + +@push('scripts') + +@endpush diff --git a/resources/views/vendor/laravel-log-viewer/index.blade.php b/resources/views/vendor/laravel-log-viewer/index.blade.php index b7b285c78..547416fbd 100644 --- a/resources/views/vendor/laravel-log-viewer/index.blade.php +++ b/resources/views/vendor/laravel-log-viewer/index.blade.php @@ -19,6 +19,7 @@