mirror of https://github.com/kcal-app/kcal.git
Refactor ingredients field structure
This commit is contained in:
parent
0c0febed6c
commit
9f180b9b62
|
@ -70,8 +70,37 @@ class RecipeController extends Controller
|
|||
*/
|
||||
public function edit(Recipe $recipe): View
|
||||
{
|
||||
// Pre-populate ingredients from form data or current recipe.
|
||||
$ingredients = [];
|
||||
if ($old = old('ingredients')) {
|
||||
foreach ($old['id'] as $key => $food_id) {
|
||||
if (empty($food_id)) {
|
||||
continue;
|
||||
}
|
||||
$ingredients[] = [
|
||||
'amount' => $old['amount'][$key],
|
||||
'unit' => $old['unit'][$key],
|
||||
'food_id' => $food_id,
|
||||
'food_name' => $old['name'][$key],
|
||||
'detail' => $old['detail'][$key],
|
||||
];
|
||||
}
|
||||
}
|
||||
else {
|
||||
foreach ($recipe->foodAmounts as $foodAmount) {
|
||||
$ingredients[] = [
|
||||
'amount' => $foodAmount->amount_formatted,
|
||||
'unit' => $foodAmount->unit,
|
||||
'food_id' => $foodAmount->food->id,
|
||||
'food_name' => $foodAmount->food->name,
|
||||
'detail' => $foodAmount->detail,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return view('recipes.edit')
|
||||
->with('recipe', $recipe)
|
||||
->with('ingredients', $ingredients)
|
||||
->with('ingredients_units', new Collection([
|
||||
['value' => 'tsp', 'label' => 'tsp.'],
|
||||
['value' => 'tbsp', 'label' => 'tbsp.'],
|
||||
|
@ -98,14 +127,14 @@ class RecipeController extends Controller
|
|||
'description' => 'nullable|string',
|
||||
'source' => 'nullable|string',
|
||||
'servings' => 'required|numeric',
|
||||
'ingredients_amount' => ['required', 'array', new ArrayNotEmpty],
|
||||
'ingredients_amount.*' => ['required_with:ingredients.*', 'nullable', new StringIsDecimalOrFraction],
|
||||
'ingredients_unit' => ['required', 'array'],
|
||||
'ingredients_unit.*' => 'nullable|string',
|
||||
'ingredients_detail' => ['required', 'array'],
|
||||
'ingredients_detail.*' => 'nullable|string',
|
||||
'ingredients' => ['required', 'array', new ArrayNotEmpty],
|
||||
'ingredients.*' => 'required_with:ingredients_amount.*|nullable|exists:App\Models\Food,id',
|
||||
'ingredients.amount' => ['required', 'array', new ArrayNotEmpty],
|
||||
'ingredients.amount.*' => ['required_with:ingredients.id.*', 'nullable', new StringIsDecimalOrFraction],
|
||||
'ingredients.unit' => ['required', 'array'],
|
||||
'ingredients.unit.*' => 'nullable|string',
|
||||
'ingredients.detail' => ['required', 'array'],
|
||||
'ingredients.detail.*' => 'nullable|string',
|
||||
'ingredients.id' => ['required', 'array', new ArrayNotEmpty],
|
||||
'ingredients.id.*' => 'required_with:ingredients.amount.*|nullable|exists:App\Models\Food,id',
|
||||
'steps' => ['required', 'array', new ArrayNotEmpty],
|
||||
'steps.*' => 'nullable|string',
|
||||
]);
|
||||
|
@ -126,15 +155,15 @@ class RecipeController extends Controller
|
|||
$food_amounts = [];
|
||||
$weight = 0;
|
||||
// TODO: Handle removals.
|
||||
foreach (array_filter($input['ingredients_amount']) as $key => $amount) {
|
||||
foreach (array_filter($input['ingredients']['id']) as $key => $food_id) {
|
||||
$food_amounts[$key] = $recipe->foodAmounts[$key] ?? new FoodAmount();
|
||||
$food_amounts[$key]->fill([
|
||||
'amount' => Number::floatFromString($amount),
|
||||
'unit' => $input['ingredients_unit'][$key],
|
||||
'detail' => $input['ingredients_detail'][$key],
|
||||
'amount' => Number::floatFromString($input['ingredients']['amount'][$key]),
|
||||
'unit' => $input['ingredients']['unit'][$key],
|
||||
'detail' => $input['ingredients']['detail'][$key],
|
||||
'weight' => $weight++,
|
||||
]);
|
||||
$food_amounts[$key]->food()->associate($input['ingredients'][$key]);
|
||||
$food_amounts[$key]->food()->associate($food_id);
|
||||
}
|
||||
$recipe->foodAmounts()->saveMany($food_amounts);
|
||||
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
<div>
|
||||
<div>
|
||||
<x-inputs.input type="hidden"
|
||||
name="ingredients[]"
|
||||
name="ingredients[id][]"
|
||||
value="{{ $defaultId ?? '' }}"
|
||||
x-ref="ingredients"/>
|
||||
<x-inputs.input type="text"
|
||||
name="ingredients_name[]"
|
||||
name="ingredients[name][]"
|
||||
value="{{ $defaultName ?? '' }}"
|
||||
placeholder="Search..."
|
||||
autocomplete="off"
|
||||
|
|
|
@ -64,30 +64,9 @@
|
|||
<!-- Ingredients -->
|
||||
<h3 class="pt-2 mb-2 font-extrabold">Ingredients</h3>
|
||||
<div x-data="{ ingredients: 0 }">
|
||||
@if(old('ingredients'))
|
||||
@foreach(old('ingredients') as $i => $ingredient)
|
||||
@if (empty($ingredient) && empty(old('ingredients_amount')[$i]) && empty(old('ingredients_unit')[$i]))
|
||||
@continue
|
||||
@endif
|
||||
@include('recipes.partials.ingredient-input', [
|
||||
'amount' => old('ingredients_amount')[$i],
|
||||
'unit' => old('ingredients_unit')[$i],
|
||||
'food_id' => old('ingredients')[$i],
|
||||
'food_name' => old('ingredients_name')[$i],
|
||||
'detail' => old('ingredients_detail')[$i],
|
||||
])
|
||||
@endforeach
|
||||
@else
|
||||
@foreach($recipe->foodAmounts as $foodAmount)
|
||||
@include('recipes.partials.ingredient-input', [
|
||||
'amount' => $foodAmount->amount_formatted,
|
||||
'unit' => $foodAmount->unit,
|
||||
'food_id' => $foodAmount->food->id,
|
||||
'food_name' => $foodAmount->food->name,
|
||||
'detail' => $foodAmount->detail,
|
||||
])
|
||||
@endforeach
|
||||
@endif
|
||||
@foreach($ingredients as $ingredient)
|
||||
@include('recipes.partials.ingredient-input', $ingredient)
|
||||
@endforeach
|
||||
<template x-for="i in ingredients + 1">
|
||||
@include('recipes.partials.ingredient-input')
|
||||
</template>
|
||||
|
@ -100,7 +79,7 @@
|
|||
|
||||
<!-- Steps -->
|
||||
<h3 class="pt-2 mb-2 font-extrabold">Steps</h3>
|
||||
<div x-data="{ steps: 0, step_number: 0 }">
|
||||
<div x-data="{ steps: 0 }">
|
||||
@if(old('steps'))
|
||||
@foreach(old('steps') as $i => $step_default)
|
||||
@if (empty($step)) @continue @endif
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<div class="flex flex-row space-x-4 mb-4">
|
||||
<x-inputs.input type="text"
|
||||
name="ingredients_amount[]"
|
||||
name="ingredients[amount][]"
|
||||
size="5"
|
||||
:value="$amount ?? null" />
|
||||
<x-inputs.select name="ingredients_unit[]"
|
||||
<x-inputs.select name="ingredients[unit][]"
|
||||
:options="$ingredients_units"
|
||||
:selectedValue="$unit ?? null">
|
||||
<option value=""></option>
|
||||
|
@ -12,7 +12,7 @@
|
|||
:default-name="$food_name ?? null" />
|
||||
<x-inputs.input type="text"
|
||||
class="block"
|
||||
name="ingredients_detail[]"
|
||||
name="ingredients[detail][]"
|
||||
:value="$detail ?? null" />
|
||||
<x-inputs.icon-button type="button" color="red" x-on:click="$event.target.parentNode.remove();">
|
||||
<svg class="h-8 w-8 pointer-events-none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
|
||||
|
|
|
@ -1,7 +1,14 @@
|
|||
<x-app-layout>
|
||||
<x-slot name="header">
|
||||
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
|
||||
<h2 class="font-semibold text-xl text-gray-800 leading-tight flex flex-auto">
|
||||
{{ $recipe->name }}
|
||||
<a class="ml-2 text-gray-500 hover:text-gray-700 hover:border-gray-300 text-sm"
|
||||
href="{{ route('recipes.edit', $recipe) }}">
|
||||
<svg class="h-6 w-6" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path d="M17.414 2.586a2 2 0 00-2.828 0L7 10.172V13h2.828l7.586-7.586a2 2 0 000-2.828z" />
|
||||
<path fill-rule="evenodd" d="M2 6a2 2 0 012-2h4a1 1 0 010 2H4v10h10v-4a1 1 0 112 0v4a2 2 0 01-2 2H4a2 2 0 01-2-2V6z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</a>
|
||||
</h2>
|
||||
</x-slot>
|
||||
<div class="py-12">
|
||||
|
|
Loading…
Reference in New Issue