Files
eatvio-infra/app/Livewire/Recipe/Edit.php
2023-12-28 17:07:09 +03:00

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();
}
}