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