diff --git a/app/assets/stylesheets/application.postcss.css b/app/assets/stylesheets/application.postcss.css index 0b0fcf5..fbd7944 100755 --- a/app/assets/stylesheets/application.postcss.css +++ b/app/assets/stylesheets/application.postcss.css @@ -13,3 +13,16 @@ /* Import pages */ @import "pages/home"; + +/* QR Code Styles */ +.qr-code-container { + @apply flex items-center justify-center; +} + +.qr-code-container svg { + max-width: 100% !important; + max-height: 100% !important; + width: 208px !important; + height: 208px !important; + display: block !important; +} diff --git a/app/controllers/tickets_controller.rb b/app/controllers/tickets_controller.rb index 60b1763..704e2bd 100644 --- a/app/controllers/tickets_controller.rb +++ b/app/controllers/tickets_controller.rb @@ -3,7 +3,7 @@ # This controller now primarily handles legacy redirects and backward compatibility # Most ticket creation functionality has been moved to OrdersController class TicketsController < ApplicationController - before_action :authenticate_user!, only: [ :payment_success, :payment_cancel, :show, :download_ticket ] + before_action :authenticate_user!, only: [ :payment_success, :payment_cancel, :show, :ticket_view, :download_ticket ] before_action :set_event, only: [ :checkout, :retry_payment ] @@ -59,6 +59,23 @@ class TicketsController < ApplicationController redirect_to dashboard_path, alert: "Billet non trouvé" end + # Display ticket in PDF-like format + def ticket_view + @ticket = Ticket.joins(order: :user).includes(:event, :ticket_type, order: :user).find_by( + tickets: { id: params[:ticket_id] }, + orders: { user_id: current_user.id } + ) + + if @ticket.nil? + redirect_to dashboard_path, alert: "Billet non trouvé ou vous n'avez pas l'autorisation d'accéder à ce billet" + return + end + + @event = @ticket.event + rescue ActiveRecord::RecordNotFound + redirect_to dashboard_path, alert: "Billet non trouvé" + end + # Download PDF ticket - only accessible by ticket owner # User must be authenticated to download ticket # TODO: change ID to an unique identifier (UUID) diff --git a/app/views/tickets/show.html.erb b/app/views/tickets/show.html.erb index 203c55d..b22a0c6 100644 --- a/app/views/tickets/show.html.erb +++ b/app/views/tickets/show.html.erb @@ -1,46 +1,46 @@ -
+
-
+
-
+

Billet Électronique

ID: #<%= @ticket.id %>

-
"> - <%= + <%= case @ticket.status when 'active' then 'Valide' when 'draft' then 'En attente' @@ -58,47 +58,49 @@
-

Détails de l'événement

- -
+

Détails de l'événement

+ +
- -

<%= @event.name %>

+ +

<%= @event.name %>

- -
- - + +
+ + - <%= @event.start_time.strftime("%d %B %Y") %>
- <%= @event.start_time.strftime("%H:%M") %> +
+
<%= @event.start_time.strftime("%d %B %Y") %>
+
<%= @event.start_time.strftime("%H:%M") %>
+
- -
- - - + +
+ + + - <%= @event.venue_name %> + <%= @event.venue_name %>
- -

<%= @ticket.ticket_type.name %>

-

<%= @ticket.ticket_type.description %>

+ +

<%= @ticket.ticket_type.name %>

+

<%= @ticket.ticket_type.description %>

- -

+ +

<%= number_to_currency(@ticket.price_euros, unit: "€", separator: ",", delimiter: " ", format: "%n %u") %>

@@ -107,38 +109,36 @@
-

Informations du billet

- -
+

Informations du billet

+ +
- -

<%= @ticket.first_name %>

+ +

<%= @ticket.first_name %>

- -

<%= @ticket.last_name %>

+ +

<%= @ticket.last_name %>

- -

<%= @ticket.created_at.strftime("%d %B %Y à %H:%M") %>

+ +

<%= @ticket.created_at.strftime("%d %B %Y à %H:%M") %>

- -
-
- -
- - - + +
+
+
+ <%= raw @ticket.generate_qr_svg %>
-

<%= @ticket.qr_code %>

+

<%= @ticket.qr_code[0..7]... %>

+

Scannez ce code à l'entrée

