label('Article') ->relationship('article', 'name') ->searchable() ->preload() ->required() ->live() ->afterStateUpdated(function (Get $get, Set $set, $state, $livewire, $component) { // Set price from article if ($state) { $article = Article::find($state); if($article){ $set('price', $article->price); $set('unit', $article->unit); $set('quantity', $article->unit === 'hour' ? 0 : 1); // Auto-open the modal if unit is hour if ($article->unit === 'hour') { $livewire->mountFormComponentAction( $component->getStatePath(), 'show_time_modal' ); } static::calculateLineItemTotal($get, $set); static::calculateTotals($get, $set); } } }) ->registerActions([ Action::make('show_time_modal') ->label('Calculate Time') ->modalHeading('Work Time Calculation') ->modalWidth(MaxWidth::Small) ->form([ TimePicker::make('from_time')->required()->seconds(false), TimePicker::make('to_time')->required()->seconds(false), TextInput::make('lunch_break')->label('Lunch Break (minutes)')->required()->numeric(), ]) ->action(function (array $data, Get $get, Set $set) { $from = \Carbon\Carbon::parse($data['from_time']); $to = \Carbon\Carbon::parse($data['to_time']); $hours = $from->floatDiffInHours($to); $lunchBreakHours = (float) $data['lunch_break'] / 60; $finalHours = $hours - $lunchBreakHours; // Set quantity (hours) $set('quantity', number_format($finalHours, 2)); // Append to description $currentDescription = $get('description') ?? ''; $timeDetails = "{$data['from_time']} - {$data['to_time']} inc {$data['lunch_break']}min break"; $newDescription = $currentDescription ? "{$currentDescription}\n{$timeDetails}" : $timeDetails; $set('description', $newDescription); }) ->mountUsing(function ($form) { $form->fill([ 'from_time' => now()->format('H:i'), 'to_time' => now()->addHour()->format('H:i'), ]); }) ->modalSubmitActionLabel('Apply') ->modalCancelActionLabel('Cancel'), ]); } protected static function getUnitSelectField(): Select { return Select::make('unit') ->required() ->options([ 'hour' => 'hour', 'm2' => 'm2', 'piece' => 'piece', 'length' => 'length', ]) ->preload(); } }