Template
Add shopper accounts, reviews, tracking, and seed_demo (#10)
## Summary - Closes #9. Port shop-gated buyer accounts (register/login/profile, password reset, order history), purchase-gated reviews, and Stripe customer ids. Cards stay on Stripe. - Slim public contact form to email + interest + message. Shipping tracking status, scan events, paste-in numbers, and EasyPost webhook when FEATURE_SHIPPING is on. - Add template-neutral `seed_demo` (generic SKUs, demo shoppers, guest orders, tracking stubs). Prod refused. `--reset` deletes tagged demo rows after invoices. ## Test plan - [ ] `cd site && uv run python manage.py test` (173 tests passed locally) - [ ] Shop on: `/account/register`, login, profile, password reset, claim guest orders by email - [ ] Shop off: `/account/` URLs absent; Sign in / Account links hidden - [ ] Checkout as logged-in buyer stores `Order.user` and Stripe customer id; product review only after paid purchase - [ ] Shipping on: portal paste-in tracking + EasyPost webhook updates status; shipping off: orders still work without tracking UI - [ ] `seed_demo` refused in prod; `--reset` rebuilds tagged catalog/shoppers without deleting staff invoices Reviewed-on: #10
This commit was merged in pull request #10.
This commit is contained in:
1 parent
9cdce7a897
commit
f3e34f5099
66 files changed
+3051
-285
No files matched your search
@@ -3,8 +3,52 @@
|
||||
{% block topbar_title %}{{ shipment.order.number }}{% endblock %}
|
||||
{% block portal_content %}
|
||||
<p>{{ shipment.order.email }} · {{ shipment.get_status_display }}</p>
|
||||
{% if shipment.tracking_number %}<p>Tracking: {{ shipment.tracking_number }}</p>{% endif %}
|
||||
{% if shipment.tracking_number %}
|
||||
<p>
|
||||
Tracking: {{ shipment.tracking_number }}
|
||||
{% if shipment.tracking_status %} · {{ shipment.get_tracking_status_display }}{% endif %}
|
||||
</p>
|
||||
{% if shipment.tracking_url %}<p><a href="{{ shipment.tracking_url }}" target="_blank" rel="noopener">Track package</a></p>{% endif %}
|
||||
<form method="post" action="{% url 'shipping:shipment_refresh_tracking' shipment.pk %}">
|
||||
{% csrf_token %}
|
||||
<button class="btn btn-ghost btn-sm" type="submit">Refresh tracking</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
{% if shipment.label_url %}<p><a href="{{ shipment.label_url }}">Download label</a></p>{% endif %}
|
||||
|
||||
<h3>Add tracking</h3>
|
||||
<p class="hint-block">Paste a number from Pirate Ship or the carrier. EasyPost looks up scan events when an API key is set.</p>
|
||||
<form method="post" action="{% url 'shipping:shipment_attach_tracking' shipment.pk %}">
|
||||
{% csrf_token %}
|
||||
<div class="form-grid">
|
||||
<div class="field">
|
||||
<label for="id_tracking_number">Tracking number</label>
|
||||
<input id="id_tracking_number" name="tracking_number" value="{{ shipment.tracking_number }}" required>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="id_carrier">Carrier</label>
|
||||
<input id="id_carrier" name="carrier" value="{{ shipment.carrier }}" placeholder="USPS, UPS, FedEx">
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-primary" type="submit">Save tracking</button>
|
||||
</form>
|
||||
|
||||
{% if shipment.tracking_events %}
|
||||
<h3>Scan history</h3>
|
||||
<table class="table">
|
||||
<thead><tr><th>When</th><th>Status</th><th>Detail</th></tr></thead>
|
||||
<tbody>
|
||||
{% for event in shipment.tracking_events %}
|
||||
<tr>
|
||||
<td>{{ event.datetime }}</td>
|
||||
<td>{{ event.status }}</td>
|
||||
<td>{{ event.message }}{% if event.location %} · {{ event.location }}{% endif %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endif %}
|
||||
|
||||
{% if shipment.status != 'labeled' %}
|
||||
<form method="post" action="{% url 'shipping:shipment_buy' shipment.pk %}">
|
||||
{% csrf_token %}
|
||||
|
||||
Reference in new issue
Block a user