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
37 lines
1.1 KiB
Python
37 lines
1.1 KiB
Python
from django import forms
|
|
from django.conf import settings
|
|
|
|
|
|
class ContactForm(forms.Form):
|
|
INTEREST_CHOICES = [
|
|
("general", "General inquiry"),
|
|
("quote", "Request a quote"),
|
|
("support", "Support"),
|
|
("other", "Something else"),
|
|
]
|
|
|
|
email = forms.EmailField(
|
|
widget=forms.EmailInput(attrs={"class": "form-input", "id": "contact-email"}),
|
|
)
|
|
interest = forms.ChoiceField(
|
|
choices=INTEREST_CHOICES,
|
|
widget=forms.Select(attrs={"class": "form-input", "id": "contact-interest"}),
|
|
)
|
|
message = forms.CharField(
|
|
widget=forms.Textarea(attrs={"class": "form-input", "id": "contact-message"}),
|
|
)
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
if settings.RECAPTCHA_PUBLIC_KEY and settings.RECAPTCHA_PRIVATE_KEY:
|
|
from django_recaptcha.fields import ReCaptchaField
|
|
from django_recaptcha.widgets import ReCaptchaV3
|
|
|
|
self.fields["captcha"] = ReCaptchaField(widget=ReCaptchaV3)
|
|
|
|
|
|
class NotifyForm(forms.Form):
|
|
email = forms.EmailField(
|
|
widget=forms.EmailInput(attrs={"class": "form-input"}),
|
|
)
|