Files
aperonight/app/views/promoter/events/index.html.erb
kbe aa5dccb508 feat: Implement comprehensive event management system for promoters
This commit adds a complete event management interface allowing promoters to 
create, edit, and manage their events with full CRUD operations.

## Backend Features
- New Promoter::EventsController with full CRUD operations
- Event state management (draft, published, canceled, sold_out)
- User authorization system with can_manage_events? method
- Proper scoping to ensure users only see their own events

## Frontend Features  
- Modern responsive UI with Tailwind CSS styling
- Event listing with status indicators and quick actions
- Comprehensive event creation and editing forms
- Detailed event show page with metrics and management options
- Integration with main dashboard via promoter action buttons

## JavaScript Improvements
- Refactored inline JavaScript to dedicated Stimulus controller
- Auto-slug generation from event names with proper sanitization
- Improved code organization following Rails conventions

## Routes & Navigation
- Namespaced promoter routes under /promoter/
- RESTful endpoints with state management actions
- Proper breadcrumb navigation and user flow

## Files Added/Modified
- app/controllers/promoter/events_controller.rb (new)
- app/javascript/controllers/event_form_controller.js (new) 
- app/views/promoter/events/*.html.erb (4 new view files)
- app/models/user.rb (added authorization methods)
- app/views/pages/dashboard.html.erb (added promoter buttons)
- config/routes.rb (added promoter namespace)
- app/javascript/controllers/index.js (registered new controller)

🎯 Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2025-08-31 19:22:19 +02:00

136 lines
7.3 KiB
Plaintext

<% content_for(:title, "Mes événements") %>
<div class="container py-8">
<div class="mb-8 flex items-center justify-between">
<div>
<h1 class="text-3xl font-bold text-gray-900 mb-2">Mes événements</h1>
<p class="text-gray-600">Gérez tous vos événements depuis cette interface</p>
</div>
<%= link_to new_promoter_event_path, class: "inline-flex items-center px-6 py-3 bg-black text-white font-medium rounded-lg hover:bg-gray-800 transition-colors duration-200" do %>
<i data-lucide="plus" class="w-4 h-4 mr-2"></i>
Créer un événement
<% end %>
</div>
<% if @events.any? %>
<div class="bg-white rounded-lg shadow-sm border border-gray-200 overflow-hidden">
<div class="overflow-x-auto">
<table class="w-full">
<thead class="bg-gray-50 border-b border-gray-200">
<tr>
<th class="px-6 py-4 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Événement</th>
<th class="px-6 py-4 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Statut</th>
<th class="px-6 py-4 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Date</th>
<th class="px-6 py-4 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Lieu</th>
<th class="px-6 py-4 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Actions</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
<% @events.each do |event| %>
<tr class="hover:bg-gray-50 transition-colors duration-150">
<td class="px-6 py-4">
<div class="flex items-center">
<div class="h-12 w-12 rounded-lg bg-gradient-to-br from-purple-500 to-pink-500 flex items-center justify-center flex-shrink-0">
<i data-lucide="calendar" class="w-6 h-6 text-white"></i>
</div>
<div class="ml-4">
<div class="text-sm font-medium text-gray-900">
<%= link_to event.name, promoter_event_path(event), class: "hover:text-purple-600 transition-colors" %>
</div>
<div class="text-sm text-gray-500 truncate max-w-xs">
<%= event.description.truncate(60) %>
</div>
</div>
</div>
</td>
<td class="px-6 py-4">
<% case event.state %>
<% when "draft" %>
<span class="inline-flex px-2 py-1 text-xs font-semibold rounded-full bg-gray-100 text-gray-800">
<i data-lucide="edit-3" class="w-3 h-3 mr-1"></i>
Brouillon
</span>
<% when "published" %>
<span class="inline-flex px-2 py-1 text-xs font-semibold rounded-full bg-green-100 text-green-800">
<i data-lucide="eye" class="w-3 h-3 mr-1"></i>
Publié
</span>
<% when "canceled" %>
<span class="inline-flex px-2 py-1 text-xs font-semibold rounded-full bg-red-100 text-red-800">
<i data-lucide="x-circle" class="w-3 h-3 mr-1"></i>
Annulé
</span>
<% when "sold_out" %>
<span class="inline-flex px-2 py-1 text-xs font-semibold rounded-full bg-blue-100 text-blue-800">
<i data-lucide="users" class="w-3 h-3 mr-1"></i>
Complet
</span>
<% end %>
<% if event.featured? %>
<span class="inline-flex px-2 py-1 text-xs font-semibold rounded-full bg-yellow-100 text-yellow-800 ml-1">
<i data-lucide="star" class="w-3 h-3 mr-1"></i>
À la une
</span>
<% end %>
</td>
<td class="px-6 py-4 text-sm text-gray-500">
<% if event.start_time %>
<div><%= event.start_time.strftime("%d/%m/%Y") %></div>
<div class="text-xs text-gray-400"><%= event.start_time.strftime("%H:%M") %></div>
<% else %>
<span class="text-gray-400">Date non définie</span>
<% end %>
</td>
<td class="px-6 py-4 text-sm text-gray-500">
<div><%= event.venue_name %></div>
<div class="text-xs text-gray-400 truncate max-w-xs"><%= event.venue_address %></div>
</td>
<td class="px-6 py-4">
<div class="flex items-center space-x-2">
<%= link_to promoter_event_path(event), class: "text-gray-400 hover:text-gray-600 transition-colors", title: "Voir" do %>
<i data-lucide="eye" class="w-4 h-4"></i>
<% end %>
<%= link_to edit_promoter_event_path(event), class: "text-gray-400 hover:text-blue-600 transition-colors", title: "Modifier" do %>
<i data-lucide="edit" class="w-4 h-4"></i>
<% end %>
<% if event.draft? %>
<%= button_to publish_promoter_event_path(event), method: :patch, class: "text-gray-400 hover:text-green-600 transition-colors", title: "Publier" do %>
<i data-lucide="upload" class="w-4 h-4"></i>
<% end %>
<% elsif event.published? %>
<%= button_to unpublish_promoter_event_path(event), method: :patch, class: "text-gray-400 hover:text-yellow-600 transition-colors", title: "Dépublier" do %>
<i data-lucide="download" class="w-4 h-4"></i>
<% end %>
<% end %>
<%= button_to promoter_event_path(event), method: :delete,
data: { confirm: "Êtes-vous sûr de vouloir supprimer cet événement ?" },
class: "text-gray-400 hover:text-red-600 transition-colors", title: "Supprimer" do %>
<i data-lucide="trash-2" class="w-4 h-4"></i>
<% end %>
</div>
</td>
</tr>
<% end %>
</tbody>
</table>
</div>
</div>
<div class="mt-6">
<%= paginate @events if respond_to?(:paginate) %>
</div>
<% else %>
<div class="bg-white rounded-lg border-2 border-dashed border-gray-300 p-12 text-center">
<div class="mx-auto h-24 w-24 rounded-full bg-gray-100 flex items-center justify-center mb-6">
<i data-lucide="calendar-plus" class="w-12 h-12 text-gray-400"></i>
</div>
<h3 class="text-xl font-semibold text-gray-900 mb-2">Aucun événement</h3>
<p class="text-gray-500 mb-6">Vous n'avez pas encore créé d'événement. Commencez dès maintenant !</p>
<%= link_to new_promoter_event_path, class: "inline-flex items-center px-6 py-3 bg-black text-white font-medium rounded-lg hover:bg-gray-800 transition-colors duration-200" do %>
<i data-lucide="plus" class="w-4 h-4 mr-2"></i>
Créer mon premier événement
<% end %>
</div>
<% end %>
</div>