feat: add media library picker for product images

- Add admin media API endpoints for vendor media management
- Create reusable media_picker_modal macro in modals.html
- Create mediaPickerMixin Alpine.js helper for media selection
- Update product create/edit forms with media picker UI
- Support main image + additional images selection
- Add upload functionality within the picker modal
- Update vendor_product_service to handle additional_images
- Add additional_images field to Pydantic schemas

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-08 02:16:55 +01:00
parent 5e188cd253
commit 5271ecb378
10 changed files with 1207 additions and 42 deletions

View File

@@ -107,6 +107,7 @@ class VendorProductDetail(BaseModel):
availability_source: str | None = None
primary_image_url: str | None = None
primary_image_url_source: str | None = None
additional_images: list[str] | None = None
is_digital: bool | None = None
product_type: str | None = None
# Vendor-specific fields
@@ -138,6 +139,10 @@ class VendorProductDetail(BaseModel):
# Translations
marketplace_translations: dict | None = None
vendor_translations: dict | None = None
# Convenience fields for UI display
title: str | None = None
description: str | None = None
image_url: str | None = None # Alias for primary_image_url
# Timestamps
created_at: str | None = None
updated_at: str | None = None
@@ -177,8 +182,9 @@ class VendorProductCreate(BaseModel):
tax_rate_percent: int | None = 17 # Default Luxembourg VAT
availability: str | None = None
# Image
# Images
primary_image_url: str | None = None
additional_images: list[str] | None = None
# Status
is_active: bool = True
@@ -227,6 +233,7 @@ class VendorProductUpdate(BaseModel):
# Images
primary_image_url: str | None = None
additional_images: list[str] | None = None
# Optional supplier info
supplier: str | None = None