I lowkey forgot to commit
This commit is contained in:
68
templates/album/search.html.twig
Normal file
68
templates/album/search.html.twig
Normal file
@@ -0,0 +1,68 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
{% block title %}Album Search{% endblock %}
|
||||
{% block body %}
|
||||
<h1 class="h4 mb-3">Search Albums</h1>
|
||||
<form class="row g-2 mb-2" action="{{ path('album_search') }}" method="get">
|
||||
<div class="col-sm">
|
||||
<input class="form-control" type="search" name="q" value="{{ query }}" placeholder="Free text (optional)" autocomplete="off" />
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<button class="btn btn-success" type="submit">Search</button>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<a class="link-secondary" data-bs-toggle="collapse" href="#advancedSearch" role="button" aria-expanded="false" aria-controls="advancedSearch">Advanced search</a>
|
||||
</div>
|
||||
<div class="collapse col-12" id="advancedSearch">
|
||||
<div class="row g-2 mt-1">
|
||||
<div class="col-sm-4">
|
||||
<input class="form-control" type="text" name="album" value="{{ album }}" placeholder="Album title" />
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<input class="form-control" type="text" name="artist" value="{{ artist }}" placeholder="Artist" />
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<input class="form-control" type="number" name="year_from" value="{{ year_from }}" 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 }}" placeholder="Year to" min="1900" max="2100" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{% if query is empty and (album is empty) and (artist is empty) and (year_from is empty) and (year_to is empty) %}
|
||||
<p class="text-secondary">Tip: Use the Advanced search to filter by album, artist, or year range.</p>
|
||||
{% endif %}
|
||||
|
||||
{% 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</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">
|
||||
<a class="btn btn-outline-success btn-sm" href="{{ album.external_urls.spotify }}" target="_blank" rel="noopener">Open in Spotify</a>
|
||||
<a class="btn btn-success btn-sm" href="{{ path('album_show', {id: album.id}) }}">Reviews</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% elseif query or album or artist or year_from or year_to %}
|
||||
<p>No albums found.</p>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
68
templates/album/show.html.twig
Normal file
68
templates/album/show.html.twig
Normal file
@@ -0,0 +1,68 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
{% block title %}{{ album.name }} — Reviews{% endblock %}
|
||||
{% block body %}
|
||||
<div class="row g-4 mb-4">
|
||||
<div class="col-md-4">
|
||||
<div class="card h-100">
|
||||
{% set image = (album.images[1] ?? album.images[0] ?? null) %}
|
||||
{% if image %}
|
||||
<img class="card-img-top" src="{{ image.url }}" alt="{{ album.name }} cover" />
|
||||
{% endif %}
|
||||
<div class="card-body">
|
||||
<h5 class="card-title mb-1">{{ album.name }}</h5>
|
||||
<div class="text-secondary mb-2">{{ album.artists|map(a => a.name)|join(', ') }}</div>
|
||||
<p class="text-secondary mb-2">Released {{ album.release_date }} • {{ album.total_tracks }} tracks</p>
|
||||
<p class="mb-2"><strong>User score:</strong> {{ avg }}/10 ({{ count }})</p>
|
||||
<a class="btn btn-outline-success btn-sm" href="{{ album.external_urls.spotify }}" target="_blank" rel="noopener">Open in Spotify</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||
<h2 class="h5 mb-0">Reviews</h2>
|
||||
</div>
|
||||
<div class="vstack gap-3 mb-4">
|
||||
{% for r in reviews %}
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h6 class="card-title mb-1">{{ r.title }} <span class="text-secondary">(Rating {{ r.rating }}/10)</span></h6>
|
||||
<div class="text-secondary mb-2">by {{ r.author.displayName ?? r.author.userIdentifier }} • {{ r.createdAt|date('Y-m-d H:i') }}</div>
|
||||
<p class="card-text">{{ r.content|u.truncate(300, '…', false) }}</p>
|
||||
<a class="btn btn-link p-0" href="{{ path('review_show', {id: r.id}) }}">Read more</a>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="text-secondary">No reviews yet for this album.</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% if app.user %}
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h3 class="h6">Leave a review</h3>
|
||||
{{ form_start(form, {attr: {class: 'vstack gap-3', novalidate: 'novalidate'}}) }}
|
||||
<div>{{ form_label(form.title) }}{{ form_widget(form.title, {attr: {class: 'form-control'}}) }}{{ form_errors(form.title) }}</div>
|
||||
<div>{{ form_label(form.content) }}{{ form_widget(form.content, {attr: {class: 'form-control', rows: 6}}) }}{{ form_errors(form.content) }}</div>
|
||||
<div>
|
||||
{{ form_label(form.rating) }}
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
{{ form_widget(form.rating, {attr: {class: 'form-range', min:1, max:10, step:1, list:'rating-ticks', oninput:'document.getElementById("rating-value").textContent=this.value;'}}) }}
|
||||
<span id="rating-value" class="badge text-bg-success">{{ form.rating.vars.value ?? 5 }}</span>
|
||||
</div>
|
||||
<datalist id="rating-ticks">
|
||||
{% for i in 1..10 %}<option value="{{ i }}">{{ i }}</option>{% endfor %}
|
||||
</datalist>
|
||||
{{ form_errors(form.rating) }}
|
||||
</div>
|
||||
<button class="btn btn-success" type="submit">Post review</button>
|
||||
{{ form_end(form) }}
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="alert alert-info">Sign in to leave a review. <button class="btn btn-sm btn-success ms-2" type="button" data-open-auth="login">Login / Sign up</button></div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user