Recipe versioning, inline recipe create, recipe summary, Shopify description
Deploy / deploy (push) Successful in 15s

- Add version + product_id to recipes table (migration)
- Recipe select shows version label (e.g. "Kurkuma v2")
- Creating recipe from product page pre-fills product name, auto-increments version
- Recipe ingredient summary shown read-only below the select
- Remove package_content field (redundant with recipe ingredients)
- Pull product description from Shopify body_html on import
- Update existing products with empty description on re-import

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Malek TellissiandClaude Sonnet 4.6 committed 2026-09-12 05:18:11 +02:00
1 parent 6e28984278
commit a7f5c4a83e
6 files changed
+74 -10

No files matched your search

@@ -18,6 +18,7 @@ use Filament\Tables;
use Filament\Tables\Table;
use Illuminate\Support\HtmlString;
use App\Models\Packing;
use App\Models\Recipe;
use Picqer\Barcode\BarcodeGeneratorSVG;
class ProductResource extends Resource {
@@ -45,21 +46,32 @@ class ProductResource extends Resource {
->columnSpanFull(),
Forms\Components\Textarea::make('description')
->label('Beschreibung'),
Forms\Components\Textarea::make('package_content')
->label('Inhaltsangabe'),
Forms\Components\Select::make('recipes_id')
->label('Rezept')
->native(false)
->searchable()
->live()
->relationship('recipe', 'name')
->getOptionLabelFromRecordUsing(fn (Recipe $r) => "{$r->name} (v{$r->version})")
->required()
->createOptionForm([
->createOptionForm(fn () => [
Forms\Components\TextInput::make('name')
->label('Name')
->required(),
->required()
->default(fn ($livewire) => $livewire->data['title'] ?? ''),
Forms\Components\Textarea::make('description')
->label('Beschreibung'),
])
->createOptionUsing(function (array $data, $livewire) {
$productId = $livewire->record?->id;
$nextVersion = Recipe::where('product_id', $productId)->max('version') + 1;
return Recipe::create([
'name' => $data['name'],
'description' => $data['description'] ?? null,
'product_id' => $productId,
'version' => $nextVersion,
])->getKey();
})
->editOptionForm([
Forms\Components\TextInput::make('name')
->label('Name')
@@ -67,6 +79,20 @@ class ProductResource extends Resource {
Forms\Components\Textarea::make('description')
->label('Beschreibung'),
]),
Placeholder::make('recipe_summary')
->label('Rezept-Inhalt')
->content(function (Forms\Get $get, $record): HtmlString {
$recipeId = $get('recipes_id');
$recipe = $recipeId ? Recipe::with('spices')->find($recipeId) : $record?->recipe?->load('spices');
if (! $recipe || $recipe->spices->isEmpty()) {
return new HtmlString('<span class="text-sm text-gray-400">Keine Zutaten hinterlegt</span>');
}
$items = $recipe->spices->map(fn ($s) => "<li>{$s->name} ({$s->pivot->amount_in_percent}%)</li>")->implode('');
$meta = "v{$recipe->version} · erstellt " . $recipe->created_at->format('d.m.Y');
return new HtmlString("<p class='text-xs text-gray-400 mb-1'>{$meta}</p><ul class='list-disc list-inside text-sm'>{$items}</ul>");
})
->columnSpanFull()
->visible(fn (Forms\Get $get, $record) => filled($get('recipes_id')) || $record?->recipes_id),
Repeater::make('sizes')
->schema([
Select::make('packing_id')