diff options
| author | Tyler Hoang <tyler@tylerhoang.xyz> | 2026-05-06 14:34:01 -0700 |
|---|---|---|
| committer | Tyler Hoang <tyler@tylerhoang.xyz> | 2026-05-06 14:34:01 -0700 |
| commit | a3df69ff5218cee132a6def9d860cd0276cc0cd4 (patch) | |
| tree | 2d8bf71b98a606b2f1194ce608c23a8e17d8cb6c /templates | |
| parent | e708bec6cd76c2686de4158dde4d04f72a3c300d (diff) | |
Add year review and inline diary ratings
Diffstat (limited to 'templates')
| -rw-r--r-- | templates/_film_card.html | 14 | ||||
| -rw-r--r-- | templates/detail.html | 80 | ||||
| -rw-r--r-- | templates/stats.html | 9 | ||||
| -rw-r--r-- | templates/year_review.html | 175 |
4 files changed, 256 insertions, 22 deletions
diff --git a/templates/_film_card.html b/templates/_film_card.html index 9fcd89b..7147a1e 100644 --- a/templates/_film_card.html +++ b/templates/_film_card.html @@ -21,7 +21,19 @@ {% endif %} </p> </div> - {% if film.stars %} + {% if film.shelf == 'diary' %} + <div class="star-control" role="group" aria-label="Rate film" data-film-id="{{ film.id }}" data-current-stars="{{ film.stars }}"> + {% for value in range(1, 4) %} + <button + type="button" + class="star-button {% if film.stars >= value %}is-active{% endif %}" + data-stars="{{ value }}" + aria-label="{{ value }} star{% if value > 1 %}s{% endif %}" + aria-pressed="{% if film.stars >= value %}true{% else %}false{% endif %}" + >✦</button> + {% endfor %} + </div> + {% elif film.stars %} <span class="rating">{% for _ in range(film.stars) %}✦{% endfor %}</span> {% endif %} </div> diff --git a/templates/detail.html b/templates/detail.html index b937c6b..df3f96a 100644 --- a/templates/detail.html +++ b/templates/detail.html @@ -12,6 +12,20 @@ <span>{{ film.title[:1] }}</span> {% endif %} </div> + <div class="detail-aside-meta"> + <div> + <span class="summary-label">Shelf</span> + <strong>{{ film.shelf|title }}</strong> + </div> + <div> + <span class="summary-label">Watched</span> + <strong>{% if film.date_watched %}{{ film.date_watched }}{% else %}Not set{% endif %}</strong> + </div> + <div> + <span class="summary-label">Stars</span> + <strong>{% if film.stars %}{% for _ in range(film.stars) %}✦{% endfor %}{% else %}Unstarred{% endif %}</strong> + </div> + </div> </aside> <section class="detail-body"> @@ -31,29 +45,57 @@ {% endif %} </p> - <div class="detail-meta"> - {% if film.stars %}<span class="rating">{% for _ in range(film.stars) %}✦{% endfor %}</span>{% endif %} - {% if film.date_watched %}<span>{{ film.date_watched }}</span>{% endif %} - {% if film.runtime %}<span>{{ film.runtime }} min</span>{% endif %} - {% if film.rewatch %}<span>Rewatch{% if film.rewatch_count %} #{{ film.rewatch_count }}{% endif %}</span>{% endif %} - {% if film.country %}<span>{{ film.country }}</span>{% endif %} - {% if film.language %}<span>{{ film.language }}</span>{% endif %} - </div> + <section class="detail-grid"> + <article class="detail-panel"> + <p class="eyebrow">Watch log</p> + <div class="detail-meta"> + {% if film.date_watched %}<span>{{ film.date_watched }}</span>{% endif %} + {% if film.runtime %}<span>{{ film.runtime }} min</span>{% endif %} + {% if film.rewatch %}<span>Rewatch{% if film.rewatch_count %} #{{ film.rewatch_count }}{% endif %}</span>{% endif %} + {% if film.watched_with %}<span>With {{ film.watched_with }}</span>{% endif %} + {% if film.context %}<span>{{ film.context }}</span>{% endif %} + {% if film.how_found %}<span>{{ film.how_found }}</span>{% endif %} + </div> + </article> - {% if film.context or film.how_found or film.watched_with %} - <div class="tag-row detail-tags"> - {% if film.context %}<span>{{ film.context }}</span>{% endif %} - {% if film.how_found %}<span>{{ film.how_found }}</span>{% endif %} - {% if film.watched_with %}<span>With {{ film.watched_with }}</span>{% endif %} - </div> - {% endif %} + <article class="detail-panel"> + <p class="eyebrow">Production</p> + <div class="detail-meta"> + {% if film.country %}<span>{{ film.country }}</span>{% endif %} + {% if film.language %}<span>{{ film.language }}</span>{% endif %} + {% if film.year %}<span>{{ film.year }}</span>{% endif %} + {% if film.tmdb_id %}<span>TMDB {{ film.tmdb_id }}</span>{% endif %} + </div> + </article> + </section> - {% if film.notes %} - <div class="notes-body"> - {{ film.notes }} - </div> + {% if tmdb_context %} + <section class="detail-panel"> + <p class="eyebrow">Summary</p> + {% if tmdb_context.tagline %} + <p class="detail-tagline">{{ tmdb_context.tagline }}</p> + {% endif %} + {% if tmdb_context.overview %} + <p class="detail-overview">{{ tmdb_context.overview }}</p> + {% endif %} + {% if tmdb_context.cast %} + <div class="detail-cast"> + <span class="summary-label">Cast</span> + <p>{{ tmdb_context.cast|join(", ") }}</p> + </div> + {% endif %} + </section> {% endif %} + <section class="detail-panel"> + <p class="eyebrow">Notes</p> + {% if film.notes %} + <div class="notes-body">{{ film.notes }}</div> + {% else %} + <p class="muted">No notes saved.</p> + {% endif %} + </section> + <div class="detail-actions"> <a class="secondary-button" href="/films/{{ film.id }}/edit">Edit</a> {% if film.shelf == 'queue' %} diff --git a/templates/stats.html b/templates/stats.html index 7b54634..2983418 100644 --- a/templates/stats.html +++ b/templates/stats.html @@ -4,8 +4,13 @@ {% block content %} <section class="page-heading"> - <p class="eyebrow">Stats</p> - <h1>Watching patterns</h1> + <div class="page-heading-row"> + <div> + <p class="eyebrow">Stats</p> + <h1>Watching patterns</h1> + </div> + <a class="button-link" href="/stats/year-in-review">Year in review</a> + </div> </section> <section class="stats-layout"> diff --git a/templates/year_review.html b/templates/year_review.html new file mode 100644 index 0000000..5339c34 --- /dev/null +++ b/templates/year_review.html @@ -0,0 +1,175 @@ +{% extends "base.html" %} + +{% block title %}{{ selected_year }} Year in Review · Lumière{% endblock %} + +{% block content %} + <section class="review-hero"> + <div> + <p class="eyebrow">Year in Review</p> + <h1>{{ selected_year }}</h1> + <p class="review-intro">A snapshot of the films you logged that year.</p> + </div> + + <form class="year-picker" method="get" action="/stats/year-in-review"> + <label for="year">Year</label> + <select id="year" name="year" onchange="this.form.submit()"> + {% for option in available_years %} + <option value="{{ option }}" {% if option == selected_year %}selected{% endif %}>{{ option }}</option> + {% endfor %} + </select> + </form> + </section> + + {% if total_watched == 0 %} + <section class="empty-state"> + <p class="eyebrow">No entries</p> + <h2>No diary films for this year</h2> + <p>Pick another year or add more diary entries.</p> + </section> + {% else %} + <section class="review-metrics"> + <article class="summary-card"> + <span class="summary-label">Films watched</span> + <strong>{{ total_watched }}</strong> + </article> + <article class="summary-card"> + <span class="summary-label">Average stars</span> + <strong>{{ "%.1f"|format(average_stars) }}</strong> + </article> + <article class="summary-card"> + <span class="summary-label">Rewatch rate</span> + <strong>{{ (rewatch_rate.rate * 100)|round(0) }}%</strong> + </article> + <article class="summary-card"> + <span class="summary-label">Top director</span> + <strong>{% if top_director %}{{ top_director.director }}{% else %}—{% endif %}</strong> + </article> + <article class="summary-card"> + <span class="summary-label">Top month</span> + <strong>{% if top_month %}{{ top_month.month }}{% else %}—{% endif %}</strong> + </article> + </section> + + <section class="review-grid"> + <article class="review-panel review-panel-wide"> + <p class="eyebrow">Monthly activity</p> + <div class="year-bars"> + {% set max_month = films_per_month | map(attribute='count') | max if films_per_month else 1 %} + {% for item in films_per_month %} + <div class="year-bar-row"> + <span>{{ item.month[:3] }}</span> + <div class="year-bar-track"> + <div class="year-bar-fill" style="width: {{ (item.count / max_month * 100) if max_month else 0 }}%"></div> + </div> + <strong>{{ item.count }}</strong> + </div> + {% endfor %} + </div> + </article> + + <article class="review-panel"> + <p class="eyebrow">Stars</p> + <div class="stats-bars"> + {% set max_stars = star_distribution | map(attribute='count') | max if star_distribution else 1 %} + {% for item in star_distribution %} + <div class="stats-bar-row"> + <span>{{ item.stars }} star</span> + <div class="stats-bar-track"><div class="stats-bar-fill" style="width: {{ (item.count / max_stars * 100) if max_stars else 0 }}%"></div></div> + <strong>{{ item.count }}</strong> + </div> + {% endfor %} + </div> + </article> + + <article class="review-panel"> + <p class="eyebrow">Companions</p> + <ol class="stats-list"> + {% for item in watched_with_breakdown %} + <li><span>{{ item.watched_with }}</span><strong>{{ item.count }}</strong></li> + {% endfor %} + </ol> + </article> + </section> + + <section class="review-panel"> + <p class="eyebrow">Highlights</p> + <div class="highlight-grid"> + {% if highlight_films.highest_rated %} + {% for film in highlight_films.highest_rated %} + <article class="highlight-card"> + <a class="poster-frame" href="/films/{{ film.id }}"> + {% if film.poster_url %} + <img src="{{ film.poster_url }}" alt="{{ film.title }} poster"> + {% else %} + <span>{{ film.title[:1] }}</span> + {% endif %} + </a> + <div> + <h2><a href="/films/{{ film.id }}">{{ film.title }}</a></h2> + <p class="muted">{{ film.director or "Unknown director" }}</p> + <p class="highlight-meta"> + {% if film.date_watched %}{{ film.date_watched }}{% endif %} + {% if film.stars %} · {% for _ in range(film.stars) %}✦{% endfor %}{% endif %} + </p> + {% if film.notes_excerpt %} + <p class="notes-preview">{{ film.notes_excerpt }}</p> + {% endif %} + </div> + </article> + {% endfor %} + {% endif %} + + {% if highlight_films.first_watch %} + <article class="highlight-card"> + <a class="poster-frame" href="/films/{{ highlight_films.first_watch.id }}"> + {% if highlight_films.first_watch.poster_url %} + <img src="{{ highlight_films.first_watch.poster_url }}" alt="{{ highlight_films.first_watch.title }} poster"> + {% else %} + <span>{{ highlight_films.first_watch.title[:1] }}</span> + {% endif %} + </a> + <div> + <p class="summary-label">First watch</p> + <h2><a href="/films/{{ highlight_films.first_watch.id }}">{{ highlight_films.first_watch.title }}</a></h2> + <p class="muted">{{ highlight_films.first_watch.date_watched }}</p> + </div> + </article> + {% endif %} + + {% if highlight_films.last_watch %} + <article class="highlight-card"> + <a class="poster-frame" href="/films/{{ highlight_films.last_watch.id }}"> + {% if highlight_films.last_watch.poster_url %} + <img src="{{ highlight_films.last_watch.poster_url }}" alt="{{ highlight_films.last_watch.title }} poster"> + {% else %} + <span>{{ highlight_films.last_watch.title[:1] }}</span> + {% endif %} + </a> + <div> + <p class="summary-label">Last watch</p> + <h2><a href="/films/{{ highlight_films.last_watch.id }}">{{ highlight_films.last_watch.title }}</a></h2> + <p class="muted">{{ highlight_films.last_watch.date_watched }}</p> + </div> + </article> + {% endif %} + + {% if highlight_films.most_rewatched %} + <article class="highlight-card"> + <a class="poster-frame" href="/films/{{ highlight_films.most_rewatched.id }}"> + {% if highlight_films.most_rewatched.poster_url %} + <img src="{{ highlight_films.most_rewatched.poster_url }}" alt="{{ highlight_films.most_rewatched.title }} poster"> + {% else %} + <span>{{ highlight_films.most_rewatched.title[:1] }}</span> + {% endif %} + </a> + <div> + <p class="summary-label">Most rewatched</p> + <h2><a href="/films/{{ highlight_films.most_rewatched.id }}">{{ highlight_films.most_rewatched.title }}</a></h2> + <p class="muted">{{ highlight_films.most_rewatched.rewatch_count }} rewatches</p> + </div> + </article> + {% endif %} + </div> + </section> + {% endif %} +{% endblock %} |
