105 lines
2.5 KiB
PHP
105 lines
2.5 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace App\Livewire;
|
||
|
|
|
||
|
|
use App\Models\Category;
|
||
|
|
use App\Models\News;
|
||
|
|
use Livewire\Attributes\Url;
|
||
|
|
use Livewire\Component;
|
||
|
|
use Livewire\WithPagination;
|
||
|
|
|
||
|
|
class NewsDatabase extends Component
|
||
|
|
{
|
||
|
|
use WithPagination;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* News title search
|
||
|
|
* @var string
|
||
|
|
*/
|
||
|
|
#[Url(as: 's', except: '')]
|
||
|
|
public string $search = '';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Categories IDs filter.
|
||
|
|
* @var array
|
||
|
|
*/
|
||
|
|
#[Url(except:[])]
|
||
|
|
public array $categories = [];
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Sort by field.
|
||
|
|
* @var string
|
||
|
|
*/
|
||
|
|
#[Url(as: 'sort',except: 'created_at')]
|
||
|
|
public string $sortBy = 'created_at';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* asc/desc
|
||
|
|
* @var string
|
||
|
|
*/
|
||
|
|
#[Url(as: 'dir',except: 'desc')]
|
||
|
|
public string $sortDir = 'desc';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Translation of sort options key.
|
||
|
|
*/
|
||
|
|
public const array SORT_OPTIONS = [
|
||
|
|
'created_at' => 'Date added',
|
||
|
|
'title' => 'Title'
|
||
|
|
];
|
||
|
|
|
||
|
|
public const int PAGINATION = 30;
|
||
|
|
|
||
|
|
public function updatedSearch(): void { $this->resetPage(); $this->dispatch('filters-updated'); }
|
||
|
|
public function updatedCategories(): void { $this->resetPage(); $this->dispatch('filters-updated'); }
|
||
|
|
public function updatedCategoriesMode(): void { $this->resetPage(); $this->dispatch('filters-updated'); }
|
||
|
|
|
||
|
|
public function clearFilters(): void
|
||
|
|
{
|
||
|
|
$this->reset([
|
||
|
|
'search', 'categories',
|
||
|
|
]);
|
||
|
|
$this->resetPage();
|
||
|
|
}
|
||
|
|
|
||
|
|
public function setSort(string $field): void
|
||
|
|
{
|
||
|
|
if( $this->sortBy === $field ) {
|
||
|
|
$this->sortDir = $this->sortDir === 'asc' ? 'desc' : 'asc';
|
||
|
|
} else {
|
||
|
|
$this->sortBy = $field;
|
||
|
|
$this->sortDir = 'asc';
|
||
|
|
}
|
||
|
|
$this->resetPage();
|
||
|
|
$this->dispatch('filters-updated');
|
||
|
|
}
|
||
|
|
|
||
|
|
private function buildQuery()
|
||
|
|
{
|
||
|
|
$query = News::query()->published();
|
||
|
|
|
||
|
|
if( $this->search ){
|
||
|
|
$query->where(function($q){
|
||
|
|
$q->where('title', 'like', '%'.$this->search.'%');
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
if( $this->categories ) {
|
||
|
|
$query->whereIn('category_id', $this->categories);
|
||
|
|
}
|
||
|
|
|
||
|
|
return $query->orderBy($this->sortBy, $this->sortDir);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function render()
|
||
|
|
{
|
||
|
|
return view('livewire.news-database', [
|
||
|
|
'news' => $this->buildQuery()->paginate(self::PAGINATION),
|
||
|
|
'allCategories' => Category::where(function ($query) {
|
||
|
|
$query->whereJsonContains('restricted_to', "news")
|
||
|
|
->orWhereNull('restricted_to');
|
||
|
|
})->orderBy('name')->get()
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
}
|