- Restructure header layout with separated title and action buttons - Make all action buttons full-width on mobile (w-full sm:w-auto) - Add responsive text sizing and proper truncation for long titles - Improve status banners with flexible layouts for mobile - Enhance content cards with responsive padding (p-4 sm:p-6) - Add better text wrapping and overflow handling throughout - Optimize sidebar with responsive font sizes and spacing - Ensure consistent touch targets and button accessibility 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
286 lines
14 KiB
Plaintext
286 lines
14 KiB
Plaintext
<% content_for(:title, @event.name) %>
|
|
|
|
<div class="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
|
|
|
<!-- Breadcrumb -->
|
|
<%= render 'components/breadcrumb', crumbs: [
|
|
{ name: 'Accueil', path: root_path },
|
|
{ name: 'Tableau de bord', path: dashboard_path },
|
|
{ name: 'Mes événements', path: promoter_events_path },
|
|
{ name: @event.name }
|
|
] %>
|
|
|
|
<!-- Header with actions -->
|
|
<div class="mb-8">
|
|
<!-- Back button and title -->
|
|
<div class="flex items-center space-x-4 mb-6">
|
|
<%= link_to promoter_events_path, class: "text-gray-400 hover:text-gray-600 transition-colors flex-shrink-0" do %>
|
|
<i data-lucide="arrow-left" class="w-5 h-5"></i>
|
|
<% end %>
|
|
<div class="min-w-0 flex-1">
|
|
<h1 class="text-2xl sm:text-3xl font-bold text-gray-900 mb-2 truncate"><%= @event.name %></h1>
|
|
<div class="flex flex-col sm:flex-row sm:items-center gap-2 sm:gap-4 text-sm text-gray-500">
|
|
<span class="flex items-center">
|
|
<i data-lucide="calendar" class="w-4 h-4 mr-1 flex-shrink-0"></i>
|
|
<span class="truncate"><%= @event.start_time&.strftime("%d/%m/%Y à %H:%M") || "Date non définie" %></span>
|
|
</span>
|
|
<span class="flex items-center">
|
|
<i data-lucide="map-pin" class="w-4 h-4 mr-1 flex-shrink-0"></i>
|
|
<span class="truncate"><%= @event.venue_name %></span>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Action buttons -->
|
|
<div class="flex flex-col sm:flex-row gap-3">
|
|
<%= link_to edit_promoter_event_path(@event), class: "w-full sm:w-auto inline-flex items-center justify-center px-4 py-2 bg-white border border-gray-300 text-gray-700 font-medium rounded-lg hover:bg-gray-50 transition-colors duration-200" do %>
|
|
<i data-lucide="edit" class="w-4 h-4 mr-2"></i>
|
|
Modifier
|
|
<% end %>
|
|
|
|
<% if @event.draft? %>
|
|
<% if @event.ticket_types.blank? %>
|
|
<%= button_to publish_promoter_event_path(@event), method: :patch, disabled: true, class: "w-full sm:w-auto inline-flex items-center justify-center px-4 py-2 bg-gray-400 text-white font-medium rounded-lg cursor-not-allowed transition-colors duration-200", title: "Vous devez créer au moins un type de billet avant de publier" do %>
|
|
<i data-lucide="upload" class="w-4 h-4 mr-2"></i>
|
|
Publier
|
|
<% end %>
|
|
<% else %>
|
|
<%= button_to publish_promoter_event_path(@event), method: :patch, class: "w-full sm:w-auto inline-flex items-center justify-center px-4 py-2 bg-green-600 text-white font-medium rounded-lg hover:bg-green-700 transition-colors duration-200" do %>
|
|
<i data-lucide="upload" class="w-4 h-4 mr-2"></i>
|
|
Publier
|
|
<% end %>
|
|
<% end %>
|
|
<% elsif @event.published? %>
|
|
<%= button_to unpublish_promoter_event_path(@event), method: :patch, class: "w-full sm:w-auto inline-flex items-center justify-center px-4 py-2 bg-yellow-600 text-white font-medium rounded-lg hover:bg-yellow-700 transition-colors duration-200" do %>
|
|
<i data-lucide="download" class="w-4 h-4 mr-2"></i>
|
|
Dépublier
|
|
<% end %>
|
|
<% end %>
|
|
|
|
<% if @event.published? %>
|
|
<%= button_to cancel_promoter_event_path(@event), method: :patch, class: "w-full sm:w-auto inline-flex items-center justify-center px-4 py-2 bg-red-600 text-white font-medium rounded-lg hover:bg-red-700 transition-colors duration-200", data: { confirm: "Êtes-vous sûr de vouloir annuler cet événement ?" } do %>
|
|
<i data-lucide="x-circle" class="w-4 h-4 mr-2"></i>
|
|
Annuler
|
|
<% end %>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Status banner -->
|
|
<div class="mb-8">
|
|
<% case @event.state %>
|
|
<% when "draft" %>
|
|
<div class="bg-gray-50 border border-gray-200 rounded-2xl p-4">
|
|
<div class="flex items-center">
|
|
<i data-lucide="edit-3" class="w-5 h-5 text-gray-400 mr-3"></i>
|
|
<div>
|
|
<h3 class="text-sm font-medium text-gray-900">Événement en brouillon</h3>
|
|
<p class="text-sm text-gray-500">Cet événement n'est pas visible publiquement. Publiez-le pour le rendre accessible aux utilisateurs.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<% if @event.ticket_types.blank? %>
|
|
<div class="bg-amber-50 border border-amber-200 rounded-2xl p-4 mt-4">
|
|
<div class="flex flex-col sm:flex-row sm:items-center gap-3">
|
|
<i data-lucide="alert-triangle" class="w-5 h-5 text-amber-400 flex-shrink-0"></i>
|
|
<div class="flex-1 min-w-0">
|
|
<h3 class="text-sm font-medium text-amber-900">Aucun type de billet configuré</h3>
|
|
<p class="text-sm text-amber-700">Vous devez créer au moins un type de billet avant de pouvoir publier cet événement.</p>
|
|
</div>
|
|
<div class="flex-shrink-0">
|
|
<%= link_to promoter_event_ticket_types_path(@event), class: "text-amber-600 hover:text-amber-800 font-medium text-sm whitespace-nowrap" do %>
|
|
Configurer les billets <i data-lucide="external-link" class="w-4 h-4 inline ml-1"></i>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<% end %>
|
|
<% when "published" %>
|
|
<div class="bg-green-50 border border-green-200 rounded-2xl p-4">
|
|
<div class="flex flex-col sm:flex-row sm:items-center gap-3">
|
|
<i data-lucide="eye" class="w-5 h-5 text-green-400 flex-shrink-0"></i>
|
|
<div class="flex-1 min-w-0">
|
|
<h3 class="text-sm font-medium text-green-900">Événement publié</h3>
|
|
<p class="text-sm text-green-700">Cet événement est visible publiquement et les utilisateurs peuvent acheter des billets.</p>
|
|
</div>
|
|
<div class="flex-shrink-0">
|
|
<%= link_to event_path(@event.slug, @event), target: "_blank", class: "text-green-600 hover:text-green-800 font-medium text-sm whitespace-nowrap" do %>
|
|
Voir publiquement <i data-lucide="external-link" class="w-4 h-4 inline ml-1"></i>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<% when "canceled" %>
|
|
<div class="bg-red-50 border border-red-200 rounded-2xl p-4">
|
|
<div class="flex items-center">
|
|
<i data-lucide="x-circle" class="w-5 h-5 text-red-400 mr-3"></i>
|
|
<div>
|
|
<h3 class="text-sm font-medium text-red-900">Événement annulé</h3>
|
|
<p class="text-sm text-red-700">Cet événement a été annulé et n'est plus accessible aux utilisateurs.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<% when "sold_out" %>
|
|
<div class="bg-blue-50 border border-blue-200 rounded-2xl p-4">
|
|
<div class="flex items-center">
|
|
<i data-lucide="users" class="w-5 h-5 text-blue-400 mr-3"></i>
|
|
<div>
|
|
<h3 class="text-sm font-medium text-blue-900">Événement complet</h3>
|
|
<p class="text-sm text-blue-700">Tous les billets pour cet événement ont été vendus.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<% end %>
|
|
|
|
<% if @event.featured? %>
|
|
<div class="bg-yellow-50 border border-yellow-200 rounded-2xl p-4 mt-4">
|
|
<div class="flex items-center">
|
|
<i data-lucide="star" class="w-5 h-5 text-yellow-400 mr-3"></i>
|
|
<div>
|
|
<h3 class="text-sm font-medium text-yellow-900">Événement à la une</h3>
|
|
<p class="text-sm text-yellow-700">Cet événement est mis en avant sur la page d'accueil.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<% end %>
|
|
|
|
<% if @event.published? && @event.event_started? && !@event.allow_booking_during_event? %>
|
|
<div class="bg-orange-50 border border-orange-200 rounded-2xl p-4 mt-4">
|
|
<div class="flex items-center">
|
|
<i data-lucide="clock" class="w-5 h-5 text-orange-400 mr-3"></i>
|
|
<div>
|
|
<h3 class="text-sm font-medium text-orange-900">Réservations fermées</h3>
|
|
<p class="text-sm text-orange-700">L'événement a commencé et les nouvelles réservations sont désactivées.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
|
|
<!-- Event details -->
|
|
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6 lg:gap-8">
|
|
<!-- Main content -->
|
|
<div class="lg:col-span-2 space-y-6 lg:space-y-8">
|
|
<!-- Event image -->
|
|
<% if @event.image.present? %>
|
|
<div class="aspect-video bg-gray-100 rounded-2xl overflow-hidden">
|
|
<img src="<%= @event.image %>" alt="<%= @event.name %>" class="w-full h-full object-cover">
|
|
</div>
|
|
<% end %>
|
|
|
|
<!-- Description -->
|
|
<div class="bg-white rounded-2xl border border-gray-200 p-4 sm:p-6">
|
|
<h3 class="text-lg font-semibold text-gray-900 mb-4">Description</h3>
|
|
<div class="prose prose-gray prose-sm sm:prose-base max-w-none">
|
|
<%= simple_format(@event.description) %>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Location details -->
|
|
<div class="bg-white rounded-2xl border border-gray-200 p-4 sm:p-6">
|
|
<h3 class="text-lg font-semibold text-gray-900 mb-4">Lieu</h3>
|
|
<div class="space-y-3">
|
|
<div class="flex items-start space-x-3">
|
|
<i data-lucide="building" class="w-5 h-5 text-gray-400 mt-0.5 flex-shrink-0"></i>
|
|
<div class="min-w-0 flex-1">
|
|
<p class="font-medium text-gray-900 break-words"><%= @event.venue_name %></p>
|
|
<p class="text-gray-500 break-words"><%= @event.venue_address %></p>
|
|
</div>
|
|
</div>
|
|
<div class="flex items-center space-x-3 text-sm text-gray-500">
|
|
<i data-lucide="map-pin" class="w-4 h-4 flex-shrink-0"></i>
|
|
<span class="break-all"><%= @event.latitude %>, <%= @event.longitude %></span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Sidebar -->
|
|
<div class="space-y-6">
|
|
<!-- Event stats -->
|
|
<div class="bg-white rounded-2xl border border-gray-200 p-4 sm:p-6">
|
|
<h3 class="text-lg font-semibold text-gray-900 mb-4">Statistiques</h3>
|
|
<div class="space-y-4">
|
|
<div class="flex items-center justify-between">
|
|
<span class="text-gray-500 text-sm sm:text-base">Types de billets</span>
|
|
<span class="font-medium"><%= @event.ticket_types.count %></span>
|
|
</div>
|
|
<div class="flex items-center justify-between">
|
|
<span class="text-gray-500 text-sm sm:text-base">Billets vendus</span>
|
|
<span class="font-medium"><%= @event.tickets.count %></span>
|
|
</div>
|
|
<div class="flex items-center justify-between">
|
|
<span class="text-gray-500 text-sm sm:text-base">Revenus</span>
|
|
<span class="font-medium text-sm sm:text-base">
|
|
<%= number_to_currency(@event.tickets.sum(:price_cents) / 100.0, unit: "€") %>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Event info -->
|
|
<div class="bg-white rounded-2xl border border-gray-200 p-4 sm:p-6">
|
|
<h3 class="text-lg font-semibold text-gray-900 mb-4">Informations</h3>
|
|
<div class="space-y-4">
|
|
<div>
|
|
<span class="text-sm text-gray-500">Créé le</span>
|
|
<p class="text-sm break-words"><%= @event.created_at.strftime("%d/%m/%Y à %H:%M") %></p>
|
|
</div>
|
|
<div>
|
|
<span class="text-sm text-gray-500">Modifié le</span>
|
|
<p class="text-sm break-words"><%= @event.updated_at.strftime("%d/%m/%Y à %H:%M") %></p>
|
|
</div>
|
|
<div>
|
|
<span class="text-sm text-gray-500">Réservation pendant l'événement</span>
|
|
<p class="text-sm flex items-center">
|
|
<% if @event.allow_booking_during_event? %>
|
|
<i data-lucide="check-circle" class="w-4 h-4 text-green-500 mr-1 flex-shrink-0"></i>
|
|
Autorisée
|
|
<% else %>
|
|
<i data-lucide="x-circle" class="w-4 h-4 text-red-500 mr-1 flex-shrink-0"></i>
|
|
Interdite
|
|
<% end %>
|
|
</p>
|
|
</div>
|
|
<% if @event.start_time %>
|
|
<div>
|
|
<span class="text-sm text-gray-500">Début</span>
|
|
<p class="text-sm break-words"><%= @event.start_time.strftime("%d/%m/%Y à %H:%M") %></p>
|
|
</div>
|
|
<% end %>
|
|
<% if @event.end_time %>
|
|
<div>
|
|
<span class="text-sm text-gray-500">Fin</span>
|
|
<p class="text-sm break-words"><%= @event.end_time.strftime("%d/%m/%Y à %H:%M") %></p>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Quick actions -->
|
|
<div class="bg-white rounded-2xl border border-gray-200 p-4 sm:p-6">
|
|
<h3 class="text-lg font-semibold text-gray-900 mb-4">Actions rapides</h3>
|
|
<div class="space-y-3">
|
|
<%= link_to promoter_event_ticket_types_path(@event), class: "w-full inline-flex items-center justify-center px-4 py-3 bg-purple-600 text-white font-medium text-sm rounded-lg hover:bg-purple-700 transition-colors duration-200" do %>
|
|
<i data-lucide="ticket" class="w-4 h-4 mr-2"></i>
|
|
Gérer les types de billets
|
|
<% end %>
|
|
<%= button_to mark_sold_out_promoter_event_path(@event), method: :patch, class: "w-full inline-flex items-center justify-center px-4 py-3 bg-gray-50 text-gray-700 font-medium text-sm rounded-lg hover:bg-gray-100 transition-colors duration-200", disabled: !@event.published? do %>
|
|
<i data-lucide="users" class="w-4 h-4 mr-2"></i>
|
|
Marquer comme complet
|
|
<% end %>
|
|
<hr class="border-gray-200">
|
|
<%= button_to promoter_event_path(@event), method: :delete,
|
|
data: { confirm: "Êtes-vous sûr de vouloir supprimer cet événement ? Cette action est irréversible." },
|
|
class: "w-full inline-flex items-center justify-center px-4 py-3 text-red-600 font-medium text-sm rounded-lg hover:bg-red-50 transition-colors duration-200" do %>
|
|
<i data-lucide="trash-2" class="w-4 h-4 mr-2"></i>
|
|
Supprimer l'événement
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|