Files
aperonight/app/views/events/show.html.erb
kbe 04393add14 fix(tests): Remove service fee expectation from Stripe invoice test and fix duplicated keys in event view
- Update StripeInvoiceServiceTest to match the implementation that no longer adds service fees to customer invoices
- Remove duplicated Stimulus data attributes in events/show.html.erb that were causing warnings
- Align tests with the hybrid fee model where fees are deducted from promoter payouts
2025-09-16 17:22:00 +02:00

197 lines
9.9 KiB
Plaintext
Executable File

<div class="min-h-screen bg-gradient-to-br from-gray-50 to-gray-100">
<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: 'Événements', path: events_path },
{ name: @event.name, path: nil }
] %>
<!-- Event main wrapper -->
<div class="bg-white rounded-2xl shadow-xl overflow-hidden">
<!-- Event Header with Image -->
<% if @event.image.present? %>
<div class="relative h-96">
<%= image_tag @event.image, class: "w-full h-full object-cover" %>
<div class="absolute inset-0 bg-gradient-to-t from-black via-black/70 to-transparent"></div>
<div class="absolute bottom-0 left-0 right-0 p-6 md:p-8">
<div class="max-w-4xl mx-auto">
<h1 class="text-3xl md:text-4xl font-bold text-white mb-2 text-center md:text-left"><%= @event.name %></h1>
</div>
</div>
</div>
<% else %>
<div class="bg-gradient-to-r from-purple-600 to-indigo-700 p-8">
<h1 class="text-3xl md:text-4xl font-bold text-white mb-4"><%= @event.name %></h1>
<div class="flex flex-wrap items-center gap-4 text-white/90">
<div class="flex items-center">
<i data-lucide="map-pin" class="w-5 h-5 mr-2 text-purple-200"></i>
<span><%= @event.venue_name %></span>
</div>
<div class="flex items-center">
<i data-lucide="clock" class="w-5 h-5 mr-2 text-purple-200"></i>
<span><%= @event.start_time.strftime("%d %B %Y à %H:%M") %></span>
</div>
</div>
</div>
<% end %>
<!-- Event Content -->
<div class="p-6 md:p-8">
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
<!-- Left Column: Event Details -->
<div class="lg:col-span-2">
<div class="mb-8">
<h2 class="text-2xl font-bold text-gray-900 mb-4">Description</h2>
<div class="prose max-w-none text-gray-700">
<p class="text-lg leading-relaxed"><%= @event.description %></p>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-8">
<div class="bg-gray-50 rounded-xl p-6">
<h3 class="text-lg font-semibold text-gray-900 mb-4 flex items-center">
<i data-lucide="map-pin" class="w-5 h-5 mr-2 text-purple-600"></i>
Lieu
</h3>
<p class="text-gray-700 font-medium"><%= @event.venue_name %></p>
<p class="text-gray-600 mt-2 mb-4"><%= @event.venue_address %></p>
<% if @event.latitude.present? && @event.longitude.present? %>
<div class="border-t border-gray-200 pt-4">
<% if @event.geocoding_status_message %>
<div class="mb-3 p-2 bg-yellow-50 border border-yellow-200 rounded-lg">
<div class="flex items-center">
<i data-lucide="alert-triangle" class="w-4 h-4 text-yellow-600 mr-2"></i>
<p class="text-xs text-yellow-800"><%= @event.geocoding_status_message %></p>
</div>
</div>
<% end %>
<p class="text-sm font-medium text-gray-700 mb-2">Ouvrir dans :</p>
<div class="flex flex-wrap gap-2">
<%
encoded_address = URI.encode_www_form_component(@event.venue_address)
lat = @event.latitude
lng = @event.longitude
map_providers = {
"OpenStreetMap" => "https://www.openstreetmap.org/?mlat=#{lat}&mlon=#{lng}#map=16/#{lat}/#{lng}",
"Google Maps" => "https://www.google.com/maps/search/#{encoded_address}/@#{lat},#{lng},16z",
"Apple Plans" => "https://maps.apple.com/?address=#{encoded_address}&ll=#{lat},#{lng}"
}
icons = {
"OpenStreetMap" => "🗺️",
"Google Maps" => "🔍",
"Apple Plans" => "🍎"
}
%>
<% map_providers.each do |name, url| %>
<%= link_to url, target: "_blank", rel: "noopener",
class: "inline-flex items-center px-3 py-2 text-xs font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors" do %>
<span class="mr-1"><%= icons[name] %></span>
<%= name %>
<% end %>
<% end %>
</div>
</div>
<% end %>
</div>
<div class="bg-gray-50 rounded-xl p-6">
<h3 class="text-lg font-semibold text-gray-900 mb-4 flex items-center">
<i data-lucide="clock" class="w-5 h-5 mr-2 text-purple-600"></i>
Date & Heure
</h3>
<p class="text-gray-700 font-medium"><%= @event.start_time.strftime("%A %d %B %Y") %></p>
<p class="text-gray-600 mt-1">À <%= @event.start_time.strftime("%H:%M") %></p>
</div>
</div>
<div class="mb-8 bg-gray-50 rounded-xl p-6">
<h3 class="text-lg font-semibold text-gray-900 mb-4">Organisateur</h3>
<div class="flex items-center">
<div class="w-12 h-12 rounded-full bg-purple-500 flex items-center justify-center text-white font-bold">
<%= @event.user.email.first.upcase %>
</div>
<div class="ml-4">
<% if @event.user.first_name.present? && @event.user.last_name.present? %>
<p class="font-medium text-gray-900"><%= @event.user.first_name %> <%= @event.user.last_name %></p>
<% else %>
<p class="font-medium text-gray-900"><%= @event.user.email.split("@").first %></p>
<% end %>
<% if @event.user.company_name.present? %>
<p class="text-sm text-gray-500"><%= @event.user.company_name %></p>
<% end %>
</div>
</div>
</div>
</div>
<!-- Right Column: Ticket Selection -->
<div class="lg:col-span-1">
<%= form_with url: event_order_new_path(@event.slug, @event.id), method: :get, id: "checkout_form", local: true, data: {
controller: "ticket-selection",
ticket_selection_target: "form",
ticket_selection_event_slug_value: @event.slug,
ticket_selection_event_id_value: @event.id,
ticket_selection_order_new_url_value: event_order_new_path(@event.slug, @event.id),
ticket_selection_store_cart_url_value: api_v1_store_cart_path
} do |form| %>
<div class="bg-gradient-to-br from-purple-50 to-indigo-50 rounded-2xl border border-purple-100 p-6 shadow-sm">
<div class="flex justify-center sm:justify-start mb-6">
<h2 class="text-lg font-bold text-gray-900">Billets disponibles</h2>
</div>
<div>
<% if @event.ticket_types.any? %>
<div class="space-y-4 mb-6">
<% @event.ticket_types.each do |ticket_type| %>
<% sold_out = ticket_type.quantity <= ticket_type.tickets.count %>
<% remaining = ticket_type.quantity - ticket_type.tickets.count %>
<%= render "components/ticket_card", {
id: ticket_type.id,
name: ticket_type.name,
description: ticket_type.description,
price_cents: ticket_type.price_cents,
quantity: ticket_type.quantity,
sold_out: sold_out,
remaining: remaining,
} %>
<% end %>
</div>
<% else %>
<div class="text-center py-8">
<i data-lucide="ticket" class="w-12 h-12 mx-auto text-gray-400"></i>
<h3 class="mt-4 text-lg font-medium text-gray-900">Aucun billet disponible</h3>
<p class="mt-2 text-gray-500">Les billets pour cet événement ne sont pas encore disponibles ou sont épuisés.</p>
</div>
<% end %>
<!-- Cart Summary -->
<div class="border-t border-gray-200 pt-6 mt-6">
<div class="flex justify-between items-center mb-2">
<span class="text-gray-600">Quantité :</span>
<span class="font-medium" data-ticket-selection-target="totalQuantity">0</span>
</div>
<div class="flex justify-between items-center mb-4">
<span class="text-gray-600">Montant total :</span>
<span class="text-xl font-bold text-purple-700" data-ticket-selection-target="totalAmount">€0.00</span>
</div>
<%= form.button "Procéder au paiement", type: "submit",
data: { ticket_selection_target: "checkoutButton" },
class: "w-full btn btn-primary py-3 px-4 rounded-xl shadow-sm transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:ring-offset-2 flex items-center justify-center opacity-50 cursor-not-allowed" %>
</div>
</div>
</div>
<% end %>
</div>
</div>
</div>
</div>
</div>
</div>