Add detail page

This commit is contained in:
2026-05-15 00:08:14 +03:00
parent 219f0a5259
commit 15dc6147dd
9 changed files with 295 additions and 22 deletions

View File

@@ -8,8 +8,8 @@ urlpatterns = [
path("", views.IndexView.as_view(), name="index"),
path("my-prints/", views.MyPrintsView.as_view(), name="my_prints"),
path("p/<slug:slug>/confirm/<str:token>/", views.ConfirmEmailView.as_view(), name="confirm"),
path("p/<slug:slug>/", views.SubmissionDetailView.as_view(), name="detail"),
# Routes to be added as features land (see plan.md Section 7):
# path("p/<slug:slug>/", views.SubmissionDetailView.as_view(), name="detail"),
# path("p/<slug:slug>/status/", views.SubmissionStatusFragment.as_view(), name="status"),
# path("p/<slug:slug>/resend/", views.ResendConfirmationView.as_view(), name="resend"),
]

View File

@@ -6,7 +6,7 @@ from django.db.models import Count, Q
from django.shortcuts import get_object_or_404, redirect
from django.utils.html import format_html
from django.views import View
from django.views.generic import ListView
from django.views.generic import DetailView, ListView
from apps.submissions.models import Submission, VerifiedEmail
@@ -60,6 +60,50 @@ class IndexView(ListView):
return ctx
class SubmissionDetailView(DetailView):
"""Per-submission detail page at `/p/<slug>/` (plan.md §7.4 step 7).
Two access tiers, gated on whether the viewer owns the row:
- **Anyone with the slug** sees a minimal card -- slug, status badge,
age. That's it. Keeps the URL safe to share, gives anonymous /
non-owner visitors enough to confirm they're looking at the right
submission without leaking source URLs, uploaded filenames,
operator notes, or the submitter's notes-to-operator.
- **Logged-in owner only** (`submission.submitted_by == request.user`)
sees the full demo/detail-completed.html layout: status banner,
source card, operator notes, the user's own notes_for_op, details
sidebar with submitter / created / closed timestamps.
Guests never see the owner view -- they aren't logged in by
definition, so condition (1) fails. They can still navigate to /p/X/
via the URL we email them, they just get the minimal card. Once
operator admin actions get wired, we'll grow a `?token=` fast-path
for guests to view their own row, but that's plan.md §7.6 territory.
"""
model = Submission
template_name = "dashboard/detail.html"
context_object_name = "submission"
slug_url_kwarg = "slug"
slug_field = "slug"
def get_queryset(self):
return super().get_queryset().select_related(
"submitted_by", "requested_filament", "closed_by"
)
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
sub: Submission = self.object
ctx["is_owner"] = (
self.request.user.is_authenticated
and sub.submitted_by_id is not None
and sub.submitted_by_id == self.request.user.id
)
return ctx
class ConfirmEmailView(View):
"""Email-confirmation landing page (plan.md §7.4 step 8).