forked from eatvio/eatvio-infra
192 lines
4.8 KiB
PHP
192 lines
4.8 KiB
PHP
<?php
|
|
|
|
namespace App\Livewire\Recipe;
|
|
|
|
use App\Models\Recipe;
|
|
use App\Models\Tag;
|
|
use Livewire\Component;
|
|
use Livewire\WithFileUploads;
|
|
|
|
class Edit extends Component
|
|
{
|
|
use WithFileUploads;
|
|
|
|
public Recipe $recipe;
|
|
|
|
public $image;
|
|
|
|
public $state = 'active';
|
|
|
|
public $state_ingredient = 'active';
|
|
|
|
public $state_article = 'active';
|
|
|
|
public $type = 'other';
|
|
|
|
public $tags;
|
|
|
|
public $title;
|
|
|
|
public $video_url;
|
|
|
|
public $cooking_time = '10';
|
|
|
|
public $description = '';
|
|
|
|
public $steps = [['image' => '', 'description' => '']];
|
|
|
|
public $ingredients = [['name' => '', 'portion' => '']];
|
|
|
|
public $ingredients_name = '';
|
|
|
|
public $ingredients_portion = '';
|
|
|
|
public $ingredients_unit = 'gr';
|
|
|
|
public $state_row = ['ingredient' => 'true', 'article' => 'false'];
|
|
|
|
protected $listeners = ['stepRemoved' => '$refresh', 'parentComponentTagAdded', 'parentComponentTagRemoved'];
|
|
|
|
public function mount(Recipe $recipe)
|
|
{
|
|
$this->name = $recipe->name;
|
|
$this->image = $recipe->image;
|
|
$this->state = $recipe->state;
|
|
$this->type = $recipe->type;
|
|
$this->title = $recipe->title;
|
|
$this->description = $recipe->description;
|
|
$this->cooking_time = $recipe->cooking_time;
|
|
$this->steps = $recipe->steps;
|
|
$this->ingredients = $recipe->ingredients;
|
|
$this->tags = $recipe->tags;
|
|
$this->video_url = $recipe->video_url;
|
|
}
|
|
|
|
public function toggleStateRow(string $currentRow): void
|
|
{
|
|
collect($this->state_row)->keys()->map(fn ($key) => $key === $currentRow
|
|
? $this->state_row[$currentRow] = 'true'
|
|
: $this->state_row[$key] = 'false');
|
|
}
|
|
|
|
public function addIngredient()
|
|
{
|
|
$this->ingredients[] = [
|
|
'name' => $this->ingredients_name,
|
|
'portion' => $this->ingredients_portion,
|
|
'unit' => $this->ingredients_unit,
|
|
];
|
|
$this->reset('ingredients_name', 'ingredients_portion', 'ingredients_unit');
|
|
}
|
|
|
|
public function removeIngredient($i)
|
|
{
|
|
$newIngredients = collect($this->ingredients)
|
|
->forget($i);
|
|
$this->ingredients = $newIngredients->toArray();
|
|
}
|
|
|
|
public function addStep()
|
|
{
|
|
$this->steps[] = ['image' => '', 'description' => ''];
|
|
}
|
|
|
|
public function removeStep($i)
|
|
{
|
|
if (is_array($this->steps)) {
|
|
$steps = $this->steps;
|
|
} else {
|
|
$steps = $this->steps->toArray();
|
|
}
|
|
$searchKey = $i - 1;
|
|
$newSteps = array_filter(
|
|
$steps,
|
|
function ($key) use ($searchKey) {
|
|
return $key !== $searchKey;
|
|
},
|
|
ARRAY_FILTER_USE_KEY
|
|
);
|
|
|
|
$this->steps = array_values($newSteps);
|
|
$this->dispatch('stepRemoved')->self();
|
|
}
|
|
|
|
public function parentComponentTagAdded(Tag $tag)
|
|
{
|
|
$this->recipe->tags()->attach($tag['id']);
|
|
}
|
|
|
|
public function parentComponentTagRemoved($tag)
|
|
{
|
|
$selectedTags = Tag::where('name', $tag)->pluck('id');
|
|
$this->recipe->tags()->detach($selectedTags);
|
|
}
|
|
|
|
public function draft()
|
|
{
|
|
$this->state = 'archived';
|
|
$this->publish();
|
|
}
|
|
|
|
public function preview()
|
|
{
|
|
$this->state = 'archived';
|
|
$this->publish();
|
|
}
|
|
|
|
public function publish()
|
|
{
|
|
$this->validate();
|
|
|
|
$recipe = $this->recipe;
|
|
if (! is_string($this->image)) {
|
|
$recipe->image = $this->image->store('recipe');
|
|
}
|
|
|
|
$recipe->state = $this->state;
|
|
$recipe->cooking_time = $this->cooking_time;
|
|
$recipe->title = $this->title;
|
|
$recipe->type = $this->type;
|
|
$recipe->description = $this->description;
|
|
$recipe->video_url = $this->video_url;
|
|
$recipe->steps = $this->transformSteps($this->steps);
|
|
$recipe->ingredients = $this->ingredients;
|
|
|
|
$recipe->save();
|
|
|
|
$this->redirectRoute('recipe.show', $recipe);
|
|
}
|
|
|
|
public function render()
|
|
{
|
|
return view('livewire.recipe.edit');
|
|
}
|
|
|
|
protected function rules()
|
|
{
|
|
return [
|
|
'image' => 'filled',
|
|
'state' => 'required|in:active,archived',
|
|
'description' => 'required|min:3',
|
|
'type' => 'required|min:3',
|
|
'video_url' => 'nullable|url|max:2048',
|
|
'cooking_time' => 'nullable|numeric',
|
|
];
|
|
}
|
|
|
|
private function transformSteps($steps)
|
|
{
|
|
return collect($steps)->
|
|
map(function ($step) {
|
|
if (is_string($step['image'])) {
|
|
$data['image'] = $step['image'];
|
|
} else {
|
|
$data['image'] = $step['image']->store('steps', 'public');
|
|
}
|
|
$data['description'] = $step['description'];
|
|
|
|
return $data;
|
|
})->toArray();
|
|
}
|
|
}
|