Hello I'm trying to add pagination to a grid of posts that I have where filters get applied from a filter box. Right now works without pagination but i'm trying to add pagination using Livewire Volt (following this https://livewire.laravel.com/docs/volt#pagination) but i'm struggling to know if I should change what I already have to use with.
So what I've been trying is to paginate $this->posts = $query->get(); on the $applyFilters function but i'm not sure how should apply what the doc says (using the with)
This is my grid livewire component without the pagination.
<?php
use function Livewire\Volt\{state, uses, on, mount, computed};
use App\Models\Post;
state([
'posts' => collect(),
]);
state([
'searchTerm' => '',
])->url(as: 'search');
state(['selectedProvince'])->url(as: 'province');
state(['selectedTown'])->url(as: 'town');
state(['selectedType'])->url(as: 'type');
mount(function () {
$this->applyFilters();
});
$applyFilters = function () {
$query = Post::query();
$query->when($this->searchTerm, function ($query) {
$query->where(function ($query) {
$query->where('title', 'like', "%{$this->searchTerm}%")->orWhere('description', 'like', "%{$this->searchTerm}%")->orWhere('phone', 'like', "%{$this->searchTerm}%");
});
});
$query->when($this->selectedType, function ($query) {
$query->where('type_id', $this->selectedType);
});
$query->when($this->selectedProvince, function ($query) {
$query->where('province_id', $this->selectedProvince);
});
$query->when($this->selectedTown, function ($query) {
$query->where('town_id', $this->selectedTown);
});
$this->posts = $query->get();
};
on([
'type-selected' => function ($typeId) {
$this->selectedType = $typeId;
$this->applyFilters();
},
]);
on([
'province-selected' => function ($provinceId) {
if ($this->selectedProvince !== $provinceId) {
$this->selectedTown = null;
$this->searchTerm = '';
}
$this->selectedProvince = $provinceId;
$this->applyFilters();
},
]);
on([
'town-selected' => function ($townId) {
$this->selectedTown = $townId;
$this->applyFilters();
},
]);
on([
'post-searched' => function ($searchTerm) {
$this->searchTerm = $searchTerm;
$this->applyFilters();
},
]);
?>
<div class="block">
<div class="flex-grow bg-black-darker/50 p-4 mx-auto w-full rounded-md mb-8">
<livewire:sub-header :selectedType="$selectedType"
:selectedProvince="$selectedProvince"
:selectedTown="$selectedTown"
:posts="$posts" />
</div>
<div class="bg-black-darker/50 p-4 container w-full rounded-lg grid grid-cols-2 gap-4">
@forelse ($this->posts as $post)
<a class="relative flex bg-black-darker/50 border border-gray-500/10 p-4 rounded-md mb-4 w-full hover:border-gray-500/30 transition hover:-translate-y-1 hover:bg-black-darker/40"
href="{{ route('posts.show', $post->slug) }}"
wire:navigate>
<div class="p-4 absolute -top-8 right-0">
<p
class="uppercase text-[10px] rounded-md font-semibold w-full border py-1 px-2 bg-red text-white">
{{ $post->type->name }}
</p>
</div>
<div class="w-[400px] items-center justify-center">
<img src="{{ $post->main_image->image_path }}"
alt="{{ $post->title }}"
class="w-[200px] h-48 object-cover rounded-md">
</div>
<div class="flex flex-col justify-between px-2 pb-8">
<h3 class="text-pretty text-lg font-bold justify-self-start tracking-wide">
{{ $post->title }}</h3>
<p class="text-pretty text-base line-clamp-3 tracking-normal">{{ $post->description }}</p>
</div>
<div class="p-4 mt-8 absolute bottom-0 right-0">
<p class="uppercase text-xs font-semibold w-full opacity-40">
{{ $post->created_at->diffForHumans() }}
</p>
</div>
</a>
@empty
<div class="col-span-2 flex items-center justify-center text-white/70 text-center">
No se han encontrado anuncios
</div>
@endforelse
</div>
</div>