@@ -146,21 +146,21 @@
-
+
- <%= link_to dashboard_path, - class: "px-6 py-3 border border-gray-300 text-gray-700 rounded-xl hover:bg-gray-50 text-center font-medium transition-colors duration-200" do %> - - + <%= link_to dashboard_path, + class: "flex items-center justify-center px-6 py-3 border border-slate-300 text-slate-700 rounded-xl hover:bg-slate-50 hover:border-slate-400 font-medium transition-all duration-200" do %> + + Retour au tableau de bord <% end %> <% if @ticket.status == 'active' %> <%= link_to download_ticket_path(@ticket.id), - class: "flex-1 bg-gradient-to-r from-purple-600 to-indigo-600 hover:from-purple-700 hover:to-indigo-700 text-white font-medium py-3 px-6 rounded-xl shadow-sm transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:ring-offset-2 transform hover:-translate-y-0.5 text-center" do %> - - + class: "flex-1 flex items-center justify-center bg-gradient-to-r from-purple-600 to-violet-600 hover:from-purple-700 hover:to-violet-700 text-white font-medium py-3 px-6 rounded-xl shadow-sm hover:shadow-md transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:ring-offset-2 transform hover:-translate-y-0.5" do %> + + Télécharger le PDF <% end %> @@ -169,17 +169,26 @@
-
+
- - + +
-

Informations importantes

-
    -
  • • Présentez ce billet (ou son code QR) à l'entrée de l'événement
  • -
  • • Arrivez en avance pour éviter les files d'attente
  • -
  • • En cas de problème, contactez l'organisateur
  • +

    Informations importantes

    +
      +
    • + + Présentez ce billet (ou son code QR) à l'entrée de l'événement +
    • +
    • + + Arrivez en avance pour éviter les files d'attente +
    • +
    • + + En cas de problème, contactez l'organisateur +
diff --git a/app/views/tickets/ticket_view.html.erb b/app/views/tickets/ticket_view.html.erb new file mode 100644 index 0000000..0903967 --- /dev/null +++ b/app/views/tickets/ticket_view.html.erb @@ -0,0 +1,118 @@ +<% content_for :title, "Billet ##{@ticket.id} - #{@ticket.event.name}" %> + +
+
+ +
+ +
+

ApéroNight

+
+
+ + +
+

<%= @ticket.event.name %>

+
+ + +
+ +
+ Porteur du billet: + <%= @ticket.first_name %> <%= @ticket.last_name %> +
+ + +
+ Type de billet: + <%= @ticket.ticket_type.name %> +
+ + +
+ Prix: + + <%= number_to_currency(@ticket.price_euros, unit: "€", separator: ",", delimiter: " ", format: "%n %u") %> + +
+ + +
+ Date & Heure: +
+
<%= @ticket.event.start_time.strftime("%d %B %Y") %>
+
<%= @ticket.event.start_time.strftime("%H:%M") %>
+
+
+ + +
+ Lieu : +
<%= @ticket.event.venue_name %>
+ <% if @ticket.event.venue_address.present? %> +
<%= @ticket.event.venue_address %>
+ <% end %> +
+
+ + +
+

Code QR du billet

+
+
+ <%= raw @ticket.generate_qr_svg %> +
+
+

QR: <%= @ticket.qr_code[0..7] %>...

+
+ + +
+
+

Ce billet est valide pour une seule entrée.

+

Présentez ce billet à l'entrée du lieu.

+
+

+ Généré le <%= Time.current.strftime('%d %B %Y à %H:%M') %> +

+
+
+
+ + +
+
+ <%= link_to ticket_path(@ticket), + class: "flex-1 flex items-center justify-center bg-slate-100 hover:bg-slate-200 text-slate-700 py-2.5 px-3 rounded-lg text-sm font-medium transition-colors duration-200" do %> + + + + + Vue détaillée + <% end %> + + <% if @ticket.status == 'active' %> + <%= link_to download_ticket_path(@ticket.id), + class: "flex-1 flex items-center justify-center bg-purple-600 hover:bg-purple-700 text-white py-2.5 px-3 rounded-lg text-sm font-medium transition-colors duration-200 shadow-sm hover:shadow-md" do %> + + + + PDF + <% end %> + <% end %> +
+
+
+ + +
+ <%= link_to dashboard_path, class: "inline-flex items-center text-purple-600 hover:text-purple-800 text-sm font-medium transition-colors duration-200" do %> + + + + Retour au tableau de bord + <% end %> +
+
+
\ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index ed528a3..d1b3a7b 100755 --- a/config/routes.rb +++ b/config/routes.rb @@ -61,6 +61,7 @@ Rails.application.routes.draw do get "tickets/checkout/events/:slug.:id", to: "tickets#checkout", as: "ticket_checkout" post "tickets/retry/events/:slug.:id", to: "tickets#retry_payment", as: "ticket_retry_payment" get "tickets/:ticket_id", to: "tickets#show", as: "ticket" + get "tickets/:ticket_id/view", to: "tickets#ticket_view", as: "ticket_view" get "tickets/:ticket_id/download", to: "tickets#download_ticket", as: "download_ticket" # === Promoter Routes ===