162 lines
8.6 KiB
Twig
162 lines
8.6 KiB
Twig
{% extends 'base.html.twig' %}
|
|
{% block title %}Album Search{% endblock %}
|
|
{% block body %}
|
|
{% set query_value = query|default('') %}
|
|
{% set album_value = album|default('') %}
|
|
{% set artist_value = artist|default('') %}
|
|
{% set year_from_value = year_from|default('') %}
|
|
{% set year_to_value = year_to|default('') %}
|
|
{% set genre_value = genre|default('') %}
|
|
{% set source_value = source|default('all') %}
|
|
{% set has_search = (query_value is not empty) or (album_value is not empty) or (artist_value is not empty) or (genre_value is not empty) or (year_from_value is not empty) or (year_to_value is not empty) or (source_value != 'all') %}
|
|
{% set advanced_open = (album_value is not empty) or (artist_value is not empty) or (genre_value is not empty) or (year_from_value is not empty) or (year_to_value is not empty) or (source_value != 'all') %}
|
|
{% set landing_view = not has_search %}
|
|
|
|
{% if landing_view %}
|
|
<style>
|
|
.landing-search-form {
|
|
max-width: 640px;
|
|
margin: 0 auto;
|
|
}
|
|
.landing-search-input {
|
|
border-radius: 999px;
|
|
padding: 1rem 1.5rem;
|
|
font-size: 1.1rem;
|
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
|
|
}
|
|
</style>
|
|
{% endif %}
|
|
|
|
<h1 class="{{ landing_view ? 'display-6 text-center mb-4' : 'h4 mb-3' }}">Search Albums</h1>
|
|
{% if source_value != 'user' and spotifyConfigured is defined and not spotifyConfigured %}
|
|
<div class="alert alert-info">
|
|
Spotify is not configured yet. Results will only include user-created albums.
|
|
{% if is_granted('ROLE_ADMIN') %}
|
|
<a class="alert-link" href="{{ path('admin_settings') }}">Enter Spotify credentials</a>.
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
<form class="{{ landing_view ? 'landing-search-form mb-4' : 'row g-2 mb-2 align-items-center' }}" action="{{ path('album_search') }}" method="get">
|
|
{% if landing_view %}
|
|
<div>
|
|
<input class="form-control form-control-lg landing-search-input" type="search" name="q" value="{{ query_value }}" placeholder="Search albums, artists..." autocomplete="off" />
|
|
</div>
|
|
<div class="d-flex justify-content-center gap-3 mt-3">
|
|
<button class="btn btn-success px-4" type="submit">Search</button>
|
|
<button class="btn btn-outline-secondary px-4" type="button" data-bs-toggle="collapse" data-bs-target="#advancedSearch" aria-expanded="{{ advanced_open ? 'true' : 'false' }}" aria-controls="advancedSearch">Advanced</button>
|
|
</div>
|
|
<div class="mt-3">
|
|
<div class="collapse {{ advanced_open ? 'show' : '' }}" id="advancedSearch">
|
|
<div class="row g-2">
|
|
<div class="col-sm-3 order-sm-4">
|
|
<select class="form-select" name="source">
|
|
<option value="all" {{ source_value == 'all' ? 'selected' : '' }}>All sources</option>
|
|
<option value="spotify" {{ source_value == 'spotify' ? 'selected' : '' }}>Spotify</option>
|
|
<option value="user" {{ source_value == 'user' ? 'selected' : '' }}>User-created</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-sm-4">
|
|
<input class="form-control" type="text" name="album" value="{{ album_value }}" placeholder="Album title" />
|
|
</div>
|
|
<div class="col-sm-4">
|
|
<input class="form-control" type="text" name="artist" value="{{ artist_value }}" placeholder="Artist" />
|
|
</div>
|
|
<div class="col-sm-4">
|
|
<input class="form-control" type="text" name="genre" value="{{ genre_value }}" placeholder="Genre" />
|
|
</div>
|
|
<div class="col-sm-2">
|
|
<input class="form-control" type="number" name="year_from" value="{{ year_from_value }}" placeholder="Year from" min="1900" max="2100" />
|
|
</div>
|
|
<div class="col-sm-2">
|
|
<input class="form-control" type="number" name="year_to" value="{{ year_to_value }}" placeholder="Year to" min="1900" max="2100" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% else %}
|
|
<div class="col-sm">
|
|
<input class="form-control" type="search" name="q" value="{{ query_value }}" placeholder="Search.." autocomplete="off" />
|
|
</div>
|
|
<div class="col-auto d-flex gap-2">
|
|
<button class="btn btn-success" type="submit">Search</button>
|
|
<button class="btn btn-outline-secondary" type="button" data-bs-toggle="collapse" data-bs-target="#advancedSearch" aria-expanded="{{ advanced_open ? 'true' : 'false' }}" aria-controls="advancedSearch">Advanced</button>
|
|
</div>
|
|
<div class="collapse col-12 {{ advanced_open ? 'show' : '' }}" id="advancedSearch">
|
|
<div class="row g-2 mt-1">
|
|
<div class="col-sm-3 order-sm-4">
|
|
<select class="form-select" name="source">
|
|
<option value="all" {{ source_value == 'all' ? 'selected' : '' }}>All sources</option>
|
|
<option value="spotify" {{ source_value == 'spotify' ? 'selected' : '' }}>Spotify</option>
|
|
<option value="user" {{ source_value == 'user' ? 'selected' : '' }}>User-created</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-sm-4">
|
|
<input class="form-control" type="text" name="album" value="{{ album_value }}" placeholder="Album title" />
|
|
</div>
|
|
<div class="col-sm-4">
|
|
<input class="form-control" type="text" name="artist" value="{{ artist_value }}" placeholder="Artist" />
|
|
</div>
|
|
<div class="col-sm-4">
|
|
<input class="form-control" type="text" name="genre" value="{{ genre_value }}" placeholder="Genre" />
|
|
</div>
|
|
<div class="col-sm-2">
|
|
<input class="form-control" type="number" name="year_from" value="{{ year_from_value }}" placeholder="Year from" min="1900" max="2100" />
|
|
</div>
|
|
<div class="col-sm-2">
|
|
<input class="form-control" type="number" name="year_to" value="{{ year_to_value }}" placeholder="Year to" min="1900" max="2100" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
</form>
|
|
|
|
{% if albums is defined and albums|length > 0 %}
|
|
<div class="row row-cols-1 row-cols-sm-2 row-cols-md-3 row-cols-lg-4 g-3">
|
|
{% for album in albums %}
|
|
<div class="col">
|
|
<div class="card h-100">
|
|
{% set image = (album.images[1] ?? album.images[0] ?? null) %}
|
|
{% if image %}
|
|
<a href="{{ path('album_show', {id: album.id}) }}">
|
|
<img class="card-img-top" src="{{ image.url }}" alt="{{ album.name }} cover" />
|
|
</a>
|
|
{% endif %}
|
|
<div class="card-body d-flex flex-column">
|
|
<h5 class="card-title"><a href="{{ path('album_show', {id: album.id}) }}" class="text-decoration-none">{{ album.name }}</a></h5>
|
|
<p class="card-text text-secondary">{{ album.artists|map(a => a.name)|join(', ') }}</p>
|
|
<p class="card-text text-secondary">
|
|
Released {{ album.release_date }} • {{ album.total_tracks }} tracks
|
|
{% if album.genres is defined and album.genres is not empty %}
|
|
<br><small>Genre: {{ album.genres|join(', ') }}</small>
|
|
{% endif %}
|
|
</p>
|
|
{% set s = stats[album.id] ?? { 'avg': 0, 'count': 0 } %}
|
|
<p class="card-text"><small class="text-secondary">User score: {{ s.avg }}/10 ({{ s.count }})</small></p>
|
|
<div class="mt-auto">
|
|
{% if album.external_urls.spotify is defined and album.external_urls.spotify %}
|
|
<a class="btn btn-outline-success btn-sm" href="{{ album.external_urls.spotify }}" target="_blank" rel="noopener">Open in Spotify</a>
|
|
{% endif %}
|
|
<a class="btn btn-success btn-sm" href="{{ path('album_show', {id: album.id}) }}">Reviews</a>
|
|
{% if app.user and (album.source is not defined or album.source != 'user') %}
|
|
{% if savedIds is defined and (album.id in savedIds) %}
|
|
{# Saved indicator intentionally omitted to reduce noise #}
|
|
{% else %}
|
|
<form class="d-inline ms-2" method="post" action="{{ path('album_save', {id: album.id}) }}">
|
|
<input type="hidden" name="_token" value="{{ csrf_token('save-album-' ~ album.id) }}">
|
|
<button class="btn btn-outline-primary btn-sm" type="submit">Save</button>
|
|
</form>
|
|
{% endif %}
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
{% elseif query or album or artist or genre or year_from or year_to %}
|
|
<p>No albums found.</p>
|
|
{% endif %}
|
|
{% endblock %}
|
|
|
|
|