feat: Enhance user interface clarity and experience by updating labels, adding descriptions, icons, and refining form field attributes across various Filament resources and pages.
This commit is contained in:
parent
af7bf05b91
commit
de4aea7f2a
@ -7,9 +7,15 @@
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Auth\Pages\EmailVerification\EmailVerificationPrompt;
|
||||
use Filament\Notifications\Notification;
|
||||
use Filament\Support\Enums\Width;
|
||||
|
||||
class EmailVerification extends EmailVerificationPrompt
|
||||
{
|
||||
public function getMaxContentWidth(): Width
|
||||
{
|
||||
return Width::ExtraLarge;
|
||||
}
|
||||
|
||||
public function resendNotificationAction(): Action
|
||||
{
|
||||
return Action::make('resendNotification')
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Models\Contracts\FilamentUser;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Enums\Width;
|
||||
use Illuminate\Auth\SessionGuard;
|
||||
use Illuminate\Contracts\Auth\Authenticatable;
|
||||
use Illuminate\Contracts\Support\Htmlable;
|
||||
@ -21,6 +22,11 @@
|
||||
|
||||
class Login extends FilamentLogin
|
||||
{
|
||||
public function getMaxContentWidth(): Width
|
||||
{
|
||||
return Width::ExtraLarge;
|
||||
}
|
||||
|
||||
public function getHeading(): string|Htmlable
|
||||
{
|
||||
return '';
|
||||
@ -35,7 +41,10 @@ public function form(Schema $schema): Schema
|
||||
->placeholder('johndoe@example.com')
|
||||
->required()
|
||||
->autocomplete(false)
|
||||
->autofocus(),
|
||||
->autofocus()
|
||||
->required()
|
||||
->maxLength(255)
|
||||
->prefixIcon('heroicon-o-user'),
|
||||
|
||||
TextInput::make('password')
|
||||
->label('Kata Sandi')
|
||||
@ -45,6 +54,7 @@ public function form(Schema $schema): Schema
|
||||
->required()
|
||||
->autocomplete(false)
|
||||
->extraInputAttributes(['tabindex' => 2])
|
||||
->prefixIcon('heroicon-o-lock-closed')
|
||||
->hint(
|
||||
filament()->hasPasswordReset()
|
||||
? new HtmlString(Blade::render('<x-filament::link :href="filament()->getRequestPasswordResetUrl()" tabindex="3">{{ __(\'filament-panels::auth/pages/login.actions.request_password_reset.label\') }}</x-filament::link>'))
|
||||
|
||||
@ -5,7 +5,6 @@
|
||||
use App\Filament\Support\CheerfulNotification;
|
||||
use Filament\Auth\Pages\EditProfile;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Notifications\Notification;
|
||||
use Filament\Schemas\Components\Grid;
|
||||
use Filament\Schemas\Components\Section;
|
||||
use Filament\Schemas\Components\Utilities\Get;
|
||||
@ -26,16 +25,13 @@ public function form(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
Section::make('Informasi Profil 👤')
|
||||
->description('Kelola detail profil Anda seperti nama, alamat surel, dan nama pengguna.')
|
||||
->icon('heroicon-m-user-circle')
|
||||
Section::make()
|
||||
->schema([
|
||||
TextInput::make('name')
|
||||
->label('Nama Lengkap')
|
||||
->placeholder('Masukkan nama lengkap Anda')
|
||||
->required()
|
||||
->maxLength(100)
|
||||
->prefixIcon('heroicon-m-user'),
|
||||
->maxLength(100),
|
||||
|
||||
Grid::make(2)
|
||||
->schema([
|
||||
@ -47,7 +43,7 @@ public function form(Schema $schema): Schema
|
||||
->maxLength(254)
|
||||
->unique(ignoreRecord: true)
|
||||
->email()
|
||||
->prefixIcon('heroicon-m-envelope')
|
||||
->prefixIcon('heroicon-o-envelope')
|
||||
->live(),
|
||||
|
||||
TextInput::make('username')
|
||||
@ -59,13 +55,11 @@ public function form(Schema $schema): Schema
|
||||
->maxLength(20)
|
||||
->regex('/^[a-zA-Z0-9_.-]+$/')
|
||||
->unique(ignoreRecord: true)
|
||||
->prefixIcon('heroicon-m-at-symbol'),
|
||||
->prefixIcon('heroicon-o-at-symbol'),
|
||||
]),
|
||||
]),
|
||||
|
||||
Section::make('Keamanan Akun 🔒')
|
||||
->description('Pastikan akun Anda menggunakan kata sandi yang panjang dan aman.')
|
||||
->icon('heroicon-m-finger-print')
|
||||
Section::make()
|
||||
->schema([
|
||||
Grid::make(2)
|
||||
->schema([
|
||||
@ -81,7 +75,7 @@ public function form(Schema $schema): Schema
|
||||
->dehydrateStateUsing(fn ($state) => Hash::make($state))
|
||||
->same('passwordConfirmation')
|
||||
->validationAttribute(__('filament-panels::auth/pages/register.form.password.validation_attribute'))
|
||||
->prefixIcon('heroicon-m-lock-closed'),
|
||||
->prefixIcon('heroicon-o-lock-closed'),
|
||||
|
||||
TextInput::make('passwordConfirmation')
|
||||
->label(__('filament-panels::auth/pages/register.form.password_confirmation.label'))
|
||||
@ -90,7 +84,7 @@ public function form(Schema $schema): Schema
|
||||
->revealable(filament()->arePasswordsRevealable())
|
||||
->required(fn (Get $get) => filled($get('password')) || filled($get('passwordConfirmation')))
|
||||
->dehydrated(false)
|
||||
->prefixIcon('heroicon-m-shield-check'),
|
||||
->prefixIcon('heroicon-o-lock-closed'),
|
||||
]),
|
||||
]),
|
||||
]);
|
||||
@ -98,24 +92,29 @@ public function form(Schema $schema): Schema
|
||||
|
||||
protected function handleRecordUpdate(Model $record, array $data): Model
|
||||
{
|
||||
$passwordChanged = filled($data['password'] ?? null);
|
||||
|
||||
$record->update($data);
|
||||
|
||||
CheerfulNotification::success(
|
||||
'Profil Berhasil Diperbarui ✅',
|
||||
'Data profil Anda telah berhasil disimpan dan diperbarui di dalam sistem.'
|
||||
)->send();
|
||||
|
||||
if ($passwordChanged) {
|
||||
auth()->logout();
|
||||
}
|
||||
|
||||
return $record;
|
||||
}
|
||||
|
||||
protected function getSavedNotification(): ?Notification
|
||||
protected function afterSave(): void
|
||||
{
|
||||
return null;
|
||||
CheerfulNotification::success(
|
||||
'Profil Diperbarui! ✨',
|
||||
'Sip! Detail profil baru Anda sudah tersimpan dengan aman. Terus semangat ya! 💪😊'
|
||||
)->send();
|
||||
|
||||
if (filled($this->form->getState()['password'] ?? null)) {
|
||||
auth()->logout();
|
||||
session()->invalidate();
|
||||
session()->regenerateToken();
|
||||
|
||||
CheerfulNotification::info(
|
||||
'Sesi Berakhir 🔐',
|
||||
'Anda telah mengubah kata sandi. Silakan masuk kembali dengan kata sandi baru Anda ya. 😉👋'
|
||||
)->send();
|
||||
|
||||
$this->redirect(filament()->getLoginUrl());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
use Filament\Auth\Pages\Register;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Enums\Width;
|
||||
use Illuminate\Contracts\Support\Htmlable;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
@ -16,6 +17,11 @@
|
||||
|
||||
class Registration extends Register
|
||||
{
|
||||
public function getMaxContentWidth(): Width
|
||||
{
|
||||
return Width::ExtraLarge;
|
||||
}
|
||||
|
||||
public function getHeading(): string|Htmlable
|
||||
{
|
||||
return '';
|
||||
@ -26,7 +32,7 @@ public function form(Schema $schema): Schema
|
||||
return $schema
|
||||
->components([
|
||||
TextInput::make('name')
|
||||
->label('Nama')
|
||||
->label('Nama Lengkap')
|
||||
->placeholder('John Doe')
|
||||
->autocomplete(false)
|
||||
->autofocus()
|
||||
@ -41,7 +47,8 @@ public function form(Schema $schema): Schema
|
||||
->maxLength(254)
|
||||
->unique('users', 'email')
|
||||
->email()
|
||||
->aboveContent('Pastikan alamat surel aktif, karena akan digunakan untuk verifikasi akun Anda.'),
|
||||
->prefixIcon('heroicon-o-envelope')
|
||||
->aboveContent('Pastikan alamat surel aktif untuk verifikasi akun Anda.'),
|
||||
|
||||
TextInput::make('username')
|
||||
->label('Nama Pengguna')
|
||||
@ -49,9 +56,10 @@ public function form(Schema $schema): Schema
|
||||
->autocomplete(false)
|
||||
->required()
|
||||
->minLength(5)
|
||||
->maxLength(10)
|
||||
->maxLength(20)
|
||||
->regex('/^[a-zA-Z0-9_.-]+$/')
|
||||
->unique('users', 'username'),
|
||||
->unique('users', 'username')
|
||||
->prefixIcon('heroicon-o-at-symbol'),
|
||||
|
||||
TextInput::make('password')
|
||||
->label('Kata Sandi')
|
||||
@ -62,7 +70,8 @@ public function form(Schema $schema): Schema
|
||||
->autocomplete(false)
|
||||
->dehydrated(fn ($state): bool => filled($state))
|
||||
->dehydrateStateUsing(fn ($state): string => Hash::make($state))
|
||||
->placeholder('********'),
|
||||
->placeholder('********')
|
||||
->prefixIcon('heroicon-o-lock-closed'),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@ -50,48 +50,61 @@ public static function infolist(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->schema([
|
||||
Section::make('Informasi Pengirim')
|
||||
Section::make('Informasi Pengirim 📧')
|
||||
->description('Detail mengenai identitas pengirim pesan.')
|
||||
->icon('heroicon-o-user')
|
||||
->schema([
|
||||
Grid::make(4)
|
||||
->schema([
|
||||
TextEntry::make('name')
|
||||
->label('Nama'),
|
||||
->label('Nama Pengirim')
|
||||
->icon('heroicon-o-user'),
|
||||
|
||||
TextEntry::make('email')
|
||||
->label('Email'),
|
||||
->label('Alamat Surel')
|
||||
->icon('heroicon-o-envelope'),
|
||||
|
||||
TextEntry::make('subject')
|
||||
->label('Subyek'),
|
||||
->label('Subyek Pesan')
|
||||
->icon('heroicon-o-tag'),
|
||||
|
||||
TextEntry::make('created_at')
|
||||
->label('Diterima pada')
|
||||
->date('l, d F Y H:i'),
|
||||
->label('Diterima Pada')
|
||||
->date('l, d F Y H:i')
|
||||
->icon('heroicon-o-calendar'),
|
||||
]),
|
||||
])
|
||||
->columnSpanFull(),
|
||||
|
||||
Section::make('Pesan')
|
||||
Section::make('Isi Pesan 💬')
|
||||
->description('Pesan lengkap yang dikirimkan oleh pengguna.')
|
||||
->icon('heroicon-o-chat-bubble-left-right')
|
||||
->schema([
|
||||
TextEntry::make('message')
|
||||
->label('Isi Pesan')
|
||||
->label('Konten Pesan')
|
||||
->columnSpanFull(),
|
||||
])
|
||||
->columnSpanFull(),
|
||||
|
||||
Section::make('Balasan')
|
||||
Section::make('Riwayat Balasan 📤')
|
||||
->description('Detail mengenai tanggapan yang telah diberikan.')
|
||||
->icon('heroicon-o-paper-airplane')
|
||||
->schema([
|
||||
TextEntry::make('repliedBy.name')
|
||||
->label('Dibalas Oleh')
|
||||
->placeholder('Belum dibalas'),
|
||||
->placeholder('Belum dibalas')
|
||||
->icon('heroicon-o-user-circle'),
|
||||
|
||||
TextEntry::make('replied_at')
|
||||
->label('Dibalas pada')
|
||||
->label('Waktu Balasan')
|
||||
->date('l, d F Y H:i')
|
||||
->placeholder('Belum dibalas'),
|
||||
->placeholder('Belum dibalas')
|
||||
->icon('heroicon-o-clock'),
|
||||
|
||||
TextEntry::make('reply_message')
|
||||
->label('Pesan Balasan')
|
||||
->placeholder('Belum dibalas'),
|
||||
->label('Isi Balasan')
|
||||
->placeholder('Belum dibalas')
|
||||
->columnSpanFull(),
|
||||
])
|
||||
->columnSpanFull()
|
||||
->visible(fn (Contact $record): bool => $record->replied_at !== null),
|
||||
|
||||
@ -15,7 +15,6 @@
|
||||
use Filament\Schemas\Components\Utilities\Get;
|
||||
use Filament\Schemas\Components\Utilities\Set;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class CooperationForm
|
||||
@ -24,88 +23,94 @@ public static function configure(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
Section::make([
|
||||
TextInput::make('title')
|
||||
->label('Judul')
|
||||
->placeholder('Publikasi Pembangunan Daerah')
|
||||
->autocomplete(false)
|
||||
->autofocus()
|
||||
->required()
|
||||
->maxLength(200),
|
||||
Section::make('Detail Kerja Sama 🤝')
|
||||
->description('Lengkapi informasi mengenai judul, durasi, dan media yang terlibat.')
|
||||
->icon('heroicon-o-hand-raised')
|
||||
->schema([
|
||||
TextInput::make('title')
|
||||
->label('Judul Kerja Sama')
|
||||
->placeholder('Publikasi Pembangunan Daerah')
|
||||
->autocomplete(false)
|
||||
->autofocus()
|
||||
->required()
|
||||
->maxLength(200),
|
||||
|
||||
Grid::make(2)
|
||||
->schema([
|
||||
DatePicker::make('initial_submission_date')
|
||||
->label('Tanggal Pengajuan Awal')
|
||||
->placeholder(fn (): string => now()->translatedFormat('l, d F Y'))
|
||||
->native(false)
|
||||
->displayFormat('l, d F Y')
|
||||
->required()
|
||||
->minDate(today())
|
||||
->reactive(),
|
||||
Grid::make(2)
|
||||
->schema([
|
||||
DatePicker::make('initial_submission_date')
|
||||
->label('Tgl Pengajuan Awal')
|
||||
->placeholder(fn (): string => now()->translatedFormat('l, d F Y'))
|
||||
->native(false)
|
||||
->displayFormat('l, d F Y')
|
||||
->required()
|
||||
->minDate(today())
|
||||
->reactive(),
|
||||
|
||||
DatePicker::make('final_submission_date')
|
||||
->label('Tanggal Pengajuan Akhir')
|
||||
->placeholder(fn (): string => now()->addDays(7)->translatedFormat('l, d F Y'))
|
||||
->native(false)
|
||||
->displayFormat('l, d F Y')
|
||||
->required()
|
||||
->afterOrEqual('initial_submission_date')
|
||||
->minDate(fn (Get $get) => $get('initial_submission_date')),
|
||||
]),
|
||||
DatePicker::make('final_submission_date')
|
||||
->label('Tgl Pengajuan Akhir')
|
||||
->placeholder(fn (): string => now()->addDays(7)->translatedFormat('l, d F Y'))
|
||||
->native(false)
|
||||
->displayFormat('l, d F Y')
|
||||
->required()
|
||||
->afterOrEqual('initial_submission_date')
|
||||
->minDate(fn (Get $get) => $get('initial_submission_date')),
|
||||
]),
|
||||
|
||||
Select::make('partner_media_ids')
|
||||
->label('Media')
|
||||
->relationship('partnerMedia', 'name', fn (Builder $query): Builder => $query->verified())
|
||||
->multiple()
|
||||
->preload()
|
||||
->searchable()
|
||||
->native(false)
|
||||
->required()
|
||||
->selectablePlaceholder(false)
|
||||
->helperText('Pilih media yang akan diajak kerja sama.')
|
||||
->suffixAction(
|
||||
Action::make('select_all')
|
||||
->label('Select All')
|
||||
->icon(Heroicon::OutlinedCheckCircle)
|
||||
->action(function (Set $set): void {
|
||||
$allMediaIds = PartnerMedia::verified()->pluck('id')->toArray();
|
||||
$set('partner_media_ids', $allMediaIds);
|
||||
})
|
||||
),
|
||||
Select::make('partner_media_ids')
|
||||
->label('Media Rekanan')
|
||||
->relationship('partnerMedia', 'name', fn (Builder $query): Builder => $query->verified())
|
||||
->multiple()
|
||||
->preload()
|
||||
->searchable()
|
||||
->native(false)
|
||||
->required()
|
||||
->selectablePlaceholder(false)
|
||||
->helperText('Pilih satu atau lebih media yang akan diajak kerja sama.')
|
||||
->suffixAction(
|
||||
Action::make('select_all')
|
||||
->label('Pilih Semua')
|
||||
->icon('heroicon-o-check-circle')
|
||||
->action(function (Set $set): void {
|
||||
$allMediaIds = PartnerMedia::verified()->pluck('id')->toArray();
|
||||
$set('partner_media_ids', $allMediaIds);
|
||||
})
|
||||
),
|
||||
|
||||
Textarea::make('description')
|
||||
->label('Deskripsi')
|
||||
->placeholder('...')
|
||||
->required()
|
||||
->rows(5)
|
||||
->maxLength(65535)
|
||||
->autocomplete(false),
|
||||
])
|
||||
Textarea::make('description')
|
||||
->label('Deskripsi Kerja Sama')
|
||||
->placeholder('Jelaskan detail lingkup kerja sama di sini...')
|
||||
->required()
|
||||
->rows(5)
|
||||
->maxLength(65535)
|
||||
->autocomplete(false),
|
||||
])
|
||||
->columnSpan(2),
|
||||
|
||||
Section::make([
|
||||
SpatieMediaLibraryFileUpload::make('banner')
|
||||
->label('Banner')
|
||||
->disk(config('filesystems.default'))
|
||||
->acceptedFileTypes(['image/*'])
|
||||
->maxSize(1024 * 3)
|
||||
->collection('banner')
|
||||
->customProperties(fn (): array => [
|
||||
'feature' => 'cooperations',
|
||||
'doc_type' => 'banner',
|
||||
'date' => now()->toDateString(),
|
||||
])
|
||||
->image(),
|
||||
Section::make('Lampiran & Media 🖼️')
|
||||
->description('Unggah banner promosi dan template untuk pengajuan.')
|
||||
->icon('heroicon-o-paper-clip')
|
||||
->schema([
|
||||
SpatieMediaLibraryFileUpload::make('banner')
|
||||
->label('Banner Promosi')
|
||||
->disk(config('filesystems.default'))
|
||||
->acceptedFileTypes(['image/*'])
|
||||
->maxSize(1024 * 3)
|
||||
->collection('banner')
|
||||
->customProperties(fn (): array => [
|
||||
'feature' => 'cooperations',
|
||||
'doc_type' => 'banner',
|
||||
'date' => now()->toDateString(),
|
||||
])
|
||||
->image(),
|
||||
|
||||
AdvancedFileUpload::make('proposal_template')
|
||||
->label('Template Pengajuan')
|
||||
->disk(config('filesystems.default'))
|
||||
->acceptedFileTypes(['application/pdf'])
|
||||
->maxSize(1024 * 10)
|
||||
->directory(fn (): string => 'cooperations/proposal-template/'.now()->toDateString())
|
||||
->required(),
|
||||
]),
|
||||
AdvancedFileUpload::make('proposal_template')
|
||||
->label('Template Pengajuan (PDF)')
|
||||
->disk(config('filesystems.default'))
|
||||
->acceptedFileTypes(['application/pdf'])
|
||||
->maxSize(1024 * 10)
|
||||
->directory(fn (): string => 'cooperations/proposal-template/'.now()->toDateString())
|
||||
->required(),
|
||||
])->columnSpan(1),
|
||||
])
|
||||
->columns(3);
|
||||
}
|
||||
|
||||
@ -19,7 +19,6 @@
|
||||
use Filament\Actions\ViewAction;
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Components\Section;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
@ -59,111 +58,109 @@ public static function infolist(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->schema([
|
||||
Section::make('Perbandingan Data')
|
||||
->schema([
|
||||
TextEntry::make('comparison')
|
||||
->hiddenLabel()
|
||||
->html()
|
||||
->state(function (DataChangeRequest $record): string {
|
||||
$old = $record->old_data ?? [];
|
||||
$new = $record->new_data ?? [];
|
||||
TextEntry::make('comparison')
|
||||
->hiddenLabel()
|
||||
->html()
|
||||
->state(function (DataChangeRequest $record): string {
|
||||
$old = $record->old_data ?? [];
|
||||
$new = $record->new_data ?? [];
|
||||
|
||||
if (! is_array($old) || ! is_array($new)) {
|
||||
return '<em>Format data tidak valid.</em>';
|
||||
if (! is_array($old) || ! is_array($new)) {
|
||||
return '<em>Format data tidak valid.</em>';
|
||||
}
|
||||
|
||||
$renderValue = function ($value) {
|
||||
if (empty($value)) {
|
||||
return '<em>Kosong</em>';
|
||||
}
|
||||
|
||||
$paths = is_array($value) ? $value : [$value];
|
||||
$isProbablyPath = false;
|
||||
|
||||
foreach ($paths as $path) {
|
||||
if (is_string($path) && (str_contains($path, '/') || str_contains($path, '\\'))) {
|
||||
$isProbablyPath = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$renderValue = function ($value) {
|
||||
if (empty($value)) {
|
||||
return '<em>Kosong</em>';
|
||||
}
|
||||
|
||||
$paths = is_array($value) ? $value : [$value];
|
||||
$isProbablyPath = false;
|
||||
|
||||
foreach ($paths as $path) {
|
||||
if (is_string($path) && (str_contains($path, '/') || str_contains($path, '\\'))) {
|
||||
$isProbablyPath = true;
|
||||
break;
|
||||
if ($isProbablyPath) {
|
||||
return collect($paths)
|
||||
->map(function ($path) {
|
||||
if (! is_string($path)) {
|
||||
return e(json_encode($path));
|
||||
}
|
||||
}
|
||||
|
||||
if ($isProbablyPath) {
|
||||
return collect($paths)
|
||||
->map(function ($path) {
|
||||
if (! is_string($path)) {
|
||||
return e(json_encode($path));
|
||||
}
|
||||
$url = Storage::disk(config('filesystems.default'))->url($path);
|
||||
$extension = strtolower(pathinfo($path, PATHINFO_EXTENSION));
|
||||
|
||||
$url = Storage::disk(config('filesystems.default'))->url($path);
|
||||
$extension = strtolower(pathinfo($path, PATHINFO_EXTENSION));
|
||||
if (in_array($extension, ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg'])) {
|
||||
return "<a href='{$url}' target='_blank'><img src='{$url}' style='max-height:100px; border-radius:8px; margin-top:4px; border:1px solid #e5e7eb;'></a>";
|
||||
}
|
||||
|
||||
if (in_array($extension, ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg'])) {
|
||||
return "<a href='{$url}' target='_blank'><img src='{$url}' style='max-height:100px; border-radius:8px; margin-top:4px; border:1px solid #e5e7eb;'></a>";
|
||||
}
|
||||
|
||||
if ($extension === 'pdf') {
|
||||
return "
|
||||
if ($extension === 'pdf') {
|
||||
return "
|
||||
<div style='margin-top:4px;'>
|
||||
<iframe src='{$url}' style='width:100%; height:300px; border:1px solid #e5e7eb; border-radius:8px;'></iframe>
|
||||
<a href='{$url}' target='_blank' style='display:block; margin-top:4px; color:#3b82f6; text-decoration:underline; font-size:0.75rem;'>↗️ Buka PDF di Tab Baru</a>
|
||||
</div>
|
||||
";
|
||||
}
|
||||
}
|
||||
|
||||
return "<a href='{$url}' target='_blank' style='color:#3b82f6; text-decoration:underline; font-size:0.875rem;'>📎 Buka Dokumen (".strtoupper($extension).')</a>';
|
||||
})
|
||||
->implode('<br>');
|
||||
}
|
||||
return "<a href='{$url}' target='_blank' style='color:#3b82f6; text-decoration:underline; font-size:0.875rem;'>📎 Buka Dokumen (".strtoupper($extension).')</a>';
|
||||
})
|
||||
->implode('<br>');
|
||||
}
|
||||
|
||||
return e(is_scalar($value) ? $value : json_encode($value));
|
||||
};
|
||||
return e(is_scalar($value) ? $value : json_encode($value));
|
||||
};
|
||||
|
||||
// 1. Deletion Request
|
||||
if (isset($new['__delete_request__']) && $new['__delete_request__'] === true) {
|
||||
return "
|
||||
// 1. Deletion Request
|
||||
if (isset($new['__delete_request__']) && $new['__delete_request__'] === true) {
|
||||
return "
|
||||
<div style='background-color:#fee2e2; border:1px solid #f87171; color:#991b1b; padding:16px; border-radius:8px; margin-bottom:16px;'>
|
||||
<div style='font-weight:700; font-size:1.125rem; margin-bottom:4px;'>🚮 Permohonan Penghapusan Data</div>
|
||||
<p style='font-size:0.875rem;'>User mengajukan penghapusan permanen untuk data ini. Semua informasi terkait akan dihapus setelah disetujui.</p>
|
||||
</div>
|
||||
";
|
||||
}
|
||||
}
|
||||
|
||||
// 2. New Addition Request
|
||||
if (empty($old)) {
|
||||
$rows = collect($new)
|
||||
->map(function ($value, $key) use ($renderValue) {
|
||||
return sprintf(
|
||||
"<div style='margin-bottom:12px; border-bottom:1px solid #f3f4f6; padding-bottom:8px'>
|
||||
// 2. New Addition Request
|
||||
if (empty($old)) {
|
||||
$rows = collect($new)
|
||||
->map(function ($value, $key) use ($renderValue) {
|
||||
return sprintf(
|
||||
"<div style='margin-bottom:12px; border-bottom:1px solid #f3f4f6; padding-bottom:8px'>
|
||||
<div style='font-weight:600; color:#374151; margin-bottom:4px'>%s</div>
|
||||
<div style='color:#16a34a; font-weight:500;'>[BARU]</div>
|
||||
<div style='margin-top:4px'>%s</div>
|
||||
</div>",
|
||||
e($key),
|
||||
$renderValue($value)
|
||||
);
|
||||
})
|
||||
->implode('');
|
||||
e($key),
|
||||
$renderValue($value)
|
||||
);
|
||||
})
|
||||
->implode('');
|
||||
|
||||
return "
|
||||
return "
|
||||
<div style='background-color:#f0fdf4; border:1px solid #bbf7d0; color:#166534; padding:16px; border-radius:8px; margin-bottom:16px;'>
|
||||
<div style='font-weight:700; font-size:1.125rem; margin-bottom:4px;'>✨ Permohonan Penambahan Data</div>
|
||||
<p style='font-size:0.875rem;'>Berikut adalah data baru yang akan dibuat.</p>
|
||||
</div>
|
||||
{$rows}
|
||||
";
|
||||
}
|
||||
|
||||
// 3. Standard Comparison (Update)
|
||||
return collect($new)
|
||||
->map(function ($newValue, $key) use ($old, $renderValue) {
|
||||
$oldValue = $old[$key] ?? null;
|
||||
|
||||
if ($oldValue === $newValue) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 3. Standard Comparison (Update)
|
||||
return collect($new)
|
||||
->map(function ($newValue, $key) use ($old, $renderValue) {
|
||||
$oldValue = $old[$key] ?? null;
|
||||
|
||||
if ($oldValue === $newValue) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
"<div style='margin-bottom:16px; border-bottom:1px solid #f3f4f6; padding-bottom:12px'>
|
||||
return sprintf(
|
||||
"<div style='margin-bottom:16px; border-bottom:1px solid #f3f4f6; padding-bottom:12px'>
|
||||
<div style='font-weight:600; color:#374151; margin-bottom:4px'>%s</div>
|
||||
<div style='display:grid; grid-template-columns: 1fr 1fr; gap:16px'>
|
||||
<div>
|
||||
@ -176,16 +173,15 @@ public static function infolist(Schema $schema): Schema
|
||||
</div>
|
||||
</div>
|
||||
</div>",
|
||||
e($key),
|
||||
$renderValue($oldValue),
|
||||
$renderValue($newValue)
|
||||
);
|
||||
})
|
||||
->filter()
|
||||
->implode('');
|
||||
e($key),
|
||||
$renderValue($oldValue),
|
||||
$renderValue($newValue)
|
||||
);
|
||||
})
|
||||
->columnSpanFull(),
|
||||
]),
|
||||
->filter()
|
||||
->implode('');
|
||||
})
|
||||
->columnSpanFull(),
|
||||
])
|
||||
->columns(1);
|
||||
}
|
||||
|
||||
@ -20,11 +20,10 @@
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use Filament\Actions\ForceDeleteBulkAction;
|
||||
use Filament\Actions\RestoreBulkAction;
|
||||
use Filament\Forms\Components\Group;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Components\Group;
|
||||
use Filament\Schemas\Components\Section;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
@ -78,7 +77,7 @@ public static function form(Schema $schema): Schema
|
||||
return $schema
|
||||
->components([
|
||||
TextInput::make('name')
|
||||
->label('Nama')
|
||||
->label('Nama Lengkap')
|
||||
->placeholder('John Doe')
|
||||
->autocomplete(false)
|
||||
->autofocus()
|
||||
@ -91,7 +90,8 @@ public static function form(Schema $schema): Schema
|
||||
->autocomplete(false)
|
||||
->required()
|
||||
->maxLength(254)
|
||||
->email(),
|
||||
->email()
|
||||
->prefixIcon('heroicon-o-envelope'),
|
||||
|
||||
TextInput::make('phone_number')
|
||||
->label('Nomor Telepon')
|
||||
@ -99,41 +99,39 @@ public static function form(Schema $schema): Schema
|
||||
->autocomplete(false)
|
||||
->required()
|
||||
->maxLength(20)
|
||||
->tel(),
|
||||
->tel()
|
||||
->prefixIcon('heroicon-o-phone'),
|
||||
|
||||
Group::make()
|
||||
->schema(
|
||||
collect($documents)
|
||||
->map(function (array $doc): Section {
|
||||
return Section::make($doc['title'])
|
||||
->schema([
|
||||
TextInput::make($doc['text_name'])
|
||||
->hiddenLabel()
|
||||
->placeholder($doc['placeholder'])
|
||||
->autocomplete(false)
|
||||
->required()
|
||||
->maxLength($doc['max']),
|
||||
->map(function (array $doc): array {
|
||||
return [
|
||||
TextInput::make($doc['text_name'])
|
||||
->label('Nomor Identitas ('.$doc['title'].')')
|
||||
->placeholder($doc['placeholder'])
|
||||
->autocomplete(false)
|
||||
->required()
|
||||
->maxLength($doc['max']),
|
||||
|
||||
AdvancedFileUpload::make($doc['file_name'])
|
||||
->hiddenLabel()
|
||||
->disk(config('filesystems.default'))
|
||||
->acceptedFileTypes($doc['accept'])
|
||||
->directory(fn (): string => 'journalists/'.$doc['folder'].now()->toDateString())
|
||||
->maxSize($doc['max_size'])
|
||||
->required(),
|
||||
]);
|
||||
AdvancedFileUpload::make($doc['file_name'])
|
||||
->label('File Pendukung ('.$doc['title'].') (PDF)')
|
||||
->disk(config('filesystems.default'))
|
||||
->acceptedFileTypes($doc['accept'])
|
||||
->directory(fn (): string => 'journalists/'.$doc['folder'].now()->toDateString())
|
||||
->maxSize($doc['max_size'])
|
||||
->required(),
|
||||
];
|
||||
})
|
||||
->flatten()
|
||||
->toArray()
|
||||
),
|
||||
|
||||
Section::make('Alasan Perubahan')
|
||||
->schema([
|
||||
Textarea::make('change_reason')
|
||||
->label('Alasan')
|
||||
->placeholder('Jelaskan alasan perubahan data ini...')
|
||||
->rows(3)
|
||||
->required(),
|
||||
])
|
||||
Textarea::make('change_reason')
|
||||
->label('Alasan Perubahan')
|
||||
->placeholder('Jelaskan alasan perubahan data ini...')
|
||||
->rows(3)
|
||||
->required()
|
||||
->visible(fn () => auth()->user()->company?->verificationRequest?->status === VerificationStatus::APPROVED && auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value)),
|
||||
])
|
||||
->columns(1);
|
||||
|
||||
@ -51,7 +51,7 @@ public static function form(Schema $schema): Schema
|
||||
return $schema
|
||||
->components([
|
||||
TextInput::make('name')
|
||||
->label('Nama')
|
||||
->label('Nama Kategori')
|
||||
->placeholder('Ekonomi')
|
||||
->autocomplete(false)
|
||||
->autofocus()
|
||||
|
||||
@ -51,7 +51,7 @@ public static function form(Schema $schema): Schema
|
||||
return $schema
|
||||
->components([
|
||||
TextInput::make('name')
|
||||
->label('Nama')
|
||||
->label('Nama Klasifikasi')
|
||||
->placeholder('Pelaporan')
|
||||
->autocomplete(false)
|
||||
->autofocus()
|
||||
|
||||
@ -51,7 +51,7 @@ public static function form(Schema $schema): Schema
|
||||
return $schema
|
||||
->components([
|
||||
TextInput::make('name')
|
||||
->label('Nama')
|
||||
->label('Nama OPD')
|
||||
->placeholder('Dinas Komunikasi dan Informatika')
|
||||
->autocomplete(false)
|
||||
->autofocus()
|
||||
@ -59,6 +59,7 @@ public static function form(Schema $schema): Schema
|
||||
->maxLength(100),
|
||||
|
||||
TextInput::make('alias')
|
||||
->label('Alias')
|
||||
->placeholder('Diskominfo')
|
||||
->autocomplete(false)
|
||||
->required()
|
||||
|
||||
@ -51,7 +51,7 @@ public static function form(Schema $schema): Schema
|
||||
return $schema
|
||||
->components([
|
||||
TextInput::make('name')
|
||||
->label('Nama')
|
||||
->label('Nama Lokus')
|
||||
->placeholder('Purwakarta')
|
||||
->autocomplete(false)
|
||||
->autofocus()
|
||||
|
||||
@ -54,7 +54,7 @@ public static function form(Schema $schema): Schema
|
||||
return $schema
|
||||
->components([
|
||||
Select::make('classification_id')
|
||||
->label('Klasifikasi')
|
||||
->label('Klasifikasi Utama')
|
||||
->options(Classification::query()->active()->pluck('name', 'id'))
|
||||
->searchable()
|
||||
->native(false)
|
||||
@ -63,7 +63,7 @@ public static function form(Schema $schema): Schema
|
||||
->autofocus(),
|
||||
|
||||
TextInput::make('name')
|
||||
->label('Nama')
|
||||
->label('Nama Sub-Klasifikasi')
|
||||
->placeholder('Korupsi')
|
||||
->autocomplete(false)
|
||||
->required()
|
||||
|
||||
@ -54,7 +54,7 @@ public static function form(Schema $schema): Schema
|
||||
return $schema
|
||||
->components([
|
||||
Select::make('location_id')
|
||||
->label('Lokus')
|
||||
->label('Lokus Utama')
|
||||
->options(Location::query()->pluck('name', 'id'))
|
||||
->searchable()
|
||||
->native(false)
|
||||
@ -63,8 +63,8 @@ public static function form(Schema $schema): Schema
|
||||
->autofocus(),
|
||||
|
||||
TextInput::make('name')
|
||||
->label('Nama')
|
||||
->placeholder('Nagri Kaler')
|
||||
->label('Nama Sub-Lokus')
|
||||
->placeholder('Kecamatan Purwakarta')
|
||||
->autocomplete(false)
|
||||
->required()
|
||||
->maxLength(50),
|
||||
|
||||
@ -50,7 +50,7 @@ public static function form(Schema $schema): Schema
|
||||
return $schema
|
||||
->components([
|
||||
TextInput::make('name')
|
||||
->label('Nama')
|
||||
->label('Nama Tema')
|
||||
->placeholder('Pendidikan')
|
||||
->autocomplete(false)
|
||||
->autofocus()
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Notifications\Notification;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Components\Grid;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Enums\Width;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
@ -55,45 +56,50 @@ public static function form(Schema $schema): Schema
|
||||
return $schema
|
||||
->components([
|
||||
TextInput::make('name')
|
||||
->label('Nama')
|
||||
->label('Nama Lengkap')
|
||||
->placeholder('John Doe')
|
||||
->autocomplete(false)
|
||||
->autofocus()
|
||||
->required()
|
||||
->maxLength(100),
|
||||
|
||||
TextInput::make('email')
|
||||
->label('Alamat Surel')
|
||||
->placeholder('johndoe@example.com')
|
||||
->autocomplete(false)
|
||||
->required()
|
||||
->maxLength(254)
|
||||
->email()
|
||||
->unique(ignoreRecord: true),
|
||||
Grid::make(1)
|
||||
->schema([
|
||||
TextInput::make('email')
|
||||
->label('Alamat Surel')
|
||||
->placeholder('johndoe@example.com')
|
||||
->autocomplete(false)
|
||||
->required()
|
||||
->maxLength(254)
|
||||
->email()
|
||||
->unique(ignoreRecord: true)
|
||||
->prefixIcon('heroicon-o-envelope'),
|
||||
|
||||
TextInput::make('username')
|
||||
->label('Nama Pengguna')
|
||||
->placeholder('johndoe')
|
||||
->autocomplete(false)
|
||||
->required()
|
||||
->minLength(5)
|
||||
->maxLength(20)
|
||||
->regex('/^[a-zA-Z0-9_.-]+$/')
|
||||
->unique(ignoreRecord: true),
|
||||
TextInput::make('username')
|
||||
->label('Nama Pengguna')
|
||||
->placeholder('johndoe')
|
||||
->autocomplete(false)
|
||||
->required()
|
||||
->minLength(5)
|
||||
->maxLength(20)
|
||||
->regex('/^[a-zA-Z0-9_.-]+$/')
|
||||
->unique(ignoreRecord: true)
|
||||
->prefixIcon('heroicon-o-at-symbol'),
|
||||
|
||||
Select::make('roles')
|
||||
->label('Peran')
|
||||
->required()
|
||||
->relationship('roles', 'name', function (Builder $query): Builder {
|
||||
return $query->whereNotIn('name', [RoleEnum::DEVELOPER, RoleEnum::PERUSAHAAN]);
|
||||
})
|
||||
->multiple()
|
||||
->preload()
|
||||
->searchable(),
|
||||
Select::make('roles')
|
||||
->label('Peran')
|
||||
->required()
|
||||
->relationship('roles', 'name', function (Builder $query): Builder {
|
||||
return $query->whereNotIn('name', [RoleEnum::DEVELOPER, RoleEnum::PERUSAHAAN]);
|
||||
})
|
||||
->multiple()
|
||||
->preload()
|
||||
->searchable(),
|
||||
|
||||
Hidden::make('password')
|
||||
->default(fn (): string => config('auth.password_default'))
|
||||
->visibleOn('create'),
|
||||
Hidden::make('password')
|
||||
->default(fn (): string => config('auth.password_default'))
|
||||
->visibleOn('create'),
|
||||
]),
|
||||
])
|
||||
->columns(1);
|
||||
}
|
||||
|
||||
@ -20,77 +20,84 @@ public static function configure(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
Section::make([
|
||||
TextInput::make('title')
|
||||
->label('Judul')
|
||||
->placeholder('Reels Kerja Sama DPMPTSP')
|
||||
->autocomplete(false)
|
||||
->autofocus()
|
||||
->required()
|
||||
->maxLength(1000),
|
||||
Section::make('Informasi Konten 📝')
|
||||
->description('Lengkapi detail judul, tautan, dan jenis konten Anda.')
|
||||
->icon('heroicon-o-document-text')
|
||||
->schema([
|
||||
TextInput::make('title')
|
||||
->label('Judul Konten')
|
||||
->placeholder('Reels Kerja Sama DPMPTSP')
|
||||
->autocomplete(false)
|
||||
->autofocus()
|
||||
->required()
|
||||
->maxLength(1000),
|
||||
|
||||
TextInput::make('link')
|
||||
->label('Tautan')
|
||||
->placeholder('https://www.pwknews.com')
|
||||
->autocomplete(false)
|
||||
->nullable()
|
||||
->maxLength(255)
|
||||
->url(),
|
||||
TextInput::make('link')
|
||||
->label('Tautan (URL)')
|
||||
->placeholder('https://www.pwknews.com')
|
||||
->autocomplete(false)
|
||||
->nullable()
|
||||
->maxLength(255)
|
||||
->url(),
|
||||
|
||||
Grid::make(2)
|
||||
->schema([
|
||||
Select::make('type')
|
||||
->label('Tipe')
|
||||
->options(ContentType::options())
|
||||
->native(false)
|
||||
->in(implode(',', array_column(ContentType::cases(), 'value'))),
|
||||
Grid::make(2)
|
||||
->schema([
|
||||
Select::make('type')
|
||||
->label('Tipe Konten')
|
||||
->options(ContentType::options())
|
||||
->native(false)
|
||||
->required()
|
||||
->in(implode(',', array_column(ContentType::cases(), 'value'))),
|
||||
|
||||
Select::make('channel')
|
||||
->label('Kanal')
|
||||
->options(Channel::options())
|
||||
->native(false)
|
||||
->required()
|
||||
->in(implode(',', array_column(Channel::cases(), 'value'))),
|
||||
Select::make('channel')
|
||||
->label('Kanal')
|
||||
->options(Channel::options())
|
||||
->native(false)
|
||||
->required()
|
||||
->in(implode(',', array_column(Channel::cases(), 'value'))),
|
||||
|
||||
Select::make('social_media')
|
||||
->label('Media Sosial')
|
||||
->options(SocialMedia::options())
|
||||
->native(false)
|
||||
->required()
|
||||
->in(implode(',', array_column(SocialMedia::cases(), 'value'))),
|
||||
Select::make('social_media')
|
||||
->label('Media Sosial')
|
||||
->options(SocialMedia::options())
|
||||
->native(false)
|
||||
->required()
|
||||
->in(implode(',', array_column(SocialMedia::cases(), 'value'))),
|
||||
|
||||
DatePicker::make('posting_date')
|
||||
->label('Tanggal Posting')
|
||||
->placeholder(fn (): string => now()->translatedFormat('l, d F Y'))
|
||||
->native(false)
|
||||
->displayFormat('l, d F Y')
|
||||
->required(),
|
||||
]),
|
||||
])->columnSpan(2),
|
||||
DatePicker::make('posting_date')
|
||||
->label('Tanggal Posting')
|
||||
->placeholder(fn (): string => now()->translatedFormat('l, d F Y'))
|
||||
->native(false)
|
||||
->displayFormat('l, d F Y')
|
||||
->required(),
|
||||
]),
|
||||
])->columnSpan(2),
|
||||
|
||||
Section::make([
|
||||
Select::make('classification_id')
|
||||
->label('Klasifikasi')
|
||||
->relationship('classification', 'name', function (Builder $query): Builder {
|
||||
return $query->active();
|
||||
})
|
||||
->native(false)
|
||||
->preload()
|
||||
->required(),
|
||||
Section::make('Klasifikasi & Lampiran 📁')
|
||||
->description('Pilih klasifikasi yang sesuai dan unggah gambar pendukung.')
|
||||
->icon('heroicon-o-folder-open')
|
||||
->schema([
|
||||
Select::make('classification_id')
|
||||
->label('Klasifikasi')
|
||||
->relationship('classification', 'name', function (Builder $query): Builder {
|
||||
return $query->active();
|
||||
})
|
||||
->native(false)
|
||||
->preload()
|
||||
->required(),
|
||||
|
||||
SpatieMediaLibraryFileUpload::make('image')
|
||||
->label('Gambar')
|
||||
->disk(config('filesystems.default'))
|
||||
->acceptedFileTypes(['image/*'])
|
||||
->maxSize(1024 * 3)
|
||||
->collection('content-recpaps')
|
||||
->customProperties(fn (): array => [
|
||||
'feature' => 'content-recaps',
|
||||
'date' => now()->toDateString(),
|
||||
])
|
||||
->image()
|
||||
->required(),
|
||||
]),
|
||||
SpatieMediaLibraryFileUpload::make('image')
|
||||
->label('Gambar Konten')
|
||||
->disk(config('filesystems.default'))
|
||||
->acceptedFileTypes(['image/*'])
|
||||
->maxSize(1024 * 3)
|
||||
->collection('content-recpaps')
|
||||
->customProperties(fn (): array => [
|
||||
'feature' => 'content-recaps',
|
||||
'date' => now()->toDateString(),
|
||||
])
|
||||
->image()
|
||||
->required(),
|
||||
])->columnSpan(1),
|
||||
])
|
||||
->columns(3);
|
||||
}
|
||||
|
||||
@ -18,89 +18,95 @@ public static function configure(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
Section::make([
|
||||
Select::make('media_monitoring_id')
|
||||
->label('Monitoring Media')
|
||||
->relationship(
|
||||
'mediaMonitoring',
|
||||
'title',
|
||||
fn (Builder $query): Builder => $query->whereDoesntHave('issueManagement')
|
||||
)
|
||||
->searchable()
|
||||
->preload()
|
||||
->required()
|
||||
->autofocus()
|
||||
->helperText('Jika judul berita dari monitoring media tidak ada di opsi, silakan lakukan pencarian.'),
|
||||
Section::make('Identifikasi Isu 🔍')
|
||||
->description('Hubungkan dengan berita monitoring dan tentukan lokasi isu.')
|
||||
->icon('heroicon-o-magnifying-glass')
|
||||
->schema([
|
||||
Select::make('media_monitoring_id')
|
||||
->label('Monitoring Media')
|
||||
->relationship(
|
||||
'mediaMonitoring',
|
||||
'title',
|
||||
fn (Builder $query): Builder => $query->whereDoesntHave('issueManagement')
|
||||
)
|
||||
->searchable()
|
||||
->preload()
|
||||
->required()
|
||||
->autofocus()
|
||||
->helperText('Jika judul berita dari monitoring media tidak ada di opsi, silakan lakukan pencarian.'),
|
||||
|
||||
Select::make('departments')
|
||||
->label('Perangkat Daerah')
|
||||
->relationship('departments', 'name', fn (Builder $query): Builder => $query->active())
|
||||
->searchable()
|
||||
->preload()
|
||||
->multiple()
|
||||
->required(),
|
||||
Select::make('departments')
|
||||
->label('Perangkat Daerah Terkait')
|
||||
->relationship('departments', 'name', fn (Builder $query): Builder => $query->active())
|
||||
->searchable()
|
||||
->preload()
|
||||
->multiple()
|
||||
->required(),
|
||||
|
||||
Grid::make(2)
|
||||
->schema([
|
||||
Select::make('location_id')
|
||||
->label('Lokus')
|
||||
->relationship('location', 'name', fn (Builder $query): Builder => $query->active())
|
||||
->searchable()
|
||||
->preload()
|
||||
->live()
|
||||
->afterStateUpdated(function (Set $set): void {
|
||||
$set('sub_location_id', null);
|
||||
})
|
||||
->required(),
|
||||
Grid::make(2)
|
||||
->schema([
|
||||
Select::make('location_id')
|
||||
->label('Lokus')
|
||||
->relationship('location', 'name', fn (Builder $query): Builder => $query->active())
|
||||
->searchable()
|
||||
->preload()
|
||||
->live()
|
||||
->afterStateUpdated(function (Set $set): void {
|
||||
$set('sub_location_id', null);
|
||||
})
|
||||
->required(),
|
||||
|
||||
Select::make('sub_location_id')
|
||||
->label('Sub Lokus')
|
||||
->relationship('subLocation', 'name', fn (Builder $query, Get $get): Builder => $query->active()->where('location_id', $get('location_id')))
|
||||
->searchable()
|
||||
->preload()
|
||||
->required(),
|
||||
]),
|
||||
Select::make('sub_location_id')
|
||||
->label('Sub Lokus')
|
||||
->relationship('subLocation', 'name', fn (Builder $query, Get $get): Builder => $query->active()->where('location_id', $get('location_id')))
|
||||
->searchable()
|
||||
->preload()
|
||||
->required(),
|
||||
]),
|
||||
|
||||
RichEditor::make('description')
|
||||
->label('Keterangan')
|
||||
->placeholder('...')
|
||||
->required()
|
||||
->columnSpanFull(),
|
||||
])->columnSpan(2),
|
||||
RichEditor::make('description')
|
||||
->label('Keterangan Isu')
|
||||
->placeholder('Jelaskan detail isu yang berkembang...')
|
||||
->required()
|
||||
->columnSpanFull(),
|
||||
])->columnSpan(2),
|
||||
|
||||
Section::make([
|
||||
Select::make('issue')
|
||||
->label('Isu')
|
||||
->options(IssueSentiment::options())
|
||||
->required()
|
||||
->native(false)
|
||||
->in(implode(',', array_column(IssueSentiment::cases(), 'value'))),
|
||||
Section::make('Sentimen & Klasifikasi 📊')
|
||||
->description('Tentukan sentimen isu, respon, dan kategori klasifikasinya.')
|
||||
->icon('heroicon-o-chart-bar')
|
||||
->schema([
|
||||
Select::make('issue')
|
||||
->label('Sentimen Isu')
|
||||
->options(IssueSentiment::options())
|
||||
->required()
|
||||
->native(false)
|
||||
->in(implode(',', array_column(IssueSentiment::cases(), 'value'))),
|
||||
|
||||
Select::make('response')
|
||||
->label('Respon')
|
||||
->options(IssueSentiment::options())
|
||||
->required()
|
||||
->native(false)
|
||||
->in(implode(',', array_column(IssueSentiment::cases(), 'value'))),
|
||||
Select::make('response')
|
||||
->label('Respon Pemerintah')
|
||||
->options(IssueSentiment::options())
|
||||
->required()
|
||||
->native(false)
|
||||
->in(implode(',', array_column(IssueSentiment::cases(), 'value'))),
|
||||
|
||||
Select::make('classification_id')
|
||||
->label('Klasifikasi')
|
||||
->relationship('classification', 'name', fn (Builder $query): Builder => $query->active())
|
||||
->searchable()
|
||||
->preload()
|
||||
->live()
|
||||
->afterStateUpdated(function (Set $set): void {
|
||||
$set('sub_classification_id', null);
|
||||
})
|
||||
->required(),
|
||||
Select::make('classification_id')
|
||||
->label('Klasifikasi')
|
||||
->relationship('classification', 'name', fn (Builder $query): Builder => $query->active())
|
||||
->searchable()
|
||||
->preload()
|
||||
->live()
|
||||
->afterStateUpdated(function (Set $set): void {
|
||||
$set('sub_classification_id', null);
|
||||
})
|
||||
->required(),
|
||||
|
||||
Select::make('sub_classification_id')
|
||||
->label('Sub Klasifikasi')
|
||||
->relationship('subClassification', 'name', fn (Builder $query, Get $get): Builder => $query->where('classification_id', $get('classification_id'))->active())
|
||||
->searchable()
|
||||
->preload()
|
||||
->required(),
|
||||
])->columnSpan(1),
|
||||
Select::make('sub_classification_id')
|
||||
->label('Sub Klasifikasi')
|
||||
->relationship('subClassification', 'name', fn (Builder $query, Get $get): Builder => $query->where('classification_id', $get('location_id'))->active())
|
||||
->searchable()
|
||||
->preload()
|
||||
->required(),
|
||||
])->columnSpan(1),
|
||||
])
|
||||
->columns(3);
|
||||
}
|
||||
|
||||
@ -19,109 +19,115 @@ public static function configure(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
Section::make([
|
||||
TextInput::make('media_name')
|
||||
->label('Nama Media')
|
||||
->placeholder('PWK News')
|
||||
->autocomplete(false)
|
||||
->autofocus()
|
||||
->required()
|
||||
->maxLength(50),
|
||||
Section::make('Detail Berita 📰')
|
||||
->description('Masukkan informasi lengkap mengenai pemberitaan media.')
|
||||
->icon('heroicon-o-newspaper')
|
||||
->schema([
|
||||
TextInput::make('media_name')
|
||||
->label('Nama Media')
|
||||
->placeholder('PWK News')
|
||||
->autocomplete(false)
|
||||
->autofocus()
|
||||
->required()
|
||||
->maxLength(50),
|
||||
|
||||
TextInput::make('title')
|
||||
->label('Judul')
|
||||
->placeholder('Berita Purwakarta Hari Ini')
|
||||
->autocomplete(false)
|
||||
->required()
|
||||
->maxLength(255),
|
||||
TextInput::make('title')
|
||||
->label('Judul Berita')
|
||||
->placeholder('Berita Purwakarta Hari Ini')
|
||||
->autocomplete(false)
|
||||
->required()
|
||||
->maxLength(255),
|
||||
|
||||
Grid::make(2)
|
||||
->schema([
|
||||
TextInput::make('writter')
|
||||
->label('Penulis')
|
||||
->placeholder('John Doe')
|
||||
->autocomplete(false)
|
||||
->required()
|
||||
->maxLength(50),
|
||||
Grid::make(2)
|
||||
->schema([
|
||||
TextInput::make('writter')
|
||||
->label('Penulis')
|
||||
->placeholder('John Doe')
|
||||
->autocomplete(false)
|
||||
->required()
|
||||
->maxLength(50),
|
||||
|
||||
TextInput::make('news_page')
|
||||
->label('Halaman Berita')
|
||||
->placeholder('Halaman 1 s/d 10')
|
||||
->autocomplete(false)
|
||||
->nullable()
|
||||
->maxLength(20),
|
||||
]),
|
||||
TextInput::make('news_page')
|
||||
->label('Halaman Berita')
|
||||
->placeholder('Halaman 1 s/d 10')
|
||||
->autocomplete(false)
|
||||
->nullable()
|
||||
->maxLength(20),
|
||||
]),
|
||||
|
||||
TextInput::make('link')
|
||||
->label('Tautan')
|
||||
->placeholder('https://www.pwknews.com')
|
||||
->autocomplete(false)
|
||||
->nullable()
|
||||
->url(),
|
||||
TextInput::make('link')
|
||||
->label('Tautan (URL)')
|
||||
->placeholder('https://www.pwknews.com')
|
||||
->autocomplete(false)
|
||||
->nullable()
|
||||
->url(),
|
||||
|
||||
RichEditor::make('quote')
|
||||
->label('Kutipan')
|
||||
->placeholder('....')
|
||||
->nullable(),
|
||||
RichEditor::make('quote')
|
||||
->label('Kutipan Penting')
|
||||
->placeholder('Masukkan kutipan penting dari berita...')
|
||||
->nullable(),
|
||||
|
||||
RichEditor::make('content')
|
||||
->label('Konten')
|
||||
->placeholder('....')
|
||||
->required(),
|
||||
])->columnSpan(2),
|
||||
RichEditor::make('content')
|
||||
->label('Konten Berita')
|
||||
->placeholder('Tuliskan isi berita di sini...')
|
||||
->required(),
|
||||
])->columnSpan(2),
|
||||
|
||||
Section::make([
|
||||
Select::make('channel')
|
||||
->label('Kanal')
|
||||
->options(Channel::options())
|
||||
->native(false)
|
||||
->required()
|
||||
->in(implode(',', array_column(Channel::cases(), 'value'))),
|
||||
Section::make('Kategori & Metadata 🏷️')
|
||||
->description('Tentukan kategori berita dan informasi tambahan lainnya.')
|
||||
->icon('heroicon-o-tag')
|
||||
->schema([
|
||||
Select::make('channel')
|
||||
->label('Kanal')
|
||||
->options(Channel::options())
|
||||
->native(false)
|
||||
->required()
|
||||
->in(implode(',', array_column(Channel::cases(), 'value'))),
|
||||
|
||||
Select::make('themes')
|
||||
->label('Tema')
|
||||
->relationship('themes', 'name', function (Builder $query): Builder {
|
||||
return $query->active();
|
||||
})
|
||||
->native(false)
|
||||
->multiple()
|
||||
->preload()
|
||||
->required(),
|
||||
Select::make('themes')
|
||||
->label('Tema')
|
||||
->relationship('themes', 'name', function (Builder $query): Builder {
|
||||
return $query->active();
|
||||
})
|
||||
->native(false)
|
||||
->multiple()
|
||||
->preload()
|
||||
->required(),
|
||||
|
||||
DatePicker::make('release_date')
|
||||
->label('Tanggal Rilis')
|
||||
->placeholder(fn (): string => now()->translatedFormat('l, d F Y'))
|
||||
->native(false)
|
||||
->displayFormat('l, d F Y')
|
||||
->required(),
|
||||
DatePicker::make('release_date')
|
||||
->label('Tanggal Rilis')
|
||||
->placeholder(fn (): string => now()->translatedFormat('l, d F Y'))
|
||||
->native(false)
|
||||
->displayFormat('l, d F Y')
|
||||
->required(),
|
||||
|
||||
TextInput::make('influencer')
|
||||
->label('Influencer')
|
||||
->placeholder('Sekretariat Daerah')
|
||||
->autocomplete(false)
|
||||
->nullable()
|
||||
->maxLength(50),
|
||||
TextInput::make('influencer')
|
||||
->label('Influencer')
|
||||
->placeholder('Sekretariat Daerah')
|
||||
->autocomplete(false)
|
||||
->nullable()
|
||||
->maxLength(50),
|
||||
|
||||
TextInput::make('keyword')
|
||||
->label('Kata Kunci')
|
||||
->placeholder('Purwakarta, Berita Terbaru, Hari Ini')
|
||||
->autocomplete(false)
|
||||
->required()
|
||||
->maxLength(100),
|
||||
TextInput::make('keyword')
|
||||
->label('Kata Kunci')
|
||||
->placeholder('Purwakarta, Berita Terbaru, Hari Ini')
|
||||
->autocomplete(false)
|
||||
->required()
|
||||
->maxLength(100),
|
||||
|
||||
SpatieMediaLibraryFileUpload::make('image')
|
||||
->label('Gambar')
|
||||
->disk(config('filesystems.default'))
|
||||
->acceptedFileTypes(['image/*'])
|
||||
->maxSize(1024 * 3)
|
||||
->collection('media-monitorings')
|
||||
->customProperties(fn (): array => [
|
||||
'feature' => 'media-monitorings',
|
||||
'date' => now()->toDateString(),
|
||||
])
|
||||
->image()
|
||||
->required(),
|
||||
]),
|
||||
SpatieMediaLibraryFileUpload::make('image')
|
||||
->label('Gambar Utama')
|
||||
->disk(config('filesystems.default'))
|
||||
->acceptedFileTypes(['image/*'])
|
||||
->maxSize(1024 * 3)
|
||||
->collection('media-monitorings')
|
||||
->customProperties(fn (): array => [
|
||||
'feature' => 'media-monitorings',
|
||||
'date' => now()->toDateString(),
|
||||
])
|
||||
->image()
|
||||
->required(),
|
||||
])->columnSpan(1),
|
||||
])
|
||||
->columns(3);
|
||||
}
|
||||
|
||||
@ -54,22 +54,21 @@ public static function form(Schema $schema): Schema
|
||||
return $schema
|
||||
->components([
|
||||
TextInput::make('title')
|
||||
->label('Judul')
|
||||
->label('Judul Pengumuman')
|
||||
->placeholder('Pencairan Dana Kerja Sama Media')
|
||||
->autocomplete(false)
|
||||
->autofocus()
|
||||
->required()
|
||||
->maxLength(200)
|
||||
->columnSpanFull(),
|
||||
|
||||
RichEditor::make('content')
|
||||
->label('Konten')
|
||||
->placeholder('...')
|
||||
->label('Isi Pengumuman')
|
||||
->placeholder('Tuliskan detail pengumuman di sini...')
|
||||
->required()
|
||||
->columnSpanFull(),
|
||||
|
||||
Radio::make('type')
|
||||
->label('Tipe')
|
||||
->label('Tipe Pengumuman')
|
||||
->options(AnnouncementType::class)
|
||||
->required()
|
||||
->default(AnnouncementType::PUBLIC->value)
|
||||
@ -77,20 +76,19 @@ public static function form(Schema $schema): Schema
|
||||
->inline(),
|
||||
|
||||
CheckboxList::make('partnerMedia')
|
||||
->label('Kirim Kepada')
|
||||
->label('Penerima Khusus')
|
||||
->relationship('partnerMedia', 'name', fn (Builder $query): Builder => $query->verified())
|
||||
->visible(fn (Get $get): bool => in_array($get('type'), [AnnouncementType::COMPANY, AnnouncementType::COMPANY->value]))
|
||||
->required(fn (Get $get): bool => in_array($get('type'), [AnnouncementType::COMPANY, AnnouncementType::COMPANY->value]))
|
||||
->searchable()
|
||||
->noSearchResultsMessage('Tidak ada media yang ditemukan.')
|
||||
->helperText('Pilih media yang akan menerima pengumuman ini')
|
||||
->helperText('Pilih media yang akan menerima pengumuman ini.')
|
||||
->columnSpanFull()
|
||||
->bulkToggleable()
|
||||
->selectAllAction(
|
||||
fn (Action $action): Action => $action->label('Pilih Semua Media'),
|
||||
)
|
||||
->dehydrated(),
|
||||
|
||||
])
|
||||
->columns(1);
|
||||
}
|
||||
|
||||
@ -25,91 +25,95 @@ public static function configure(Schema $schema): Schema
|
||||
Hidden::make('author_id')
|
||||
->default(auth()->id()),
|
||||
|
||||
Section::make([
|
||||
TextInput::make('title')
|
||||
->label('Judul')
|
||||
->placeholder('Berita Purwakarta Hari Ini')
|
||||
->autocomplete(false)
|
||||
->autofocus()
|
||||
->required()
|
||||
->maxLength(200),
|
||||
Section::make('Konten Berita ✍️')
|
||||
->description('Tuliskan judul, ringkasan, dan isi lengkap berita Anda.')
|
||||
->icon('heroicon-o-pencil-square')
|
||||
->schema([
|
||||
TextInput::make('title')
|
||||
->label('Judul Berita')
|
||||
->placeholder('Berita Purwakarta Hari Ini')
|
||||
->autocomplete(false)
|
||||
->autofocus()
|
||||
->required()
|
||||
->maxLength(200),
|
||||
|
||||
RichEditor::make('content')
|
||||
->label('Konten')
|
||||
->placeholder('...')
|
||||
->required()
|
||||
->columnSpanFull(),
|
||||
RichEditor::make('excerpt')
|
||||
->label('Ringkasan (Excerpt)')
|
||||
->placeholder('Berikan ringkasan singkat berita...')
|
||||
->required()
|
||||
->columnSpanFull(),
|
||||
|
||||
RichEditor::make('excerpt')
|
||||
->label('Ringkasan')
|
||||
->placeholder('...')
|
||||
->required()
|
||||
->columnSpanFull(),
|
||||
])->columnSpan(2),
|
||||
RichEditor::make('content')
|
||||
->label('Isi Lengkap Berita')
|
||||
->placeholder('Tuliskan konten berita secara mendetail...')
|
||||
->required()
|
||||
->columnSpanFull(),
|
||||
])->columnSpan(2),
|
||||
|
||||
Section::make([
|
||||
TextInput::make('link')
|
||||
->label('Tautan')
|
||||
->placeholder('https://www.pwknews.com')
|
||||
->autocomplete(false)
|
||||
->nullable()
|
||||
->maxLength(255)
|
||||
->url(),
|
||||
Section::make('Kategori & Publikasi 🏷️')
|
||||
->description('Tentukan kategori, tautan media, dan status publikasi.')
|
||||
->icon('heroicon-o-tag')
|
||||
->schema([
|
||||
TextInput::make('link')
|
||||
->label('Tautan Media (Opsional)')
|
||||
->placeholder('https://www.pwknews.com')
|
||||
->autocomplete(false)
|
||||
->nullable()
|
||||
->maxLength(255)
|
||||
->url(),
|
||||
|
||||
Select::make('categories')
|
||||
->label('Kategori')
|
||||
->relationship('categories', 'name', function (Builder $query): Builder {
|
||||
return $query->active();
|
||||
})
|
||||
->native(false)
|
||||
->multiple()
|
||||
->preload()
|
||||
->required(),
|
||||
Select::make('categories')
|
||||
->label('Kategori')
|
||||
->relationship('categories', 'name', function (Builder $query): Builder {
|
||||
return $query->active();
|
||||
})
|
||||
->native(false)
|
||||
->multiple()
|
||||
->preload()
|
||||
->required(),
|
||||
|
||||
TagsInput::make('tags')
|
||||
->reactive()
|
||||
->afterStateHydrated(function ($component, $state, $record): void {
|
||||
if (! $record) {
|
||||
return;
|
||||
}
|
||||
$component->state(
|
||||
$record->tags->pluck('name')->toArray()
|
||||
);
|
||||
})
|
||||
->helperText('Tekan enter untuk menambahkan tag.'),
|
||||
TagsInput::make('tags')
|
||||
->label('Tag Berita')
|
||||
->reactive()
|
||||
->afterStateHydrated(function ($component, $state, $record): void {
|
||||
if (! $record) {
|
||||
return;
|
||||
}
|
||||
$component->state(
|
||||
$record->tags->pluck('name')->toArray()
|
||||
);
|
||||
})
|
||||
->helperText('Tekan enter untuk menambahkan tag.'),
|
||||
|
||||
Radio::make('status')
|
||||
->label('Status')
|
||||
->required()
|
||||
->options(NewsStatus::options())
|
||||
->default(NewsStatus::PUBLISHED->value)
|
||||
->inline()
|
||||
->live()
|
||||
->afterStateUpdated(function (Set $set, ?string $state, ?News $news): void {
|
||||
if ($state == NewsStatus::PUBLISHED->value && ! $news?->published_at) {
|
||||
$set('published_at', now());
|
||||
} elseif ($state != NewsStatus::PUBLISHED->value && ! $news) {
|
||||
$set('published_at', null);
|
||||
}
|
||||
})
|
||||
->rules(['in:'.implode(',', NewsStatus::values())]),
|
||||
Radio::make('status')
|
||||
->label('Status Publikasi')
|
||||
->required()
|
||||
->options(NewsStatus::options())
|
||||
->default(NewsStatus::PUBLISHED->value)
|
||||
->inline()
|
||||
->live()
|
||||
->afterStateUpdated(function (Set $set, ?string $state, ?News $news): void {
|
||||
if ($state == NewsStatus::PUBLISHED->value && ! $news?->published_at) {
|
||||
$set('published_at', now());
|
||||
} elseif ($state != NewsStatus::PUBLISHED->value && ! $news) {
|
||||
$set('published_at', null);
|
||||
}
|
||||
})
|
||||
->rules(['in:'.implode(',', NewsStatus::values())]),
|
||||
|
||||
Hidden::make('published_at')
|
||||
->default(now()),
|
||||
|
||||
SpatieMediaLibraryFileUpload::make('thumbnail')
|
||||
->label('Thumbnail')
|
||||
->disk(config('filesystems.default'))
|
||||
->acceptedFileTypes(['image/*'])
|
||||
->maxSize(1024 * 3)
|
||||
->collection('news')
|
||||
->customProperties(fn (): array => [
|
||||
'feature' => 'news',
|
||||
'date' => now()->toDateString(),
|
||||
])
|
||||
->image()
|
||||
->required(),
|
||||
]),
|
||||
SpatieMediaLibraryFileUpload::make('thumbnail')
|
||||
->label('Thumbnail Utama')
|
||||
->disk(config('filesystems.default'))
|
||||
->acceptedFileTypes(['image/*'])
|
||||
->maxSize(1024 * 3)
|
||||
->collection('news')
|
||||
->customProperties(fn (): array => [
|
||||
'feature' => 'news',
|
||||
'date' => now()->toDateString(),
|
||||
])
|
||||
->image()
|
||||
->required(),
|
||||
])->columnSpan(1),
|
||||
])
|
||||
->columns(3);
|
||||
}
|
||||
|
||||
@ -69,7 +69,7 @@ class="p-4 rounded-xl bg-warning-50 dark:bg-warning-500/10 border border-warning
|
||||
</p>
|
||||
<div class="mt-3">
|
||||
<x-filament::button tag="a" :href="$progress['editUrl']" size="sm" color="warning"
|
||||
icon="heroicon-m-pencil-square">
|
||||
icon="heroicon-o-pencil-square">
|
||||
Perbaiki Data
|
||||
</x-filament::button>
|
||||
</div>
|
||||
@ -154,7 +154,7 @@ class="p-4 rounded-xl bg-success-50 dark:bg-success-500/10 border border-success
|
||||
</p>
|
||||
<div class="mt-3">
|
||||
<x-filament::button tag="a" :href="$progress['editUrl']" size="sm" color="gray"
|
||||
icon="heroicon-m-plus">
|
||||
icon="heroicon-o-plus">
|
||||
Lengkapi Data
|
||||
</x-filament::button>
|
||||
</div>
|
||||
@ -220,7 +220,7 @@ class="w-full flex items-center justify-between p-4 bg-gray-50 dark:bg-gray-800
|
||||
<div class="flex items-center gap-2">
|
||||
@if ($hasEntity && !$progress['isPending'] && !$progress['isApproved'])
|
||||
<x-filament::button tag="a" :href="$progress['editUrl']" color="gray" size="sm"
|
||||
icon="heroicon-m-pencil">
|
||||
icon="heroicon-o-pencil">
|
||||
Edit Data
|
||||
</x-filament::button>
|
||||
@endif
|
||||
|
||||
@ -199,7 +199,7 @@ class="w-4 h-4 text-gray-500 transition-transform duration-200"
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
{{-- View Detail Button --}}
|
||||
@if ($verification['company']['detailUrl'])
|
||||
<x-filament::button color="gray" size="sm" icon="heroicon-m-eye" tag="a"
|
||||
<x-filament::button color="gray" size="sm" icon="heroicon-o-eye" tag="a"
|
||||
:href="$verification['company']['detailUrl']">
|
||||
Detail
|
||||
</x-filament::button>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user