techblog/resources/views/livewire/posts/form.blade.php
PeterChrz 75561faf25
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled
initialize project and update gitignore
2026-03-19 09:35:42 -04:00

168 lines
4.9 KiB
PHP

<?php
use App\Data\PostData;
use App\Models\Tag;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use App\Livewire\IncludesSorting;
use App\Livewire\WithDeleteFilter;
use App\Models\Category;
use App\Models\User;
use Flux\Flux;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
use Livewire\Attributes\On;
use Livewire\Component;
use Livewire\Attributes\Computed;
use App\Models\Post;
use Livewire\WithPagination;
new class extends Component {
public PostData $data;
public function mount($id = 0): void
{
$this->data = $this->populate($id);
}
#[On('post.create')]
public function handlePostCreate(): void
{
$this->data = $this->populate(0);
}
#[On('post.edit')]
public function handlePostEdit($id): void
{
$this->data = $this->populate($id);
}
public function process(): void
{
$this->data->slug = Str::kebab($this->data->title);
$this->validate();
if ($this->data->id) {
$post = Post::findOrFail($this->data->id);
$post->update($this->data->toArray());
if (count($this->data->tags) > 0) {
$post->tags()->detach();
$post->tags()->attach($this->data->tags);
}
Flux::toast(text: __('Post updated.'), variant: 'success');
} else {
$post = Post::create($this->data->toArray());
if (count($this->data->tags) > 0) {
$post->tags()->attach($this->data->tags);
}
Flux::toast(text: __('Post created.'), variant: 'success');
}
$this->data = $this->populate(0);
$this->dispatch('post.processed');
}
public function populate($id): PostData
{
if ($id) {
$post = PostData::from($model = Post::findOrFail($id));
$post->tags = $model->tags->pluck('id')->toArray();
return $post;
}
return PostData::blank();
}
public function rules(): array
{
$rules = PostData::rules();
return Arr::prependKeysWith(
array: $rules,
prependWith: 'data.'
);
}
public function messages(): array
{
return Arr::prependKeysWith(
array: PostData::messages(),
prependWith: 'data.'
);
}
public function updatedDataSlug(): void
{
$this->data->slug = Str::kebab($this->data->title);
}
#[Computed]
public function authors(): Collection
{
return User::orderBy('name')->get();
}
#[Computed]
public function categories(): Collection
{
return Category::orderBy('name')->get();
}
#[Computed]
public function tags(): Collection
{
return Tag::orderBy('name')->get();
}
};
?>
<form wire:submit="process" class="space-y-4">
<div>
<flux:heading size="lg">@lang('Post Management')</flux:heading>
<flux:text class="mt-2">@lang('Manage categories for your blog.')</flux:text>
</div>
<div class="grid grid-cols-2 gap-4">
<flux:input :label="__('Title')" wire:model.live.debounce.300ms="data.title"/>
<flux:select :label="__('Status')" wire:model="data.status" placeholder="Status">
<flux:select.option value="draft">{{ __('Draft') }}</flux:select.option>
<flux:select.option value="published">{{ __('Published') }}</flux:select.option>
</flux:select>
</div>
<flux:textarea :label="__('Excerpt')" wire:model="data.excerpt" rows="2"/>
<flux:editor :label="__('Content')" wire:model="data.content"/>
<div class="grid grid-cols-2 gap-4">
<flux:select :label="__('Authors')" wire:model="data.author_id" placeholder="Authors" variant="combobox">
@foreach ($this->authors as $author)
<flux:select.option value="{{$author->id }}" wire:key="$author->id">
{{ $author->name }}
</flux:select.option>
@endforeach
</flux:select>
<flux:select :label="__('Categories')" wire:model="data.category_id" placeholder="Categories"
variant="combobox">
@foreach ($this->categories as $category)
<flux:select.option value="{{ $category->id }}" wire:key="$category->id">
<x-category :category="$category"/>
</flux:select.option>
@endforeach
</flux:select>
</div>
<div>
<flux:select wire:model="data.tags" variant="listbox" multiple :placeholder="__('Select your tags...')">
@foreach ($this->tags as $tag)
<flux:select.option :value="$tag->id">{{ $tag->name }}</flux:select.option>
@endforeach
</flux:select>
</div>
<flux:button type="submit" variant="primary">@lang('Save changes')</flux:button>
</form>