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:
Yoga Pangestu 2026-03-26 13:53:07 +07:00
parent af7bf05b91
commit de4aea7f2a
23 changed files with 657 additions and 593 deletions

View File

@ -7,9 +7,15 @@
use Filament\Actions\Action; use Filament\Actions\Action;
use Filament\Auth\Pages\EmailVerification\EmailVerificationPrompt; use Filament\Auth\Pages\EmailVerification\EmailVerificationPrompt;
use Filament\Notifications\Notification; use Filament\Notifications\Notification;
use Filament\Support\Enums\Width;
class EmailVerification extends EmailVerificationPrompt class EmailVerification extends EmailVerificationPrompt
{ {
public function getMaxContentWidth(): Width
{
return Width::ExtraLarge;
}
public function resendNotificationAction(): Action public function resendNotificationAction(): Action
{ {
return Action::make('resendNotification') return Action::make('resendNotification')

View File

@ -11,6 +11,7 @@
use Filament\Forms\Components\TextInput; use Filament\Forms\Components\TextInput;
use Filament\Models\Contracts\FilamentUser; use Filament\Models\Contracts\FilamentUser;
use Filament\Schemas\Schema; use Filament\Schemas\Schema;
use Filament\Support\Enums\Width;
use Illuminate\Auth\SessionGuard; use Illuminate\Auth\SessionGuard;
use Illuminate\Contracts\Auth\Authenticatable; use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Support\Htmlable; use Illuminate\Contracts\Support\Htmlable;
@ -21,6 +22,11 @@
class Login extends FilamentLogin class Login extends FilamentLogin
{ {
public function getMaxContentWidth(): Width
{
return Width::ExtraLarge;
}
public function getHeading(): string|Htmlable public function getHeading(): string|Htmlable
{ {
return ''; return '';
@ -35,7 +41,10 @@ public function form(Schema $schema): Schema
->placeholder('johndoe@example.com') ->placeholder('johndoe@example.com')
->required() ->required()
->autocomplete(false) ->autocomplete(false)
->autofocus(), ->autofocus()
->required()
->maxLength(255)
->prefixIcon('heroicon-o-user'),
TextInput::make('password') TextInput::make('password')
->label('Kata Sandi') ->label('Kata Sandi')
@ -45,6 +54,7 @@ public function form(Schema $schema): Schema
->required() ->required()
->autocomplete(false) ->autocomplete(false)
->extraInputAttributes(['tabindex' => 2]) ->extraInputAttributes(['tabindex' => 2])
->prefixIcon('heroicon-o-lock-closed')
->hint( ->hint(
filament()->hasPasswordReset() 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>')) ? 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>'))

View File

@ -5,7 +5,6 @@
use App\Filament\Support\CheerfulNotification; use App\Filament\Support\CheerfulNotification;
use Filament\Auth\Pages\EditProfile; use Filament\Auth\Pages\EditProfile;
use Filament\Forms\Components\TextInput; use Filament\Forms\Components\TextInput;
use Filament\Notifications\Notification;
use Filament\Schemas\Components\Grid; use Filament\Schemas\Components\Grid;
use Filament\Schemas\Components\Section; use Filament\Schemas\Components\Section;
use Filament\Schemas\Components\Utilities\Get; use Filament\Schemas\Components\Utilities\Get;
@ -26,16 +25,13 @@ public function form(Schema $schema): Schema
{ {
return $schema return $schema
->components([ ->components([
Section::make('Informasi Profil 👤') Section::make()
->description('Kelola detail profil Anda seperti nama, alamat surel, dan nama pengguna.')
->icon('heroicon-m-user-circle')
->schema([ ->schema([
TextInput::make('name') TextInput::make('name')
->label('Nama Lengkap') ->label('Nama Lengkap')
->placeholder('Masukkan nama lengkap Anda') ->placeholder('Masukkan nama lengkap Anda')
->required() ->required()
->maxLength(100) ->maxLength(100),
->prefixIcon('heroicon-m-user'),
Grid::make(2) Grid::make(2)
->schema([ ->schema([
@ -47,7 +43,7 @@ public function form(Schema $schema): Schema
->maxLength(254) ->maxLength(254)
->unique(ignoreRecord: true) ->unique(ignoreRecord: true)
->email() ->email()
->prefixIcon('heroicon-m-envelope') ->prefixIcon('heroicon-o-envelope')
->live(), ->live(),
TextInput::make('username') TextInput::make('username')
@ -59,13 +55,11 @@ public function form(Schema $schema): Schema
->maxLength(20) ->maxLength(20)
->regex('/^[a-zA-Z0-9_.-]+$/') ->regex('/^[a-zA-Z0-9_.-]+$/')
->unique(ignoreRecord: true) ->unique(ignoreRecord: true)
->prefixIcon('heroicon-m-at-symbol'), ->prefixIcon('heroicon-o-at-symbol'),
]), ]),
]), ]),
Section::make('Keamanan Akun 🔒') Section::make()
->description('Pastikan akun Anda menggunakan kata sandi yang panjang dan aman.')
->icon('heroicon-m-finger-print')
->schema([ ->schema([
Grid::make(2) Grid::make(2)
->schema([ ->schema([
@ -81,7 +75,7 @@ public function form(Schema $schema): Schema
->dehydrateStateUsing(fn ($state) => Hash::make($state)) ->dehydrateStateUsing(fn ($state) => Hash::make($state))
->same('passwordConfirmation') ->same('passwordConfirmation')
->validationAttribute(__('filament-panels::auth/pages/register.form.password.validation_attribute')) ->validationAttribute(__('filament-panels::auth/pages/register.form.password.validation_attribute'))
->prefixIcon('heroicon-m-lock-closed'), ->prefixIcon('heroicon-o-lock-closed'),
TextInput::make('passwordConfirmation') TextInput::make('passwordConfirmation')
->label(__('filament-panels::auth/pages/register.form.password_confirmation.label')) ->label(__('filament-panels::auth/pages/register.form.password_confirmation.label'))
@ -90,7 +84,7 @@ public function form(Schema $schema): Schema
->revealable(filament()->arePasswordsRevealable()) ->revealable(filament()->arePasswordsRevealable())
->required(fn (Get $get) => filled($get('password')) || filled($get('passwordConfirmation'))) ->required(fn (Get $get) => filled($get('password')) || filled($get('passwordConfirmation')))
->dehydrated(false) ->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 protected function handleRecordUpdate(Model $record, array $data): Model
{ {
$passwordChanged = filled($data['password'] ?? null);
$record->update($data); $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; 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());
}
} }
} }

View File

@ -9,6 +9,7 @@
use Filament\Auth\Pages\Register; use Filament\Auth\Pages\Register;
use Filament\Forms\Components\TextInput; use Filament\Forms\Components\TextInput;
use Filament\Schemas\Schema; use Filament\Schemas\Schema;
use Filament\Support\Enums\Width;
use Illuminate\Contracts\Support\Htmlable; use Illuminate\Contracts\Support\Htmlable;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Hash;
@ -16,6 +17,11 @@
class Registration extends Register class Registration extends Register
{ {
public function getMaxContentWidth(): Width
{
return Width::ExtraLarge;
}
public function getHeading(): string|Htmlable public function getHeading(): string|Htmlable
{ {
return ''; return '';
@ -26,7 +32,7 @@ public function form(Schema $schema): Schema
return $schema return $schema
->components([ ->components([
TextInput::make('name') TextInput::make('name')
->label('Nama') ->label('Nama Lengkap')
->placeholder('John Doe') ->placeholder('John Doe')
->autocomplete(false) ->autocomplete(false)
->autofocus() ->autofocus()
@ -41,7 +47,8 @@ public function form(Schema $schema): Schema
->maxLength(254) ->maxLength(254)
->unique('users', 'email') ->unique('users', 'email')
->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') TextInput::make('username')
->label('Nama Pengguna') ->label('Nama Pengguna')
@ -49,9 +56,10 @@ public function form(Schema $schema): Schema
->autocomplete(false) ->autocomplete(false)
->required() ->required()
->minLength(5) ->minLength(5)
->maxLength(10) ->maxLength(20)
->regex('/^[a-zA-Z0-9_.-]+$/') ->regex('/^[a-zA-Z0-9_.-]+$/')
->unique('users', 'username'), ->unique('users', 'username')
->prefixIcon('heroicon-o-at-symbol'),
TextInput::make('password') TextInput::make('password')
->label('Kata Sandi') ->label('Kata Sandi')
@ -62,7 +70,8 @@ public function form(Schema $schema): Schema
->autocomplete(false) ->autocomplete(false)
->dehydrated(fn ($state): bool => filled($state)) ->dehydrated(fn ($state): bool => filled($state))
->dehydrateStateUsing(fn ($state): string => Hash::make($state)) ->dehydrateStateUsing(fn ($state): string => Hash::make($state))
->placeholder('********'), ->placeholder('********')
->prefixIcon('heroicon-o-lock-closed'),
]); ]);
} }

View File

@ -50,48 +50,61 @@ public static function infolist(Schema $schema): Schema
{ {
return $schema return $schema
->schema([ ->schema([
Section::make('Informasi Pengirim') Section::make('Informasi Pengirim 📧')
->description('Detail mengenai identitas pengirim pesan.')
->icon('heroicon-o-user')
->schema([ ->schema([
Grid::make(4) Grid::make(4)
->schema([ ->schema([
TextEntry::make('name') TextEntry::make('name')
->label('Nama'), ->label('Nama Pengirim')
->icon('heroicon-o-user'),
TextEntry::make('email') TextEntry::make('email')
->label('Email'), ->label('Alamat Surel')
->icon('heroicon-o-envelope'),
TextEntry::make('subject') TextEntry::make('subject')
->label('Subyek'), ->label('Subyek Pesan')
->icon('heroicon-o-tag'),
TextEntry::make('created_at') TextEntry::make('created_at')
->label('Diterima pada') ->label('Diterima Pada')
->date('l, d F Y H:i'), ->date('l, d F Y H:i')
->icon('heroicon-o-calendar'),
]), ]),
]) ])
->columnSpanFull(), ->columnSpanFull(),
Section::make('Pesan') Section::make('Isi Pesan 💬')
->description('Pesan lengkap yang dikirimkan oleh pengguna.')
->icon('heroicon-o-chat-bubble-left-right')
->schema([ ->schema([
TextEntry::make('message') TextEntry::make('message')
->label('Isi Pesan') ->label('Konten Pesan')
->columnSpanFull(), ->columnSpanFull(),
]) ])
->columnSpanFull(), ->columnSpanFull(),
Section::make('Balasan') Section::make('Riwayat Balasan 📤')
->description('Detail mengenai tanggapan yang telah diberikan.')
->icon('heroicon-o-paper-airplane')
->schema([ ->schema([
TextEntry::make('repliedBy.name') TextEntry::make('repliedBy.name')
->label('Dibalas Oleh') ->label('Dibalas Oleh')
->placeholder('Belum dibalas'), ->placeholder('Belum dibalas')
->icon('heroicon-o-user-circle'),
TextEntry::make('replied_at') TextEntry::make('replied_at')
->label('Dibalas pada') ->label('Waktu Balasan')
->date('l, d F Y H:i') ->date('l, d F Y H:i')
->placeholder('Belum dibalas'), ->placeholder('Belum dibalas')
->icon('heroicon-o-clock'),
TextEntry::make('reply_message') TextEntry::make('reply_message')
->label('Pesan Balasan') ->label('Isi Balasan')
->placeholder('Belum dibalas'), ->placeholder('Belum dibalas')
->columnSpanFull(),
]) ])
->columnSpanFull() ->columnSpanFull()
->visible(fn (Contact $record): bool => $record->replied_at !== null), ->visible(fn (Contact $record): bool => $record->replied_at !== null),

View File

@ -15,7 +15,6 @@
use Filament\Schemas\Components\Utilities\Get; use Filament\Schemas\Components\Utilities\Get;
use Filament\Schemas\Components\Utilities\Set; use Filament\Schemas\Components\Utilities\Set;
use Filament\Schemas\Schema; use Filament\Schemas\Schema;
use Filament\Support\Icons\Heroicon;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
class CooperationForm class CooperationForm
@ -24,9 +23,12 @@ public static function configure(Schema $schema): Schema
{ {
return $schema return $schema
->components([ ->components([
Section::make([ Section::make('Detail Kerja Sama 🤝')
->description('Lengkapi informasi mengenai judul, durasi, dan media yang terlibat.')
->icon('heroicon-o-hand-raised')
->schema([
TextInput::make('title') TextInput::make('title')
->label('Judul') ->label('Judul Kerja Sama')
->placeholder('Publikasi Pembangunan Daerah') ->placeholder('Publikasi Pembangunan Daerah')
->autocomplete(false) ->autocomplete(false)
->autofocus() ->autofocus()
@ -36,7 +38,7 @@ public static function configure(Schema $schema): Schema
Grid::make(2) Grid::make(2)
->schema([ ->schema([
DatePicker::make('initial_submission_date') DatePicker::make('initial_submission_date')
->label('Tanggal Pengajuan Awal') ->label('Tgl Pengajuan Awal')
->placeholder(fn (): string => now()->translatedFormat('l, d F Y')) ->placeholder(fn (): string => now()->translatedFormat('l, d F Y'))
->native(false) ->native(false)
->displayFormat('l, d F Y') ->displayFormat('l, d F Y')
@ -45,7 +47,7 @@ public static function configure(Schema $schema): Schema
->reactive(), ->reactive(),
DatePicker::make('final_submission_date') DatePicker::make('final_submission_date')
->label('Tanggal Pengajuan Akhir') ->label('Tgl Pengajuan Akhir')
->placeholder(fn (): string => now()->addDays(7)->translatedFormat('l, d F Y')) ->placeholder(fn (): string => now()->addDays(7)->translatedFormat('l, d F Y'))
->native(false) ->native(false)
->displayFormat('l, d F Y') ->displayFormat('l, d F Y')
@ -55,7 +57,7 @@ public static function configure(Schema $schema): Schema
]), ]),
Select::make('partner_media_ids') Select::make('partner_media_ids')
->label('Media') ->label('Media Rekanan')
->relationship('partnerMedia', 'name', fn (Builder $query): Builder => $query->verified()) ->relationship('partnerMedia', 'name', fn (Builder $query): Builder => $query->verified())
->multiple() ->multiple()
->preload() ->preload()
@ -63,11 +65,11 @@ public static function configure(Schema $schema): Schema
->native(false) ->native(false)
->required() ->required()
->selectablePlaceholder(false) ->selectablePlaceholder(false)
->helperText('Pilih media yang akan diajak kerja sama.') ->helperText('Pilih satu atau lebih media yang akan diajak kerja sama.')
->suffixAction( ->suffixAction(
Action::make('select_all') Action::make('select_all')
->label('Select All') ->label('Pilih Semua')
->icon(Heroicon::OutlinedCheckCircle) ->icon('heroicon-o-check-circle')
->action(function (Set $set): void { ->action(function (Set $set): void {
$allMediaIds = PartnerMedia::verified()->pluck('id')->toArray(); $allMediaIds = PartnerMedia::verified()->pluck('id')->toArray();
$set('partner_media_ids', $allMediaIds); $set('partner_media_ids', $allMediaIds);
@ -75,8 +77,8 @@ public static function configure(Schema $schema): Schema
), ),
Textarea::make('description') Textarea::make('description')
->label('Deskripsi') ->label('Deskripsi Kerja Sama')
->placeholder('...') ->placeholder('Jelaskan detail lingkup kerja sama di sini...')
->required() ->required()
->rows(5) ->rows(5)
->maxLength(65535) ->maxLength(65535)
@ -84,9 +86,12 @@ public static function configure(Schema $schema): Schema
]) ])
->columnSpan(2), ->columnSpan(2),
Section::make([ Section::make('Lampiran & Media 🖼️')
->description('Unggah banner promosi dan template untuk pengajuan.')
->icon('heroicon-o-paper-clip')
->schema([
SpatieMediaLibraryFileUpload::make('banner') SpatieMediaLibraryFileUpload::make('banner')
->label('Banner') ->label('Banner Promosi')
->disk(config('filesystems.default')) ->disk(config('filesystems.default'))
->acceptedFileTypes(['image/*']) ->acceptedFileTypes(['image/*'])
->maxSize(1024 * 3) ->maxSize(1024 * 3)
@ -99,13 +104,13 @@ public static function configure(Schema $schema): Schema
->image(), ->image(),
AdvancedFileUpload::make('proposal_template') AdvancedFileUpload::make('proposal_template')
->label('Template Pengajuan') ->label('Template Pengajuan (PDF)')
->disk(config('filesystems.default')) ->disk(config('filesystems.default'))
->acceptedFileTypes(['application/pdf']) ->acceptedFileTypes(['application/pdf'])
->maxSize(1024 * 10) ->maxSize(1024 * 10)
->directory(fn (): string => 'cooperations/proposal-template/'.now()->toDateString()) ->directory(fn (): string => 'cooperations/proposal-template/'.now()->toDateString())
->required(), ->required(),
]), ])->columnSpan(1),
]) ])
->columns(3); ->columns(3);
} }

View File

@ -19,7 +19,6 @@
use Filament\Actions\ViewAction; use Filament\Actions\ViewAction;
use Filament\Infolists\Components\TextEntry; use Filament\Infolists\Components\TextEntry;
use Filament\Resources\Resource; use Filament\Resources\Resource;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema; use Filament\Schemas\Schema;
use Filament\Support\Icons\Heroicon; use Filament\Support\Icons\Heroicon;
use Filament\Tables\Columns\TextColumn; use Filament\Tables\Columns\TextColumn;
@ -58,8 +57,6 @@ public static function getNavigationBadge(): ?string
public static function infolist(Schema $schema): Schema public static function infolist(Schema $schema): Schema
{ {
return $schema return $schema
->schema([
Section::make('Perbandingan Data')
->schema([ ->schema([
TextEntry::make('comparison') TextEntry::make('comparison')
->hiddenLabel() ->hiddenLabel()
@ -185,7 +182,6 @@ public static function infolist(Schema $schema): Schema
->implode(''); ->implode('');
}) })
->columnSpanFull(), ->columnSpanFull(),
]),
]) ])
->columns(1); ->columns(1);
} }

View File

@ -20,11 +20,10 @@
use Filament\Actions\DeleteBulkAction; use Filament\Actions\DeleteBulkAction;
use Filament\Actions\ForceDeleteBulkAction; use Filament\Actions\ForceDeleteBulkAction;
use Filament\Actions\RestoreBulkAction; use Filament\Actions\RestoreBulkAction;
use Filament\Forms\Components\Group;
use Filament\Forms\Components\Textarea; use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput; use Filament\Forms\Components\TextInput;
use Filament\Resources\Resource; use Filament\Resources\Resource;
use Filament\Schemas\Components\Group;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema; use Filament\Schemas\Schema;
use Filament\Support\Icons\Heroicon; use Filament\Support\Icons\Heroicon;
use Filament\Tables\Columns\TextColumn; use Filament\Tables\Columns\TextColumn;
@ -78,7 +77,7 @@ public static function form(Schema $schema): Schema
return $schema return $schema
->components([ ->components([
TextInput::make('name') TextInput::make('name')
->label('Nama') ->label('Nama Lengkap')
->placeholder('John Doe') ->placeholder('John Doe')
->autocomplete(false) ->autocomplete(false)
->autofocus() ->autofocus()
@ -91,7 +90,8 @@ public static function form(Schema $schema): Schema
->autocomplete(false) ->autocomplete(false)
->required() ->required()
->maxLength(254) ->maxLength(254)
->email(), ->email()
->prefixIcon('heroicon-o-envelope'),
TextInput::make('phone_number') TextInput::make('phone_number')
->label('Nomor Telepon') ->label('Nomor Telepon')
@ -99,41 +99,39 @@ public static function form(Schema $schema): Schema
->autocomplete(false) ->autocomplete(false)
->required() ->required()
->maxLength(20) ->maxLength(20)
->tel(), ->tel()
->prefixIcon('heroicon-o-phone'),
Group::make() Group::make()
->schema( ->schema(
collect($documents) collect($documents)
->map(function (array $doc): Section { ->map(function (array $doc): array {
return Section::make($doc['title']) return [
->schema([
TextInput::make($doc['text_name']) TextInput::make($doc['text_name'])
->hiddenLabel() ->label('Nomor Identitas ('.$doc['title'].')')
->placeholder($doc['placeholder']) ->placeholder($doc['placeholder'])
->autocomplete(false) ->autocomplete(false)
->required() ->required()
->maxLength($doc['max']), ->maxLength($doc['max']),
AdvancedFileUpload::make($doc['file_name']) AdvancedFileUpload::make($doc['file_name'])
->hiddenLabel() ->label('File Pendukung ('.$doc['title'].') (PDF)')
->disk(config('filesystems.default')) ->disk(config('filesystems.default'))
->acceptedFileTypes($doc['accept']) ->acceptedFileTypes($doc['accept'])
->directory(fn (): string => 'journalists/'.$doc['folder'].now()->toDateString()) ->directory(fn (): string => 'journalists/'.$doc['folder'].now()->toDateString())
->maxSize($doc['max_size']) ->maxSize($doc['max_size'])
->required(), ->required(),
]); ];
}) })
->flatten()
->toArray() ->toArray()
), ),
Section::make('Alasan Perubahan')
->schema([
Textarea::make('change_reason') Textarea::make('change_reason')
->label('Alasan') ->label('Alasan Perubahan')
->placeholder('Jelaskan alasan perubahan data ini...') ->placeholder('Jelaskan alasan perubahan data ini...')
->rows(3) ->rows(3)
->required(), ->required()
])
->visible(fn () => auth()->user()->company?->verificationRequest?->status === VerificationStatus::APPROVED && auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value)), ->visible(fn () => auth()->user()->company?->verificationRequest?->status === VerificationStatus::APPROVED && auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value)),
]) ])
->columns(1); ->columns(1);

View File

@ -51,7 +51,7 @@ public static function form(Schema $schema): Schema
return $schema return $schema
->components([ ->components([
TextInput::make('name') TextInput::make('name')
->label('Nama') ->label('Nama Kategori')
->placeholder('Ekonomi') ->placeholder('Ekonomi')
->autocomplete(false) ->autocomplete(false)
->autofocus() ->autofocus()

View File

@ -51,7 +51,7 @@ public static function form(Schema $schema): Schema
return $schema return $schema
->components([ ->components([
TextInput::make('name') TextInput::make('name')
->label('Nama') ->label('Nama Klasifikasi')
->placeholder('Pelaporan') ->placeholder('Pelaporan')
->autocomplete(false) ->autocomplete(false)
->autofocus() ->autofocus()

View File

@ -51,7 +51,7 @@ public static function form(Schema $schema): Schema
return $schema return $schema
->components([ ->components([
TextInput::make('name') TextInput::make('name')
->label('Nama') ->label('Nama OPD')
->placeholder('Dinas Komunikasi dan Informatika') ->placeholder('Dinas Komunikasi dan Informatika')
->autocomplete(false) ->autocomplete(false)
->autofocus() ->autofocus()
@ -59,6 +59,7 @@ public static function form(Schema $schema): Schema
->maxLength(100), ->maxLength(100),
TextInput::make('alias') TextInput::make('alias')
->label('Alias')
->placeholder('Diskominfo') ->placeholder('Diskominfo')
->autocomplete(false) ->autocomplete(false)
->required() ->required()

View File

@ -51,7 +51,7 @@ public static function form(Schema $schema): Schema
return $schema return $schema
->components([ ->components([
TextInput::make('name') TextInput::make('name')
->label('Nama') ->label('Nama Lokus')
->placeholder('Purwakarta') ->placeholder('Purwakarta')
->autocomplete(false) ->autocomplete(false)
->autofocus() ->autofocus()

View File

@ -54,7 +54,7 @@ public static function form(Schema $schema): Schema
return $schema return $schema
->components([ ->components([
Select::make('classification_id') Select::make('classification_id')
->label('Klasifikasi') ->label('Klasifikasi Utama')
->options(Classification::query()->active()->pluck('name', 'id')) ->options(Classification::query()->active()->pluck('name', 'id'))
->searchable() ->searchable()
->native(false) ->native(false)
@ -63,7 +63,7 @@ public static function form(Schema $schema): Schema
->autofocus(), ->autofocus(),
TextInput::make('name') TextInput::make('name')
->label('Nama') ->label('Nama Sub-Klasifikasi')
->placeholder('Korupsi') ->placeholder('Korupsi')
->autocomplete(false) ->autocomplete(false)
->required() ->required()

View File

@ -54,7 +54,7 @@ public static function form(Schema $schema): Schema
return $schema return $schema
->components([ ->components([
Select::make('location_id') Select::make('location_id')
->label('Lokus') ->label('Lokus Utama')
->options(Location::query()->pluck('name', 'id')) ->options(Location::query()->pluck('name', 'id'))
->searchable() ->searchable()
->native(false) ->native(false)
@ -63,8 +63,8 @@ public static function form(Schema $schema): Schema
->autofocus(), ->autofocus(),
TextInput::make('name') TextInput::make('name')
->label('Nama') ->label('Nama Sub-Lokus')
->placeholder('Nagri Kaler') ->placeholder('Kecamatan Purwakarta')
->autocomplete(false) ->autocomplete(false)
->required() ->required()
->maxLength(50), ->maxLength(50),

View File

@ -50,7 +50,7 @@ public static function form(Schema $schema): Schema
return $schema return $schema
->components([ ->components([
TextInput::make('name') TextInput::make('name')
->label('Nama') ->label('Nama Tema')
->placeholder('Pendidikan') ->placeholder('Pendidikan')
->autocomplete(false) ->autocomplete(false)
->autofocus() ->autofocus()

View File

@ -21,6 +21,7 @@
use Filament\Forms\Components\TextInput; use Filament\Forms\Components\TextInput;
use Filament\Notifications\Notification; use Filament\Notifications\Notification;
use Filament\Resources\Resource; use Filament\Resources\Resource;
use Filament\Schemas\Components\Grid;
use Filament\Schemas\Schema; use Filament\Schemas\Schema;
use Filament\Support\Enums\Width; use Filament\Support\Enums\Width;
use Filament\Support\Icons\Heroicon; use Filament\Support\Icons\Heroicon;
@ -55,13 +56,15 @@ public static function form(Schema $schema): Schema
return $schema return $schema
->components([ ->components([
TextInput::make('name') TextInput::make('name')
->label('Nama') ->label('Nama Lengkap')
->placeholder('John Doe') ->placeholder('John Doe')
->autocomplete(false) ->autocomplete(false)
->autofocus() ->autofocus()
->required() ->required()
->maxLength(100), ->maxLength(100),
Grid::make(1)
->schema([
TextInput::make('email') TextInput::make('email')
->label('Alamat Surel') ->label('Alamat Surel')
->placeholder('johndoe@example.com') ->placeholder('johndoe@example.com')
@ -69,7 +72,8 @@ public static function form(Schema $schema): Schema
->required() ->required()
->maxLength(254) ->maxLength(254)
->email() ->email()
->unique(ignoreRecord: true), ->unique(ignoreRecord: true)
->prefixIcon('heroicon-o-envelope'),
TextInput::make('username') TextInput::make('username')
->label('Nama Pengguna') ->label('Nama Pengguna')
@ -79,7 +83,8 @@ public static function form(Schema $schema): Schema
->minLength(5) ->minLength(5)
->maxLength(20) ->maxLength(20)
->regex('/^[a-zA-Z0-9_.-]+$/') ->regex('/^[a-zA-Z0-9_.-]+$/')
->unique(ignoreRecord: true), ->unique(ignoreRecord: true)
->prefixIcon('heroicon-o-at-symbol'),
Select::make('roles') Select::make('roles')
->label('Peran') ->label('Peran')
@ -94,6 +99,7 @@ public static function form(Schema $schema): Schema
Hidden::make('password') Hidden::make('password')
->default(fn (): string => config('auth.password_default')) ->default(fn (): string => config('auth.password_default'))
->visibleOn('create'), ->visibleOn('create'),
]),
]) ])
->columns(1); ->columns(1);
} }

View File

@ -20,9 +20,12 @@ public static function configure(Schema $schema): Schema
{ {
return $schema return $schema
->components([ ->components([
Section::make([ Section::make('Informasi Konten 📝')
->description('Lengkapi detail judul, tautan, dan jenis konten Anda.')
->icon('heroicon-o-document-text')
->schema([
TextInput::make('title') TextInput::make('title')
->label('Judul') ->label('Judul Konten')
->placeholder('Reels Kerja Sama DPMPTSP') ->placeholder('Reels Kerja Sama DPMPTSP')
->autocomplete(false) ->autocomplete(false)
->autofocus() ->autofocus()
@ -30,7 +33,7 @@ public static function configure(Schema $schema): Schema
->maxLength(1000), ->maxLength(1000),
TextInput::make('link') TextInput::make('link')
->label('Tautan') ->label('Tautan (URL)')
->placeholder('https://www.pwknews.com') ->placeholder('https://www.pwknews.com')
->autocomplete(false) ->autocomplete(false)
->nullable() ->nullable()
@ -40,9 +43,10 @@ public static function configure(Schema $schema): Schema
Grid::make(2) Grid::make(2)
->schema([ ->schema([
Select::make('type') Select::make('type')
->label('Tipe') ->label('Tipe Konten')
->options(ContentType::options()) ->options(ContentType::options())
->native(false) ->native(false)
->required()
->in(implode(',', array_column(ContentType::cases(), 'value'))), ->in(implode(',', array_column(ContentType::cases(), 'value'))),
Select::make('channel') Select::make('channel')
@ -68,7 +72,10 @@ public static function configure(Schema $schema): Schema
]), ]),
])->columnSpan(2), ])->columnSpan(2),
Section::make([ Section::make('Klasifikasi & Lampiran 📁')
->description('Pilih klasifikasi yang sesuai dan unggah gambar pendukung.')
->icon('heroicon-o-folder-open')
->schema([
Select::make('classification_id') Select::make('classification_id')
->label('Klasifikasi') ->label('Klasifikasi')
->relationship('classification', 'name', function (Builder $query): Builder { ->relationship('classification', 'name', function (Builder $query): Builder {
@ -79,7 +86,7 @@ public static function configure(Schema $schema): Schema
->required(), ->required(),
SpatieMediaLibraryFileUpload::make('image') SpatieMediaLibraryFileUpload::make('image')
->label('Gambar') ->label('Gambar Konten')
->disk(config('filesystems.default')) ->disk(config('filesystems.default'))
->acceptedFileTypes(['image/*']) ->acceptedFileTypes(['image/*'])
->maxSize(1024 * 3) ->maxSize(1024 * 3)
@ -90,7 +97,7 @@ public static function configure(Schema $schema): Schema
]) ])
->image() ->image()
->required(), ->required(),
]), ])->columnSpan(1),
]) ])
->columns(3); ->columns(3);
} }

View File

@ -18,7 +18,10 @@ public static function configure(Schema $schema): Schema
{ {
return $schema return $schema
->components([ ->components([
Section::make([ Section::make('Identifikasi Isu 🔍')
->description('Hubungkan dengan berita monitoring dan tentukan lokasi isu.')
->icon('heroicon-o-magnifying-glass')
->schema([
Select::make('media_monitoring_id') Select::make('media_monitoring_id')
->label('Monitoring Media') ->label('Monitoring Media')
->relationship( ->relationship(
@ -33,7 +36,7 @@ public static function configure(Schema $schema): Schema
->helperText('Jika judul berita dari monitoring media tidak ada di opsi, silakan lakukan pencarian.'), ->helperText('Jika judul berita dari monitoring media tidak ada di opsi, silakan lakukan pencarian.'),
Select::make('departments') Select::make('departments')
->label('Perangkat Daerah') ->label('Perangkat Daerah Terkait')
->relationship('departments', 'name', fn (Builder $query): Builder => $query->active()) ->relationship('departments', 'name', fn (Builder $query): Builder => $query->active())
->searchable() ->searchable()
->preload() ->preload()
@ -62,22 +65,25 @@ public static function configure(Schema $schema): Schema
]), ]),
RichEditor::make('description') RichEditor::make('description')
->label('Keterangan') ->label('Keterangan Isu')
->placeholder('...') ->placeholder('Jelaskan detail isu yang berkembang...')
->required() ->required()
->columnSpanFull(), ->columnSpanFull(),
])->columnSpan(2), ])->columnSpan(2),
Section::make([ Section::make('Sentimen & Klasifikasi 📊')
->description('Tentukan sentimen isu, respon, dan kategori klasifikasinya.')
->icon('heroicon-o-chart-bar')
->schema([
Select::make('issue') Select::make('issue')
->label('Isu') ->label('Sentimen Isu')
->options(IssueSentiment::options()) ->options(IssueSentiment::options())
->required() ->required()
->native(false) ->native(false)
->in(implode(',', array_column(IssueSentiment::cases(), 'value'))), ->in(implode(',', array_column(IssueSentiment::cases(), 'value'))),
Select::make('response') Select::make('response')
->label('Respon') ->label('Respon Pemerintah')
->options(IssueSentiment::options()) ->options(IssueSentiment::options())
->required() ->required()
->native(false) ->native(false)
@ -96,7 +102,7 @@ public static function configure(Schema $schema): Schema
Select::make('sub_classification_id') Select::make('sub_classification_id')
->label('Sub Klasifikasi') ->label('Sub Klasifikasi')
->relationship('subClassification', 'name', fn (Builder $query, Get $get): Builder => $query->where('classification_id', $get('classification_id'))->active()) ->relationship('subClassification', 'name', fn (Builder $query, Get $get): Builder => $query->where('classification_id', $get('location_id'))->active())
->searchable() ->searchable()
->preload() ->preload()
->required(), ->required(),

View File

@ -19,7 +19,10 @@ public static function configure(Schema $schema): Schema
{ {
return $schema return $schema
->components([ ->components([
Section::make([ Section::make('Detail Berita 📰')
->description('Masukkan informasi lengkap mengenai pemberitaan media.')
->icon('heroicon-o-newspaper')
->schema([
TextInput::make('media_name') TextInput::make('media_name')
->label('Nama Media') ->label('Nama Media')
->placeholder('PWK News') ->placeholder('PWK News')
@ -29,7 +32,7 @@ public static function configure(Schema $schema): Schema
->maxLength(50), ->maxLength(50),
TextInput::make('title') TextInput::make('title')
->label('Judul') ->label('Judul Berita')
->placeholder('Berita Purwakarta Hari Ini') ->placeholder('Berita Purwakarta Hari Ini')
->autocomplete(false) ->autocomplete(false)
->required() ->required()
@ -53,24 +56,27 @@ public static function configure(Schema $schema): Schema
]), ]),
TextInput::make('link') TextInput::make('link')
->label('Tautan') ->label('Tautan (URL)')
->placeholder('https://www.pwknews.com') ->placeholder('https://www.pwknews.com')
->autocomplete(false) ->autocomplete(false)
->nullable() ->nullable()
->url(), ->url(),
RichEditor::make('quote') RichEditor::make('quote')
->label('Kutipan') ->label('Kutipan Penting')
->placeholder('....') ->placeholder('Masukkan kutipan penting dari berita...')
->nullable(), ->nullable(),
RichEditor::make('content') RichEditor::make('content')
->label('Konten') ->label('Konten Berita')
->placeholder('....') ->placeholder('Tuliskan isi berita di sini...')
->required(), ->required(),
])->columnSpan(2), ])->columnSpan(2),
Section::make([ Section::make('Kategori & Metadata 🏷️')
->description('Tentukan kategori berita dan informasi tambahan lainnya.')
->icon('heroicon-o-tag')
->schema([
Select::make('channel') Select::make('channel')
->label('Kanal') ->label('Kanal')
->options(Channel::options()) ->options(Channel::options())
@ -110,7 +116,7 @@ public static function configure(Schema $schema): Schema
->maxLength(100), ->maxLength(100),
SpatieMediaLibraryFileUpload::make('image') SpatieMediaLibraryFileUpload::make('image')
->label('Gambar') ->label('Gambar Utama')
->disk(config('filesystems.default')) ->disk(config('filesystems.default'))
->acceptedFileTypes(['image/*']) ->acceptedFileTypes(['image/*'])
->maxSize(1024 * 3) ->maxSize(1024 * 3)
@ -121,7 +127,7 @@ public static function configure(Schema $schema): Schema
]) ])
->image() ->image()
->required(), ->required(),
]), ])->columnSpan(1),
]) ])
->columns(3); ->columns(3);
} }

View File

@ -54,22 +54,21 @@ public static function form(Schema $schema): Schema
return $schema return $schema
->components([ ->components([
TextInput::make('title') TextInput::make('title')
->label('Judul') ->label('Judul Pengumuman')
->placeholder('Pencairan Dana Kerja Sama Media') ->placeholder('Pencairan Dana Kerja Sama Media')
->autocomplete(false) ->autocomplete(false)
->autofocus() ->autofocus()
->required() ->required()
->maxLength(200)
->columnSpanFull(), ->columnSpanFull(),
RichEditor::make('content') RichEditor::make('content')
->label('Konten') ->label('Isi Pengumuman')
->placeholder('...') ->placeholder('Tuliskan detail pengumuman di sini...')
->required() ->required()
->columnSpanFull(), ->columnSpanFull(),
Radio::make('type') Radio::make('type')
->label('Tipe') ->label('Tipe Pengumuman')
->options(AnnouncementType::class) ->options(AnnouncementType::class)
->required() ->required()
->default(AnnouncementType::PUBLIC->value) ->default(AnnouncementType::PUBLIC->value)
@ -77,20 +76,19 @@ public static function form(Schema $schema): Schema
->inline(), ->inline(),
CheckboxList::make('partnerMedia') CheckboxList::make('partnerMedia')
->label('Kirim Kepada') ->label('Penerima Khusus')
->relationship('partnerMedia', 'name', fn (Builder $query): Builder => $query->verified()) ->relationship('partnerMedia', 'name', fn (Builder $query): Builder => $query->verified())
->visible(fn (Get $get): bool => in_array($get('type'), [AnnouncementType::COMPANY, AnnouncementType::COMPANY->value])) ->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])) ->required(fn (Get $get): bool => in_array($get('type'), [AnnouncementType::COMPANY, AnnouncementType::COMPANY->value]))
->searchable() ->searchable()
->noSearchResultsMessage('Tidak ada media yang ditemukan.') ->noSearchResultsMessage('Tidak ada media yang ditemukan.')
->helperText('Pilih media yang akan menerima pengumuman ini') ->helperText('Pilih media yang akan menerima pengumuman ini.')
->columnSpanFull() ->columnSpanFull()
->bulkToggleable() ->bulkToggleable()
->selectAllAction( ->selectAllAction(
fn (Action $action): Action => $action->label('Pilih Semua Media'), fn (Action $action): Action => $action->label('Pilih Semua Media'),
) )
->dehydrated(), ->dehydrated(),
]) ])
->columns(1); ->columns(1);
} }

View File

@ -25,31 +25,37 @@ public static function configure(Schema $schema): Schema
Hidden::make('author_id') Hidden::make('author_id')
->default(auth()->id()), ->default(auth()->id()),
Section::make([ Section::make('Konten Berita ✍️')
->description('Tuliskan judul, ringkasan, dan isi lengkap berita Anda.')
->icon('heroicon-o-pencil-square')
->schema([
TextInput::make('title') TextInput::make('title')
->label('Judul') ->label('Judul Berita')
->placeholder('Berita Purwakarta Hari Ini') ->placeholder('Berita Purwakarta Hari Ini')
->autocomplete(false) ->autocomplete(false)
->autofocus() ->autofocus()
->required() ->required()
->maxLength(200), ->maxLength(200),
RichEditor::make('content') RichEditor::make('excerpt')
->label('Konten') ->label('Ringkasan (Excerpt)')
->placeholder('...') ->placeholder('Berikan ringkasan singkat berita...')
->required() ->required()
->columnSpanFull(), ->columnSpanFull(),
RichEditor::make('excerpt') RichEditor::make('content')
->label('Ringkasan') ->label('Isi Lengkap Berita')
->placeholder('...') ->placeholder('Tuliskan konten berita secara mendetail...')
->required() ->required()
->columnSpanFull(), ->columnSpanFull(),
])->columnSpan(2), ])->columnSpan(2),
Section::make([ Section::make('Kategori & Publikasi 🏷️')
->description('Tentukan kategori, tautan media, dan status publikasi.')
->icon('heroicon-o-tag')
->schema([
TextInput::make('link') TextInput::make('link')
->label('Tautan') ->label('Tautan Media (Opsional)')
->placeholder('https://www.pwknews.com') ->placeholder('https://www.pwknews.com')
->autocomplete(false) ->autocomplete(false)
->nullable() ->nullable()
@ -67,6 +73,7 @@ public static function configure(Schema $schema): Schema
->required(), ->required(),
TagsInput::make('tags') TagsInput::make('tags')
->label('Tag Berita')
->reactive() ->reactive()
->afterStateHydrated(function ($component, $state, $record): void { ->afterStateHydrated(function ($component, $state, $record): void {
if (! $record) { if (! $record) {
@ -79,7 +86,7 @@ public static function configure(Schema $schema): Schema
->helperText('Tekan enter untuk menambahkan tag.'), ->helperText('Tekan enter untuk menambahkan tag.'),
Radio::make('status') Radio::make('status')
->label('Status') ->label('Status Publikasi')
->required() ->required()
->options(NewsStatus::options()) ->options(NewsStatus::options())
->default(NewsStatus::PUBLISHED->value) ->default(NewsStatus::PUBLISHED->value)
@ -94,11 +101,8 @@ public static function configure(Schema $schema): Schema
}) })
->rules(['in:'.implode(',', NewsStatus::values())]), ->rules(['in:'.implode(',', NewsStatus::values())]),
Hidden::make('published_at')
->default(now()),
SpatieMediaLibraryFileUpload::make('thumbnail') SpatieMediaLibraryFileUpload::make('thumbnail')
->label('Thumbnail') ->label('Thumbnail Utama')
->disk(config('filesystems.default')) ->disk(config('filesystems.default'))
->acceptedFileTypes(['image/*']) ->acceptedFileTypes(['image/*'])
->maxSize(1024 * 3) ->maxSize(1024 * 3)
@ -109,7 +113,7 @@ public static function configure(Schema $schema): Schema
]) ])
->image() ->image()
->required(), ->required(),
]), ])->columnSpan(1),
]) ])
->columns(3); ->columns(3);
} }

View File

@ -69,7 +69,7 @@ class="p-4 rounded-xl bg-warning-50 dark:bg-warning-500/10 border border-warning
</p> </p>
<div class="mt-3"> <div class="mt-3">
<x-filament::button tag="a" :href="$progress['editUrl']" size="sm" color="warning" <x-filament::button tag="a" :href="$progress['editUrl']" size="sm" color="warning"
icon="heroicon-m-pencil-square"> icon="heroicon-o-pencil-square">
Perbaiki Data Perbaiki Data
</x-filament::button> </x-filament::button>
</div> </div>
@ -154,7 +154,7 @@ class="p-4 rounded-xl bg-success-50 dark:bg-success-500/10 border border-success
</p> </p>
<div class="mt-3"> <div class="mt-3">
<x-filament::button tag="a" :href="$progress['editUrl']" size="sm" color="gray" <x-filament::button tag="a" :href="$progress['editUrl']" size="sm" color="gray"
icon="heroicon-m-plus"> icon="heroicon-o-plus">
Lengkapi Data Lengkapi Data
</x-filament::button> </x-filament::button>
</div> </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"> <div class="flex items-center gap-2">
@if ($hasEntity && !$progress['isPending'] && !$progress['isApproved']) @if ($hasEntity && !$progress['isPending'] && !$progress['isApproved'])
<x-filament::button tag="a" :href="$progress['editUrl']" color="gray" size="sm" <x-filament::button tag="a" :href="$progress['editUrl']" color="gray" size="sm"
icon="heroicon-m-pencil"> icon="heroicon-o-pencil">
Edit Data Edit Data
</x-filament::button> </x-filament::button>
@endif @endif

View File

@ -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"> <div class="flex flex-wrap items-center gap-2">
{{-- View Detail Button --}} {{-- View Detail Button --}}
@if ($verification['company']['detailUrl']) @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']"> :href="$verification['company']['detailUrl']">
Detail Detail
</x-filament::button> </x-filament::button>