Template
## 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
60 lines
2.5 KiB
HTML
60 lines
2.5 KiB
HTML
{% extends "base.html" %}
|
|
{% block title %}Create account · {{ SITE_NAME }}{% endblock %}
|
|
{% block content %}
|
|
<section class="section section-lg">
|
|
<div class="container">
|
|
<div class="row justify-content-center">
|
|
<div class="col-md-8 col-lg-6">
|
|
<h3>Create an account</h3>
|
|
<p>Track orders, save a shipping address, and review products you bought. Card details stay with Stripe — we never store them.</p>
|
|
<form class="rd-form" method="post">
|
|
{% csrf_token %}
|
|
{{ form.non_field_errors }}
|
|
<div class="row row-20 gutter-20">
|
|
<div class="col-sm-6">
|
|
<div class="form-wrap">
|
|
<label class="form-label-outside" for="{{ form.first_name.id_for_label }}">First name</label>
|
|
{{ form.first_name }}
|
|
{{ form.first_name.errors }}
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-6">
|
|
<div class="form-wrap">
|
|
<label class="form-label-outside" for="{{ form.last_name.id_for_label }}">Last name</label>
|
|
{{ form.last_name }}
|
|
{{ form.last_name.errors }}
|
|
</div>
|
|
</div>
|
|
<div class="col-12">
|
|
<div class="form-wrap">
|
|
<label class="form-label-outside" for="{{ form.email.id_for_label }}">Email</label>
|
|
{{ form.email }}
|
|
{{ form.email.errors }}
|
|
</div>
|
|
</div>
|
|
<div class="col-12">
|
|
<div class="form-wrap">
|
|
<label class="form-label-outside" for="{{ form.password1.id_for_label }}">Password</label>
|
|
{{ form.password1 }}
|
|
{{ form.password1.errors }}
|
|
</div>
|
|
</div>
|
|
<div class="col-12">
|
|
<div class="form-wrap">
|
|
<label class="form-label-outside" for="{{ form.password2.id_for_label }}">Confirm password</label>
|
|
{{ form.password2 }}
|
|
{{ form.password2.errors }}
|
|
</div>
|
|
</div>
|
|
<div class="col-12">
|
|
<button class="button button-lg button-primary" type="submit">Create account</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
<p>Already have an account? <a href="{% url 'account:login' %}">Sign in</a></p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
{% endblock %}
|