label('Calculate price') ->icon(Heroicon::Calculator) ->modalIcon(Heroicon::OutlinedCalculator) ->modalWidth(Width::SixExtraLarge) ->schema(fn () => self::getSchema()) ->fillForm(function (array $arguments, Repeater $component): array { $meta = $component->getRawItemState($arguments['item'])['meta'] ?? []; return $meta; }) ->after(function (array $arguments, array $data, Set $set): void { $key = $arguments['item']; $set("items.{$key}.meta", $data); }); } /** @return array */ private static function getSchema(): array { return Layout::make( [ Section::make('Material') ->schema([ MoneyInput::make('material_cost') ->label('Purchase price') ->required() ->lazy() ->afterStateUpdated(function (?float $state, Get $get, Set $set): void { $margin = (float) ($get('material_margin') ?? 0); if (! is_numeric($state)) { $set('material_price', null); return; } $price = $state + ($state * ($margin / 100)); $set('material_price', round($price, 2)); }), TextInput::make('material_margin') ->label('Margin') ->suffix('%') ->default(50) ->required() ->numeric() ->step(0.1) ->minValue(0) ->columnSpan(2) ->lazy() ->afterStateUpdated(function (?float $state, Get $get, Set $set): void { $cost = (float) ($get('material_cost') ?? 0); $price = $cost + ($cost * ($state / 100)); $set('material_price', round($price, 2)); }), ]) ->columns(8) ->compact(), Section::make('Another costs') ->schema([ MoneyInput::make('measurement') ->label('Measurement') ->columnSpan(2) ->lazy() ->afterStateUpdated(function (?float $state, Set $set): void { if (! is_numeric($state)) { $set('measurement_price', null); return; } $set('measurement_price', round($state, 2)); }), ]) ->compact() ->secondary(), ], [ Section::make('Summary') ->schema([ TextEntry::make('material_price') ->label('Material') ->inlineLabel() ->money() ->alignEnd(), TextEntry::make('measurement_price') ->label('Measurement') ->inlineLabel() ->money() ->alignEnd(), TextEntry::make('item_total') ->label('Total') ->inlineLabel() ->state(function (Get $get): float { $material = (float) ($get('material_price') ?? 0.0); $measurement = (float) ($get('measurement_price') ?? 0.0); return $material + $measurement; }) ->money() ->weight(FontWeight::Bold) ->alignEnd() ->extraEntryWrapperAttributes(['class' => 'pt-3 border-t border-gray-300']), ]) ->columns(null) ->compact(), ], ); } }