feat: enhance profile page with student information section and updated layout
This commit is contained in:
parent
740ebe6a7b
commit
dc1d753cbe
@ -2,92 +2,212 @@
|
|||||||
|
|
||||||
namespace App\Filament\Pages;
|
namespace App\Filament\Pages;
|
||||||
|
|
||||||
|
use App\Enums\Sex;
|
||||||
use App\Filament\Support\SystemNotification;
|
use App\Filament\Support\SystemNotification;
|
||||||
|
use Carbon\Carbon;
|
||||||
use Filament\Auth\Pages\EditProfile;
|
use Filament\Auth\Pages\EditProfile;
|
||||||
|
use Filament\Forms\Components\DatePicker;
|
||||||
|
use Filament\Forms\Components\Radio;
|
||||||
|
use Filament\Forms\Components\Textarea;
|
||||||
use Filament\Forms\Components\TextInput;
|
use Filament\Forms\Components\TextInput;
|
||||||
use Filament\Notifications\Notification;
|
use Filament\Notifications\Notification;
|
||||||
|
use Filament\Schemas\Components\Grid;
|
||||||
use Filament\Schemas\Components\Section;
|
use Filament\Schemas\Components\Section;
|
||||||
use Filament\Schemas\Components\Utilities\Get;
|
|
||||||
use Filament\Schemas\Schema;
|
use Filament\Schemas\Schema;
|
||||||
|
use Filament\Support\Enums\Width;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
use Illuminate\Validation\Rules\Password;
|
use Illuminate\Validation\Rules\Password;
|
||||||
|
|
||||||
class Profile extends EditProfile
|
class Profile extends EditProfile
|
||||||
{
|
{
|
||||||
|
public function getMaxWidth(): Width
|
||||||
|
{
|
||||||
|
return Width::FourExtraLarge;
|
||||||
|
}
|
||||||
|
|
||||||
public function form(Schema $schema): Schema
|
public function form(Schema $schema): Schema
|
||||||
{
|
{
|
||||||
return $schema
|
return $schema
|
||||||
->components([
|
->components([
|
||||||
Section::make('Akun')
|
Section::make('Akun')
|
||||||
|
->description('Kelola informasi detail akun Anda agar selalu terkini.')
|
||||||
|
->icon('heroicon-o-user')
|
||||||
->schema([
|
->schema([
|
||||||
TextInput::make('email')
|
Grid::make(2)
|
||||||
->label('Alamat Surel')
|
->schema([
|
||||||
->placeholder('johndoe@puskesmas.com')
|
TextInput::make('email')
|
||||||
->autocomplete(false)
|
->label('Alamat Surel')
|
||||||
->required()
|
->placeholder('contoh@email.com')
|
||||||
->maxLength(254)
|
->autocomplete(false)
|
||||||
->unique(ignoreRecord: true)
|
->required()
|
||||||
->email()
|
->maxLength(254)
|
||||||
->live(),
|
->unique(ignoreRecord: true)
|
||||||
|
->email()
|
||||||
|
->prefixIcon('heroicon-o-envelope')
|
||||||
|
->live(),
|
||||||
|
|
||||||
TextInput::make('username')
|
TextInput::make('username')
|
||||||
->label('Nama Pengguna')
|
->label('Nama Pengguna')
|
||||||
->placeholder('johndoe')
|
->placeholder('nama_pengguna')
|
||||||
->autocomplete(false)
|
->autocomplete(false)
|
||||||
->required()
|
->required()
|
||||||
->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'),
|
||||||
|
]),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
Section::make('Kata Sandi')
|
Section::make('Informasi Mahasiswa')
|
||||||
|
->description('Pastikan data akademik Anda sesuai dengan record sistem.')
|
||||||
|
->icon('heroicon-o-academic-cap')
|
||||||
|
->statePath('student')
|
||||||
->schema([
|
->schema([
|
||||||
TextInput::make('password')
|
TextInput::make('full_name')
|
||||||
->label(__('filament-panels::auth/pages/register.form.password.label'))
|
->label('Nama Lengkap')
|
||||||
->placeholder('********')
|
->placeholder('John Doe')
|
||||||
->password()
|
->autocomplete(false)
|
||||||
->revealable(filament()->arePasswordsRevealable())
|
->required()
|
||||||
->required(fn (Get $get) => filled($get('passwoed')) || filled($get('passwordConfirmation')))
|
->maxLength(100)
|
||||||
->rule(Password::default())
|
->minLength(3)
|
||||||
->showAllValidationMessages()
|
->autofocus()
|
||||||
->dehydrateStateUsing(fn ($state) => Hash::make($state))
|
->columnSpanFull(),
|
||||||
->same('passwordConfirmation')
|
|
||||||
->validationAttribute(__('filament-panels::auth/pages/register.form.password.validation_attribute')),
|
|
||||||
|
|
||||||
TextInput::make('passwordConfirmation')
|
Grid::make(3)
|
||||||
->label(__('filament-panels::auth/pages/register.form.password_confirmation.label'))
|
->schema([
|
||||||
->placeholder('********')
|
TextInput::make('student_number')
|
||||||
->password()
|
->label('NIM')
|
||||||
->revealable(filament()->arePasswordsRevealable())
|
->placeholder('1234567890')
|
||||||
->required(fn (Get $get) => filled($get('passwoed')) || filled($get('passwordConfirmation')))
|
->autocomplete(false)
|
||||||
->dehydrated(false),
|
->disabled()
|
||||||
|
->dehydrated(false),
|
||||||
|
|
||||||
|
TextInput::make('phone_number')
|
||||||
|
->label('Nomor Telepon')
|
||||||
|
->placeholder('0812 3456 78910')
|
||||||
|
->autocomplete(false)
|
||||||
|
->required()
|
||||||
|
->maxLength(20)
|
||||||
|
->minLength(10)
|
||||||
|
->rules(['regex:/^[0-9 ]+$/'])
|
||||||
|
->mask('9999 9999 99999'),
|
||||||
|
|
||||||
|
Radio::make('sex')
|
||||||
|
->label('Jenis Kelamin')
|
||||||
|
->options(Sex::class)
|
||||||
|
->required()
|
||||||
|
->inline(),
|
||||||
|
])
|
||||||
|
->columnSpanFull(),
|
||||||
|
|
||||||
|
Textarea::make('address')
|
||||||
|
->label('Alamat')
|
||||||
|
->placeholder('Jl. Contoh No. 123, Kota, Provinsi')
|
||||||
|
->autocomplete(false)
|
||||||
|
->rows(3)
|
||||||
|
->nullable()
|
||||||
|
->columnSpanFull(),
|
||||||
|
|
||||||
|
DatePicker::make('date_of_birth')
|
||||||
|
->label('Tanggal Lahir')
|
||||||
|
->placeholder('Pilih Tanggal')
|
||||||
|
->required()
|
||||||
|
->native(false)
|
||||||
|
->displayFormat('d F Y')
|
||||||
|
->maxDate(Carbon::now()->subYears(15)),
|
||||||
|
|
||||||
|
TextInput::make('place_of_birth')
|
||||||
|
->label('Tempat Lahir')
|
||||||
|
->placeholder('Purwakarta')
|
||||||
|
->autocomplete(false)
|
||||||
|
->required()
|
||||||
|
->maxLength(50)
|
||||||
|
->minLength(3),
|
||||||
|
])
|
||||||
|
->columns(2)
|
||||||
|
->visible(fn () => auth()->user()?->student()->exists()),
|
||||||
|
|
||||||
|
Section::make('Keamanan Akun')
|
||||||
|
->description('Perbarui kata sandi Anda secara berkala untuk menjaga keamanan akun.')
|
||||||
|
->icon('heroicon-o-lock-closed')
|
||||||
|
->schema([
|
||||||
|
Grid::make(2)
|
||||||
|
->schema([
|
||||||
|
TextInput::make('password')
|
||||||
|
->label(__('filament-panels::auth/pages/register.form.password.label'))
|
||||||
|
->placeholder('********')
|
||||||
|
->password()
|
||||||
|
->revealable(filament()->arePasswordsRevealable())
|
||||||
|
->rule(Password::default())
|
||||||
|
->showAllValidationMessages()
|
||||||
|
->dehydrated(fn ($state) => filled($state))
|
||||||
|
->dehydrateStateUsing(fn ($state) => Hash::make($state))
|
||||||
|
->same('passwordConfirmation')
|
||||||
|
->validationAttribute(__('filament-panels::auth/pages/register.form.password.validation_attribute'))
|
||||||
|
->prefixIcon('heroicon-o-lock-closed'),
|
||||||
|
|
||||||
|
TextInput::make('passwordConfirmation')
|
||||||
|
->label(__('filament-panels::auth/pages/register.form.password_confirmation.label'))
|
||||||
|
->placeholder('********')
|
||||||
|
->password()
|
||||||
|
->revealable(filament()->arePasswordsRevealable())
|
||||||
|
->dehydrated(false)
|
||||||
|
->prefixIcon('heroicon-o-lock-closed'),
|
||||||
|
]),
|
||||||
]),
|
]),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function mutateFormDataBeforeFill(array $data): array
|
||||||
|
{
|
||||||
|
$student = $this->getUser()->student;
|
||||||
|
|
||||||
|
if ($student) {
|
||||||
|
$data['student'] = $student->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
protected function handleRecordUpdate(Model $record, array $data): Model
|
protected function handleRecordUpdate(Model $record, array $data): Model
|
||||||
{
|
{
|
||||||
$shouldLogout = false;
|
$studentData = $data['student'] ?? null;
|
||||||
if (isset($data['new_password'])) {
|
unset($data['student']);
|
||||||
$data['password'] = $data['new_password'];
|
|
||||||
unset($data['new_password']);
|
|
||||||
$shouldLogout = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
$record->update($data);
|
$record->update($data);
|
||||||
|
|
||||||
|
if ($studentData && $record->student) {
|
||||||
|
$record->student->update($studentData);
|
||||||
|
} elseif ($studentData) {
|
||||||
|
$record->student()->create($studentData);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $record;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function afterSave(): void
|
||||||
|
{
|
||||||
SystemNotification::success(
|
SystemNotification::success(
|
||||||
'Profil Berhasil Diperbarui ✅',
|
'Profil Berhasil Diperbarui ✅',
|
||||||
'Data profil Anda telah berhasil disimpan dan diperbarui di dalam sistem.'
|
'Data profil Anda telah berhasil disimpan dan diperbarui di dalam sistem.'
|
||||||
)->send();
|
)->send();
|
||||||
|
|
||||||
if ($shouldLogout) {
|
if (filled($this->form->getState()['password'] ?? null)) {
|
||||||
auth()->logout();
|
filament()->auth()->logout();
|
||||||
}
|
session()->invalidate();
|
||||||
|
session()->regenerateToken();
|
||||||
|
|
||||||
return $record;
|
SystemNotification::info(
|
||||||
|
'Keamanan Akun Diperbarui 🔐',
|
||||||
|
'Anda telah mengubah kata sandi. Untuk alasan keamanan, silakan masuk kembali dengan kata sandi baru Anda.'
|
||||||
|
)->send();
|
||||||
|
|
||||||
|
$this->redirect(filament()->getLoginUrl());
|
||||||
|
} else {
|
||||||
|
$this->redirect($this->getUrl());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getSavedNotification(): ?Notification
|
protected function getSavedNotification(): ?Notification
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user