diff --git a/app/Filament/Resources/OfftimeResource.php b/app/Filament/Resources/OfftimeResource.php index b8bcd92..10c2c16 100644 --- a/app/Filament/Resources/OfftimeResource.php +++ b/app/Filament/Resources/OfftimeResource.php @@ -5,6 +5,7 @@ use App\Enums\OfftimeCategory; use App\Filament\Resources\OfftimeResource\Pages\ListOfftimes; use App\Models\Offtime; +use Carbon\Carbon; use Filament\Actions\ActionGroup; use Filament\Actions\BulkActionGroup; use Filament\Actions\CreateAction; @@ -18,6 +19,8 @@ use Filament\Resources\Resource; use Filament\Schemas\Components\Grid; use Filament\Schemas\Components\Section; +use Filament\Schemas\Components\Utilities\Get; +use Filament\Schemas\Components\Utilities\Set; use Filament\Schemas\Schema; use Filament\Support\Enums\FontFamily; use Filament\Support\Enums\Width; @@ -133,12 +136,19 @@ public static function formFields(int $columns = 12, bool $useSection = true): a ->weekStartsOnMonday() ->suffixIcon('tabler-calendar-dot') ->columnSpan($columns / 2) - ->required(), + ->required() + ->live() + ->afterStateUpdated(function (?string $state, Get $get, Set $set) { + if ($state && $get('end')) { + $set('end', Carbon::parse($state)->addDay()->toDateString()); + } + }), DatePicker::make('end') ->label(__('finished')) ->weekStartsOnMonday() ->columnSpan($columns / 2) - ->suffixIcon('tabler-calendar-pause'), + ->suffixIcon('tabler-calendar-pause') + ->after('start'), Select::make('category') ->label(__('category')) ->columnSpanFull() diff --git a/database/factories/OfftimeFactory.php b/database/factories/OfftimeFactory.php index eaf8de2..4841e58 100644 --- a/database/factories/OfftimeFactory.php +++ b/database/factories/OfftimeFactory.php @@ -26,7 +26,7 @@ class OfftimeFactory extends Factory public function definition(): array { $start = fake()->dateTimeBetween('-1 year', '+1 year'); - $end = fake()->dateTimeBetween($start, (clone $start)->modify('+5 days')); + $end = fake()->dateTimeBetween((clone $start)->modify('+1 day'), (clone $start)->modify('+5 days')); return [ 'start' => $start->format('Y-m-d'), diff --git a/tests/Feature/OfftimeResourceTest.php b/tests/Feature/OfftimeResourceTest.php index 75dad86..bf152bf 100644 --- a/tests/Feature/OfftimeResourceTest.php +++ b/tests/Feature/OfftimeResourceTest.php @@ -82,6 +82,45 @@ public function it_requires_a_start_date_and_category_when_creating_an_offtime() $this->assertDatabaseCount('offtimes', 0); } + #[Test] + public function it_requires_the_end_date_to_be_after_the_start_date(): void + { + $this->actingAs(User::factory()->create()); + + Livewire::test(ListOfftimes::class) + ->callAction(CreateAction::class, data: [ + 'start' => '2026-01-10', + 'end' => '2026-01-10', + 'category' => OfftimeCategory::Vacation, + ]) + ->assertHasFormErrors(['end' => 'after']); + + $this->assertDatabaseCount('offtimes', 0); + } + + #[Test] + public function it_sets_the_end_date_to_the_day_after_a_changed_start_date(): void + { + $this->actingAs(User::factory()->create()); + $offtime = Offtime::factory()->create(['start' => '2026-01-01', 'end' => '2026-01-05']); + + Livewire::test(ListOfftimes::class) + ->mountAction(TestAction::make(EditAction::class)->table($offtime)) + ->fillForm(['start' => '2026-01-10']) + ->assertActionDataSet(['end' => '2026-01-11']); + } + + #[Test] + public function it_keeps_the_end_date_empty_when_changing_the_start_date(): void + { + $this->actingAs(User::factory()->create()); + + Livewire::test(ListOfftimes::class) + ->mountAction(CreateAction::class) + ->fillForm(['start' => '2026-01-10']) + ->assertActionDataSet(['end' => null]); + } + #[Test] public function it_updates_an_offtime(): void {