Add completed/abandoned shelves with status transitions
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

Items can be moved to Completed or Abandoned via card buttons.
Only active items appear in the default/category tabs; completed and
abandoned items are visible only in their respective shelf tabs.
Restore button moves items back to active.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-01 23:19:10 +03:00
parent 095614cb65
commit da11a056ed
5 changed files with 81 additions and 2 deletions

View File

@@ -53,6 +53,10 @@
.btn-outline { background: transparent; color: #94a3b8; border: 1px solid #334155; }
.btn-danger { background: transparent; color: #f87171; border: 1px solid #f87171; padding: 0.3rem 0.65rem; font-size: 0.78rem; }
.btn-danger:hover { background: #f87171; color: #0f172a; opacity: 1; }
.btn-done { background: transparent; color: #34d399; border: 1px solid #34d399; padding: 0.3rem 0.65rem; font-size: 0.78rem; }
.btn-done:hover { background: #34d399; color: #0f172a; opacity: 1; }
.btn-abandon { background: transparent; color: #fb923c; border: 1px solid #fb923c; padding: 0.3rem 0.65rem; font-size: 0.78rem; }
.btn-abandon:hover { background: #fb923c; color: #0f172a; opacity: 1; }
.filter-bar {
display: flex;
@@ -72,6 +76,7 @@
}
.tab:hover { color: #e2e8f0; }
.tab.active { color: #38bdf8; border-bottom-color: #38bdf8; }
.tab-sep { width: 1px; background: #1e293b; margin: 0.5rem 0.25rem; align-self: stretch; }
.sort-wrap { padding-bottom: 0.75rem; }
.sort-wrap select {
@@ -175,13 +180,19 @@
<div class="filter-bar">
<div class="tabs">
<a href="?sort={{ sort }}" class="tab {% if shelf == 'active' %}active{% endif %}">Active</a>
<a href="?shelf=completed&sort={{ sort }}" class="tab {% if shelf == 'completed' %}active{% endif %}">Completed</a>
<a href="?shelf=abandoned&sort={{ sort }}" class="tab {% if shelf == 'abandoned' %}active{% endif %}">Abandoned</a>
{% if shelf == 'active' %}
<span class="tab-sep"></span>
<a href="?sort={{ sort }}" class="tab {% if not category %}active{% endif %}">All</a>
{% for val, label in categories %}
<a href="?category={{ val }}&sort={{ sort }}" class="tab {% if category == val %}active{% endif %}">{{ label }}</a>
{% endfor %}
{% endif %}
</div>
<div class="sort-wrap">
<select onchange="location='?category={{ category }}&sort='+this.value">
<select onchange="location='?shelf={{ shelf }}&category={{ category }}&sort='+this.value">
<option value="fav" {% if sort == 'fav' %}selected{% endif %}>Favorites first</option>
<option value="az" {% if sort == 'az' %}selected{% endif %}>A → Z</option>
<option value="za" {% if sort == 'za' %}selected{% endif %}>Z → A</option>
@@ -229,6 +240,27 @@
<div class="card-actions">
<a href="{% url 'backlogger:edit' item.pk %}" class="btn btn-sm btn-outline">Edit</a>
{% if shelf == 'active' %}
<form method="post" action="{% url 'backlogger:set_status' item.pk %}">
{% csrf_token %}
<input type="hidden" name="status" value="completed">
<input type="hidden" name="next" value="{{ request.get_full_path }}">
<button type="submit" class="btn btn-done">Done</button>
</form>
<form method="post" action="{% url 'backlogger:set_status' item.pk %}">
{% csrf_token %}
<input type="hidden" name="status" value="abandoned">
<input type="hidden" name="next" value="{{ request.get_full_path }}">
<button type="submit" class="btn btn-abandon">Abandon</button>
</form>
{% else %}
<form method="post" action="{% url 'backlogger:set_status' item.pk %}">
{% csrf_token %}
<input type="hidden" name="status" value="active">
<input type="hidden" name="next" value="{{ request.get_full_path }}">
<button type="submit" class="btn btn-sm btn-outline">Restore</button>
</form>
{% endif %}
<form method="post" action="{% url 'backlogger:delete' item.pk %}" onsubmit="return confirm('Delete &quot;{{ item.name }}&quot;?')">
{% csrf_token %}
<button type="submit" class="btn btn-danger">Delete</button>