feat: Implement event image upload system for promoters

- Add Active Storage migrations for file attachments
- Update Event model to handle image uploads with validation
- Replace image URL fields with file upload in forms
- Add client-side image preview with validation
- Update all views to display uploaded images properly
- Fix JSON serialization to prevent stack overflow in API
- Add custom image validation methods for format and size
- Include image processing variants for different display sizes
- Fix promotion code test infrastructure and Stripe configuration

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
kbe
2025-09-30 00:41:03 +02:00
parent be7b3d5c18
commit 6be8b95ed3
22 changed files with 450 additions and 36 deletions

View File

@@ -22,7 +22,9 @@ class Event < ApplicationRecord
has_many :tickets, through: :ticket_types
has_many :orders
has_many :promotion_codes
has_one_attached :image
# === Callbacks ===
before_validation :geocode_address, if: :should_geocode_address?
@@ -32,7 +34,8 @@ class Event < ApplicationRecord
validates :slug, presence: true, length: { minimum: 3, maximum: 100 }
validates :description, presence: true, length: { minimum: 10, maximum: 2000 }
validates :state, presence: true, inclusion: { in: states.keys }
validates :image, length: { maximum: 500 } # URL or path to image
validate :image_format, if: -> { image.attached? }
validate :image_size, if: -> { image.attached? }
# Venue information
validates :venue_name, presence: true, length: { maximum: 100 }
@@ -58,6 +61,20 @@ class Event < ApplicationRecord
# === Instance Methods ===
# Get image variants for different display sizes
def event_image_variant(size = :medium)
case size
when :large
image.variant(resize_to_limit: [1200, 630])
when :medium
image.variant(resize_to_limit: [800, 450])
when :small
image.variant(resize_to_limit: [400, 225])
else
image
end
end
# Check if coordinates were successfully geocoded or are fallback coordinates
def geocoding_successful?
coordinates_look_valid?
@@ -131,6 +148,25 @@ class Event < ApplicationRecord
nil
end
# Validate image format
def image_format
return unless image.attached?
allowed_types = %w[image/jpeg image/jpg image/png image/webp]
unless allowed_types.include?(image.content_type)
errors.add(:image, "doit être au format JPG, PNG ou WebP")
end
end
# Validate image size
def image_size
return unless image.attached?
if image.byte_size > 5.megabytes
errors.add(:image, "doit faire moins de 5MB")
end
end
private
# Determine if we should perform server-side geocoding