feat: implement dynamic event display with party images and seed data

• Files changed: app/controllers/pages_controller.rb, app/models/party.rb, app/views/pages/home.html.erb, db/migrate/20250823145902_create_parties.rb, db/schema.rb, db/seeds.rb
• Nature of changes: Added image support to parties, updated homepage to dynamically display parties, enhanced seed data with parties and ticket types, schema updates for foreign keys
• Purpose: Enable dynamic event display on homepage with real data instead of static placeholders, add image support for parties, improve database relationships
• Impact: Homepage now shows real party data from database, parties can have images, database schema improved with proper foreign keys
• Commit message: feat: implement dynamic event display with party images and seed data
This commit is contained in:
kbe
2025-08-25 03:39:20 +02:00
parent 632055c44d
commit 6fbd24e36e
8 changed files with 798 additions and 68 deletions

View File

@@ -1,9 +1,15 @@
# Controller for static pages and user dashboard
# Handles basic page rendering and user-specific content
class PagesController < ApplicationController
# Require user authentication for dashboard access
# Redirects to login page if user is not signed in
before_action :authenticate_user!, only: [ :dashboard ]
# Skip authentication for public pages
# skip_before_action :authenticate_user!, only: [ :home ]
# Homepage showing featured parties
def home
# @parties = Party.published.featured.limit(3)
@parties = Party.where(state: :published).order(created_at: :desc)
puts @parties
end
# User dashboard showing personalized content
# Accessible only to authenticated users

View File

@@ -23,6 +23,7 @@ class Party < ApplicationRecord
validates :name, presence: true, length: { minimum: 3, maximum: 100 }
validates :description, presence: true, length: { minimum: 10, maximum: 1000 }
validates :state, presence: true, inclusion: { in: states.keys }
validates :image, length: { maximum: 500 } # URL or path to image
# Venue information
validates :venue_name, presence: true, length: { maximum: 100 }

View File

@@ -165,71 +165,33 @@
</div>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
<!-- Event Card 1 -->
<div class="bg-white border border-neutral-200 rounded-2xl overflow-hidden hover:transform hover:scale-105 transition-all duration-300 shadow-lg">
<div class="h-56 bg-gradient-to-br from-purple-500 via-pink-500 to-red-500 relative">
<div class="absolute top-4 right-4 bg-white bg-opacity-90 text-neutral-900 px-3 py-1 rounded-full text-sm font-medium">
Club
<% @parties.each do |party| %>
<div class="bg-white border border-neutral-200 rounded-2xl overflow-hidden hover:transform hover:scale-105 transition-all duration-300 shadow-lg">
<div class="h-56 bg-gradient-to-br from-purple-500 via-pink-500 to-red-500 relative"
style="background-image: url('<%= party.image || "https://images.unsplash.com/photo-1506157786151-b84b9d3d78d8?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80" %>');
background-size: cover;
background-position: center;">
<div class="absolute top-4 right-4 bg-white bg-opacity-90 text-neutral-900 px-3 py-1 rounded-full text-sm font-medium">
<%= party.venue_name.split(' ').first %>
</div>
</div>
<div class="p-6">
<div class="flex justify-between items-start mb-3">
<h3 class="text-2xl font-bold text-neutral-900"><%= party.name.upcase %></h3>
<% if party.ticket_types.any? %>
<span class="text-purple-600 font-semibold"><%= number_to_currency(party.ticket_types.first.price_cents / 100.0, unit: "€", separator: ",", delimiter: " ") %></span>
<% end %>
</div>
<p class="text-neutral-600 mb-2"><%= party.venue_name %>, <%= party.venue_address.split(',').first %></p>
<p class="text-neutral-700 mb-4"><%= I18n.l(party.start_time, format: "%A %Hh") if party.start_time %> • <%= party.description.split('.').first %></p>
<%= link_to "Réserver ma place", "#", class: "w-full bg-gradient-to-r from-purple-600 to-pink-600 hover:from-purple-700 hover:to-pink-700 text-white font-semibold py-3 rounded-lg transition-all duration-300 text-center block" %>
</div>
</div>
<div class="p-6">
<div class="flex justify-between items-start mb-3">
<h3 class="text-2xl font-bold text-neutral-900">TECHNO NIGHT</h3>
<span class="text-purple-600 font-semibold">25€</span>
</div>
<p class="text-neutral-600 mb-2">Rex Club, Paris 2ème</p>
<p class="text-neutral-700 mb-4">Vendredi 22h • Soirée techno underground</p>
<button class="w-full bg-gradient-to-r from-purple-600 to-pink-600 hover:from-purple-700 hover:to-pink-700 text-white font-semibold py-3 rounded-lg transition-all duration-300">
Réserver ma place
</button>
</div>
</div>
<!-- Event Card 2 -->
<div class="bg-white border border-neutral-200 rounded-2xl overflow-hidden hover:transform hover:scale-105 transition-all duration-300 shadow-lg">
<div class="h-56 bg-gradient-to-br from-blue-500 via-cyan-500 to-teal-500 relative">
<div class="absolute top-4 right-4 bg-white bg-opacity-90 text-neutral-900 px-3 py-1 rounded-full text-sm font-medium">
Afterwork
</div>
</div>
<div class="p-6">
<div class="flex justify-between items-start mb-3">
<h3 class="text-2xl font-bold text-neutral-900">SUNSET APÉRO</h3>
<span class="text-blue-600 font-semibold">15€</span>
</div>
<p class="text-neutral-600 mb-2">Nuba, Paris 13ème</p>
<p class="text-neutral-700 mb-4">Jeudi 18h • Apéro sur les quais</p>
<button class="w-full bg-gradient-to-r from-blue-600 to-cyan-600 hover:from-blue-700 hover:to-cyan-700 text-white font-semibold py-3 rounded-lg transition-all duration-300">
Réserver ma place
</button>
</div>
</div>
<!-- Event Card 3 -->
<div class="bg-white border border-neutral-200 rounded-2xl overflow-hidden hover:transform hover:scale-105 transition-all duration-300 shadow-lg">
<div class="h-56 bg-gradient-to-br from-green-500 via-emerald-500 to-teal-500 relative">
<div class="absolute top-4 right-4 bg-white bg-opacity-90 text-neutral-900 px-3 py-1 rounded-full text-sm font-medium">
Concert
</div>
</div>
<div class="p-6">
<div class="flex justify-between items-start mb-3">
<h3 class="text-2xl font-bold text-neutral-900">LIVE SESSION</h3>
<span class="text-green-600 font-semibold">20€</span>
</div>
<p class="text-neutral-600 mb-2">La Bellevilloise, Paris 20ème</p>
<p class="text-neutral-700 mb-4">Samedi 20h • Concert live acoustique</p>
<button class="w-full bg-gradient-to-r from-green-600 to-emerald-600 hover:from-green-700 hover:to-emerald-700 text-white font-semibold py-3 rounded-lg transition-all duration-300">
Réserver ma place
</button>
</div>
</div>
<% end %>
</div>
<div class="text-center mt-12">
<button class="text-purple-600 hover:text-purple-700 text-lg font-medium transition-all duration-300 border-b-2 border-purple-600 hover:border-purple-700">
Voir tous les événements →
</button>
<%= link_to "Voir tous les événements →", "#", class: "text-purple-600 hover:text-purple-700 text-lg font-medium transition-all duration-300 border-b-2 border-purple-600 hover:border-purple-700" %>
</div>
</div>
</section>