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

182 lines
4.5 KiB
PHP

<?php
namespace App\Livewire\Recipe;
use App\Models\Recipe;
use App\Models\Tag;
use Illuminate\Support\Facades\Auth;
use Livewire\Attributes\On;
use Livewire\Component;
use Livewire\WithFileUploads;
class Create extends Component
{
use WithFileUploads;
public $image;
public $state = 'active';
public $state_ingredient = 'active';
public $state_article = 'active';
public $tags = [];
public $title;
public $type = 'other';
public $video_url = '';
public $cooking_time = '10';
public $description = '';
public $steps = [['image' => '', 'description' => '']];
public $ingredients = [];
public $ingredients_name = '';
public $ingredients_portion = '';
public $ingredients_unit = 'gr';
public $state_row = ['ingredient' => 'true', 'article' => 'false'];
protected $listeners = ['stepRemoved' => '$refresh'];
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(): void
{
$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)
{
$searchKey = $i - 1;
$newSteps = array_filter(
$this->steps,
function ($key) use ($searchKey) {
return $key !== $searchKey;
},
ARRAY_FILTER_USE_KEY
);
$this->steps = array_values($newSteps);
$this->dispatch('stepRemoved')->self();
}
#[On('parentComponentTagAdded')]
public function parentComponentTagAdded(Tag $tag)
{
$tagIndex = $tag->id;
$this->tags[$tagIndex] = $tag;
}
#[On('parentComponentTagRemoved')]
public function parentComponentTagRemoved($tag)
{
$this->tags = collect($this->tags)
->filter(fn ($curTag) => $curTag['name'] !== $tag)
->all();
}
public function draft()
{
$this->state = 'archived';
$this->publish();
}
public function preview()
{
$this->validate();
$this->state = 'archived';
$this->publish();
}
public function publish()
{
$this->validate();
$recipe = new Recipe();
$recipe->image = $this->image->store('recipe');
$recipe->state = $this->state;
$recipe->type = $this->type;
$recipe->cooking_time = $this->cooking_time;
$recipe->title = $this->title;
$recipe->description = $this->description;
$recipe->video_url = $this->video_url;
$recipe->steps = $this->transformSteps($this->steps);
$recipe->ingredients = $this->ingredients;
$recipe->save();
$tagsIds = collect($this->tags)->map(fn ($curTag) => $curTag['id']);
$recipe->tags()->attach($tagsIds);
$user = Auth::user();
$user->author_of_recipe()->attach($recipe->id);
$this->redirectRoute('recipe.show', $recipe);
}
public function render()
{
return view('livewire.recipe.create');
}
protected function rules()
{
return [
'image' => 'required|image|max:2048',
'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 (gettype($step['image']) === 'string') {
$data['image'] = $step['image'];
} else {
$data['image'] = ! is_null($step['image']) ? $step['image']->store('steps', 'public') : '';
}
$data['description'] = $step['description'];
return $data;
}
)->toArray();
}
}