Files

78 lines
4.2 KiB
HTML

{{- /* games-filter.html — Alpine.js-powered filter for the slots library.
Call with (dict "page" . "games" <slice of game pages>).
Cards are rendered server-side (so thumbnails use the image pipeline) and
shown/hidden by the gamesFilter Alpine component (assets/js/games-filter.js). */ -}}
{{- $games := .games -}}
{{- $providers := slice -}}
{{- range $games -}}{{ with .Params.provider }}{{ $providers = $providers | append . }}{{ end }}{{- end -}}
{{- $providers = $providers | uniq | sort -}}
{{- $categories := slice -}}
{{- range $games -}}{{ with .Params.category }}{{ $categories = $categories | append . }}{{ end }}{{- end -}}
{{- $categories = $categories | uniq | sort -}}
<div x-data="gamesFilter()" x-init="recount()" x-effect="recount()">
{{/* Controls */}}
<div class="grid gap-3 rounded-xl border border-secondary/10 bg-secondary/5 p-4 sm:grid-cols-3">
<div>
<label for="game-search" class="mb-1 block text-xs font-semibold uppercase tracking-wide text-secondary/60">{{ i18n "filterSearch" }}</label>
<input id="game-search" type="search" x-model="search" placeholder="Game name&hellip;"
class="w-full rounded-md border border-secondary/20 px-3 py-2 text-sm focus-visible:outline-primary">
</div>
<div>
<label for="game-provider" class="mb-1 block text-xs font-semibold uppercase tracking-wide text-secondary/60">{{ i18n "filterProvider" }}</label>
<select id="game-provider" x-model="provider" class="w-full rounded-md border border-secondary/20 px-3 py-2 text-sm focus-visible:outline-primary">
<option value="all">{{ i18n "filterAllProviders" }}</option>
{{- range $providers }}<option value="{{ . }}">{{ . }}</option>{{ end -}}
</select>
</div>
<div>
<label for="game-category" class="mb-1 block text-xs font-semibold uppercase tracking-wide text-secondary/60">{{ i18n "filterCategory" }}</label>
<select id="game-category" x-model="category" class="w-full rounded-md border border-secondary/20 px-3 py-2 text-sm focus-visible:outline-primary">
<option value="all">{{ i18n "filterAllCategories" }}</option>
{{- range $categories }}<option value="{{ . }}">{{ . | title }}</option>{{ end -}}
</select>
</div>
</div>
<div class="mt-3 flex items-center justify-between text-sm text-secondary/60">
<p><span x-text="visibleCount"></span> game(s) shown</p>
<button type="button" @click="reset()" class="font-semibold text-primary hover:underline">{{ i18n "filterReset" }}</button>
</div>
{{/* Cards */}}
<div class="mt-5 grid gap-5 sm:grid-cols-2 lg:grid-cols-3">
{{- range $games -}}
{{- $img := .Resources.GetMatch "thumb.*" -}}
<article data-game
data-provider="{{ .Params.provider }}"
data-category="{{ .Params.category }}"
data-title="{{ .Title | lower }}"
x-show="cardVisible($el)" x-transition.opacity
class="card card-hover overflow-hidden p-0">
<div class="aspect-[3/2] w-full overflow-hidden bg-secondary/10">
{{ partial "responsive-image.html" (dict
"resource" $img
"alt" (printf "%s by %s" .Title (.Params.provider | default "provider"))
"class" "h-full w-full object-cover"
"widths" (slice 300 600)
"sizes" "(min-width:1024px) 300px, (min-width:640px) 50vw, 100vw") }}
</div>
<div class="p-4">
<div class="flex items-center justify-between gap-2">
<span class="badge-primary">{{ .Params.provider }}</span>
<span class="badge-muted capitalize">{{ .Params.category }}</span>
</div>
<h3 class="mt-2 text-lg font-bold"><a href="{{ .RelPermalink }}" class="no-underline hover:underline">{{ .Title }}</a></h3>
{{ with .Params.rtp }}<p class="mt-1 text-sm text-secondary/60">RTP {{ . }}%</p>{{ end }}
</div>
</article>
{{- end -}}
</div>
<p x-show="visibleCount === 0" x-cloak class="mt-6 rounded-lg bg-secondary/5 p-6 text-center text-secondary/70">
No games match your filters. <button type="button" @click="reset()" class="font-semibold text-primary underline">Reset</button>
</p>
</div>