feat: skin grid info

This commit is contained in:
Rico van Zelst
2023-11-09 14:55:57 +01:00
parent 050c8c7975
commit c542a2421b
8 changed files with 275 additions and 8 deletions

View File

@@ -51,7 +51,25 @@ class ChampionSkinController extends Controller
*/ */
public function show(ChampionSkin $championSkin) public function show(ChampionSkin $championSkin)
{ {
// $skin = Cache::remember(
'championSkinShowCache' . $championSkin->slug,
60 * 60 * 8,
function () use ($championSkin) {
return $championSkin->load('champion', 'chromas');
}
);
$splashColor = Cache::remember(
'championSkinSplashColorCache' . $championSkin->slug,
60 * 60 * 24,
function () use ($championSkin) {
return getAverageColorFromImageUrl($championSkin->getSkinImageAttribute());
}
);
$skin->splash_color = $splashColor;
return view('skins.show', compact('skin'));
} }
/** /**

View File

@@ -35,6 +35,11 @@ class SkinChroma extends Model
public function skin(): BelongsTo public function skin(): BelongsTo
{ {
return $this->belongsTo(Skin::class); return $this->belongsTo(ChampionSkin::class, 'full_skin_id', 'full_skin_id');
}
public function getChromaImageAttribute()
{
return 'https://raw.communitydragon.org/pbe/plugins/rcp-be-lol-game-data/global/default/v1/champion-chroma-images/' . $this->skin->champion_id . '/' . $this->chroma_id . '.png';
} }
} }

View File

@@ -0,0 +1,19 @@
<?php
namespace App\View\Components\Skins;
use App\Models\ChampionSkin;
use Illuminate\Contracts\View\View;
use Illuminate\View\Component;
class Grid_info extends Component
{
public function __construct(public ChampionSkin $skin)
{
}
public function render(): View
{
return view('components.skins.grid_info');
}
}

View File

@@ -0,0 +1,172 @@
<section class="max-w-screen-xl mx-auto mt-12">
<p class="sr-only">Heimerdinger Presents:</p>
<h3
class="text-sm font-bold text-center text-transparent uppercase sm:text-md
bg-gradient-to-bl from-orange-300 to-orange-500 bg-clip-text">
SKIN DETAILS</h3>
<h1
class="text-3xl font-bold text-center text-transparent uppercase sm:text-4xl
bg-gradient-to-bl from-orange-300 to-orange-500 bg-clip-text">
{{$skin->skin_name}}</h1>
<div class="container mx-auto p-4 flex items-center justify-center mt-3">
<div class="w-screen grid grid-cols-1 md-grid-cols-2 lg:grid-cols-3 gap-5">
<div
class="relative rounded-2xl bg-stone-800/40 border border-neutral-300/5 shadow-sm shadow-stone-800/80 lg:col-span-2 ">
<div class="aspect-w-16 aspect-h-9 glow-shadow absolute inset-0 rounded-2xl"
style="--splash-color: {{$skin->splash_color}}"></div>
<div class="aspect-w-16 aspect-h-9 overflow-hidden rounded-2xl relative">
<img
src="//wsrv.nl/?url={{ $skin->getSkinImageAttribute() }}&w=880&output=webp&q=85&il"
alt="{{$skin->skin_name}} Splash Art"
class="w-full h-full object-cover transform scale-100 transition-transform duration-700 hover:scale-105 z-10"
>
</div>
</div>
<div
class="rounded-2xl border border-3 border-white/10
lg:col-start-3 shadow-md transition-all duration-700"
style="--tw-shadow-color:{{$skin->splash_color}}; --tw-shadow: var(--tw-shadow-colored); background-color: {{$skin->splash_color}};">
<h4 class="text-center text-lg font-semibold text-neutral-100 uppercase mt-3.5 shadow-sm mx-2">
{{$skin->skin_name}} Details</h4>
<ul class="ml-7 ">
<li class="text-neutral-100 hyphens-auto text-base font-medium leading-loose items-center mt-8"
lang="en">
<span class="font-bold">Riot Points Cost:</span>
@if ($skin->rp_price == '99999')
Not Available for RP
@else
<x-icon-RiotPoints class="inline-block w-4"/>
{{ $skin->rp_price }} RP
@endif
</li>
<li class="text-neutral-100 hyphens-auto text-base font-medium leading-loose items-center"
lang="en">
<span class="font-bold">Release Date:</span> {{$skin->release_date}}
</li>
<li class="text-neutral-100 hyphens-auto text-base font-medium leading-loose items-center"
lang="en">
<span class="font-bold">Rarity:</span> {{$skin->rarity}}
</li>
<li class="text-neutral-100 hyphens-auto text-base font-medium leading-loose items-center"
lang="en">
<span class="font-bold">Availability:</span> {{$skin->availability}}
</li>
<li class="text-neutral-100 hyphens-auto text-base font-medium leading-loose items-center"
lang="en">
<span class="font-bold">Chromas:</span> @if ($skin->chromas->count() > 0)
{{$skin->chromas->count()}}
@else
None
@endif
</li>
<li class="text-neutral-100 hyphens-auto text-base font-medium leading-loose items-center"
lang="en">
<span class="font-bold">Lootable:</span> {{$skin->loot_eligible ? 'Yes' : 'No'}}
</li>
<li class="text-neutral-100 hyphens-auto text-base font-medium leading-loose items-center"
lang="en">
<span class="font-bold">New Effects:</span> {{$skin->new_effects ? 'Yes' : 'No'}}
</li>
<li class="text-neutral-100 hyphens-auto text-base font-medium leading-loose items-center"
lang="en">
<span class="font-bold">New Animations:</span> {{$skin->new_animations ? 'Yes' : 'No'}}
</li>
<li class="text-neutral-100 hyphens-auto text-base font-medium leading-loose items-center"
lang="en">
<span class="font-bold">New Recall:</span> {{$skin->new_recall ? 'Yes' : 'No'}}
</li>
<li class="text-neutral-100 hyphens-auto text-base font-medium leading-loose items-center"
lang="en">
<span class="font-bold">New Voice:</span> {{$skin->new_voice ? 'Yes' : 'No'}}
</li>
<li class="text-neutral-100 hyphens-auto text-base font-medium leading-loose items-center"
lang="en">
<span class="font-bold">New Quotes:</span> {{$skin->new_quotes ? 'Yes' : 'No'}}
</li>
<li class="text-neutral-100 hyphens-auto text-base font-medium leading-loose items-center"
lang="en">
<span class="font-bold">Voice Actor:</span>
@if(count($skin->voice_actor) < 1)
Unknown
@else
@foreach($skin->voice_actor as $voice_actor)
{{ $voice_actor }}
@endforeach
@endif
</li>
<li class="text-neutral-100 hyphens-auto text-base font-medium leading-loose items-center"
lang="en">
<span class="font-bold">Splash Artist:</span>
@if(count($skin->splash_artist) < 1)
Unknown
@else
@foreach($skin->splash_artist as $key => $splash_artist)
{{ $splash_artist }}
@if($key < count($skin->splash_artist) - 2)
,
@elseif($key == count($skin->splash_artist) - 2)
&amp;
@endif
@endforeach
@endif
</li>
</ul>
</div>
<div class="rounded-2xl border border-3 border-white/10 shadow-md
shadow-stone-800/80 hover:shadow-orange-500/20 transition-all duration-700"
style="--tw-shadow-color:{{$skin->splash_color}}; --tw-shadow: var(--tw-shadow-colored); background-color: {{$skin->splash_color}};">
<div class="p-4">
<h4 class="text-center text-xl font-semibold text-neutral-100 uppercase mt-2.5 shadow-sm">
{{$skin->name}} Lore</h4>
<p class="text-neutral-100 hyphens-auto text-base mt-2.5 leading-loose" lang="en">
{{$skin->lore}}
</p>
</div>
</div>
<div
class="rounded-2xl border border-3 border-white/10 shadow-md
shadow-stone-800/80 lg:col-span-2 hover:shadow-orange-500/20 transition-all duration-700"
style="--tw-shadow-color:{{$skin->splash_color}}; --tw-shadow: var(--tw-shadow-colored); background-color: {{$skin->splash_color}};">
<div class="p-4">
<h4 class="text-center text-xl font-semibold text-neutral-100 uppercase mt-2.5 shadow-sm">
{{$skin->name}} Chromas ({{count($skin->chromas)}}) </h4>
<div id="skinsElement" class="overflow-x-scroll mt-2.5">
<div class="grid grid-flow-col grid-rows-2 w-max gap-4 mb-2.5">
@foreach($skin->chromas as $key => $chroma)
<div class="group flex flex-col ">
<a href="/skin/{{$skin->slug}}">
<img
src="//wsrv.nl/?url={{ $chroma->getChromaImageAttribute() }}&w=220&output=webp&q=70&il"
alt="{{$chroma->chroma_name}} {{$chroma->skin_name}} ScreenShot"
@if($key < 6) loading="eager" @else loading="lazy" @endif
class=" inline-block h-36 object-cover rounded-2xl shadow-md border border-3 border-white/10
hover:shadow-orange-500/20 transition-all duration-700 mr-2.5">
</a>
<div>
<p class="align-bottom text-center text-neutral-100 text-sm mt-1.5 items-center">
<span
class="hover:text-orange-400 group-hover:text-orange-400">
{{$chroma->chroma_name}}
</span>
</p>
</div>
</div>
@endforeach
</div>
</div>
</div>
</div>
</div>
</div>
</section>

View File

@@ -5,7 +5,7 @@
<h2 <h2
class="text-3xl font-bold text-center text-transparent uppercase sm:text-4xl class="text-3xl font-bold text-center text-transparent uppercase sm:text-4xl
bg-gradient-to-bl from-orange-300 to-orange-500 bg-clip-text"> bg-gradient-to-bl from-orange-300 to-orange-500 bg-clip-text">
Skins</h2> Champion Skins</h2>
<div class="flex justify-center items-center mx-auto max-w-screen-xl mt-2.5"> <div class="flex justify-center items-center mx-auto max-w-screen-xl mt-2.5">
</div> </div>
@@ -52,7 +52,7 @@
<div <div
class="mb-2 px-4 flex justify-center items-end text-white text-2xl md:text-lg mt-auto"> class="mb-2 px-4 flex justify-center items-end text-white text-2xl md:text-lg mt-auto">
<p class="font-medium text-sm hover:text-orange-400 "><a <p class="font-medium text-sm hover:text-orange-400 "><a
href="#">More details href="/skin/{{$skin->slug}}">More details
<x-iconsax-bul-arrow-circle-right class="inline-block w-6"/> <x-iconsax-bul-arrow-circle-right class="inline-block w-6"/>
</a> </a>
</p> </p>

View File

@@ -0,0 +1,56 @@
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Favicon -->
<link rel="apple-touch-icon" sizes="180x180" href="/icons/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/icons/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/icons/favicon-16x16.png">
<link rel="manifest" href="/icons/site.webmanifest">
<link rel="mask-icon" href="/icons/safari-pinned-tab.svg" color="#e6855e">
<link rel="shortcut icon" href="/icons/favicon.ico">
<meta name="msapplication-TileColor" content="#ff7c47">
<meta name="msapplication-config" content="/icons/browserconfig.xml">
<meta name="theme-color" content="#ff7c47">
<title>{{$skin->skin_name}} Heimerdinger.LoL</title>
<meta name="description"
content="Heimerdinger.LoL: {{$skin->skin_name}} details showing all the information about the {{$skin->rarity}} {{$skin->champion->name}} skin. {{substr($skin->lore, 0, 50)}}...">
<!-- OpenGraph -->
<meta property="og:site_name" content="Heimerdinger.LoL">
<meta property="og:title" content="{{$skin->skin_name}} • Heimerdinger.LoL">
<meta property="og:description"
content="Heimerdinger.LoL: {{$skin->skin_name}} details showing all the information about the {{$skin->rarity}} {{$skin->champion->name}} skin. {{substr($skin->lore, 0, 50)}}...">
<meta property="og:locale" content="en">
<meta property="og:type" content="website">
<meta property="og:image" content="{{asset('img/og_image.png')}}">
<!-- Twitter -->
<meta name="twitter:card" content="summary_large_image">
<meta property="twitter:domain" content="heimerdinger.lol">
<meta property="twitter:title" content="{{$skin->skin_name}} • Heimerdinger.LoL">
<meta property="twitter:description"
content="Heimerdinger.LoL: {{$skin->skin_name}} details showing all the information about the {{$skin->rarity}} {{$skin->champion->name}} skin. {{substr($skin->lore, 0, 50)}}...">
<meta property="twitter:image" content="{{asset('img/og_image.png')}}">
<link rel="preconnect" href="https://rsms.me/">
<link rel="preload" href="https://rsms.me/inter/inter.css" as="style">
<link rel="stylesheet" href="https://rsms.me/inter/inter.css" media="print" onload="this.media='all'">
@vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body class="antialiased bg-stone-900 dark scroll-smooth">
<x-navbar/>
<x-skins.grid_info :skin="$skin"/>
<x-footer/>
@vite('resources/js/vert-scroll.js')
</body>
</html>

View File

@@ -13,7 +13,3 @@ use Illuminate\Support\Facades\Route;
| be assigned to the "api" middleware group. Make something great! | be assigned to the "api" middleware group. Make something great!
| |
*/ */
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});

View File

@@ -23,3 +23,4 @@ Route::get('/champions', [ChampionController::class, 'index']);
Route::get('/champion/{champion}', [ChampionController::class, 'show']); Route::get('/champion/{champion}', [ChampionController::class, 'show']);
// Skins // Skins
Route::get('/skins', [ChampionSkinController::class, 'index']); Route::get('/skins', [ChampionSkinController::class, 'index']);
Route::get('/skin/{championSkin}', [ChampionSkinController::class, 'show']);