From 396ecdb4899e89ba66adc8e527222823a6850a64 Mon Sep 17 00:00:00 2001 From: tuxarmy Date: Fri, 3 Apr 2026 05:33:21 +0700 Subject: [PATCH] feat: tambah halaman kontak publik dan inbox pesan masuk di dashboard --- .../ContactMessageResource.php | 59 ++++++++++++++++ .../Pages/CreateContactMessage.php | 11 +++ .../Pages/EditContactMessage.php | 19 ++++++ .../Pages/ListContactMessages.php | 19 ++++++ .../Pages/ViewContactMessage.php | 37 ++++++++++ .../Schemas/ContactMessageForm.php | 16 +++++ .../Tables/ContactMessagesTable.php | 30 ++++++++ app/Http/Controllers/PublicController.php | 20 +++++- app/Models/ContactMessage.php | 12 ++++ ...2_222618_create_contact_messages_table.php | 27 ++++++++ resources/views/public/kontak.blade.php | 68 +++++++++++++++++++ resources/views/public/layout.blade.php | 1 + routes/web.php | 2 + 13 files changed, 318 insertions(+), 3 deletions(-) create mode 100644 app/Filament/Resources/ContactMessages/ContactMessageResource.php create mode 100644 app/Filament/Resources/ContactMessages/Pages/CreateContactMessage.php create mode 100644 app/Filament/Resources/ContactMessages/Pages/EditContactMessage.php create mode 100644 app/Filament/Resources/ContactMessages/Pages/ListContactMessages.php create mode 100644 app/Filament/Resources/ContactMessages/Pages/ViewContactMessage.php create mode 100644 app/Filament/Resources/ContactMessages/Schemas/ContactMessageForm.php create mode 100644 app/Filament/Resources/ContactMessages/Tables/ContactMessagesTable.php create mode 100644 app/Models/ContactMessage.php create mode 100644 database/migrations/2026_04_02_222618_create_contact_messages_table.php create mode 100644 resources/views/public/kontak.blade.php diff --git a/app/Filament/Resources/ContactMessages/ContactMessageResource.php b/app/Filament/Resources/ContactMessages/ContactMessageResource.php new file mode 100644 index 0000000..8a2799b --- /dev/null +++ b/app/Filament/Resources/ContactMessages/ContactMessageResource.php @@ -0,0 +1,59 @@ +schema([]); + } + + public static function table(Table $table): Table + { + return $table + ->columns([ + TextColumn::make('name')->label('Nama')->searchable(), + TextColumn::make('subject')->label('Subjek')->searchable()->limit(40), + TextColumn::make('email')->label('Email'), + TextColumn::make('phone')->label('Telepon')->default('-'), + TextColumn::make('read_at')->label('Dibaca') + ->badge() + ->state(fn ($record) => $record->read_at ? 'Sudah dibaca' : 'Belum dibaca') + ->color(fn ($record) => $record->read_at ? 'success' : 'warning'), + TextColumn::make('created_at')->label('Diterima')->dateTime('d M Y H:i')->sortable(), + ]) + ->defaultSort('created_at', 'desc') + ->recordActions([ + ViewAction::make() + ->after(fn ($record) => $record->read_at ?? $record->update(['read_at' => now()])), + ]) + ->toolbarActions([BulkActionGroup::make([DeleteBulkAction::make()])]); + } + + public static function getPages(): array + { + return [ + 'index' => ListContactMessages::route('/'), + 'view' => ViewContactMessage::route('/{record}'), + ]; + } +} diff --git a/app/Filament/Resources/ContactMessages/Pages/CreateContactMessage.php b/app/Filament/Resources/ContactMessages/Pages/CreateContactMessage.php new file mode 100644 index 0000000..a19fb83 --- /dev/null +++ b/app/Filament/Resources/ContactMessages/Pages/CreateContactMessage.php @@ -0,0 +1,11 @@ +record->read_at ?? $this->record->update(['read_at' => now()]); + } + + public function infolist(Schema $infolist): Schema + { + return $infolist->schema([ + Section::make('Informasi Pengirim')->schema([ + TextEntry::make('name')->label('Nama'), + TextEntry::make('email')->label('Email')->default('-'), + TextEntry::make('phone')->label('Telepon')->default('-'), + TextEntry::make('created_at')->label('Dikirim')->dateTime('d M Y H:i'), + ])->columns(2), + + Section::make('Pesan')->schema([ + TextEntry::make('subject')->label('Subjek'), + TextEntry::make('message')->label('Isi Pesan')->columnSpanFull(), + ]), + ]); + } +} diff --git a/app/Filament/Resources/ContactMessages/Schemas/ContactMessageForm.php b/app/Filament/Resources/ContactMessages/Schemas/ContactMessageForm.php new file mode 100644 index 0000000..4a94b74 --- /dev/null +++ b/app/Filament/Resources/ContactMessages/Schemas/ContactMessageForm.php @@ -0,0 +1,16 @@ +components([ + // + ]); + } +} diff --git a/app/Filament/Resources/ContactMessages/Tables/ContactMessagesTable.php b/app/Filament/Resources/ContactMessages/Tables/ContactMessagesTable.php new file mode 100644 index 0000000..08b4b05 --- /dev/null +++ b/app/Filament/Resources/ContactMessages/Tables/ContactMessagesTable.php @@ -0,0 +1,30 @@ +columns([ + // + ]) + ->filters([ + // + ]) + ->recordActions([ + EditAction::make(), + ]) + ->toolbarActions([ + BulkActionGroup::make([ + DeleteBulkAction::make(), + ]), + ]); + } +} diff --git a/app/Http/Controllers/PublicController.php b/app/Http/Controllers/PublicController.php index 2d7ec2d..8ce3dab 100644 --- a/app/Http/Controllers/PublicController.php +++ b/app/Http/Controllers/PublicController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers; use App\Models\Activity; +use App\Models\ContactMessage; use App\Models\Division; use App\Models\Post; use App\Models\User; @@ -48,10 +49,23 @@ class PublicController extends Controller ]); } - public function blogDetail(Post $post) + public function kontak() { - abort_if(! $post->published_at || $post->published_at->isFuture(), 404); + return view('public.kontak'); + } - return view('public.blog-detail', compact('post')); + public function kontakStore(\Illuminate\Http\Request $request) + { + $data = $request->validate([ + 'name' => 'required|string|max:100', + 'email' => 'nullable|email|max:100', + 'phone' => 'nullable|string|max:20', + 'subject' => 'required|string|max:150', + 'message' => 'required|string|max:2000', + ]); + + ContactMessage::create($data); + + return back()->with('success', 'Pesan Anda berhasil dikirim. Kami akan segera menghubungi Anda.'); } } diff --git a/app/Models/ContactMessage.php b/app/Models/ContactMessage.php new file mode 100644 index 0000000..1d608c6 --- /dev/null +++ b/app/Models/ContactMessage.php @@ -0,0 +1,12 @@ + 'datetime']; +} diff --git a/database/migrations/2026_04_02_222618_create_contact_messages_table.php b/database/migrations/2026_04_02_222618_create_contact_messages_table.php new file mode 100644 index 0000000..5697c63 --- /dev/null +++ b/database/migrations/2026_04_02_222618_create_contact_messages_table.php @@ -0,0 +1,27 @@ +id(); + $table->string('name'); + $table->string('email')->nullable(); + $table->string('phone')->nullable(); + $table->string('subject'); + $table->text('message'); + $table->timestamp('read_at')->nullable(); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('contact_messages'); + } +}; diff --git a/resources/views/public/kontak.blade.php b/resources/views/public/kontak.blade.php new file mode 100644 index 0000000..1ff77be --- /dev/null +++ b/resources/views/public/kontak.blade.php @@ -0,0 +1,68 @@ +@extends('public.layout') + +@section('title', 'Kontak') + +@section('content') + +
+

Hubungi Kami

+

Kirimkan pesan, pertanyaan, atau saran kepada kami.

+ + @if(session('success')) +
+ {{ session('success') }} +
+ @endif + +
+
+ @csrf + +
+ + + @error('name')

{{ $message }}

@enderror +
+ +
+
+ + + @error('email')

{{ $message }}

@enderror +
+
+ + +
+
+ +
+ + + @error('subject')

{{ $message }}

@enderror +
+ +
+ + + @error('message')

{{ $message }}

@enderror +
+ + +
+
+ +
+

📍 Desa Karangdadap, Kecamatan Kalibagor, Kabupaten Banyumas

+
+
+ +@endsection diff --git a/resources/views/public/layout.blade.php b/resources/views/public/layout.blade.php index 8bc3aac..346115d 100644 --- a/resources/views/public/layout.blade.php +++ b/resources/views/public/layout.blade.php @@ -16,6 +16,7 @@ Tentang Kegiatan Blog + Kontak Login diff --git a/routes/web.php b/routes/web.php index 840bf14..73e417f 100644 --- a/routes/web.php +++ b/routes/web.php @@ -8,3 +8,5 @@ Route::get('/kegiatan', [\App\Http\Controllers\PublicController::class, 'kegiata Route::get('/kegiatan/{activity}', [\App\Http\Controllers\PublicController::class, 'kegiatanDetail'])->name('kegiatan.detail'); Route::get('/blog', [\App\Http\Controllers\PublicController::class, 'blog'])->name('blog'); Route::get('/blog/{post:slug}', [\App\Http\Controllers\PublicController::class, 'blogDetail'])->name('blog.detail'); +Route::get('/kontak', [\App\Http\Controllers\PublicController::class, 'kontak'])->name('kontak'); +Route::post('/kontak', [\App\Http\Controllers\PublicController::class, 'kontakStore'])->name('kontak.store');