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:
@@ -60,9 +60,38 @@
|
||||
</div>
|
||||
|
||||
<div class="mt-6">
|
||||
<%= form.label :image, "Image (URL)", class: "block text-sm font-medium text-gray-700 mb-2" %>
|
||||
<%= form.url_field :image, class: "w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent", placeholder: "https://example.com/image.jpg" %>
|
||||
<p class="mt-1 text-sm text-gray-500">URL de l'image de couverture de l'événement</p>
|
||||
<%= form.label :image, "Image de couverture", class: "block text-sm font-medium text-gray-700 mb-2" %>
|
||||
<div class="space-y-4">
|
||||
<!-- Current image preview (for edit mode) -->
|
||||
<% if @event.image.attached? %>
|
||||
<div class="relative">
|
||||
<%= image_tag @event.image.variant(resize_to_limit: [400, 225]), class: "w-full h-48 object-cover rounded-lg border border-gray-200" %>
|
||||
<div class="absolute top-2 right-2">
|
||||
<button type="button" onclick="this.closest('div').previousElementSibling.querySelector('input[type=file]').click()" class="bg-red-500 text-white p-2 rounded-full hover:bg-red-600 transition-colors">
|
||||
<i data-lucide="trash-2" class="w-4 h-4"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<!-- File upload field -->
|
||||
<div class="relative">
|
||||
<%= form.file_field :image, class: "w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent file:mr-4 file:py-2 file:px-4 file:rounded-lg file:border-0 file:text-sm file:font-semibold file:bg-purple-50 file:text-purple-700 hover:file:bg-purple-100", accept: "image/png,image/jpeg,image/jpg,image/webp", data: { action: "change->event-form#previewImage" } %>
|
||||
<div class="mt-1 text-sm text-gray-500">
|
||||
Formats acceptés : PNG, JPG, JPEG, WebP (max 5MB)
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Image preview container -->
|
||||
<div id="image-preview" class="hidden">
|
||||
<div class="relative">
|
||||
<img id="preview-img" src="" alt="Preview" class="w-full h-48 object-cover rounded-lg border border-gray-200">
|
||||
<button type="button" onclick="document.getElementById('event_image').value = ''; document.getElementById('image-preview').classList.add('hidden');" class="absolute top-2 right-2 bg-red-500 text-white p-2 rounded-full hover:bg-red-600 transition-colors">
|
||||
<i data-lucide="x" class="w-4 h-4"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user