mirror of
https://github.com/rico-vz/HeimerdingerLoL.git
synced 2025-12-06 10:10:48 +01:00
feat: Active Search for skins
This commit is contained in:
@@ -8,13 +8,14 @@ use App\Models\ChampionSkin;
|
|||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
use Spatie\QueryBuilder\AllowedFilter;
|
use Spatie\QueryBuilder\AllowedFilter;
|
||||||
use Spatie\QueryBuilder\QueryBuilder;
|
use Spatie\QueryBuilder\QueryBuilder;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class ChampionSkinController extends Controller
|
class ChampionSkinController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index(Request $request)
|
||||||
{
|
{
|
||||||
$skins = QueryBuilder::for(ChampionSkin::class)
|
$skins = QueryBuilder::for(ChampionSkin::class)
|
||||||
->allowedFilters(AllowedFilter::partial('name', 'skin_name'), 'rarity')
|
->allowedFilters(AllowedFilter::partial('name', 'skin_name'), 'rarity')
|
||||||
@@ -31,7 +32,7 @@ class ChampionSkinController extends Controller
|
|||||||
'Transcendent' => 'text-violet-400',
|
'Transcendent' => 'text-violet-400',
|
||||||
];
|
];
|
||||||
|
|
||||||
return view('skins.index', ['skins' => $skins, 'rarityColor' => $rarityColor]);
|
return view('skins.index', ['skins' => $skins, 'rarityColor' => $rarityColor])->fragmentIf($request->hasHeader('HX-Request'), 'skin-list');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -2,6 +2,10 @@
|
|||||||
@tailwind components;
|
@tailwind components;
|
||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
|
|
||||||
|
@view-transition {
|
||||||
|
navigation: auto; /* enabled! */
|
||||||
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-display: swap;
|
font-display: swap;
|
||||||
font-family: "Inter";
|
font-family: "Inter";
|
||||||
|
|||||||
@@ -8,58 +8,59 @@
|
|||||||
Champion Skins</h1>
|
Champion Skins</h1>
|
||||||
<x-skins.searchbar />
|
<x-skins.searchbar />
|
||||||
|
|
||||||
<div class="flex justify-center items-center mx-auto max-w-screen-xl mt-2.5">
|
@fragment('skin-list')
|
||||||
</div>
|
<div id="skin-list">
|
||||||
|
<div class="container flex items-center justify-center p-4 mx-auto mt-3" >
|
||||||
|
<div class="grid grid-cols-1 gap-12 md:grid-cols-2 lg:grid-cols-4">
|
||||||
|
@foreach ($skins as $key => $skin)
|
||||||
|
<div
|
||||||
|
class="flex flex-col text-gray-700 border shadow-md champ-card bg-stone-800/40 rounded-2xl bg-clip-border border-stone-800 hover:border-orange-500/10 hover:shadow-orange-500/10">
|
||||||
|
|
||||||
<div class="container flex items-center justify-center p-4 mx-auto mt-3">
|
@if ($skin->associated_skinline != null)
|
||||||
<div class="grid grid-cols-1 gap-12 md:grid-cols-2 lg:grid-cols-4">
|
<div class="flex justify-center px-2">
|
||||||
|
@foreach ($skin->associated_skinline as $skinline)
|
||||||
@foreach ($skins as $key => $skin)
|
<span class="sr-only">Associated Skinline:</span>
|
||||||
<div
|
<span
|
||||||
class="flex flex-col text-gray-700 border shadow-md champ-card bg-stone-800/40 rounded-2xl bg-clip-border border-stone-800 hover:border-orange-500/10 hover:shadow-orange-500/10">
|
class="m-2 bg-orange-100 text-orange-800 text-xs font-medium mr-2 px-2.5 py-0.5 rounded border border-orange-300">
|
||||||
|
{{ $skinline }}</span>
|
||||||
@if ($skin->associated_skinline != null)
|
@endforeach
|
||||||
<div class="flex justify-center px-2">
|
</div>
|
||||||
@foreach ($skin->associated_skinline as $skinline)
|
@endif
|
||||||
<span class="sr-only">Associated Skinline:</span>
|
<div class="mx-4 overflow-hidden border-2 h-52 rounded-2xl bg-clip-border border-orange-400/40">
|
||||||
<span
|
|
||||||
class="m-2 bg-orange-100 text-orange-800 text-xs font-medium mr-2 px-2.5 py-0.5 rounded border border-orange-300">
|
|
||||||
{{ $skinline }}</span>
|
|
||||||
@endforeach
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
<div class="mx-4 overflow-hidden border-2 h-52 rounded-2xl bg-clip-border border-orange-400/40">
|
|
||||||
<a href="/skin/{{ $skin->slug }}">
|
|
||||||
<img @if ($key < 8) loading="eager" @else loading="lazy" @endif
|
|
||||||
src="//wsrv.nl/?url={{ $skin->getSkinImageAttribute() }}&w=540&output=webp&q=70&il"
|
|
||||||
class="object-cover w-full h-full" alt="{{ $skin->skin_name }} Splash Art" />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="px-4 py-2">
|
|
||||||
<div class="flex items-center justify-between">
|
|
||||||
<p class="block text-base antialiased font-medium text-gray-100">
|
|
||||||
<a href="/skin/{{ $skin->slug }}">
|
<a href="/skin/{{ $skin->slug }}">
|
||||||
{{ $skin->skin_name }}
|
<img @if ($key < 8) loading="eager" @else loading="lazy" @endif
|
||||||
|
src="//wsrv.nl/?url={{ $skin->getSkinImageAttribute() }}&w=540&output=webp&q=70&il"
|
||||||
|
class="object-cover w-full h-full" alt="{{ $skin->skin_name }} Splash Art" />
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</div>
|
||||||
<span
|
|
||||||
class="text-xs font-bold {{ $rarityColor[$skin->rarity] }}">{{ $skin->rarity }}</span>
|
|
||||||
|
|
||||||
|
<div class="px-4 py-2">
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<p class="block text-base antialiased font-medium text-gray-100">
|
||||||
|
<a href="/skin/{{ $skin->slug }}">
|
||||||
|
{{ $skin->skin_name }}
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
<span
|
||||||
|
class="text-xs font-bold {{ $rarityColor[$skin->rarity] }}">{{ $skin->rarity }}</span>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex items-end justify-center px-4 mt-auto mb-2 text-2xl text-white md:text-lg">
|
||||||
|
<p class="text-sm font-medium hover:text-orange-400"><a
|
||||||
|
href="/skin/{{ $skin->slug }}">More
|
||||||
|
details
|
||||||
|
<x-iconsax-bul-arrow-circle-right class="inline-block w-6" />
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
@endforeach
|
||||||
|
|
||||||
<div class="flex items-end justify-center px-4 mt-auto mb-2 text-2xl text-white md:text-lg">
|
|
||||||
<p class="text-sm font-medium hover:text-orange-400"><a href="/skin/{{ $skin->slug }}">More
|
|
||||||
details
|
|
||||||
<x-iconsax-bul-arrow-circle-right class="inline-block w-6" />
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
@endforeach
|
</div>
|
||||||
|
{{ $skins->links() }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
@endfragment
|
||||||
{{ $skins->links() }}
|
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@@ -1,20 +1,16 @@
|
|||||||
|
<script src="https://unpkg.com/htmx.org@2.0.0"></script>
|
||||||
<div class="flex items-center justify-center mt-8">
|
<div class="flex items-center justify-center mt-8">
|
||||||
<form action="{{ route('skins.index') }}" method="GET" class="flex" id="searchForm">
|
<form method="GET" class="flex" id="searchForm">
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<input type="text" name="filter[name]" placeholder="Search by skin name"
|
<input hx-get="{{ route('skins.index') }}" hx-trigger="keyup changed delay:100ms" hx-target="#skin-list" hx-swap-oob="true" type="text" name="filter[name]" placeholder="Search by skin name" value="{{ request('filter.name') }}"
|
||||||
value="{{ request('filter.name') }}"
|
class="px-4 py-2 pr-10 text-white border border-transparent rounded shadow-md focus:border-transparent focus:ring-0 border-stone-700 bg-stone-800 ring-orange-500">
|
||||||
class="border border-transparent focus:border-transparent focus:ring-0 border-stone-700 rounded-l px-4 py-2 bg-stone-800 text-white ring-orange-500 pr-10">
|
|
||||||
@if (request('filter.name'))
|
@if (request('filter.name'))
|
||||||
<button type="button" onclick="clearSearchAndSubmit()"
|
<button type="button" onclick="clearSearchAndSubmit()"
|
||||||
class="absolute inset-y-0 right-0 flex items-center px-3 bg-stone-800 text-white cursor-pointer">
|
class="absolute inset-y-0 right-0 flex items-center px-3 text-white cursor-pointer bg-stone-800">
|
||||||
<x-iconsax-lin-clipboard-close class="w-6 text-white"/>
|
<x-iconsax-lin-clipboard-close class="w-6 text-white" />
|
||||||
</button>
|
</button>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
<button type="submit"
|
|
||||||
class="bg-orange-500 hover:bg-orange-600 text-white font-semibold px-4 py-2 rounded-r focus:outline-none ring-orange-500">
|
|
||||||
Search
|
|
||||||
</button>
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ Route::get('roadmap', static fn () => (new HomeController())->roadmap())->name('
|
|||||||
Route::get('champions', static fn () => (new ChampionController())->index())->name('champions.index');
|
Route::get('champions', static fn () => (new ChampionController())->index())->name('champions.index');
|
||||||
Route::get('champion/{champion}', static fn (Champion $champion) => (new ChampionController())->show($champion))->name('champions.show');
|
Route::get('champion/{champion}', static fn (Champion $champion) => (new ChampionController())->show($champion))->name('champions.show');
|
||||||
// Skins
|
// Skins
|
||||||
Route::get('skins', static fn () => (new ChampionSkinController())->index())->name('skins.index');
|
Route::get('skins', static fn (Request $request) => (new ChampionSkinController())->index($request))->name('skins.index');
|
||||||
Route::get('skin/{championSkin}', static fn (ChampionSkin $championSkin) => (new ChampionSkinController())->show($championSkin))->name('skins.show');
|
Route::get('skin/{championSkin}', static fn (ChampionSkin $championSkin) => (new ChampionSkinController())->show($championSkin))->name('skins.show');
|
||||||
|
|
||||||
// Icons
|
// Icons
|
||||||
|
|||||||
Reference in New Issue
Block a user