Files
eatvio-infra/app/Livewire/Recipe/Create.php

195 lines
5.1 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;
use Illuminate\View\View;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Storage;
use Illuminate\Filesystem\FilesystemAdapter;
use Livewire\Features\SupportFileUploads\TemporaryUploadedFile;
use Illuminate\Http\UploadedFile;
class Create extends Component
{
use WithFileUploads;
// public TemporaryUploadedFile $image;
public UploadedFile|null $image = null;
public string $state = 'active';
public string $state_ingredient = 'active';
public string $state_article = 'active';
public array $tags = [];
public string $title;
public string $type = 'other';
public string $video_url = '';
public int|string $cooking_time = '10';
public string $description = '';
public Collection|array $steps = [['image' => '', 'description' => '']];
public Collection|array $ingredients = [];
public string $ingredients_name = '';
public string $ingredients_portion = '';
public string $ingredients_unit = 'gr';
public array $state_row = ['ingredient' => 'true', 'article' => 'false'];
protected function getListeners(): array
{
return ['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(int $i): void
{
$newIngredients = collect($this->ingredients)
->forget($i);
$this->ingredients = $newIngredients->toArray();
}
public function addStep(): void
{
$this->steps[] = ['image' => '', 'description' => ''];
}
public function removeStep(int $i): void
{
$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): void
{
$tagIndex = $tag->id;
$this->tags[$tagIndex] = $tag;
}
#[On('parentComponentTagRemoved')]
public function parentComponentTagRemoved(Tag $tag): void
{
$this->tags = collect($this->tags)
->filter(fn ($curTag) => $curTag['name'] !== $tag)
->all();
}
public function draft(): void
{
$this->state = 'archived';
$this->publish();
}
public function preview(): void
{
$this->validate();
$this->state = 'archived';
$this->publish();
}
public function publish(): void
{
$this->validate();
$recipe = new Recipe();
// $recipe->image = $this->image->store('recipe', 'public');
$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(): View
{
return view('livewire.recipe.create');
}
protected function rules(): array
{
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(array $steps): array
{
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();
}
}