168 lines
4.9 KiB
PHP
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>
|