feat: penanganan pelanggaran (handling system)

- Migration: handling_status, handled_at, handled_by ke violations
- Migration: tabel violation_handlings, handling_participants
- Model: ViolationHandling, HandlingParticipant + relasi
- Routes: storeHandling, resolveHandling, destroyHandling, calendar data
- ViolationController: CRUD penanganan + filter status handling
- DashboardController: data handling stats + calendar endpoint
- Dashboard view: kalender pelanggaran interaktif (Alpine.js)
- Violations index: filter status penanganan + kolom status
- Violations show: stat card penanganan + timeline + modal tambah
- Menambahkan handling_status filter di index
This commit is contained in:
Bro
2026-07-22 22:19:19 +07:00
parent f86aa84d12
commit 8529a49174
24 changed files with 2152 additions and 842 deletions
@@ -0,0 +1,25 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::table('violations', function (Blueprint $table) {
$table->string('handling_status', 20)->default('unhandled')->after('recorded_by')->comment('unhandled|in_progress|resolved');
$table->timestamp('handled_at')->nullable()->after('handling_status');
$table->foreignId('handled_by')->nullable()->constrained('users')->nullOnDelete()->after('handled_at');
});
}
public function down(): void
{
Schema::table('violations', function (Blueprint $table) {
$table->dropConstrainedForeignId('handled_by');
$table->dropColumn(['handling_status', 'handled_at']);
});
}
};
@@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('violation_handlings', function (Blueprint $table) {
$table->id();
$table->foreignId('violation_id')->constrained()->cascadeOnDelete();
$table->string('handling_type', 50);
$table->date('handling_date');
$table->text('description')->nullable();
$table->string('location', 255)->nullable();
$table->string('evidence', 255)->nullable();
$table->unsignedBigInteger('created_by')->nullable()->index();
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('violation_handlings');
}
};
@@ -0,0 +1,25 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('handling_participants', function (Blueprint $table) {
$table->id();
$table->foreignId('handling_id')->constrained('violation_handlings')->cascadeOnDelete();
$table->unsignedBigInteger('user_id');
$table->string('role', 50)->nullable()->comment('peran dalam penanganan: Wakil Ketua Tim, Anggota Tim, Wali Kelas, Guru BK, Saksi, dll');
$table->timestamps();
$table->unique(['handling_id', 'user_id']);
});
}
public function down(): void
{
Schema::dropIfExists('handling_participants');
}
};