generated from westfarn/web_django_template
Match banner brand, print splash, optional crop, and demo seed (#6)
## Summary - Rebrand public site, portal, and emails from Ecoprint orange to the PRINTFORGE banner palette (navy / cyan / lime). - Replace the loading splash with a CSS 3D-print animation; product uploads get a default-on smart crop + background filter checkbox. - Add `manage.py seed_demo` for client walkthroughs on dev/beta only (refuses prod). Closes #5. ## Test plan - [ ] Public pages and buttons are cyan/lime, not orange - [ ] Splash shows a printer building a model (or a static print if reduced motion) - [ ] Product edit: smart-crop checked by default; uncheck stores the original photo - [ ] `uv run python manage.py seed_demo` fills shop, contacts, leads, orders, campaigns - [ ] `DJANGO_ENV=prod` seed_demo exits with an error Reviewed-on: #6
This commit was merged in pull request #6.
This commit is contained in:
+11
-5
@@ -418,7 +418,7 @@ def normalize_hex(value: str) -> str:
|
||||
return raw.lower()
|
||||
|
||||
|
||||
def store_product_image(*, upload, user) -> StoredFile:
|
||||
def store_product_image(*, upload, user, smart_crop: bool = True) -> StoredFile:
|
||||
content_type = (getattr(upload, "content_type", None) or "").lower()
|
||||
if content_type not in _ALLOWED_IMAGE_TYPES:
|
||||
raise ShopError("Use a JPEG, PNG, GIF, or WebP image.")
|
||||
@@ -427,15 +427,18 @@ def store_product_image(*, upload, user) -> StoredFile:
|
||||
raise ShopError("Image must be 15 MB or smaller.")
|
||||
original = (getattr(upload, "name", None) or "product")[:255]
|
||||
try:
|
||||
from shop.imaging import prepare_product_photo, product_image_filename
|
||||
from shop.imaging import open_image, prepare_product_photo, product_image_filename
|
||||
except ImportError as exc:
|
||||
logger.exception("product photo processing dependencies missing")
|
||||
raise ShopError(
|
||||
"Image processing is not installed. Rebuild the app container."
|
||||
) from exc
|
||||
try:
|
||||
data, content_type = prepare_product_photo(data)
|
||||
original = product_image_filename(original)
|
||||
if smart_crop:
|
||||
data, content_type = prepare_product_photo(data)
|
||||
original = product_image_filename(original)
|
||||
else:
|
||||
open_image(data)
|
||||
except ShopError:
|
||||
raise
|
||||
except Exception as exc:
|
||||
@@ -569,12 +572,15 @@ def append_product_images(
|
||||
uploads,
|
||||
user,
|
||||
color: ProductColor | None = None,
|
||||
smart_crop: bool = True,
|
||||
) -> None:
|
||||
existing = product.images.filter(color=color).count()
|
||||
for offset, upload in enumerate(uploads):
|
||||
if not upload:
|
||||
continue
|
||||
stored = store_product_image(upload=upload, user=user)
|
||||
stored = store_product_image(
|
||||
upload=upload, user=user, smart_crop=smart_crop
|
||||
)
|
||||
ProductImage.objects.create(
|
||||
product=product,
|
||||
color=color,
|
||||
|
||||
Reference in New Issue
Block a user