mirror of
https://github.com/sp-tarkov/forge.git
synced 2025-02-12 20:20:41 -05:00
Merge branch 'listing-per-page' into develop
This commit is contained in:
commit
5cfffef2b4
@ -9,6 +9,7 @@ use Illuminate\Contracts\View\View;
|
|||||||
use Illuminate\Database\Eloquent\Collection;
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
use Livewire\Attributes\Computed;
|
use Livewire\Attributes\Computed;
|
||||||
|
use Livewire\Attributes\Locked;
|
||||||
use Livewire\Attributes\Session;
|
use Livewire\Attributes\Session;
|
||||||
use Livewire\Attributes\Url;
|
use Livewire\Attributes\Url;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
@ -32,6 +33,19 @@ class Listing extends Component
|
|||||||
#[Url]
|
#[Url]
|
||||||
public string $order = 'created';
|
public string $order = 'created';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of results to show on a single page.
|
||||||
|
*/
|
||||||
|
#[Session]
|
||||||
|
#[Url]
|
||||||
|
public int $perPage = 12;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The options that are available for the per page setting.
|
||||||
|
*/
|
||||||
|
#[Locked]
|
||||||
|
public array $perPageOptions = [6, 12, 24, 50];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The SPT versions filter value.
|
* The SPT versions filter value.
|
||||||
*/
|
*/
|
||||||
@ -62,7 +76,15 @@ class Listing extends Component
|
|||||||
return SptVersion::getVersionsForLastThreeMinors();
|
return SptVersion::getVersionsForLastThreeMinors();
|
||||||
});
|
});
|
||||||
|
|
||||||
$this->sptVersions = $this->sptVersions ?? $this->getLatestMinorVersions()->pluck('version')->toArray();
|
$this->sptVersions = $this->sptVersions ?? $this->getDefaultSptVersions();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the default values for the SPT Versions filter.
|
||||||
|
*/
|
||||||
|
protected function getDefaultSptVersions(): array
|
||||||
|
{
|
||||||
|
return $this->getLatestMinorVersions()->pluck('version')->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -80,6 +102,8 @@ class Listing extends Component
|
|||||||
*/
|
*/
|
||||||
public function render(): View
|
public function render(): View
|
||||||
{
|
{
|
||||||
|
$this->validatePerPage();
|
||||||
|
|
||||||
// Fetch the mods using the filters saved to the component properties.
|
// Fetch the mods using the filters saved to the component properties.
|
||||||
$filters = [
|
$filters = [
|
||||||
'query' => $this->query,
|
'query' => $this->query,
|
||||||
@ -87,13 +111,32 @@ class Listing extends Component
|
|||||||
'order' => $this->order,
|
'order' => $this->order,
|
||||||
'sptVersions' => $this->sptVersions,
|
'sptVersions' => $this->sptVersions,
|
||||||
];
|
];
|
||||||
$mods = (new ModFilter($filters))->apply()->paginate(16);
|
|
||||||
|
$mods = (new ModFilter($filters))->apply()->paginate($this->perPage);
|
||||||
|
|
||||||
$this->redirectOutOfBoundsPage($mods);
|
$this->redirectOutOfBoundsPage($mods);
|
||||||
|
|
||||||
return view('livewire.mod.listing', compact('mods'));
|
return view('livewire.mod.listing', compact('mods'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate that the option selected is an option that is available by setting it to the closest available version.
|
||||||
|
*/
|
||||||
|
public function validatePerPage(): void
|
||||||
|
{
|
||||||
|
$this->perPage = collect($this->perPageOptions)->pipe(function ($data) {
|
||||||
|
$closest = null;
|
||||||
|
|
||||||
|
foreach ($data as $item) {
|
||||||
|
if ($closest === null || abs($this->perPage - $closest) > abs($item - $this->perPage)) {
|
||||||
|
$closest = $item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $closest;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the current page is greater than the last page. Redirect if it is.
|
* Check if the current page is greater than the last page. Redirect if it is.
|
||||||
*/
|
*/
|
||||||
@ -110,7 +153,7 @@ class Listing extends Component
|
|||||||
public function resetFilters(): void
|
public function resetFilters(): void
|
||||||
{
|
{
|
||||||
$this->query = '';
|
$this->query = '';
|
||||||
$this->sptVersions = $this->getLatestMinorVersions()->pluck('version')->toArray();
|
$this->sptVersions = $this->getDefaultSptVersions();
|
||||||
$this->featured = 'include';
|
$this->featured = 'include';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
8
resources/views/components/filter-menu-item.blade.php
Normal file
8
resources/views/components/filter-menu-item.blade.php
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
@props(['filterName', 'filter', 'currentFilter'])
|
||||||
|
|
||||||
|
<a href="#{{ $filter }}"
|
||||||
|
@click.prevent="$wire.set('{{ $filterName }}', '{{ $filter }}')"
|
||||||
|
class="flex items-center gap-2 bg-slate-100 px-4 py-2 text-sm hover:bg-slate-800/5 focus-visible:bg-slate-800/10 focus-visible:text-black focus-visible:outline-none dark:bg-slate-800 dark:hover:bg-slate-100/5 dark:focus-visible:bg-slate-100/10 dark:focus-visible:text-white {{ strval($filter) === strval($currentFilter) ? "font-bold text-cyan-500 dark:text-cyan-500 hover:text-cyan-400 dark:hover:text-cyan-400" : "text-slate-700 dark:text-slate-300 hover:text-black dark:hover:text-white" }}"
|
||||||
|
role="menuitem" tabindex="-1">
|
||||||
|
{{ $slot }}
|
||||||
|
</a>
|
@ -1,8 +0,0 @@
|
|||||||
@props(['order', 'currentOrder'])
|
|
||||||
|
|
||||||
<a href="#{{ $order }}"
|
|
||||||
@click.prevent="$wire.set('order', '{{ $order }}')"
|
|
||||||
class="flex items-center gap-2 bg-slate-100 px-4 py-2 text-sm text-slate-700 hover:bg-slate-800/5 hover:text-black focus-visible:bg-slate-800/10 focus-visible:text-black focus-visible:outline-none dark:bg-slate-800 dark:text-slate-300 dark:hover:bg-slate-100/5 dark:hover:text-white dark:focus-visible:bg-slate-100/10 dark:focus-visible:text-white {{ $order === $currentOrder ? "font-bold text-slate-900 dark:text-white" : "" }}"
|
|
||||||
role="menuitem" tabindex="-1">
|
|
||||||
{{ $slot }}
|
|
||||||
</a>
|
|
@ -99,7 +99,44 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-start-1 row-start-1 py-4">
|
<div class="col-start-1 row-start-1 py-4">
|
||||||
<div class="mx-auto flex max-w-7xl justify-end px-4 sm:px-6 lg:px-8">
|
<div class="mx-auto flex max-w-7xl justify-end px-4 sm:px-6 lg:px-8 gap-6">
|
||||||
|
{{-- Results Per Page Dropdown --}}
|
||||||
|
<div class="relative inline-block" x-data="{ isResultsPerPageOpen: false }" @click.away="isResultsPerPageOpen = false">
|
||||||
|
<div class="flex">
|
||||||
|
{{-- Large display can show full text --}}
|
||||||
|
<button type="button" @click="isResultsPerPageOpen = !isResultsPerPageOpen" class="hidden lg:flex group inline-flex justify-center text-sm font-medium text-gray-700 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100" id="menu-button" :aria-expanded="isResultsPerPageOpen.toString()" aria-haspopup="true">
|
||||||
|
{{ __('Per Page') }}
|
||||||
|
<svg class="-mr-1 ml-1 h-5 w-5 flex-shrink-0 text-gray-400 group-hover:text-gray-500" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||||
|
<path fill-rule="evenodd" d="M5.23 7.21a.75.75 0 011.06.02L10 11.168l3.71-3.938a.75.75 0 111.08 1.04l-4.25 4.5a.75.75 0 01-1.08 0l-4.25-4.5a.75.75 0 01.02-1.06z" clip-rule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
{{-- Only show selected number on smaller screens --}}
|
||||||
|
<button type="button" @click="isResultsPerPageOpen = !isResultsPerPageOpen" class="lg:hidden group inline-flex justify-center text-sm font-medium text-gray-700 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100" id="menu-button" :aria-expanded="isResultsPerPageOpen.toString()" aria-haspopup="true" title="{{ __(':perPage results per page', ['perPage' => $perPage]) }}">
|
||||||
|
{{ __(':perPage/p', ['perPage' => $perPage]) }}
|
||||||
|
<svg class="-mr-1 ml-1 h-5 w-5 flex-shrink-0 text-gray-400 group-hover:text-gray-500" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||||
|
<path fill-rule="evenodd" d="M5.23 7.21a.75.75 0 011.06.02L10 11.168l3.71-3.938a.75.75 0 111.08 1.04l-4.25 4.5a.75.75 0 01-1.08 0l-4.25-4.5a.75.75 0 01.02-1.06z" clip-rule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div x-cloak
|
||||||
|
x-show="isResultsPerPageOpen"
|
||||||
|
x-transition:enter="transition ease-out duration-100"
|
||||||
|
x-transition:enter-start="transform opacity-0 scale-95"
|
||||||
|
x-transition:enter-end="transform opacity-100 scale-100"
|
||||||
|
x-transition:leave="transition ease-in duration-75"
|
||||||
|
x-transition:leave-start="transform opacity-100 scale-100"
|
||||||
|
x-transition:leave-end="transform opacity-0 scale-95"
|
||||||
|
class="absolute top-7 right-0 z-10 flex w-full min-w-[12rem] flex-col divide-y divide-slate-300 overflow-hidden rounded-xl border border-gray-300 bg-gray-100 dark:divide-gray-700 dark:border-gray-700 dark:bg-gray-800"
|
||||||
|
role="menu" aria-orientation="vertical" aria-labelledby="menu-button" tabindex="-1">
|
||||||
|
<div class="flex flex-col py-1.5">
|
||||||
|
@foreach($perPageOptions as $option)
|
||||||
|
<x-filter-menu-item filterName="perPage" :filter="$option" :currentFilter="$perPage">{{ $option }}</x-filter-menu-item>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{-- Sort Dropdown --}}
|
||||||
<div class="relative inline-block" x-data="{ isSortOpen: false }" @click.away="isSortOpen = false">
|
<div class="relative inline-block" x-data="{ isSortOpen: false }" @click.away="isSortOpen = false">
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<button type="button" @click="isSortOpen = !isSortOpen" class="group inline-flex justify-center text-sm font-medium text-gray-700 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100" id="menu-button" :aria-expanded="isSortOpen.toString()" aria-haspopup="true">
|
<button type="button" @click="isSortOpen = !isSortOpen" class="group inline-flex justify-center text-sm font-medium text-gray-700 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100" id="menu-button" :aria-expanded="isSortOpen.toString()" aria-haspopup="true">
|
||||||
@ -120,9 +157,9 @@
|
|||||||
class="absolute top-7 right-0 z-10 flex w-full min-w-[12rem] flex-col divide-y divide-slate-300 overflow-hidden rounded-xl border border-gray-300 bg-gray-100 dark:divide-gray-700 dark:border-gray-700 dark:bg-gray-800"
|
class="absolute top-7 right-0 z-10 flex w-full min-w-[12rem] flex-col divide-y divide-slate-300 overflow-hidden rounded-xl border border-gray-300 bg-gray-100 dark:divide-gray-700 dark:border-gray-700 dark:bg-gray-800"
|
||||||
role="menu" aria-orientation="vertical" aria-labelledby="menu-button" tabindex="-1">
|
role="menu" aria-orientation="vertical" aria-labelledby="menu-button" tabindex="-1">
|
||||||
<div class="flex flex-col py-1.5">
|
<div class="flex flex-col py-1.5">
|
||||||
<x-filter-sort-menu-item order="created" :currentOrder="$order">{{ __('Newest') }}</x-filter-sort-menu-item>
|
<x-filter-menu-item filterName="order" filter="created" :currentFilter="$order">{{ __('Newest') }}</x-filter-menu-item>
|
||||||
<x-filter-sort-menu-item order="updated" :currentOrder="$order">{{ __('Recently Updated') }}</x-filter-sort-menu-item>
|
<x-filter-menu-item filterName="order" filter="updated" :currentFilter="$order">{{ __('Recently Updated') }}</x-filter-menu-item>
|
||||||
<x-filter-sort-menu-item order="downloaded" :currentOrder="$order">{{ __('Most Downloaded') }}</x-filter-sort-menu-item>
|
<x-filter-menu-item filterName="order" filter="downloaded" :currentFilter="$order">{{ __('Most Downloaded') }}</x-filter-menu-item>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -75,8 +75,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{-- Mods --}}
|
{{-- Mods --}}
|
||||||
<div x-show="selectedTab === 'mods'" class="">
|
<div x-show="selectedTab === 'mods'">
|
||||||
@if($mods)
|
@if($mods->count())
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
{{ $mods->links() }}
|
{{ $mods->links() }}
|
||||||
</div>
|
</div>
|
||||||
@ -89,7 +89,9 @@
|
|||||||
{{ $mods->links() }}
|
{{ $mods->links() }}
|
||||||
</div>
|
</div>
|
||||||
@else
|
@else
|
||||||
<p>{{ __('This user has not yet published any mods.') }}</p>
|
<p class="p-4 sm:p-6 bg-white dark:bg-gray-950 rounded-xl shadow-md dark:shadow-gray-950 text-gray-800 dark:text-gray-200 drop-shadow-2xl">
|
||||||
|
{{ __('This user has not yet published any mods.') }}
|
||||||
|
</p>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user