ABOUTKEVINYAHYACOM
[kevinya1@sc139 layouts]$ cd ~
[kevinya1@sc139 ~]$ cp ~/laravel-about/.env ~/backup_env
[kevinya1@sc139 ~]$
[kevinya1@sc139 ~]$ rm -rf ~/about.kevinyahya.com
[kevinya1@sc139 ~]$ rm -rf ~/laravel-about
[kevinya1@sc139 ~]$ composer create-project laravel/laravel about.kevinyahya.com
Creating a "laravel/laravel" project at "./about.kevinyahya.com"
Cannot use laravel/laravel's latest version v13.8.0 as it requires php ^8.3 which is not satisfied by your platform.
Installing laravel/laravel (v12.12.2)
- Installing laravel/laravel (v12.12.2): Extracting archive
Created project in /DATA/kevinya1/about.kevinyahya.com
> @php -r "file_exists('.env') || copy('.env.example', '.env');"
Loading composer repositories with package information
Updating dependencies
Lock file operations: 111 installs, 0 updates, 0 removals
- Locking brick/math (0.14.8)
- Locking carbonphp/carbon-doctrine-types (3.2.0)
- Locking dflydev/dot-access-data (v3.0.3)
- Locking doctrine/inflector (2.1.0)
- Locking doctrine/lexer (3.0.1)
- Locking dragonmantank/cron-expression (v3.6.0)
- Locking egulias/email-validator (4.0.4)
- Locking fakerphp/faker (v1.24.1)
- Locking filp/whoops (2.18.4)
- Locking fruitcake/php-cors (v1.4.0)
- Locking graham-campbell/result-type (v1.1.4)
- Locking guzzlehttp/guzzle (7.11.0)
- Locking guzzlehttp/promises (2.5.0)
- Locking guzzlehttp/psr7 (2.11.0)
- Locking guzzlehttp/uri-template (v1.0.6)
- Locking hamcrest/hamcrest-php (v2.1.1)
- Locking laravel/framework (v12.61.1)
- Locking laravel/pail (v1.2.7)
- Locking laravel/pint (v1.29.1)
- Locking laravel/prompts (v0.3.18)
- Locking laravel/sail (v1.62.0)
- Locking laravel/serializable-closure (v2.0.13)
- Locking laravel/tinker (v2.11.1)
- Locking league/commonmark (2.8.2)
- Locking league/config (v1.2.0)
- Locking league/flysystem (3.34.0)
- Locking league/flysystem-local (3.31.0)
- Locking league/mime-type-detection (1.16.0)
- Locking league/uri (7.8.1)
- Locking league/uri-interfaces (7.8.1)
- Locking mockery/mockery (1.6.12)
- Locking monolog/monolog (3.10.0)
- Locking myclabs/deep-copy (1.13.4)
- Locking nesbot/carbon (3.11.4)
- Locking nette/schema (v1.3.5)
- Locking nette/utils (v4.1.4)
- Locking nikic/php-parser (v5.7.0)
- Locking nunomaduro/collision (v8.9.4)
- Locking nunomaduro/termwind (v2.4.0)
- Locking phar-io/manifest (2.0.4)
- Locking phar-io/version (3.2.1)
- Locking phpoption/phpoption (1.9.5)
- Locking phpunit/php-code-coverage (11.0.12)
- Locking phpunit/php-file-iterator (5.1.1)
- Locking phpunit/php-invoker (5.0.1)
- Locking phpunit/php-text-template (4.0.1)
- Locking phpunit/php-timer (7.0.1)
- Locking phpunit/phpunit (11.5.55)
- Locking psr/clock (1.0.0)
- Locking psr/container (2.0.2)
- Locking psr/event-dispatcher (1.0.0)
- Locking psr/http-client (1.0.3)
- Locking psr/http-factory (1.1.0)
- Locking psr/http-message (2.0)
- Locking psr/log (3.0.2)
- Locking psr/simple-cache (3.0.0)
- Locking psy/psysh (v0.12.23)
- Locking ralouphie/getallheaders (3.0.3)
- Locking ramsey/collection (2.1.1)
- Locking ramsey/uuid (4.9.2)
- Locking sebastian/cli-parser (3.0.2)
- Locking sebastian/code-unit (3.0.3)
- Locking sebastian/code-unit-reverse-lookup (4.0.1)
- Locking sebastian/comparator (6.3.3)
- Locking sebastian/complexity (4.0.1)
- Locking sebastian/diff (6.0.2)
- Locking sebastian/environment (7.2.1)
- Locking sebastian/exporter (6.3.2)
- Locking sebastian/global-state (7.0.2)
- Locking sebastian/lines-of-code (3.0.1)
- Locking sebastian/object-enumerator (6.0.1)
- Locking sebastian/object-reflector (4.0.1)
- Locking sebastian/recursion-context (6.0.3)
- Locking sebastian/type (5.1.3)
- Locking sebastian/version (5.0.2)
- Locking staabm/side-effects-detector (1.0.5)
- Locking symfony/clock (v7.4.8)
- Locking symfony/console (v7.4.13)
- Locking symfony/css-selector (v7.4.9)
- Locking symfony/deprecation-contracts (v3.7.0)
- Locking symfony/error-handler (v7.4.8)
- Locking symfony/event-dispatcher (v7.4.9)
- Locking symfony/event-dispatcher-contracts (v3.7.0)
- Locking symfony/finder (v7.4.8)
- Locking symfony/http-foundation (v7.4.13)
- Locking symfony/http-kernel (v7.4.13)
- Locking symfony/mailer (v7.4.12)
- Locking symfony/mime (v7.4.13)
- Locking symfony/polyfill-ctype (v1.37.0)
- Locking symfony/polyfill-intl-grapheme (v1.38.1)
- Locking symfony/polyfill-intl-idn (v1.38.1)
- Locking symfony/polyfill-intl-normalizer (v1.38.0)
- Locking symfony/polyfill-mbstring (v1.38.1)
- Locking symfony/polyfill-php80 (v1.37.0)
- Locking symfony/polyfill-php83 (v1.38.1)
- Locking symfony/polyfill-php84 (v1.38.1)
- Locking symfony/polyfill-php85 (v1.38.1)
- Locking symfony/polyfill-uuid (v1.37.0)
- Locking symfony/process (v7.4.13)
- Locking symfony/routing (v7.4.13)
- Locking symfony/service-contracts (v3.7.0)
- Locking symfony/string (v7.4.13)
- Locking symfony/translation (v7.4.10)
- Locking symfony/translation-contracts (v3.7.0)
- Locking symfony/uid (v7.4.9)
- Locking symfony/var-dumper (v7.4.8)
- Locking symfony/yaml (v7.4.13)
- Locking theseer/tokenizer (1.3.1)
- Locking tijsverkoyen/css-to-inline-styles (v2.4.0)
- Locking vlucas/phpdotenv (v5.6.3)
- Locking voku/portable-ascii (2.1.1)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 111 installs, 0 updates, 0 removals
- Downloading laravel/framework (v12.61.1)
- Installing doctrine/inflector (2.1.0): Extracting archive
- Installing doctrine/lexer (3.0.1): Extracting archive
- Installing dragonmantank/cron-expression (v3.6.0): Extracting archive
- Installing symfony/deprecation-contracts (v3.7.0): Extracting archive
- Installing psr/container (2.0.2): Extracting archive
- Installing fakerphp/faker (v1.24.1): Extracting archive
- Installing symfony/polyfill-mbstring (v1.38.1): Extracting archive
- Installing symfony/http-foundation (v7.4.13): Extracting archive
- Installing fruitcake/php-cors (v1.4.0): Extracting archive
- Installing symfony/polyfill-php80 (v1.37.0): Extracting archive
- Installing psr/http-message (2.0): Extracting archive
- Installing psr/http-client (1.0.3): Extracting archive
- Installing ralouphie/getallheaders (3.0.3): Extracting archive
- Installing psr/http-factory (1.1.0): Extracting archive
- Installing guzzlehttp/psr7 (2.11.0): Extracting archive
- Installing guzzlehttp/promises (2.5.0): Extracting archive
- Installing guzzlehttp/guzzle (7.11.0): Extracting archive
- Installing guzzlehttp/uri-template (v1.0.6): Extracting archive
- Installing symfony/polyfill-intl-normalizer (v1.38.0): Extracting archive
- Installing symfony/polyfill-intl-grapheme (v1.38.1): Extracting archive
- Installing symfony/polyfill-ctype (v1.37.0): Extracting archive
- Installing symfony/string (v7.4.13): Extracting archive
- Installing symfony/service-contracts (v3.7.0): Extracting archive
- Installing symfony/console (v7.4.13): Extracting archive
- Installing nunomaduro/termwind (v2.4.0): Extracting archive
- Installing voku/portable-ascii (2.1.1): Extracting archive
- Installing phpoption/phpoption (1.9.5): Extracting archive
- Installing graham-campbell/result-type (v1.1.4): Extracting archive
- Installing vlucas/phpdotenv (v5.6.3): Extracting archive
- Installing symfony/css-selector (v7.4.9): Extracting archive
- Installing tijsverkoyen/css-to-inline-styles (v2.4.0): Extracting archive
- Installing symfony/var-dumper (v7.4.8): Extracting archive
- Installing symfony/polyfill-uuid (v1.37.0): Extracting archive
- Installing symfony/uid (v7.4.9): Extracting archive
- Installing symfony/routing (v7.4.13): Extracting archive
- Installing symfony/process (v7.4.13): Extracting archive
- Installing symfony/polyfill-php85 (v1.38.1): Extracting archive
- Installing symfony/polyfill-php84 (v1.38.1): Extracting archive
- Installing symfony/polyfill-php83 (v1.38.1): Extracting archive
- Installing symfony/polyfill-intl-idn (v1.38.1): Extracting archive
- Installing symfony/mime (v7.4.13): Extracting archive
- Installing psr/event-dispatcher (1.0.0): Extracting archive
- Installing symfony/event-dispatcher-contracts (v3.7.0): Extracting archive
- Installing symfony/event-dispatcher (v7.4.9): Extracting archive
- Installing psr/log (3.0.2): Extracting archive
- Installing egulias/email-validator (4.0.4): Extracting archive
- Installing symfony/mailer (v7.4.12): Extracting archive
- Installing symfony/error-handler (v7.4.8): Extracting archive
- Installing symfony/http-kernel (v7.4.13): Extracting archive
- Installing symfony/finder (v7.4.8): Extracting archive
- Installing ramsey/collection (2.1.1): Extracting archive
- Installing brick/math (0.14.8): Extracting archive
- Installing ramsey/uuid (4.9.2): Extracting archive
- Installing psr/simple-cache (3.0.0): Extracting archive
- Installing symfony/translation-contracts (v3.7.0): Extracting archive
- Installing symfony/translation (v7.4.10): Extracting archive
- Installing psr/clock (1.0.0): Extracting archive
- Installing symfony/clock (v7.4.8): Extracting archive
- Installing carbonphp/carbon-doctrine-types (3.2.0): Extracting archive
- Installing nesbot/carbon (3.11.4): Extracting archive
- Installing monolog/monolog (3.10.0): Extracting archive
- Installing league/uri-interfaces (7.8.1): Extracting archive
- Installing league/uri (7.8.1): Extracting archive
- Installing league/mime-type-detection (1.16.0): Extracting archive
- Installing league/flysystem-local (3.31.0): Extracting archive
- Installing league/flysystem (3.34.0): Extracting archive
- Installing nette/utils (v4.1.4): Extracting archive
- Installing nette/schema (v1.3.5): Extracting archive
- Installing dflydev/dot-access-data (v3.0.3): Extracting archive
- Installing league/config (v1.2.0): Extracting archive
- Installing league/commonmark (2.8.2): Extracting archive
- Installing laravel/serializable-closure (v2.0.13): Extracting archive
- Installing laravel/prompts (v0.3.18): Extracting archive
- Installing laravel/framework (v12.61.1): Extracting archive
- Installing laravel/pail (v1.2.7): Extracting archive
- Installing laravel/pint (v1.29.1): Extracting archive
- Installing symfony/yaml (v7.4.13): Extracting archive
- Installing laravel/sail (v1.62.0): Extracting archive
- Installing nikic/php-parser (v5.7.0): Extracting archive
- Installing psy/psysh (v0.12.23): Extracting archive
- Installing laravel/tinker (v2.11.1): Extracting archive
- Installing hamcrest/hamcrest-php (v2.1.1): Extracting archive
- Installing mockery/mockery (1.6.12): Extracting archive
- Installing filp/whoops (2.18.4): Extracting archive
- Installing nunomaduro/collision (v8.9.4): Extracting archive
- Installing staabm/side-effects-detector (1.0.5): Extracting archive
- Installing sebastian/version (5.0.2): Extracting archive
- Installing sebastian/type (5.1.3): Extracting archive
- Installing sebastian/recursion-context (6.0.3): Extracting archive
- Installing sebastian/object-reflector (4.0.1): Extracting archive
- Installing sebastian/object-enumerator (6.0.1): Extracting archive
- Installing sebastian/global-state (7.0.2): Extracting archive
- Installing sebastian/exporter (6.3.2): Extracting archive
- Installing sebastian/environment (7.2.1): Extracting archive
- Installing sebastian/diff (6.0.2): Extracting archive
- Installing sebastian/comparator (6.3.3): Extracting archive
- Installing sebastian/code-unit (3.0.3): Extracting archive
- Installing sebastian/cli-parser (3.0.2): Extracting archive
- Installing phpunit/php-timer (7.0.1): Extracting archive
- Installing phpunit/php-text-template (4.0.1): Extracting archive
- Installing phpunit/php-invoker (5.0.1): Extracting archive
- Installing phpunit/php-file-iterator (5.1.1): Extracting archive
- Installing theseer/tokenizer (1.3.1): Extracting archive
- Installing sebastian/lines-of-code (3.0.1): Extracting archive
- Installing sebastian/complexity (4.0.1): Extracting archive
- Installing sebastian/code-unit-reverse-lookup (4.0.1): Extracting archive
- Installing phpunit/php-code-coverage (11.0.12): Extracting archive
- Installing phar-io/version (3.2.1): Extracting archive
- Installing phar-io/manifest (2.0.4): Extracting archive
- Installing myclabs/deep-copy (1.13.4): Extracting archive
- Installing phpunit/phpunit (11.5.55): Extracting archive
59 package suggestions were added by new dependencies, use `composer suggest` to see details.
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi
INFO Discovering packages.
laravel/pail ..................................................................................................................... DONE
laravel/sail ..................................................................................................................... DONE
laravel/tinker ................................................................................................................... DONE
nesbot/carbon .................................................................................................................... DONE
nunomaduro/collision ............................................................................................................. DONE
nunomaduro/termwind .............................................................................................................. DONE
81 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
> @php artisan vendor:publish --tag=laravel-assets --ansi --force
INFO No publishable resources for tag [laravel-assets].
No security vulnerability advisories found.
> @php artisan key:generate --ansi
INFO Application key set successfully.
> @php -r "file_exists('database/database.sqlite') || touch('database/database.sqlite');"
> @php artisan migrate --graceful --ansi
INFO Preparing database.
Creating migration table ................................................................................................. 36.97ms DONE
INFO Running migrations.
0001_01_01_000000_create_users_table ..................................................................................... 19.36ms DONE
0001_01_01_000001_create_cache_table ..................................................................................... 15.97ms DONE
0001_01_01_000002_create_jobs_table ...................................................................................... 17.42ms DONE
[kevinya1@sc139 ~]$
[kevinya1@sc139 ~]$
[kevinya1@sc139 ~]$
[kevinya1@sc139 ~]$ mv ~/backup_env ~/://kevinyahya.com
mv: cannot move '/DATA/kevinya1/backup_env' to '/DATA/kevinya1/://kevinyahya.com': No such file or directory
[kevinya1@sc139 ~]$ mv ~/backup_env ~about.kevinyahya.com
[kevinya1@sc139 ~]$
[kevinya1@sc139 ~]$
[kevinya1@sc139 ~]$ cat << 'EOF' > ~about.kevinyahya.com
> <IfModule mod_rewrite.c>
> RewriteEngine On
> RewriteRule ^(.*)$ public/$1 [L]
> </IfModule>
> EOF
[kevinya1@sc139 ~]$ cd ~/about.kevinyahya.com
[kevinya1@sc139 about.kevinyahya.com]$
[kevinya1@sc139 about.kevinyahya.com]$
[kevinya1@sc139 about.kevinyahya.com]$
[kevinya1@sc139 about.kevinyahya.com]$ composer require laravel/breeze --dev
./composer.json has been updated
Running composer update laravel/breeze
Loading composer repositories with package information
Updating dependencies
Lock file operations: 1 install, 0 updates, 0 removals
- Locking laravel/breeze (v2.4.2)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
- Installing laravel/breeze (v2.4.2): Extracting archive
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi
INFO Discovering packages.
laravel/breeze ................................................................................................................... DONE
laravel/pail ..................................................................................................................... DONE
laravel/sail ..................................................................................................................... DONE
laravel/tinker ................................................................................................................... DONE
nesbot/carbon .................................................................................................................... DONE
nunomaduro/collision ............................................................................................................. DONE
nunomaduro/termwind .............................................................................................................. DONE
81 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
> @php artisan vendor:publish --tag=laravel-assets --ansi --force
INFO No publishable resources for tag [laravel-assets].
No security vulnerability advisories found.
Using version ^2.4 for laravel/breeze
[kevinya1@sc139 about.kevinyahya.com]$ php artisan breeze:install blade
INFO Installing and building Node dependencies.
sh: npm: command not found
INFO Breeze scaffolding installed successfully.
[kevinya1@sc139 about.kevinyahya.com]$ php artisan migrate
INFO Nothing to migrate.
[kevinya1@sc139 about.kevinyahya.com]$
KEVINYAHYADOTCOM
Tentu saja bisa! Memisahkan halaman fitur khusus Anda dari halaman bawaan Laravel Breeze adalah keputusan arsitektur yang sangat tepat. Breeze menggunakan sistem Layout Blade (resources/views/layouts/app.blade.php), yang berarti kita bisa membuat file PHP tampilan baru yang bersih di folder terpisah, tetapi tetap dikunci oleh sistem login Breeze hanya dengan memanfaatkan Middleware Auth di dalam file konfigurasi Route.
Mari kita bangun aplikasi Dynamic Database Manager ini secara utuh, rapi, dan super lengkap.
📂 Struktur File Baru yang Akan Kita Buat
Kita akan membuat 3 file utama via Terminal dan File Manager:
- Controller: app/Http/Controllers/DbManagerController.php (Logika koneksi dan CRUD dinamis)
- Route: Di dalam routes/web.php (Pengatur URL yang dikunci sistem login)
- View (Tampilan): resources/views/db-manager/index.blade.php (Antarmuka Form & Tabel)
🛠️ Langkah 1: Buat Controller Utama via Terminal
Masuk ke folder proyek Anda (cd ~/://kevinyahya.com) dan jalankan perintah Artisan untuk membuat Controller baru:
php artisan make:controller DbManagerController
Setelah file berhasil dibuat, buka file tersebut menggunakan nano app/Http/Controllers/DbManagerController.php dan isi dengan kode logika super lengkap di bawah ini:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Schema;
class DbManagerController extends Controller
{
// 1. Fungsi mengonfigurasi database eksternal/dinamis secara otomatis saat runtime
private function setDynamicConnection(Request $request)
{
// Validasi input wajib
$request->validate([
'db_name' => 'required|string',
'db_user' => 'required|string',
]);
// Proteksi nilai default jika host atau port kosong
$host = $request->input('db_host') ?: '127.0.0.1';
$port = $request->input('db_port') ?: '3306';
$password = $request->input('db_pass') ?: '';
// Suntik konfigurasi baru ke dalam runtime Laravel
Config::set('database.connections.mysql_dynamic', [
'driver' => 'mysql',
'host' => $host,
'port' => $port,
'database' => $request->input('db_name'),
'username' => $request->input('db_user'),
'password' => $password,
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => true,
]);
// Bersihkan cache koneksi lama agar konfigurasi baru langsung segar
DB::purge('mysql_dynamic');
}
// 2. Tampilan utama aplikasi (Form koneksi dan list data)
public function index(Request $request)
{
$tables = [];
$columns = [];
$rows = [];
$selectedTable = $request->input('table');
$errorMessage = null;
// Jika user mengirimkan form koneksi
if ($request->has('db_name')) {
try {
$this->setDynamicConnection($request);
// Ambil daftar semua tabel dari database dinamis
$tables = Schema::connection('mysql_dynamic')->getTables();
$tables = array_map(function($table) {
return is_object($table) ? $table->name : $table;
}, $tables);
// Jika user memilih salah satu tabel, ambil kolom dan baris datanya
if ($selectedTable && in_array($selectedTable, $tables)) {
$columns = Schema::connection('mysql_dynamic')->getColumnListing($selectedTable);
$rows = DB::connection('mysql_dynamic')->table($selectedTable)->limit(50)->get();
}
} catch (\Exception $e) {
$errorMessage = "Gagal Terhubung: " . $e->getMessage();
}
}
// Kirim semua variabel ke file PHP tampilan terpisah
return view('db-manager.index', compact('tables', 'columns', 'rows', 'selectedTable', 'errorMessage'));
}
// 3. Fungsi eksekutor CRUD / Perintah SQL murni secara instan
public function executeQuery(Request $request)
{
$request->validate(['sql_query' => 'required|string']);
try {
$this->setDynamicConnection($request);
$query = trim($request->input('sql_query'));
// Deteksi jenis perintah SQL untuk eksekusi yang tepat
if (stripos($query, 'select') === 0 || stripos($query, 'show') === 0) {
$result = DB::connection('mysql_dynamic')->select($query);
return redirect()->back()->withInput()->with('query_result', json_decode(json_encode($result), true));
} else {
$affected = DB::connection('mysql_dynamic')->statement($query);
return redirect()->back()->withInput()->with('success_message', "Perintah berhasil dieksekusi!");
}
} catch (\Exception $e) {
return redirect()->back()->withInput()->with('error_message', "Eror SQL: " . $e->getMessage());
}
}
}
🛠️ Langkah 2: Daftarkan Jalur URL (Route Web)
Buka file route Anda menggunakan perintah nano routes/web.php. Modifikasi isinya dengan menambahkan akses Controller baru kita. Agar aman dan wajib login Breeze, kita bungkus Route tersebut di dalam kelompok middleware auth:
<?php
use App\Http\Controllers\ProfileController;
use App\Http\Controllers\DbManagerController; // <-- Daftarkan Controller Baru
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
return view('welcome');
});
Route::get('/dashboard', function () {
return view('dashboard');
})->middleware(['auth', 'verified'])->name('dashboard');
// Kelompok Route Aplikasi DB Manager (Hanya bisa diakses jika sudah login)
Route::middleware('auth')->group(function () {
Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit');
Route::patch('/profile', [ProfileController::class, 'update'])->name('profile.update');
Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy');
// Route Fitur Utama DB Manager Anda
Route::get('/db-manager', [DbManagerController::class, 'index'])->name('db.manager');
Route::post('/db-manager/execute', [DbManagerController::class, 'executeQuery'])->name('db.execute');
});
require __DIR__.'/auth.php';
🛠️ Langkah 3: Buat Halaman Tampilan PHP Terpisah (Blade View)
Terlebih dahulu buat folder penampungnya via terminal:
mkdir -p resources/views/db-manager
Kemudian buat file barunya:
nano resources/views/db-manager/index.blade.php
Salin dan tempel kode antarmuka premium berbasis Tailwind CSS di bawah ini seutuhnya:
<x-app-layout>
<x-slot name="header">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
{{ __('Dynamic Database Manager & CRUD Universal') }}
</h2>
</x-slot>
<div class="py-12">
<div class="max-w-7xl x-auto sm:px-6 lg:px-8 space-y-6" style="margin: 0 auto;">
@if($errorMessage || session('error_message'))
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded">
{{ $errorMessage ?? session('error_message') }}
</div>
@endif
@if(session('success_message'))
<div class="bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded">
{{ session('success_message') }}
</div>
@endif
<div class="p-4 sm:p-8 bg-white shadow sm:rounded-lg">
<form method="GET" action="{{ route('db.manager') }}" class="space-y-4">
<div class="grid grid-cols-1 md:grid-cols-5 gap-4">
<div>
<label class="block text-sm font-medium text-gray-700">Host Server</label>
<input type="text" name="db_host" value="{{ request('db_host', '127.0.0.1') }}" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm text-sm">
</div>
<div>
<label class="block text-sm font-medium text-gray-700">Port</label>
<input type="text" name="db_port" value="{{ request('db_port', '3306') }}" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm text-sm">
</div>
<div>
<label class="block text-sm font-medium text-gray-700">Nama DB *</label>
<input type="text" name="db_name" value="{{ request('db_name') }}" required class="mt-1 block w-full rounded-md border-gray-300 shadow-sm text-sm">
</div>
<div>
<label class="block text-sm font-medium text-gray-700">User DB *</label>
<input type="text" name="db_user" value="{{ request('db_user') }}" required class="mt-1 block w-full rounded-md border-gray-300 shadow-sm text-sm">
</div>
<div>
<label class="block text-sm font-medium text-gray-700">Password DB</label>
<input type="password" name="db_pass" value="{{ request('db_pass') }}" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm text-sm">
</div>
</div>
<button type="submit" class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded text-sm">
Hubungkan Basis Data
</button>
</form>
</div>
@if(count($tables) > 0)
<div class="grid grid-cols-1 md:grid-cols-4 gap-6">
<div class="p-4 bg-white shadow sm:rounded-lg">
<h3 class="font-bold text-gray-900 mb-3 border-b pb-2 text-sm">Daftar Tabel ({{ count($tables) }})</h3>
<ul class="space-y-1 text-xs">
@foreach($tables as $table)
<li>
<a href="{{ request()->fullUrlWithQuery(['table' => $table]) }}" class="block p-2 rounded {{ $selectedTable == $table ? 'bg-blue-500 text-white font-semibold' : 'text-gray-700 hover:bg-gray-100' }}">
📁 {{ $table }}
</a>
</li>
@endforeach
</ul>
</div>
<div class="md:col-span-3 space-y-6">
<div class="p-4 bg-white shadow sm:rounded-lg">
<h3 class="font-bold text-gray-900 mb-2 text-sm">Konsol SQL Murni (Kesaktian CLI)</h3>
<form method="POST" action="{{ route('db.execute', request()->query()) }}" class="space-y-2">
@csrf
<textarea name="sql_query" rows="2" placeholder="Contoh: SELECT * FROM users WHERE id = 1" class="w-full rounded-md border-gray-300 font-mono text-xs">{{ old('sql_query') }}</textarea>
<button type="submit" class="bg-gray-800 hover:bg-gray-900 text-white text-xs font-semibold py-1.5 px-3 rounded">
Jalankan Kueri
</button>
</form>
@if(session('query_result'))
<div class="mt-4 overflow-x-auto max-h-40 bg-gray-900 text-green-400 p-3 rounded font-mono text-xs">
<pre>{{ print_r(session('query_result'), true) }}</pre>
</div>
@endif
</div>
<div class="p-4 bg-white shadow sm:rounded-lg">
@if($selectedTable)
<h3 class="font-bold text-gray-900 mb-3 text-sm">Data Tabel: <span class="underline text-blue-600">{{ $selectedTable }}</span></h3>
<div class="overflow-x-auto max-h-96 border rounded">
<table class="min-w-full divide-y divide-gray-200 text-xs">
<thead class="bg-gray-50">
<tr>
@foreach($columns as $col)
<th class="px-3 py-2 text-left font-semibold text-gray-600 border-b uppercase">{{ $col }}</th>
@endforeach
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
@forelse($rows as $row)
<tr class="hover:bg-gray-50">
@foreach($columns as $col)
<td class="px-3 py-2 whitespace-nowrap text-gray-700 border-b">{{ $row->$col ?? 'NULL' }}</td>
@endforeach
</tr>
@empty
<tr>
<td colspan="{{ count($columns) }}" class="px-3 py-4 text-center text-gray-400">Tabel Kosong / Tidak ada data.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
@else
<div class="text-center py-12 text-gray-400 text-sm">
Silakan klik salah satu nama tabel di menu kiri untuk membaca isinya.
</div>
@endif
</div>
</div>
</div>
@endif
</div>
</div>
</x-app-layout>
🧪 Langkah Akhir: Bersihkan Cache dan Tes Hasilnya
Jalankan perintah ini di Terminal agar Laravel langsung mendaftarkan rute baru Anda:
php artisan route:clear
Sekarang, buka browser Anda dan akses halaman barunya: 🔗 kevinyahya.com Jika Anda belum login, sistem Breeze otomatis akan menghadang Anda dan me-redirect ke halaman login. Silakan login menggunakan akun yang Anda buat tadi.
🎯 Cara Mencoba Kesaktiannya:
- Masukkan detail database utama cPanel Anda sendiri terlebih dahulu sebagai bahan uji coba:
* Host: 127.0.0.1 * Nama DB: kevinya1_el107 * User DB: kevinya1_el107 * Password: Password database Anda 2. Klik Hubungkan Basis Data. 3. Sistem secara ajaib akan langsung membaca daftar tabel Anda di panel sebelah kiri! Klik salah satu tabel (misal tabel users), dan seluruh isi datanya langsung tampil rapi secara otomatis. 4. Anda juga bisa mengetikkan perintah SQL murni seperti SHOW DATABASES; di kolom konsol atas untuk menguji kehebatannya.
Sistem Anda kini siap digunakan! Beri tahu saya jika pengujian koneksi database dinamis pertama Anda berhasil memunculkan daftar tabel dengan lancar.