diff --git a/app-modules/panel-app/resources/views/components/profile-media-header.blade.php b/app-modules/panel-app/resources/views/components/profile-media-header.blade.php
index d1057003..e4fe4c21 100644
--- a/app-modules/panel-app/resources/views/components/profile-media-header.blade.php
+++ b/app-modules/panel-app/resources/views/components/profile-media-header.blade.php
@@ -2,7 +2,8 @@
'avatarPreviewUrl' => null,
'coverPreviewUrl' => null,
'initials' => '',
- 'name' => ''
+ 'name' => '',
+ 'birthdateForm' => null,
])
@@ -100,7 +101,7 @@ class="absolute -top-1 -right-1 z-20 rounded-full bg-red-500 p-1 text-white shad
{{-- Nickname + Birthdate --}}
-
diff --git a/app-modules/panel-app/resources/views/pages/profile.blade.php b/app-modules/panel-app/resources/views/pages/profile.blade.php
index e1a495de..e2403e56 100644
--- a/app-modules/panel-app/resources/views/pages/profile.blade.php
+++ b/app-modules/panel-app/resources/views/pages/profile.blade.php
@@ -11,7 +11,8 @@
'avatarPreviewUrl' => $this->avatarPreviewUrl,
'coverPreviewUrl' => $this->coverPreviewUrl,
'initials' => $this->initials,
- 'name' => auth()->user()->name
+ 'name' => auth()->user()->name,
+ 'birthdateForm' => $this->birthdateForm,
])
{{ $this->form }}
diff --git a/app-modules/panel-app/src/Pages/ProfilePage.php b/app-modules/panel-app/src/Pages/ProfilePage.php
index 49108718..cfc0a937 100644
--- a/app-modules/panel-app/src/Pages/ProfilePage.php
+++ b/app-modules/panel-app/src/Pages/ProfilePage.php
@@ -46,6 +46,7 @@
/**
* @property-read Schema $form
+ * @property-read Schema $birthdateForm
*/
class ProfilePage extends Page
{
@@ -54,6 +55,9 @@ class ProfilePage extends Page
/** @var array|null */
public ?array $data = [];
+ /** @var array|null */
+ public ?array $birthdateData = [];
+
protected static string|null|BackedEnum $navigationIcon = 'heroicon-o-user-circle';
protected static ?string $title = 'Profile';
@@ -72,7 +76,6 @@ public function mount(): void
$this->form->fill([
'nickname' => $profile->nickname,
- 'birthdate' => $profile->birthdate?->format('Y-m-d'),
'headline' => $profile->headline,
'seniority_level' => $profile->seniority_level,
'years_experience' => $profile->years_experience,
@@ -91,6 +94,27 @@ public function mount(): void
$profile->preferences->employmentTypes,
),
]);
+
+ $this->birthdateForm->fill([
+ 'birthdate' => $profile->birthdate?->format('Y-m-d'),
+ ]);
+ }
+
+ public function birthdateForm(Schema $schema): Schema
+ {
+ return $schema
+ ->components([
+ DatePicker::make('birthdate')
+ ->label(__('panel-app::profile.fields.birthdate'))
+ ->native(condition: false)
+ ->displayFormat('d/m/Y')
+ ->format('Y-m-d')
+ ->minDate(now()->subYears(120))
+ ->maxDate(now()),
+ ])
+ // Own state path: fill() replaces the whole path, so sharing `data` with
+ // the main form wiped headline/seniority/etc. on mount.
+ ->statePath('birthdateData');
}
public function form(Schema $schema): Schema
@@ -387,6 +411,7 @@ public function form(Schema $schema): Schema
public function save(): void
{
+ $birthdateData = $this->birthdateForm->getState();
$formData = $this->form->getState();
$profile = $this->getRecord();
@@ -394,7 +419,7 @@ public function save(): void
$dto = UpsertProfileDTO::fromArray([
'nickname' => $this->data['nickname'] ?? null,
- 'birthdate' => $this->data['birthdate'] ?? null,
+ 'birthdate' => $birthdateData['birthdate'] ?? null,
'about' => $formData['about'] ?? null,
'headline' => $formData['headline'] ?? null,
'seniority_level' => $formData['seniority_level'] ?? null,
diff --git a/app-modules/panel-app/tests/Feature/ProfilePageTest.php b/app-modules/panel-app/tests/Feature/ProfilePageTest.php
index aa6fcff6..0014d8e3 100644
--- a/app-modules/panel-app/tests/Feature/ProfilePageTest.php
+++ b/app-modules/panel-app/tests/Feature/ProfilePageTest.php
@@ -95,6 +95,20 @@
->and($this->profile->about)->toBe('Dev PHP apaixonado por Laravel');
});
+test('profile page saves birthdate from date picker', function (): void {
+ livewire(ProfilePage::class)
+ ->fillForm([
+ 'birthdate' => '1996-02-15',
+ ], 'birthdateForm')
+ ->call('save')
+ ->assertHasNoFormErrors([], 'birthdateForm')
+ ->assertNotified();
+
+ $this->profile->refresh();
+
+ expect($this->profile->birthdate?->format('Y-m-d'))->toBe('1996-02-15');
+});
+
test('profile page saves social links from repeater', function (): void {
livewire(ProfilePage::class)
->fillForm([
diff --git a/resources/css/filament/app/theme.css b/resources/css/filament/app/theme.css
index 0d56f1f5..5fc7ba0e 100644
--- a/resources/css/filament/app/theme.css
+++ b/resources/css/filament/app/theme.css
@@ -69,3 +69,13 @@
.fi-sidebar {
@apply border-e border-gray-200 dark:border-white/10;
}
+
+/* Make "today" stand out in date pickers (esp. dark mode) */
+.fi-fo-date-time-picker-calendar-day.fi-fo-date-time-picker-calendar-day-today:not(.fi-selected):not(.fi-disabled) {
+ @apply font-semibold text-primary-600 ring-1 ring-inset ring-primary-500/50 dark:text-primary-300 dark:ring-primary-400/60;
+}
+
+/* Calendar suffix icon should feel clickable */
+.fi-fo-date-time-picker .fi-input-wrp-suffix {
+ @apply cursor-pointer;
+}