This commit is contained in:
2026-05-12 19:35:15 +03:00
parent c451a106a1
commit 0fdb8b8a02
17 changed files with 1351 additions and 8 deletions

View File

@@ -0,0 +1,105 @@
{% extends "base.html" %}
{% load humanize %}
{% block title %}Print dashboard — hamprint{% endblock %}
{% block content %}
<header class="mb-6">
<h1 class="text-2xl font-bold tracking-tight">Print dashboard</h1>
<p class="text-slate-600 mt-1">Every public print job submitted to the hamlab.lt 3d printers. Look up your submission by its codename. Prints are <b>pickup-only</b>.</p>
</header>
{% comment %}
Status filter chips. The "All" chip is active when no ?status= filter is
set. Each specific chip is active when its value matches `active_status`.
{% endcomment %}
<div class="flex flex-wrap items-center gap-2 mb-4">
<a href="?" class="px-3 py-1.5 text-sm rounded-full border {% if not active_status %}border-slate-900 bg-slate-900 text-white{% else %}border-slate-300 bg-white text-slate-700 hover:bg-slate-100{% endif %}">
All <span class="{% if not active_status %}opacity-70{% else %}text-slate-400{% endif %}">{{ counts.total }}</span>
</a>
<a href="?status=verifying" class="px-3 py-1.5 text-sm rounded-full border {% if active_status == 'verifying' %}border-slate-900 bg-slate-900 text-white{% else %}border-slate-300 bg-white text-slate-700 hover:bg-slate-100{% endif %}">
Verifying <span class="{% if active_status == 'verifying' %}opacity-70{% else %}text-slate-400{% endif %}">{{ counts.verifying }}</span>
</a>
<a href="?status=queued" class="px-3 py-1.5 text-sm rounded-full border {% if active_status == 'queued' %}border-slate-900 bg-slate-900 text-white{% else %}border-slate-300 bg-white text-slate-700 hover:bg-slate-100{% endif %}">
Queued <span class="{% if active_status == 'queued' %}opacity-70{% else %}text-slate-400{% endif %}">{{ counts.queued }}</span>
</a>
<a href="?status=printing" class="px-3 py-1.5 text-sm rounded-full border {% if active_status == 'printing' %}border-slate-900 bg-slate-900 text-white{% else %}border-slate-300 bg-white text-slate-700 hover:bg-slate-100{% endif %}">
Printing <span class="{% if active_status == 'printing' %}opacity-70{% else %}text-slate-400{% endif %}">{{ counts.printing }}</span>
</a>
<a href="?status=completed" class="px-3 py-1.5 text-sm rounded-full border {% if active_status == 'completed' %}border-slate-900 bg-slate-900 text-white{% else %}border-slate-300 bg-white text-slate-700 hover:bg-slate-100{% endif %}">
Completed <span class="{% if active_status == 'completed' %}opacity-70{% else %}text-slate-400{% endif %}">{{ counts.completed }}</span>
</a>
</div>
{% if submissions %}
<div class="bg-white border border-slate-200 rounded-lg overflow-hidden">
<table class="w-full text-sm">
<thead class="bg-slate-50 border-b border-slate-200 text-slate-600">
<tr class="text-left">
<th class="px-4 py-2.5 font-medium">Codename</th>
<th class="px-4 py-2.5 font-medium">Status</th>
<th class="px-4 py-2.5 font-medium hidden sm:table-cell">Age</th>
</tr>
</thead>
<tbody class="divide-y divide-slate-100">
{% for sub in submissions %}
<tr class="hover:bg-slate-50">
<td class="px-4 py-3">
<span class="mono text-amber-700 font-medium">{{ sub.slug }}</span>
{% if user.is_authenticated and sub.submitted_by_id == user.id %}
<span class="ml-2 inline-flex items-center px-1.5 py-0.5 rounded bg-amber-100 text-amber-900 text-[10px] font-semibold uppercase tracking-wide" title="You submitted this print">yours</span>
{% endif %}
</td>
<td class="px-4 py-3">
<span class="inline-flex items-center gap-1.5 px-2 py-0.5 rounded-full {{ sub.status_badge_class }} text-xs font-medium">{{ sub.get_status_display }}</span>
</td>
<td class="px-4 py-3 hidden sm:table-cell text-slate-500">{{ sub.created_at|naturaltime }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% if is_paginated %}
<div class="flex items-center justify-between mt-4 text-sm">
<p class="text-slate-500">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}
&middot; {{ page_obj.paginator.count }} total
</p>
<div class="flex items-center gap-1">
{% if page_obj.has_previous %}
<a href="?{% if active_status %}status={{ active_status }}&{% endif %}page={{ page_obj.previous_page_number }}" class="px-3 py-1.5 rounded-md border border-slate-300 bg-white text-slate-700 hover:bg-slate-100">← Previous</a>
{% else %}
<span class="px-3 py-1.5 rounded-md border border-slate-200 text-slate-400 cursor-not-allowed">← Previous</span>
{% endif %}
{% if page_obj.has_next %}
<a href="?{% if active_status %}status={{ active_status }}&{% endif %}page={{ page_obj.next_page_number }}" class="px-3 py-1.5 rounded-md border border-slate-300 bg-white text-slate-700 hover:bg-slate-100">Next →</a>
{% else %}
<span class="px-3 py-1.5 rounded-md border border-slate-200 text-slate-400 cursor-not-allowed">Next →</span>
{% endif %}
</div>
</div>
{% endif %}
{% else %}
<div class="rounded-lg border border-slate-200 bg-white p-8 text-center">
<p class="text-slate-700 font-medium">
{% if active_status %}No submissions in <span class="lowercase">{{ active_status }}</span> right now.{% else %}No submissions yet.{% endif %}
</p>
<p class="text-slate-500 text-sm mt-1">
{% if active_status %}Try one of the other filter chips above, or{% else %}Be the first &mdash;{% endif %}
submit a print and you'll see it appear here once an operator has verified it.
</p>
<a href="{% url 'submissions:create' %}" class="inline-block mt-5 px-4 py-2 rounded-md bg-amber-500 text-white hover:bg-amber-600 font-medium text-sm">+ Submit a print</a>
</div>
{% endif %}
{% if not user.is_authenticated %}
<div class="mt-10 rounded-lg border border-amber-200 bg-amber-50 p-4 flex items-start gap-3">
<div class="w-8 h-8 rounded-full bg-amber-500 text-white grid place-items-center flex-shrink-0 font-bold">?</div>
<div class="text-sm">
<p class="font-semibold text-amber-900">Don't have an account?</p>
<p class="text-amber-800/90 mt-0.5">You don't need one. Just hit <a href="{% url 'submissions:create' %}" class="underline font-medium">Submit a print</a>, give us an email, and we'll send you a codename to track your job.</p>
</div>
</div>
{% endif %}
{% endblock %}